diff --git a/Trigger/TrigT1/TrigT1CaloByteStream/src/CpByteStreamV2Tool.cxx b/Trigger/TrigT1/TrigT1CaloByteStream/src/CpByteStreamV2Tool.cxx
index 6aba09b6d753d159826cd546ee1c9fd063bae554..7b244a24693472ad9bed087d0cbdcbb0ee6602f3 100755
--- a/Trigger/TrigT1/TrigT1CaloByteStream/src/CpByteStreamV2Tool.cxx
+++ b/Trigger/TrigT1/TrigT1CaloByteStream/src/CpByteStreamV2Tool.cxx
@@ -196,10 +196,10 @@ StatusCode CpByteStreamV2Tool::convert(const LVL1::CPBSCollectionV2 *const cp,
 
     FullEventAssembler<L1CaloSrcIdMap>::RODDATA *theROD = 0;
 
-    // Set up the container maps
-
     LVL1::TriggerTowerKey towerKey;
 
+    // Set up the container maps
+
     // CPM tower map
     ConstCpmTowerMap  ttMap;
     setupCpmTowerMap(cp->towers(), ttMap, towerKey);
diff --git a/Trigger/TrigT1/TrigT1CaloByteStream/src/JepByteStreamTool.cxx b/Trigger/TrigT1/TrigT1CaloByteStream/src/JepByteStreamTool.cxx
index 90c9f859ed060835c1bc013965f9699603fc2b17..c05177bf7e06fedc23c21f05f3f7c90330b61833 100755
--- a/Trigger/TrigT1/TrigT1CaloByteStream/src/JepByteStreamTool.cxx
+++ b/Trigger/TrigT1/TrigT1CaloByteStream/src/JepByteStreamTool.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 
@@ -20,7 +20,6 @@
 #include "TrigT1CaloEvent/JEPBSCollection.h"
 #include "TrigT1CaloEvent/JetElement.h"
 #include "TrigT1CaloUtils/DataError.h"
-#include "TrigT1CaloUtils/JetElementKey.h"
 #include "TrigT1CaloToolInterfaces/IL1CaloMappingTool.h"
 
 #include "CmmEnergySubBlock.h"
@@ -29,7 +28,6 @@
 #include "JemJetElement.h"
 #include "JemSubBlock.h"
 #include "L1CaloErrorByteStreamTool.h"
-#include "L1CaloSrcIdMap.h"
 #include "L1CaloSubBlock.h"
 #include "L1CaloUserHeader.h"
 #include "ModifySlices.h"
@@ -55,11 +53,8 @@ JepByteStreamTool::JepByteStreamTool(const std::string& type,
   : AthAlgTool(type, name, parent),
     m_jemMaps("LVL1::JemMappingTool/JemMappingTool"),
     m_errorTool("LVL1BS::L1CaloErrorByteStreamTool/L1CaloErrorByteStreamTool"),
-    m_channels(44), m_crates(2), m_modules(16), m_coreOverlap(0),
-    m_subDetector(eformat::TDAQ_CALO_JET_PROC_DAQ),
-    m_srcIdMap(0), m_elementKey(0),
-    m_jemSubBlock(0), m_cmmEnergySubBlock(0), m_cmmJetSubBlock(0),
-    m_rodStatus(0), m_fea(0)
+    m_channels(44), m_crates(2), m_modules(16), 
+    m_subDetector(eformat::TDAQ_CALO_JET_PROC_DAQ)
 {
   declareInterface<JepByteStreamTool>(this);
 
@@ -74,7 +69,7 @@ JepByteStreamTool::JepByteStreamTool(const std::string& type,
                   "The number of S-Links per crate");
 
   // Properties for reading bytestream only
-  declareProperty("ROBSourceIDs",       m_sourceIDs,
+  declareProperty("ROBSourceIDs",       m_sourceIDsProp,
                   "ROB fragment source identifiers");
 
   // Properties for writing bytestream only
@@ -115,13 +110,6 @@ StatusCode JepByteStreamTool::initialize()
     return sc;
   } else msg(MSG::INFO) << "Retrieved tool " << m_errorTool << endmsg;
 
-  m_srcIdMap          = new L1CaloSrcIdMap();
-  m_elementKey        = new LVL1::JetElementKey();
-  m_jemSubBlock       = new JemSubBlock();
-  m_cmmEnergySubBlock = new CmmEnergySubBlock();
-  m_cmmJetSubBlock    = new CmmJetSubBlock();
-  m_rodStatus         = new std::vector<uint32_t>(2);
-  m_fea               = new FullEventAssembler<L1CaloSrcIdMap>();
   return StatusCode::SUCCESS;
 }
 
@@ -129,92 +117,107 @@ StatusCode JepByteStreamTool::initialize()
 
 StatusCode JepByteStreamTool::finalize()
 {
-  delete m_fea;
-  delete m_rodStatus;
-  delete m_cmmJetSubBlock;
-  delete m_cmmEnergySubBlock;
-  delete m_jemSubBlock;
-  delete m_elementKey;
-  delete m_srcIdMap;
   return StatusCode::SUCCESS;
 }
 
 // Conversion bytestream to jet elements
 
 StatusCode JepByteStreamTool::convert(
+  const std::string& sgKey,
   const IROBDataProviderSvc::VROBFRAG& robFrags,
-  DataVector<LVL1::JetElement>* const jeCollection)
+  DataVector<LVL1::JetElement>* const jeCollection) const
 {
   JetElementData data (jeCollection);
-  return convertBs(robFrags, data);
+  return convertBs(sgKey, robFrags, data);
 }
 
 // Conversion bytestream to jet hits
 
 StatusCode JepByteStreamTool::convert(
+  const std::string& sgKey,
   const IROBDataProviderSvc::VROBFRAG& robFrags,
-  DataVector<LVL1::JEMHits>* const hitCollection)
+  DataVector<LVL1::JEMHits>* const hitCollection) const
 {
   JetHitsData data (hitCollection);
-  return convertBs(robFrags, data);
+  return convertBs(sgKey, robFrags, data);
 }
 
 // Conversion bytestream to energy sums
 
 StatusCode JepByteStreamTool::convert(
+  const std::string& sgKey,
   const IROBDataProviderSvc::VROBFRAG& robFrags,
-  DataVector<LVL1::JEMEtSums>* const etCollection)
+  DataVector<LVL1::JEMEtSums>* const etCollection) const
 {
   EnergySumsData data (etCollection);
-  return convertBs(robFrags, data);
+  return convertBs(sgKey, robFrags, data);
 }
 
 // Conversion bytestream to CMM hits
 
 StatusCode JepByteStreamTool::convert(
+  const std::string& sgKey,
   const IROBDataProviderSvc::VROBFRAG& robFrags,
-  DataVector<LVL1::CMMJetHits>* const hitCollection)
+  DataVector<LVL1::CMMJetHits>* const hitCollection) const
 {
   CmmHitsData data (hitCollection);
-  return convertBs(robFrags, data);
+  return convertBs(sgKey, robFrags, data);
 }
 
 // Conversion bytestream to CMM energy sums
 
 StatusCode JepByteStreamTool::convert(
+  const std::string& sgKey,
   const IROBDataProviderSvc::VROBFRAG& robFrags,
-  DataVector<LVL1::CMMEtSums>* const etCollection)
+  DataVector<LVL1::CMMEtSums>* const etCollection) const
 {
   CmmSumsData data (etCollection);
-  return convertBs(robFrags, data);
+  return convertBs(sgKey, robFrags, data);
 }
 
 // Conversion of JEP container to bytestream
 
+// xxx
 StatusCode JepByteStreamTool::convert(const LVL1::JEPBSCollection* const jep,
-                                      RawEventWrite* const re)
+                                      RawEventWrite* const re) const
 {
   const bool debug = msgLvl(MSG::DEBUG);
   if (debug) msg(MSG::DEBUG);
 
   // Clear the event assembler
-
-  m_fea->clear();
-  const uint16_t minorVersion = m_srcIdMap->minorVersion();
-  m_fea->setRodMinorVersion(minorVersion);
-  m_rodStatusMap.clear();
+  FullEventAssembler<L1CaloSrcIdMap> fea;
+  fea.clear();
+  const uint16_t minorVersion = m_srcIdMap.minorVersion();
+  fea.setRodMinorVersion(minorVersion);
 
   // Pointer to ROD data vector
 
   FullEventAssembler<L1CaloSrcIdMap>::RODDATA* theROD = 0;
 
+  // Jet element key provider
+  LVL1::JetElementKey elementKey;
+
   // Set up the container maps
 
-  setupJeMap(jep->JetElements());
-  setupHitsMap(jep->JetHits());
-  setupEtMap(jep->EnergySums());
-  setupCmmHitsMap(jep->CmmHits());
-  setupCmmEtMap(jep->CmmSums());
+  // Jet element map
+  ConstJetElementMap jeMap;
+  setupJeMap(jep->JetElements(), jeMap, elementKey);
+
+  // Jet hits map
+  ConstJetHitsMap hitsMap;
+  setupHitsMap(jep->JetHits(), hitsMap);
+
+  // Energy sums map
+  ConstEnergySumsMap etMap;
+  setupEtMap(jep->EnergySums(), etMap);
+
+  // CMM hits map
+  ConstCmmHitsMap cmmHitsMap;
+  setupCmmHitsMap(jep->CmmHits(), cmmHitsMap);
+
+  // CMM energy sums map
+  ConstCmmSumsMap cmmEtMap;
+  setupCmmEtMap(jep->CmmSums(), cmmEtMap);
 
   // Loop over data
 
@@ -241,7 +244,14 @@ StatusCode JepByteStreamTool::convert(const LVL1::JEPBSCollection* const jep,
         // Get number of JEM slices and triggered slice offset
         // for this slink
         if ( ! slinkSlices(crate, module, modulesPerSlink,
-                           timeslices, trigJem)) {
+                           timeslices, trigJem,
+                           jeMap,
+                           hitsMap,
+                           etMap,
+                           cmmHitsMap,
+                           cmmEtMap,
+                           elementKey))
+        {
           msg(MSG::ERROR) << "Inconsistent number of slices or "
                           << "triggered slice offsets in data for crate "
                           << hwCrate << " slink " << slink << endmsg;
@@ -260,22 +270,23 @@ StatusCode JepByteStreamTool::convert(const LVL1::JEPBSCollection* const jep,
         }
         L1CaloUserHeader userHeader;
         userHeader.setJem(trigJemNew);
-        const uint32_t rodIdJem = m_srcIdMap->getRodID(hwCrate, slink, daqOrRoi,
+        const uint32_t rodIdJem = m_srcIdMap.getRodID(hwCrate, slink, daqOrRoi,
                                   m_subDetector);
-        theROD = m_fea->getRodData(rodIdJem);
+        theROD = fea.getRodData(rodIdJem);
         theROD->push_back(userHeader.header());
-        m_rodStatusMap.insert(make_pair(rodIdJem, m_rodStatus));
       }
       if (debug) msg() << "Module " << module << endmsg;
 
       // Create a sub-block for each slice (except Neutral format)
 
-      m_jemBlocks.clear();
+      // Vector for current JEM sub-blocks
+      DataVector<JemSubBlock> jemBlocks;
+
       for (int slice = 0; slice < timeslicesNew; ++slice) {
         JemSubBlock* const subBlock = new JemSubBlock();
         subBlock->setJemHeader(m_version, m_dataFormat, slice,
                                hwCrate, module, timeslicesNew);
-        m_jemBlocks.push_back(subBlock);
+        jemBlocks.push_back(subBlock);
         if (neutralFormat) break;
       }
 
@@ -287,7 +298,7 @@ StatusCode JepByteStreamTool::convert(const LVL1::JEPBSCollection* const jep,
         double phi = 0.;
         int layer = 0;
         if (m_jemMaps->mapping(crate, module, chan, eta, phi, layer)) {
-          const LVL1::JetElement* const je = findJetElement(eta, phi);
+          const LVL1::JetElement* const je = findJetElement(eta, phi, jeMap, elementKey);
           if (je ) {
             std::vector<int> emData;
             std::vector<int> hadData;
@@ -301,7 +312,7 @@ StatusCode JepByteStreamTool::convert(const LVL1::JEPBSCollection* const jep,
               const LVL1::DataError emErrBits(emErrors[slice]);
               const LVL1::DataError hadErrBits(hadErrors[slice]);
               const int index = ( neutralFormat ) ? 0 : slice;
-              JemSubBlock* const subBlock = m_jemBlocks[index];
+              JemSubBlock* const subBlock = jemBlocks[index];
               const JemJetElement jetEle(chan, emData[slice], hadData[slice],
                                          emErrBits.get(LVL1::DataError::Parity),
                                          hadErrBits.get(LVL1::DataError::Parity),
@@ -315,17 +326,17 @@ StatusCode JepByteStreamTool::convert(const LVL1::JEPBSCollection* const jep,
 
       // Add jet hits and energy subsums
 
-      const LVL1::JEMHits* const hits = findJetHits(crate, module);
+      const LVL1::JEMHits* const hits = findJetHits(crate, module, hitsMap);
       if (hits) {
         std::vector<unsigned int> vec;
         ModifySlices::data(hits->JetHitsVec(), vec, timeslicesNew);
         for (int slice = 0; slice < timeslicesNew; ++slice) {
           const int index = ( neutralFormat ) ? 0 : slice;
-          JemSubBlock* const subBlock = m_jemBlocks[index];
+          JemSubBlock* const subBlock = jemBlocks[index];
           subBlock->setJetHits(slice, vec[slice]);
         }
       }
-      const LVL1::JEMEtSums* const et = findEnergySums(crate, module);
+      const LVL1::JEMEtSums* const et = findEnergySums(crate, module, etMap);
       if (et) {
         std::vector<unsigned int> exVec;
         std::vector<unsigned int> eyVec;
@@ -335,7 +346,7 @@ StatusCode JepByteStreamTool::convert(const LVL1::JEPBSCollection* const jep,
         ModifySlices::data(et->EtVec(), etVec, timeslicesNew);
         for (int slice = 0; slice < timeslicesNew; ++slice) {
           const int index = ( neutralFormat ) ? 0 : slice;
-          JemSubBlock* const subBlock = m_jemBlocks[index];
+          JemSubBlock* const subBlock = jemBlocks[index];
           subBlock->setEnergySubsums(slice, exVec[slice], eyVec[slice],
                                      etVec[slice]);
         }
@@ -344,7 +355,7 @@ StatusCode JepByteStreamTool::convert(const LVL1::JEPBSCollection* const jep,
       // Pack and write the sub-blocks
 
       DataVector<JemSubBlock>::iterator pos;
-      for (pos = m_jemBlocks.begin(); pos != m_jemBlocks.end(); ++pos) {
+      for (pos = jemBlocks.begin(); pos != jemBlocks.end(); ++pos) {
         JemSubBlock* const subBlock = *pos;
         if ( !subBlock->pack()) {
           msg(MSG::ERROR) << "JEM sub-block packing failed" << endmsg;
@@ -362,8 +373,11 @@ StatusCode JepByteStreamTool::convert(const LVL1::JEPBSCollection* const jep,
 
     // Create a sub-block for each slice (except Neutral format)
 
-    m_cmmEnergyBlocks.clear();
-    m_cmmJetBlocks.clear();
+    // Vector for current CMM-Energy sub-blocks
+    DataVector<CmmEnergySubBlock> cmmEnergyBlocks;
+    // Vector for current CMM-Jet sub-blocks
+    DataVector<CmmJetSubBlock> cmmJetBlocks;
+
     const int summing = (crate == m_crates - 1) ? CmmSubBlock::SYSTEM
                         : CmmSubBlock::CRATE;
     for (int slice = 0; slice < timeslicesNew; ++slice) {
@@ -372,12 +386,12 @@ StatusCode JepByteStreamTool::convert(const LVL1::JEPBSCollection* const jep,
       enBlock->setCmmHeader(cmmEnergyVersion, m_dataFormat, slice, hwCrate,
                             summing, CmmSubBlock::CMM_ENERGY,
                             CmmSubBlock::LEFT, timeslicesNew);
-      m_cmmEnergyBlocks.push_back(enBlock);
+      cmmEnergyBlocks.push_back(enBlock);
       CmmJetSubBlock* const jetBlock = new CmmJetSubBlock();
       jetBlock->setCmmHeader(m_version, m_dataFormat, slice, hwCrate,
                              summing, CmmSubBlock::CMM_JET,
                              CmmSubBlock::RIGHT, timeslicesNew);
-      m_cmmJetBlocks.push_back(jetBlock);
+      cmmJetBlocks.push_back(jetBlock);
       if (neutralFormat) break;
     }
 
@@ -410,7 +424,7 @@ StatusCode JepByteStreamTool::convert(const LVL1::JEPBSCollection* const jep,
           continue;
         }
       }
-      const LVL1::CMMEtSums* const sums = findCmmSums(crate, dataID);
+      const LVL1::CMMEtSums* const sums = findCmmSums(crate, dataID, cmmEtMap);
       if ( sums ) {
         std::vector<unsigned int> ex;
         std::vector<unsigned int> ey;
@@ -439,7 +453,7 @@ StatusCode JepByteStreamTool::convert(const LVL1::JEPBSCollection* const jep,
             etError = (etError << 1) + etErrBits.get(LVL1::DataError::Overflow);
           }
           const int index = ( neutralFormat ) ? 0 : slice;
-          CmmEnergySubBlock* const subBlock = m_cmmEnergyBlocks[index];
+          CmmEnergySubBlock* const subBlock = cmmEnergyBlocks[index];
           if (dataID == LVL1::CMMEtSums::MISSING_ET_MAP) {
             subBlock->setMissingEtHits(slice, et[slice]);
           } else if (dataID == LVL1::CMMEtSums::SUM_ET_MAP) {
@@ -455,8 +469,8 @@ StatusCode JepByteStreamTool::convert(const LVL1::JEPBSCollection* const jep,
       }
     }
     DataVector<CmmEnergySubBlock>::iterator pos;
-    pos = m_cmmEnergyBlocks.begin();
-    for (; pos != m_cmmEnergyBlocks.end(); ++pos) {
+    pos = cmmEnergyBlocks.begin();
+    for (; pos != cmmEnergyBlocks.end(); ++pos) {
       CmmEnergySubBlock* const subBlock = *pos;
       if ( !subBlock->pack()) {
         msg(MSG::ERROR) << "CMM-Energy sub-block packing failed" << endmsg;
@@ -503,7 +517,7 @@ StatusCode JepByteStreamTool::convert(const LVL1::JEPBSCollection* const jep,
           continue;
         }
       }
-      const LVL1::CMMJetHits* const ch = findCmmHits(crate, dataID);
+      const LVL1::CMMJetHits* const ch = findCmmHits(crate, dataID, cmmHitsMap);
       if ( ch ) {
         std::vector<unsigned int> hits;
         std::vector<int> errs;
@@ -512,7 +526,7 @@ StatusCode JepByteStreamTool::convert(const LVL1::JEPBSCollection* const jep,
         for (int slice = 0; slice < timeslicesNew; ++slice) {
           const LVL1::DataError errBits(errs[slice]);
           const int index = ( neutralFormat ) ? 0 : slice;
-          CmmJetSubBlock* const subBlock = m_cmmJetBlocks[index];
+          CmmJetSubBlock* const subBlock = cmmJetBlocks[index];
           if (dataID == LVL1::CMMJetHits::ET_MAP) {
             subBlock->setJetEtMap(slice, hits[slice]);
           } else {
@@ -523,8 +537,8 @@ StatusCode JepByteStreamTool::convert(const LVL1::JEPBSCollection* const jep,
       }
     }
     DataVector<CmmJetSubBlock>::iterator jos;
-    jos = m_cmmJetBlocks.begin();
-    for (; jos != m_cmmJetBlocks.end(); ++jos) {
+    jos = cmmJetBlocks.begin();
+    for (; jos != cmmJetBlocks.end(); ++jos) {
       CmmJetSubBlock* const subBlock = *jos;
       if ( !subBlock->pack()) {
         msg(MSG::ERROR) << "CMM-Jet sub-block packing failed" << endmsg;
@@ -540,51 +554,69 @@ StatusCode JepByteStreamTool::convert(const LVL1::JEPBSCollection* const jep,
 
   // Fill the raw event
 
-  m_fea->fill(re, msg());
-
-  // Set ROD status words
-
-  //L1CaloRodStatus::setStatus(re, m_rodStatusMap, m_srcIdMap);
+  fea.fill(re, msg());
 
   return StatusCode::SUCCESS;
 }
 
 // Return reference to vector with all possible Source Identifiers
 
-const std::vector<uint32_t>& JepByteStreamTool::sourceIDs(
-  const std::string& sgKey)
+std::vector<uint32_t> JepByteStreamTool::makeSourceIDs() const
 {
-  // Check if overlap jet element channels wanted
-  const std::string flag("Overlap");
-  const std::string::size_type pos = sgKey.find(flag);
-  m_coreOverlap =
-    (pos == std::string::npos || pos != sgKey.length() - flag.length()) ? 0 : 1;
+  std::vector<uint32_t> sourceIDs;
 
-  if (m_sourceIDs.empty()) {
+  if (!m_sourceIDsProp.empty()) {
+    sourceIDs = m_sourceIDsProp;
+  }
+  else {
     const int maxCrates = m_crates + m_crateOffsetHw;
-    const int maxSlinks = m_srcIdMap->maxSlinks();
-    for (int hwCrate = m_crateOffsetHw; hwCrate < maxCrates; ++hwCrate) {
-      for (int slink = 0; slink < maxSlinks; ++slink) {
+    const int maxSlinks = m_srcIdMap.maxSlinks();
+    for (int hwCrate = m_crateOffsetHw; hwCrate < maxCrates; ++hwCrate)
+    {
+      for (int slink = 0; slink < maxSlinks; ++slink)
+      {
         const int daqOrRoi = 0;
-        const uint32_t rodId = m_srcIdMap->getRodID(hwCrate, slink, daqOrRoi,
-                               m_subDetector);
-        const uint32_t robId = m_srcIdMap->getRobID(rodId);
-        m_sourceIDs.push_back(robId);
+        const uint32_t rodId = m_srcIdMap.getRodID(hwCrate, slink, daqOrRoi,
+                                                   m_subDetector);
+        const uint32_t robId = m_srcIdMap.getRobID(rodId);
+        sourceIDs.push_back(robId);
       }
     }
   }
-  return m_sourceIDs;
+  return sourceIDs;
+}
+
+const std::vector<uint32_t>& JepByteStreamTool::sourceIDs() const
+{
+  static const std::vector<uint32_t> sourceIDs = makeSourceIDs();
+  return sourceIDs;
 }
 
 // Convert bytestream to given container type
 
 StatusCode JepByteStreamTool::convertBs(
+  const std::string& sgKey,
   const IROBDataProviderSvc::VROBFRAG& robFrags,
-  JepByteStreamToolData& data)
+  JepByteStreamToolData& data) const
 {
+  LocalData ld;
+
+  // Check if overlap jet element channels wanted
+  const std::string flag("Overlap");
+  const std::string::size_type pos = sgKey.find(flag);
+  ld.coreOverlap =
+    (pos == std::string::npos || pos != sgKey.length() - flag.length()) ? 0 : 1;
+
   const bool debug = msgLvl(MSG::DEBUG);
   if (debug) msg(MSG::DEBUG);
 
+  // JemSubBlock for unpacking
+  JemSubBlock jemSubBlock;
+  // CmmEnergySubBlock for unpacking
+  CmmEnergySubBlock cmmEnergySubBlock;
+  // CmmJetSubBlock for unpacking
+  CmmJetSubBlock cmmJetSubBlock;
+
   // Loop over ROB fragments
 
   int robCount = 0;
@@ -634,12 +666,12 @@ StatusCode JepByteStreamTool::convertBs(
 
     // Check identifier
     const uint32_t sourceID = (*rob)->rod_source_id();
-    if (m_srcIdMap->getRobID(sourceID) != robid           ||
-        m_srcIdMap->subDet(sourceID)   != m_subDetector   ||
-        m_srcIdMap->daqOrRoi(sourceID) != 0               ||
-        m_srcIdMap->slink(sourceID)    >= m_slinks        ||
-        m_srcIdMap->crate(sourceID)    <  m_crateOffsetHw ||
-        m_srcIdMap->crate(sourceID)    >= m_crateOffsetHw + m_crates) {
+    if (m_srcIdMap.getRobID(sourceID) != robid           ||
+        m_srcIdMap.subDet(sourceID)   != m_subDetector   ||
+        m_srcIdMap.daqOrRoi(sourceID) != 0               ||
+        m_srcIdMap.slink(sourceID)    >= m_slinks        ||
+        m_srcIdMap.crate(sourceID)    <  m_crateOffsetHw ||
+        m_srcIdMap.crate(sourceID)    >= m_crateOffsetHw + m_crates) {
       m_errorTool->rodError(robid, L1CaloSubBlock::ERROR_ROD_ID);
       if (debug) {
         msg() << "Wrong source identifier in data: ROD "
@@ -648,10 +680,10 @@ StatusCode JepByteStreamTool::convertBs(
       }
       continue;
     }
-    const int rodCrate = m_srcIdMap->crate(sourceID);
+    const int rodCrate = m_srcIdMap.crate(sourceID);
     if (debug) {
       msg() << "Treating crate " << rodCrate
-            << " slink " << m_srcIdMap->slink(sourceID) << endmsg;
+            << " slink " << m_srcIdMap.slink(sourceID) << endmsg;
     }
 
     // First word should be User Header
@@ -689,75 +721,75 @@ StatusCode JepByteStreamTool::convertBs(
 
     // Loop over sub-blocks
 
-    m_rodErr = L1CaloSubBlock::ERROR_NONE;
+    ld.rodErr = L1CaloSubBlock::ERROR_NONE;
     while (payload != payloadEnd) {
 
       if (L1CaloSubBlock::wordType(*payload) != L1CaloSubBlock::HEADER) {
         if (debug) msg() << "Unexpected data sequence" << endmsg;
-        m_rodErr = L1CaloSubBlock::ERROR_MISSING_HEADER;
+        ld.rodErr = L1CaloSubBlock::ERROR_MISSING_HEADER;
         break;
       }
       if (CmmSubBlock::cmmBlock(*payload)) {
         // CMMs
         if (CmmSubBlock::cmmType(*payload) == CmmSubBlock::CMM_JET) {
-          m_cmmJetSubBlock->clear();
-          payload = m_cmmJetSubBlock->read(payload, payloadEnd);
-          if (m_cmmJetSubBlock->crate() != rodCrate) {
+          cmmJetSubBlock.clear();
+          payload = cmmJetSubBlock.read(payload, payloadEnd);
+          if (cmmJetSubBlock.crate() != rodCrate) {
             if (debug) msg() << "Inconsistent crate number in ROD source ID"
                                << endmsg;
-            m_rodErr = L1CaloSubBlock::ERROR_CRATE_NUMBER;
+            ld.rodErr = L1CaloSubBlock::ERROR_CRATE_NUMBER;
             break;
           }
           if (data.m_collection == CMM_HITS) {
-            decodeCmmJet(m_cmmJetSubBlock, trigCmm, static_cast<CmmHitsData&>(data));
-            if (m_rodErr != L1CaloSubBlock::ERROR_NONE) {
+            decodeCmmJet(&cmmJetSubBlock, trigCmm, static_cast<CmmHitsData&>(data), ld);
+            if (ld.rodErr != L1CaloSubBlock::ERROR_NONE) {
               if (debug) msg() << "decodeCmmJet failed" << endmsg;
               break;
             }
           }
         } else if (CmmSubBlock::cmmType(*payload) == CmmSubBlock::CMM_ENERGY) {
-          m_cmmEnergySubBlock->clear();
-          payload = m_cmmEnergySubBlock->read(payload, payloadEnd);
-          if (m_cmmEnergySubBlock->crate() != rodCrate) {
+          cmmEnergySubBlock.clear();
+          payload = cmmEnergySubBlock.read(payload, payloadEnd);
+          if (cmmEnergySubBlock.crate() != rodCrate) {
             if (debug) msg() << "Inconsistent crate number in ROD source ID"
                                << endmsg;
-            m_rodErr = L1CaloSubBlock::ERROR_CRATE_NUMBER;
+            ld.rodErr = L1CaloSubBlock::ERROR_CRATE_NUMBER;
             break;
           }
           if (data.m_collection == CMM_SUMS) {
-            decodeCmmEnergy(m_cmmEnergySubBlock, trigCmm, static_cast<CmmSumsData&>(data));
-            if (m_rodErr != L1CaloSubBlock::ERROR_NONE) {
+            decodeCmmEnergy(&cmmEnergySubBlock, trigCmm, static_cast<CmmSumsData&>(data), ld);
+            if (ld.rodErr != L1CaloSubBlock::ERROR_NONE) {
               if (debug) msg() << "decodeCmmEnergy failed" << endmsg;
               break;
             }
           }
         } else {
           if (debug) msg() << "Invalid CMM type in module field" << endmsg;
-          m_rodErr = L1CaloSubBlock::ERROR_MODULE_NUMBER;
+          ld.rodErr = L1CaloSubBlock::ERROR_MODULE_NUMBER;
           break;
         }
       } else {
         // JEM
-        m_jemSubBlock->clear();
-        payload = m_jemSubBlock->read(payload, payloadEnd);
-        if (m_jemSubBlock->crate() != rodCrate) {
+        jemSubBlock.clear();
+        payload = jemSubBlock.read(payload, payloadEnd);
+        if (jemSubBlock.crate() != rodCrate) {
           if (debug) msg() << "Inconsistent crate number in ROD source ID"
                              << endmsg;
-          m_rodErr = L1CaloSubBlock::ERROR_CRATE_NUMBER;
+          ld.rodErr = L1CaloSubBlock::ERROR_CRATE_NUMBER;
           break;
         }
         if (data.m_collection == JET_ELEMENTS || data.m_collection == JET_HITS ||
             data.m_collection == ENERGY_SUMS) {
-          decodeJem(m_jemSubBlock, trigJem, data);
-          if (m_rodErr != L1CaloSubBlock::ERROR_NONE) {
+          decodeJem(&jemSubBlock, trigJem, data, ld);
+          if (ld.rodErr != L1CaloSubBlock::ERROR_NONE) {
             if (debug) msg() << "decodeJem failed" << endmsg;
             break;
           }
         }
       }
     }
-    if (m_rodErr != L1CaloSubBlock::ERROR_NONE)
-      m_errorTool->rodError(robid, m_rodErr);
+    if (ld.rodErr != L1CaloSubBlock::ERROR_NONE)
+      m_errorTool->rodError(robid, ld.rodErr);
   }
 
   return StatusCode::SUCCESS;
@@ -767,7 +799,8 @@ StatusCode JepByteStreamTool::convertBs(
 
 void JepByteStreamTool::decodeCmmEnergy(CmmEnergySubBlock* subBlock,
                                         int trigCmm,
-                                        CmmSumsData& data)
+                                        CmmSumsData& data,
+                                        LocalData& ld) const
 {
   const bool debug = msgLvl(MSG::DEBUG);
   if (debug) msg(MSG::DEBUG);
@@ -790,13 +823,13 @@ void JepByteStreamTool::decodeCmmEnergy(CmmEnergySubBlock* subBlock,
     if (debug) msg() << "Triggered CMM slice from header "
                        << "inconsistent with number of slices: "
                        << trigCmm << ", " << timeslices << endmsg;
-    m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+    ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
     return;
   }
   if (timeslices <= sliceNum) {
     if (debug) msg() << "Total slices inconsistent with slice number: "
                        << timeslices << ", " << sliceNum << endmsg;
-    m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+    ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
     return;
   }
   // Unpack sub-block
@@ -805,7 +838,7 @@ void JepByteStreamTool::decodeCmmEnergy(CmmEnergySubBlock* subBlock,
       std::string errMsg(subBlock->unpackErrorMsg());
       msg() << "CMM-Energy sub-block unpacking failed: " << errMsg << endmsg;
     }
-    m_rodErr = subBlock->unpackErrorCode();
+    ld.rodErr = subBlock->unpackErrorCode();
     return;
   }
 
@@ -878,54 +911,54 @@ void JepByteStreamTool::decodeCmmEnergy(CmmEnergySubBlock* subBlock,
       if (ex || ey || et || exErr || eyErr || etErr) {
         LVL1::CMMEtSums* sums = findCmmSums(data, crate, dataID);
         if ( ! sums ) {   // create new CMM energy sums
-          m_exVec.assign(timeslices, 0);
-          m_eyVec.assign(timeslices, 0);
-          m_etVec.assign(timeslices, 0);
-          m_exErrVec.assign(timeslices, 0);
-          m_eyErrVec.assign(timeslices, 0);
-          m_etErrVec.assign(timeslices, 0);
-          m_exVec[slice] = ex;
-          m_eyVec[slice] = ey;
-          m_etVec[slice] = et;
-          m_exErrVec[slice] = exErr;
-          m_eyErrVec[slice] = eyErr;
-          m_etErrVec[slice] = etErr;
+          ld.exVec.assign(timeslices, 0);
+          ld.eyVec.assign(timeslices, 0);
+          ld.etVec.assign(timeslices, 0);
+          ld.exErrVec.assign(timeslices, 0);
+          ld.eyErrVec.assign(timeslices, 0);
+          ld.etErrVec.assign(timeslices, 0);
+          ld.exVec[slice] = ex;
+          ld.eyVec[slice] = ey;
+          ld.etVec[slice] = et;
+          ld.exErrVec[slice] = exErr;
+          ld.eyErrVec[slice] = eyErr;
+          ld.etErrVec[slice] = etErr;
           auto sumsp = 
-            std::make_unique<LVL1::CMMEtSums>(swCrate, dataID, m_etVec, m_exVec, m_eyVec,
-                                              m_etErrVec, m_exErrVec, m_eyErrVec, trigCmm);
+            std::make_unique<LVL1::CMMEtSums>(swCrate, dataID, ld.etVec, ld.exVec, ld.eyVec,
+                                              ld.etErrVec, ld.exErrVec, ld.eyErrVec, trigCmm);
           const int key = crate * 100 + dataID;
           data.m_cmmEtMap.insert(std::make_pair(key, sumsp.get()));
           data.m_cmmEtCollection->push_back(std::move(sumsp));
         } else {
-          m_exVec = sums->ExVec();
-          m_eyVec = sums->EyVec();
-          m_etVec = sums->EtVec();
-          m_exErrVec = sums->ExErrorVec();
-          m_eyErrVec = sums->EyErrorVec();
-          m_etErrVec = sums->EtErrorVec();
-          const int nsl = m_exVec.size();
+          ld.exVec = sums->ExVec();
+          ld.eyVec = sums->EyVec();
+          ld.etVec = sums->EtVec();
+          ld.exErrVec = sums->ExErrorVec();
+          ld.eyErrVec = sums->EyErrorVec();
+          ld.etErrVec = sums->EtErrorVec();
+          const int nsl = ld.exVec.size();
           if (timeslices != nsl) {
             if (debug) msg() << "Inconsistent number of slices in sub-blocks"
                                << endmsg;
-            m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+            ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
             return;
           }
-          if (m_exVec[slice] != 0 || m_eyVec[slice] != 0 || m_etVec[slice] != 0 ||
-              m_exErrVec[slice] != 0 || m_eyErrVec[slice] != 0 ||
-              m_etErrVec[slice] != 0) {
+          if (ld.exVec[slice] != 0 || ld.eyVec[slice] != 0 || ld.etVec[slice] != 0 ||
+              ld.exErrVec[slice] != 0 || ld.eyErrVec[slice] != 0 ||
+              ld.etErrVec[slice] != 0) {
             if (debug) msg() << "Duplicate data for slice " << slice << endmsg;
-            m_rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
+            ld.rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
             return;
           }
-          m_exVec[slice] = ex;
-          m_eyVec[slice] = ey;
-          m_etVec[slice] = et;
-          m_exErrVec[slice] = exErr;
-          m_eyErrVec[slice] = eyErr;
-          m_etErrVec[slice] = etErr;
-          sums->addEx(m_exVec, m_exErrVec);
-          sums->addEy(m_eyVec, m_eyErrVec);
-          sums->addEt(m_etVec, m_etErrVec);
+          ld.exVec[slice] = ex;
+          ld.eyVec[slice] = ey;
+          ld.etVec[slice] = et;
+          ld.exErrVec[slice] = exErr;
+          ld.eyErrVec[slice] = eyErr;
+          ld.etErrVec[slice] = etErr;
+          sums->addEx(ld.exVec, ld.exErrVec);
+          sums->addEy(ld.eyVec, ld.eyErrVec);
+          sums->addEt(ld.etVec, ld.etErrVec);
         }
       }
     }
@@ -938,37 +971,37 @@ void JepByteStreamTool::decodeCmmEnergy(CmmEnergySubBlock* subBlock,
         const int dataID = LVL1::CMMEtSums::MISSING_ET_MAP;
         LVL1::CMMEtSums* map = findCmmSums(data, crate, dataID);
         if ( ! map ) {
-          m_etVec.assign(timeslices, 0);
-          m_etErrVec.assign(timeslices, 0);
-          m_etVec[slice]    = missEt;
-          m_etErrVec[slice] = ssError;
+          ld.etVec.assign(timeslices, 0);
+          ld.etErrVec.assign(timeslices, 0);
+          ld.etVec[slice]    = missEt;
+          ld.etErrVec[slice] = ssError;
           auto mapp =
             std::make_unique<LVL1::CMMEtSums>(swCrate, dataID,
-                                              m_etVec, m_etVec, m_etVec,
-                                              m_etErrVec, m_etErrVec, m_etErrVec, trigCmm);
+                                              ld.etVec, ld.etVec, ld.etVec,
+                                              ld.etErrVec, ld.etErrVec, ld.etErrVec, trigCmm);
           const int key = crate * 100 + dataID;
           data.m_cmmEtMap.insert(std::make_pair(key, mapp.get()));
           data.m_cmmEtCollection->push_back(std::move(mapp));
         } else {
-          m_etVec    = map->EtVec();
-          m_etErrVec = map->EtErrorVec();
-          const int nsl = m_etVec.size();
+          ld.etVec    = map->EtVec();
+          ld.etErrVec = map->EtErrorVec();
+          const int nsl = ld.etVec.size();
           if (timeslices != nsl) {
             if (debug) msg() << "Inconsistent number of slices in sub-blocks"
                                << endmsg;
-            m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+            ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
             return;
           }
-          if (m_etVec[slice] != 0 || m_etErrVec[slice] != 0) {
+          if (ld.etVec[slice] != 0 || ld.etErrVec[slice] != 0) {
             if (debug) msg() << "Duplicate data for slice " << slice << endmsg;
-            m_rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
+            ld.rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
             return;
           }
-          m_etVec[slice]     = missEt;
-          m_etErrVec[slice]  = ssError;
-          map->addEx(m_etVec, m_etErrVec);
-          map->addEy(m_etVec, m_etErrVec);
-          map->addEt(m_etVec, m_etErrVec);
+          ld.etVec[slice]     = missEt;
+          ld.etErrVec[slice]  = ssError;
+          map->addEx(ld.etVec, ld.etErrVec);
+          map->addEy(ld.etVec, ld.etErrVec);
+          map->addEt(ld.etVec, ld.etErrVec);
         }
       }
       const unsigned int sumEt = subBlock->sumEtHits(slice);
@@ -976,37 +1009,37 @@ void JepByteStreamTool::decodeCmmEnergy(CmmEnergySubBlock* subBlock,
         const int dataID = LVL1::CMMEtSums::SUM_ET_MAP;
         LVL1::CMMEtSums* map = findCmmSums(data, crate, dataID);
         if ( ! map ) {
-          m_etVec.assign(timeslices, 0);
-          m_etErrVec.assign(timeslices, 0);
-          m_etVec[slice]    = sumEt;
-          m_etErrVec[slice] = ssError;
+          ld.etVec.assign(timeslices, 0);
+          ld.etErrVec.assign(timeslices, 0);
+          ld.etVec[slice]    = sumEt;
+          ld.etErrVec[slice] = ssError;
           auto mapp =
             std::make_unique<LVL1::CMMEtSums>(swCrate, dataID,
-                                              m_etVec, m_etVec, m_etVec,
-                                              m_etErrVec, m_etErrVec, m_etErrVec, trigCmm);
+                                              ld.etVec, ld.etVec, ld.etVec,
+                                              ld.etErrVec, ld.etErrVec, ld.etErrVec, trigCmm);
           const int key = crate * 100 + dataID;
           data.m_cmmEtMap.insert(std::make_pair(key, mapp.get()));
           data.m_cmmEtCollection->push_back(std::move(mapp));
         } else {
-          m_etVec    = map->EtVec();
-          m_etErrVec = map->EtErrorVec();
-          const int nsl = m_etVec.size();
+          ld.etVec    = map->EtVec();
+          ld.etErrVec = map->EtErrorVec();
+          const int nsl = ld.etVec.size();
           if (timeslices != nsl) {
             if (debug) msg() << "Inconsistent number of slices in sub-blocks"
                                << endmsg;
-            m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+            ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
             return;
           }
-          if (m_etVec[slice] != 0 || m_etErrVec[slice] != 0) {
+          if (ld.etVec[slice] != 0 || ld.etErrVec[slice] != 0) {
             if (debug) msg() << "Duplicate data for slice " << slice << endmsg;
-            m_rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
+            ld.rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
             return;
           }
-          m_etVec[slice]    = sumEt;
-          m_etErrVec[slice] = ssError;
-          map->addEx(m_etVec, m_etErrVec);
-          map->addEy(m_etVec, m_etErrVec);
-          map->addEt(m_etVec, m_etErrVec);
+          ld.etVec[slice]    = sumEt;
+          ld.etErrVec[slice] = ssError;
+          map->addEx(ld.etVec, ld.etErrVec);
+          map->addEy(ld.etVec, ld.etErrVec);
+          map->addEt(ld.etVec, ld.etErrVec);
         }
       }
       if (subBlock->version() > 1) {
@@ -1015,38 +1048,38 @@ void JepByteStreamTool::decodeCmmEnergy(CmmEnergySubBlock* subBlock,
           const int dataID = LVL1::CMMEtSums::MISSING_ET_SIG_MAP;
           LVL1::CMMEtSums* map = findCmmSums(data, crate, dataID);
           if ( ! map ) {
-            m_etVec.assign(timeslices, 0);
-            m_etErrVec.assign(timeslices, 0);
-            m_etVec[slice]    = missEtSig;
-            m_etErrVec[slice] = ssError;
+            ld.etVec.assign(timeslices, 0);
+            ld.etErrVec.assign(timeslices, 0);
+            ld.etVec[slice]    = missEtSig;
+            ld.etErrVec[slice] = ssError;
             auto mapp = 
               std::make_unique<LVL1::CMMEtSums>(swCrate, dataID,
-                                                m_etVec, m_etVec, m_etVec,
-                                                m_etErrVec, m_etErrVec, m_etErrVec, trigCmm);
+                                                ld.etVec, ld.etVec, ld.etVec,
+                                                ld.etErrVec, ld.etErrVec, ld.etErrVec, trigCmm);
             const int key = crate * 100 + dataID;
             data.m_cmmEtMap.insert(std::make_pair(key, mapp.get()));
             data.m_cmmEtCollection->push_back(std::move(mapp));
           } else {
-            m_etVec    = map->EtVec();
-            m_etErrVec = map->EtErrorVec();
-            const int nsl = m_etVec.size();
+            ld.etVec    = map->EtVec();
+            ld.etErrVec = map->EtErrorVec();
+            const int nsl = ld.etVec.size();
             if (timeslices != nsl) {
               if (debug) msg() << "Inconsistent number of slices in sub-blocks"
                                  << endmsg;
-              m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+              ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
               return;
             }
-            if (m_etVec[slice] != 0 || m_etErrVec[slice] != 0) {
+            if (ld.etVec[slice] != 0 || ld.etErrVec[slice] != 0) {
               if (debug) msg() << "Duplicate data for slice "
                                  << slice << endmsg;
-              m_rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
+              ld.rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
               return;
             }
-            m_etVec[slice]    = missEtSig;
-            m_etErrVec[slice] = ssError;
-            map->addEx(m_etVec, m_etErrVec);
-            map->addEy(m_etVec, m_etErrVec);
-            map->addEt(m_etVec, m_etErrVec);
+            ld.etVec[slice]    = missEtSig;
+            ld.etErrVec[slice] = ssError;
+            map->addEx(ld.etVec, ld.etErrVec);
+            map->addEy(ld.etVec, ld.etErrVec);
+            map->addEt(ld.etVec, ld.etErrVec);
           }
         }
       }
@@ -1059,7 +1092,8 @@ void JepByteStreamTool::decodeCmmEnergy(CmmEnergySubBlock* subBlock,
 // Unpack CMM-Jet sub-block
 
 void JepByteStreamTool::decodeCmmJet(CmmJetSubBlock* subBlock, int trigCmm,
-                                     CmmHitsData& data)
+                                     CmmHitsData& data,
+                                     LocalData& ld) const
 {
   const bool debug = msgLvl(MSG::DEBUG);
   if (debug) msg(MSG::DEBUG);
@@ -1082,13 +1116,13 @@ void JepByteStreamTool::decodeCmmJet(CmmJetSubBlock* subBlock, int trigCmm,
     if (debug) msg() << "Triggered CMM slice from header "
                        << "inconsistent with number of slices: "
                        << trigCmm << ", " << timeslices << endmsg;
-    m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+    ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
     return;
   }
   if (timeslices <= sliceNum) {
     if (debug) msg() << "Total slices inconsistent with slice number: "
                        << timeslices << ", " << sliceNum << endmsg;
-    m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+    ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
     return;
   }
   // Unpack sub-block
@@ -1097,7 +1131,7 @@ void JepByteStreamTool::decodeCmmJet(CmmJetSubBlock* subBlock, int trigCmm,
       std::string errMsg(subBlock->unpackErrorMsg());
       msg() << "CMM-Jet sub-block unpacking failed: " << errMsg << endmsg;
     }
-    m_rodErr = subBlock->unpackErrorCode();
+    ld.rodErr = subBlock->unpackErrorCode();
     return;
   }
 
@@ -1153,33 +1187,33 @@ void JepByteStreamTool::decodeCmmJet(CmmJetSubBlock* subBlock, int trigCmm,
       if (hits || err) {
         LVL1::CMMJetHits* jh = findCmmHits(data, crate, dataID);
         if ( ! jh ) {   // create new CMM hits
-          m_hitsVec.assign(timeslices, 0);
-          m_errVec.assign(timeslices, 0);
-          m_hitsVec[slice] = hits;
-          m_errVec[slice]  = err;
+          ld.hitsVec.assign(timeslices, 0);
+          ld.errVec.assign(timeslices, 0);
+          ld.hitsVec[slice] = hits;
+          ld.errVec[slice]  = err;
           auto jhp =
-            std::make_unique<LVL1::CMMJetHits>(swCrate, dataID, m_hitsVec, m_errVec, trigCmm);
+            std::make_unique<LVL1::CMMJetHits>(swCrate, dataID, ld.hitsVec, ld.errVec, trigCmm);
           const int key = crate * 100 + dataID;
           data.m_cmmHitsMap.insert(std::make_pair(key, jhp.get()));
           data.m_cmmHitCollection->push_back(std::move(jhp));
         } else {
-          m_hitsVec = jh->HitsVec();
-          m_errVec  = jh->ErrorVec();
-          const int nsl = m_hitsVec.size();
+          ld.hitsVec = jh->HitsVec();
+          ld.errVec  = jh->ErrorVec();
+          const int nsl = ld.hitsVec.size();
           if (timeslices != nsl) {
             if (debug) msg() << "Inconsistent number of slices in sub-blocks"
                                << endmsg;
-            m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+            ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
             return;
           }
-          if (m_hitsVec[slice] != 0 || m_errVec[slice] != 0) {
+          if (ld.hitsVec[slice] != 0 || ld.errVec[slice] != 0) {
             if (debug) msg() << "Duplicate data for slice " << slice << endmsg;
-            m_rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
+            ld.rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
             return;
           }
-          m_hitsVec[slice] = hits;
-          m_errVec[slice]  = err;
-	  jh->addHits(m_hitsVec, m_errVec);
+          ld.hitsVec[slice] = hits;
+          ld.errVec[slice]  = err;
+	  jh->addHits(ld.hitsVec, ld.errVec);
         }
       }
     }
@@ -1192,33 +1226,33 @@ void JepByteStreamTool::decodeCmmJet(CmmJetSubBlock* subBlock, int trigCmm,
         const int dataID = LVL1::CMMJetHits::ET_MAP;
         LVL1::CMMJetHits* map = findCmmHits(data, crate, dataID);
         if ( ! map ) {
-          m_hitsVec.assign(timeslices, 0);
-          m_errVec.assign(timeslices, 0);
-          m_hitsVec[slice] = etMap;
-          m_errVec[slice]  = ssError;
+          ld.hitsVec.assign(timeslices, 0);
+          ld.errVec.assign(timeslices, 0);
+          ld.hitsVec[slice] = etMap;
+          ld.errVec[slice]  = ssError;
           auto mapp =
-            std::make_unique<LVL1::CMMJetHits>(swCrate, dataID, m_hitsVec, m_errVec, trigCmm);
+            std::make_unique<LVL1::CMMJetHits>(swCrate, dataID, ld.hitsVec, ld.errVec, trigCmm);
           const int key = crate * 100 + dataID;
           data.m_cmmHitsMap.insert(std::make_pair(key, mapp.get()));
           data.m_cmmHitCollection->push_back(std::move(mapp));
         } else {
-          m_hitsVec = map->HitsVec();
-          m_errVec  = map->ErrorVec();
-          const int nsl = m_hitsVec.size();
+          ld.hitsVec = map->HitsVec();
+          ld.errVec  = map->ErrorVec();
+          const int nsl = ld.hitsVec.size();
           if (timeslices != nsl) {
             if (debug) msg() << "Inconsistent number of slices in sub-blocks"
                                << endmsg;
-            m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+            ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
             return;
           }
-          if (m_hitsVec[slice] != 0 || m_errVec[slice] != 0) {
+          if (ld.hitsVec[slice] != 0 || ld.errVec[slice] != 0) {
             if (debug) msg() << "Duplicate data for slice " << slice << endmsg;
-            m_rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
+            ld.rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
             return;
           }
-          m_hitsVec[slice] = etMap;
-          m_errVec[slice]  = ssError;
-	  map->addHits(m_hitsVec, m_errVec);
+          ld.hitsVec[slice] = etMap;
+          ld.errVec[slice]  = ssError;
+	  map->addHits(ld.hitsVec, ld.errVec);
         }
       }
     }
@@ -1230,7 +1264,8 @@ void JepByteStreamTool::decodeCmmJet(CmmJetSubBlock* subBlock, int trigCmm,
 // Unpack JEM sub-block
 
 void JepByteStreamTool::decodeJem(JemSubBlock* subBlock, int trigJem,
-                                  JepByteStreamToolData& data)
+                                  JepByteStreamToolData& data,
+                                  LocalData& ld) const
 {
   const bool debug   = msgLvl(MSG::DEBUG);
   const bool verbose = msgLvl(MSG::VERBOSE);
@@ -1250,13 +1285,13 @@ void JepByteStreamTool::decodeJem(JemSubBlock* subBlock, int trigJem,
     if (debug) msg() << "Triggered JEM slice from header "
                        << "inconsistent with number of slices: "
                        << trigJem << ", " << timeslices << endmsg;
-    m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+    ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
     return;
   }
   if (timeslices <= sliceNum) {
     if (debug) msg() << "Total slices inconsistent with slice number: "
                        << timeslices << ", " << sliceNum << endmsg;
-    m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+    ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
     return;
   }
   // Unpack sub-block
@@ -1265,7 +1300,7 @@ void JepByteStreamTool::decodeJem(JemSubBlock* subBlock, int trigJem,
       std::string errMsg(subBlock->unpackErrorMsg());
       msg() << "JEM sub-block unpacking failed: " << errMsg << endmsg;
     }
-    m_rodErr = subBlock->unpackErrorCode();
+    ld.rodErr = subBlock->unpackErrorCode();
     return;
   }
 
@@ -1294,10 +1329,10 @@ void JepByteStreamTool::decodeJem(JemSubBlock* subBlock, int trigJem,
           double phi = 0.;
           int layer = 0;
           if (m_jemMaps->mapping(crate, module, chan, eta, phi, layer)) {
-            if (layer == m_coreOverlap) {
-              LVL1::JetElement* je = findJetElement(jedata, eta, phi);
+            if (layer == ld.coreOverlap) {
+              LVL1::JetElement* je = findJetElement(jedata, eta, phi, ld.elementKey);
               if ( ! je ) {   // create new jet element
-                const unsigned int key = m_elementKey->jeKey(phi, eta);
+                const unsigned int key = ld.elementKey.jeKey(phi, eta);
                 auto jep = 
                   std::make_unique<LVL1::JetElement>(phi, eta, dummy, dummy, key,
                                                      dummy, dummy, dummy, trigJem);
@@ -1315,14 +1350,14 @@ void JepByteStreamTool::decodeJem(JemSubBlock* subBlock, int trigJem,
                     msg() << "Inconsistent number of slices in sub-blocks"
                           << endmsg;
                   }
-                  m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+                  ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
                   return;
                 }
                 if (emEnergy[slice] != 0 || hadEnergy[slice] != 0 ||
                     emError[slice]  != 0 || hadError[slice]  != 0) {
                   if (debug) msg() << "Duplicate data for slice "
                                      << slice << endmsg;
-                  m_rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
+                  ld.rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
                   return;
                 }
               }
@@ -1357,31 +1392,31 @@ void JepByteStreamTool::decodeJem(JemSubBlock* subBlock, int trigJem,
       if (hits) {
         LVL1::JEMHits* jh = findJetHits(jhdata, crate, module);
         if ( ! jh ) {   // create new jet hits
-          m_hitsVec.assign(timeslices, 0);
-          m_hitsVec[slice] = hits;
+          ld.hitsVec.assign(timeslices, 0);
+          ld.hitsVec[slice] = hits;
           auto jhp =
-            std::make_unique<LVL1::JEMHits>(swCrate, module, m_hitsVec, trigJem);
+            std::make_unique<LVL1::JEMHits>(swCrate, module, ld.hitsVec, trigJem);
           jhdata.m_hitsMap.insert(std::make_pair(crate * m_modules + module, jhp.get()));
           jhdata.m_hitCollection->push_back(std::move(jhp));
         } else {
-          m_hitsVec = jh->JetHitsVec();
-          const int nsl = m_hitsVec.size();
+          ld.hitsVec = jh->JetHitsVec();
+          const int nsl = ld.hitsVec.size();
           if (timeslices != nsl) {
             if (debug) {
               msg() << "Inconsistent number of slices in sub-blocks"
                     << endmsg;
             }
-            m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+            ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
             return;
           }
-          if (m_hitsVec[slice] != 0) {
+          if (ld.hitsVec[slice] != 0) {
             if (debug) msg() << "Duplicate data for slice "
                                << slice << endmsg;
-            m_rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
+            ld.rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
             return;
           }
-          m_hitsVec[slice] = hits;
-	  jh->addJetHits(m_hitsVec);
+          ld.hitsVec[slice] = hits;
+	  jh->addJetHits(ld.hitsVec);
         }
       } else if (verbose) {
         msg(MSG::VERBOSE) << "No jet hits data for crate/module/slice "
@@ -1400,42 +1435,42 @@ void JepByteStreamTool::decodeJem(JemSubBlock* subBlock, int trigJem,
       if (ex | ey | et) {
         LVL1::JEMEtSums* sums = findEnergySums(sumdata, crate, module);
         if ( ! sums ) {   // create new energy sums
-          m_exVec.assign(timeslices, 0);
-          m_eyVec.assign(timeslices, 0);
-          m_etVec.assign(timeslices, 0);
-          m_exVec[slice] = ex;
-          m_eyVec[slice] = ey;
-          m_etVec[slice] = et;
+          ld.exVec.assign(timeslices, 0);
+          ld.eyVec.assign(timeslices, 0);
+          ld.etVec.assign(timeslices, 0);
+          ld.exVec[slice] = ex;
+          ld.eyVec[slice] = ey;
+          ld.etVec[slice] = et;
           auto sumsp =
-            std::make_unique<LVL1::JEMEtSums>(swCrate, module, m_etVec, m_exVec, m_eyVec,
+            std::make_unique<LVL1::JEMEtSums>(swCrate, module, ld.etVec, ld.exVec, ld.eyVec,
                                               trigJem);
           sumdata.m_etMap.insert(std::make_pair(crate * m_modules + module, sumsp.get()));
           sumdata.m_etCollection->push_back(std::move(sumsp));
         } else {
-          m_exVec = sums->ExVec();
-          m_eyVec = sums->EyVec();
-          m_etVec = sums->EtVec();
-          const int nsl = m_exVec.size();
+          ld.exVec = sums->ExVec();
+          ld.eyVec = sums->EyVec();
+          ld.etVec = sums->EtVec();
+          const int nsl = ld.exVec.size();
           if (timeslices != nsl) {
             if (debug) {
               msg() << "Inconsistent number of slices in sub-blocks"
                     << endmsg;
             }
-            m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+            ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
             return;
           }
-          if (m_exVec[slice] != 0 || m_eyVec[slice] != 0 || m_etVec[slice] != 0) {
+          if (ld.exVec[slice] != 0 || ld.eyVec[slice] != 0 || ld.etVec[slice] != 0) {
             if (debug) msg() << "Duplicate data for slice "
                                << slice << endmsg;
-            m_rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
+            ld.rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
             return;
           }
-          m_exVec[slice] = ex;
-          m_eyVec[slice] = ey;
-          m_etVec[slice] = et;
-          sums->addEx(m_exVec);
-          sums->addEy(m_eyVec);
-          sums->addEt(m_etVec);
+          ld.exVec[slice] = ex;
+          ld.eyVec[slice] = ey;
+          ld.etVec[slice] = et;
+          sums->addEx(ld.exVec);
+          sums->addEy(ld.eyVec);
+          sums->addEt(ld.etVec);
         }
       } else if (verbose) {
         msg(MSG::VERBOSE) << "No energy sums data for crate/module/slice "
@@ -1452,19 +1487,22 @@ void JepByteStreamTool::decodeJem(JemSubBlock* subBlock, int trigJem,
 
 const 
 LVL1::JetElement* JepByteStreamTool::findJetElement(const double eta,
-                                                    const double phi) const
+                                                    const double phi,
+                                                    const ConstJetElementMap& jeMap,
+                                                    LVL1::JetElementKey& elementKey) const
 {
-  const unsigned int key = m_elementKey->jeKey(phi, eta);
-  ConstJetElementMap::const_iterator mapIter = m_jeMap.find(key);
-  if (mapIter != m_jeMap.end()) return mapIter->second;
+  const unsigned int key = elementKey.jeKey(phi, eta);
+  ConstJetElementMap::const_iterator mapIter = jeMap.find(key);
+  if (mapIter != jeMap.end()) return mapIter->second;
   return nullptr;
 }
 
 LVL1::JetElement* JepByteStreamTool::findJetElement(const JetElementData& data,
                                                     const double eta,
-                                                    const double phi) const
+                                                    const double phi,
+                                                    LVL1::JetElementKey& elementKey) const
 {
-  const unsigned int key = m_elementKey->jeKey(phi, eta);
+  const unsigned int key = elementKey.jeKey(phi, eta);
   JetElementMap::const_iterator mapIter = data.m_jeMap.find(key);
   if (mapIter != data.m_jeMap.end()) return mapIter->second;
   return nullptr;
@@ -1474,10 +1512,11 @@ LVL1::JetElement* JepByteStreamTool::findJetElement(const JetElementData& data,
 
 const
 LVL1::JEMHits* JepByteStreamTool::findJetHits(const int crate,
-                                              const int module) const
+                                              const int module,
+                                              const ConstJetHitsMap& hitsMap) const
 {
-  ConstJetHitsMap::const_iterator mapIter = m_hitsMap.find(crate * m_modules + module);
-  if (mapIter != m_hitsMap.end()) return mapIter->second;
+  ConstJetHitsMap::const_iterator mapIter = hitsMap.find(crate * m_modules + module);
+  if (mapIter != hitsMap.end()) return mapIter->second;
   return nullptr;
 }
 
@@ -1494,10 +1533,11 @@ LVL1::JEMHits* JepByteStreamTool::findJetHits(const JetHitsData& data,
 
 const
 LVL1::JEMEtSums* JepByteStreamTool::findEnergySums(const int crate,
-                                                   const int module) const
+                                                   const int module,
+                                                   const ConstEnergySumsMap& etMap) const
 {
-  ConstEnergySumsMap::const_iterator mapIter = m_etMap.find(crate * m_modules + module);
-  if (mapIter != m_etMap.end()) return mapIter->second;
+  ConstEnergySumsMap::const_iterator mapIter = etMap.find(crate * m_modules + module);
+  if (mapIter != etMap.end()) return mapIter->second;
   return nullptr;
 }
 
@@ -1514,10 +1554,11 @@ LVL1::JEMEtSums* JepByteStreamTool::findEnergySums(const EnergySumsData& data,
 
 const
 LVL1::CMMJetHits* JepByteStreamTool::findCmmHits(const int crate,
-                                                 const int dataID) const
+                                                 const int dataID,
+                                                 const ConstCmmHitsMap& cmmHitsMap) const
 {
-  ConstCmmHitsMap::const_iterator mapIter = m_cmmHitsMap.find(crate * 100 + dataID);
-  if (mapIter != m_cmmHitsMap.end()) return mapIter->second;
+  ConstCmmHitsMap::const_iterator mapIter = cmmHitsMap.find(crate * 100 + dataID);
+  if (mapIter != cmmHitsMap.end()) return mapIter->second;
   return nullptr;
 }
 
@@ -1534,10 +1575,11 @@ LVL1::CMMJetHits* JepByteStreamTool::findCmmHits(const CmmHitsData& data,
 
 const
 LVL1::CMMEtSums* JepByteStreamTool::findCmmSums(const int crate,
-                                                const int dataID) const
+                                                const int dataID,
+                                                const ConstCmmSumsMap& cmmEtMap) const
 {
-  ConstCmmSumsMap::const_iterator mapIter = m_cmmEtMap.find(crate * 100 + dataID);
-  if (mapIter != m_cmmEtMap.end()) return mapIter->second;
+  ConstCmmSumsMap::const_iterator mapIter = cmmEtMap.find(crate * 100 + dataID);
+  if (mapIter != cmmEtMap.end()) return mapIter->second;
   return nullptr;
 }
 
@@ -1553,16 +1595,18 @@ LVL1::CMMEtSums* JepByteStreamTool::findCmmSums(const CmmSumsData& data,
 // Set up jet element map
 
 void JepByteStreamTool::setupJeMap(const JetElementCollection*
-                                   const jeCollection)
+                                   const jeCollection,
+                                   ConstJetElementMap& jeMap,
+                                   LVL1::JetElementKey& elementKey) const
 {
-  m_jeMap.clear();
+  jeMap.clear();
   if (jeCollection) {
     JetElementCollection::const_iterator pos  = jeCollection->begin();
     JetElementCollection::const_iterator pose = jeCollection->end();
     for (; pos != pose; ++pos) {
       const LVL1::JetElement* const je = *pos;
-      const unsigned int key = m_elementKey->jeKey(je->phi(), je->eta());
-      m_jeMap.insert(std::make_pair(key, je));
+      const unsigned int key = elementKey.jeKey(je->phi(), je->eta());
+      jeMap.insert(std::make_pair(key, je));
     }
   }
 }
@@ -1570,9 +1614,10 @@ void JepByteStreamTool::setupJeMap(const JetElementCollection*
 // Set up jet hits map
 
 void JepByteStreamTool::setupHitsMap(const JetHitsCollection*
-                                     const hitCollection)
+                                     const hitCollection,
+                                     ConstJetHitsMap& hitsMap) const
 {
-  m_hitsMap.clear();
+  hitsMap.clear();
   if (hitCollection) {
     JetHitsCollection::const_iterator pos  = hitCollection->begin();
     JetHitsCollection::const_iterator pose = hitCollection->end();
@@ -1580,7 +1625,7 @@ void JepByteStreamTool::setupHitsMap(const JetHitsCollection*
       const LVL1::JEMHits* const hits = *pos;
       const int crate = hits->crate() - m_crateOffsetSw;
       const int key   = m_modules * crate + hits->module();
-      m_hitsMap.insert(std::make_pair(key, hits));
+      hitsMap.insert(std::make_pair(key, hits));
     }
   }
 }
@@ -1588,9 +1633,10 @@ void JepByteStreamTool::setupHitsMap(const JetHitsCollection*
 // Set up energy sums map
 
 void JepByteStreamTool::setupEtMap(const EnergySumsCollection*
-                                   const etCollection)
+                                   const etCollection,
+                                   ConstEnergySumsMap& etMap) const
 {
-  m_etMap.clear();
+  etMap.clear();
   if (etCollection) {
     EnergySumsCollection::const_iterator pos  = etCollection->begin();
     EnergySumsCollection::const_iterator pose = etCollection->end();
@@ -1598,7 +1644,7 @@ void JepByteStreamTool::setupEtMap(const EnergySumsCollection*
       const LVL1::JEMEtSums* const sums = *pos;
       const int crate = sums->crate() - m_crateOffsetSw;
       const int key   = m_modules * crate + sums->module();
-      m_etMap.insert(std::make_pair(key, sums));
+      etMap.insert(std::make_pair(key, sums));
     }
   }
 }
@@ -1606,9 +1652,10 @@ void JepByteStreamTool::setupEtMap(const EnergySumsCollection*
 // Set up CMM hits map
 
 void JepByteStreamTool::setupCmmHitsMap(const CmmHitsCollection*
-                                        const hitCollection)
+                                        const hitCollection,
+                                        ConstCmmHitsMap& cmmHitsMap) const
 {
-  m_cmmHitsMap.clear();
+  cmmHitsMap.clear();
   if (hitCollection) {
     CmmHitsCollection::const_iterator pos  = hitCollection->begin();
     CmmHitsCollection::const_iterator pose = hitCollection->end();
@@ -1616,7 +1663,7 @@ void JepByteStreamTool::setupCmmHitsMap(const CmmHitsCollection*
       const LVL1::CMMJetHits* const hits = *pos;
       const int crate = hits->crate() - m_crateOffsetSw;
       const int key   = crate * 100 + hits->dataID();
-      m_cmmHitsMap.insert(std::make_pair(key, hits));
+      cmmHitsMap.insert(std::make_pair(key, hits));
     }
   }
 }
@@ -1624,9 +1671,10 @@ void JepByteStreamTool::setupCmmHitsMap(const CmmHitsCollection*
 // Set up CMM energy sums map
 
 void JepByteStreamTool::setupCmmEtMap(const CmmSumsCollection*
-                                      const etCollection)
+                                      const etCollection,
+                                      ConstCmmSumsMap& cmmEtMap) const
 {
-  m_cmmEtMap.clear();
+  cmmEtMap.clear();
   if (etCollection) {
     CmmSumsCollection::const_iterator pos  = etCollection->begin();
     CmmSumsCollection::const_iterator pose = etCollection->end();
@@ -1634,7 +1682,7 @@ void JepByteStreamTool::setupCmmEtMap(const CmmSumsCollection*
       const LVL1::CMMEtSums* const sums = *pos;
       const int crate = sums->crate() - m_crateOffsetSw;
       const int key   = crate * 100 + sums->dataID();
-      m_cmmEtMap.insert(std::make_pair(key, sums));
+      cmmEtMap.insert(std::make_pair(key, sums));
     }
   }
 }
@@ -1642,7 +1690,15 @@ void JepByteStreamTool::setupCmmEtMap(const CmmSumsCollection*
 // Get number of slices and triggered slice offset for next slink
 
 bool JepByteStreamTool::slinkSlices(const int crate, const int module,
-                                    const int modulesPerSlink, int& timeslices, int& trigJem)
+                                    const int modulesPerSlink,
+                                    int& timeslices,
+                                    int& trigJem,
+                                    const ConstJetElementMap& jeMap,
+                                    const ConstJetHitsMap& hitsMap,
+                                    const ConstEnergySumsMap& etMap,
+                                    const ConstCmmHitsMap& cmmHitsMap,
+                                    const ConstCmmSumsMap& cmmEtMap,
+                                    LVL1::JetElementKey& elementKey) const
 {
   int slices = -1;
   int trigJ  = m_dfltSlices / 2;
@@ -1652,7 +1708,7 @@ bool JepByteStreamTool::slinkSlices(const int crate, const int module,
       double phi = 0.;
       int layer = 0;
       if ( !m_jemMaps->mapping(crate, mod, chan, eta, phi, layer)) continue;
-      const LVL1::JetElement* const je = findJetElement(eta, phi);
+      const LVL1::JetElement* const je = findJetElement(eta, phi, jeMap, elementKey);
       if ( !je ) continue;
       const int numdat = 5;
       std::vector<int> sums(numdat);
@@ -1681,7 +1737,7 @@ bool JepByteStreamTool::slinkSlices(const int crate, const int module,
         } else if (slices != sizes[i] || trigJ != peak) return false;
       }
     }
-    const LVL1::JEMHits* const hits = findJetHits(crate, mod);
+    const LVL1::JEMHits* const hits = findJetHits(crate, mod, hitsMap);
     if (hits) {
       const unsigned int sum = std::accumulate((hits->JetHitsVec()).begin(),
                                (hits->JetHitsVec()).end(), 0);
@@ -1694,7 +1750,7 @@ bool JepByteStreamTool::slinkSlices(const int crate, const int module,
         } else if (slices != size || trigJ != peak) return false;
       }
     }
-    const LVL1::JEMEtSums* const et = findEnergySums(crate, mod);
+    const LVL1::JEMEtSums* const et = findEnergySums(crate, mod, etMap);
     if (et) {
       const int numdat = 3;
       std::vector<unsigned int> sums(numdat);
@@ -1728,7 +1784,7 @@ bool JepByteStreamTool::slinkSlices(const int crate, const int module,
       std::vector<unsigned int> sums(numdat);
       std::vector<int> sizes(numdat);
       const LVL1::CMMJetHits* hits = 0;
-      if (dataID < maxDataID1) hits = findCmmHits(crate, dataID);
+      if (dataID < maxDataID1) hits = findCmmHits(crate, dataID, cmmHitsMap);
       if (hits) {
         sums[0] = std::accumulate((hits->HitsVec()).begin(),
                                   (hits->HitsVec()).end(), 0);
@@ -1746,7 +1802,7 @@ bool JepByteStreamTool::slinkSlices(const int crate, const int module,
         }
       }
       const LVL1::CMMEtSums* et = 0;
-      if (dataID < maxDataID2) et = findCmmSums(crate, dataID);
+      if (dataID < maxDataID2) et = findCmmSums(crate, dataID, cmmEtMap);
       if (et) {
         sums[0] = std::accumulate((et->ExVec()).begin(),
                                   (et->ExVec()).end(), 0);
diff --git a/Trigger/TrigT1/TrigT1CaloByteStream/src/JepByteStreamTool.h b/Trigger/TrigT1/TrigT1CaloByteStream/src/JepByteStreamTool.h
index a52025e28b3e8b5261d7c9e439272fe34c3e32ec..e8e3b27f8aa23a8373ea995c5bf35db700fa18ca 100755
--- a/Trigger/TrigT1/TrigT1CaloByteStream/src/JepByteStreamTool.h
+++ b/Trigger/TrigT1/TrigT1CaloByteStream/src/JepByteStreamTool.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRIGT1CALOBYTESTREAM_JEPBYTESTREAMTOOL_H
@@ -11,7 +11,9 @@
 #include <string>
 #include <vector>
 
+#include "L1CaloSrcIdMap.h"
 #include "AthenaBaseComps/AthAlgTool.h"
+#include "TrigT1CaloUtils/JetElementKey.h"
 #include "ByteStreamCnvSvcBase/IROBDataProviderSvc.h"
 #include "ByteStreamData/RawEvent.h"
 #include "AthContainers/DataVector.h"
@@ -65,28 +67,59 @@ class JepByteStreamTool : public AthAlgTool {
    virtual StatusCode finalize();
 
    /// Convert ROB fragments to jet elements
-   StatusCode convert(const IROBDataProviderSvc::VROBFRAG& robFrags,
-                      DataVector<LVL1::JetElement>* jeCollection);
+   StatusCode convert(const std::string& sgKey,
+                      const IROBDataProviderSvc::VROBFRAG& robFrags,
+                      DataVector<LVL1::JetElement>* jeCollection) const;
    /// Convert ROB fragments to jet hits
-   StatusCode convert(const IROBDataProviderSvc::VROBFRAG& robFrags,
-                      DataVector<LVL1::JEMHits>* hitCollection);
+   StatusCode convert(const std::string& sgKey,
+                      const IROBDataProviderSvc::VROBFRAG& robFrags,
+                      DataVector<LVL1::JEMHits>* hitCollection) const;
    /// Convert ROB fragments to energy sums
-   StatusCode convert(const IROBDataProviderSvc::VROBFRAG& robFrags,
-                      DataVector<LVL1::JEMEtSums>* etCollection);
+   StatusCode convert(const std::string& sgKey,
+                      const IROBDataProviderSvc::VROBFRAG& robFrags,
+                      DataVector<LVL1::JEMEtSums>* etCollection) const;
    /// Convert ROB fragments to CMM jet hits
-   StatusCode convert(const IROBDataProviderSvc::VROBFRAG& robFrags,
-                      DataVector<LVL1::CMMJetHits>* hitCollection);
+   StatusCode convert(const std::string& sgKey,
+                      const IROBDataProviderSvc::VROBFRAG& robFrags,
+                      DataVector<LVL1::CMMJetHits>* hitCollection) const;
    /// Convert ROB fragments to CMM energy sums
-   StatusCode convert(const IROBDataProviderSvc::VROBFRAG& robFrags,
-                      DataVector<LVL1::CMMEtSums>* etCollection);
+   StatusCode convert(const std::string& sgKey,
+                      const IROBDataProviderSvc::VROBFRAG& robFrags,
+                      DataVector<LVL1::CMMEtSums>* etCollection) const;
 
    /// Convert JEP Container to bytestream
-   StatusCode convert(const LVL1::JEPBSCollection* jep, RawEventWrite* re);
+   StatusCode convert(const LVL1::JEPBSCollection* jep, RawEventWrite* re) const;
 
    /// Return reference to vector with all possible Source Identifiers
-   const std::vector<uint32_t>& sourceIDs(const std::string& sgKey);
+   const std::vector<uint32_t>& sourceIDs() const;
 
  private:
+   struct LocalData
+   {
+     /// Jet elements to accept (0=Core, 1=Overlap)
+     int coreOverlap = 0;
+     /// Unpacking error code
+     unsigned int rodErr = 0;
+     /// Ex vector for unpacking
+     std::vector<unsigned int> exVec;
+     /// Ey vector for unpacking
+     std::vector<unsigned int> eyVec;
+     /// Et vector for unpacking
+     std::vector<unsigned int> etVec;
+     /// Ex error vector for unpacking
+     std::vector<int> exErrVec;
+     /// Ex error vector for unpacking
+     std::vector<int> eyErrVec;
+     /// Ex error vector for unpacking
+     std::vector<int> etErrVec;
+     /// Hits vector for unpacking
+     std::vector<unsigned int> hitsVec;
+     /// Error vector for unpacking
+     std::vector<int> errVec;
+     /// Jet element key provider
+     LVL1::JetElementKey elementKey;
+   };
+
    enum CollectionType { JET_ELEMENTS, JET_HITS, ENERGY_SUMS,
                                        CMM_HITS, CMM_SUMS };
 
@@ -152,129 +185,103 @@ class JepByteStreamTool : public AthAlgTool {
    };
 
    /// Convert bytestream to given container type
-   StatusCode convertBs(const IROBDataProviderSvc::VROBFRAG& robFrags,
-                        JepByteStreamToolData& data);
+   StatusCode convertBs(const std::string& sgKey,
+                        const IROBDataProviderSvc::VROBFRAG& robFrags,
+                        JepByteStreamToolData& data) const;
    /// Unpack CMM-Energy sub-block
-   void decodeCmmEnergy(CmmEnergySubBlock* subBlock, int trigCmm, CmmSumsData& data);
+   void decodeCmmEnergy(CmmEnergySubBlock* subBlock, int trigCmm, CmmSumsData& data,
+                        LocalData& ld) const;
    /// Unpack CMM-Jet sub-block
-   void decodeCmmJet(CmmJetSubBlock* subBlock, int trigCmm, CmmHitsData& data);
+   void decodeCmmJet(CmmJetSubBlock* subBlock, int trigCmm, CmmHitsData& data,
+                     LocalData& ld) const;
    /// Unpack JEM sub-block
    void decodeJem(JemSubBlock* subBlock, int trigJem,
-                  JepByteStreamToolData& data);
+                  JepByteStreamToolData& data,
+                  LocalData& ld) const;
 
    /// Find a jet element given eta, phi
-   const LVL1::JetElement* findJetElement(double eta, double phi) const;
-   LVL1::JetElement* findJetElement(const JetElementData& data, double eta, double phi) const;
+   const LVL1::JetElement* findJetElement(double eta, double phi,
+                                          const ConstJetElementMap& jeMap,
+                                          LVL1::JetElementKey& elementKey) const;
+   LVL1::JetElement* findJetElement(const JetElementData& data, double eta, double phi,
+                                    LVL1::JetElementKey& elementKey) const;
    /// Find jet hits for given crate, module
-   const LVL1::JEMHits*    findJetHits(int crate, int module) const;
+   const LVL1::JEMHits*    findJetHits(int crate, int module,
+                                       const ConstJetHitsMap& hitsMap) const;
    LVL1::JEMHits*    findJetHits(const JetHitsData& data, int crate, int module) const;
    /// Find energy sums for given crate, module
-   const LVL1::JEMEtSums*  findEnergySums(int crate, int module) const;
+   const LVL1::JEMEtSums*  findEnergySums(int crate, int module,
+                                          const ConstEnergySumsMap& etMap) const;
    LVL1::JEMEtSums*  findEnergySums(const EnergySumsData& data, int crate, int module) const;
    /// Find CMM hits for given crate, data ID
-   const LVL1::CMMJetHits* findCmmHits(int crate, int dataID) const;
+   const LVL1::CMMJetHits* findCmmHits(int crate, int dataID,
+                                       const ConstCmmHitsMap& cmmHitsMap) const;
    LVL1::CMMJetHits* findCmmHits(const CmmHitsData& data, int crate, int dataID) const;
    /// Find CMM energy sums for given crate, data ID
-   const LVL1::CMMEtSums*  findCmmSums(int crate, int dataID) const;
+   const LVL1::CMMEtSums*  findCmmSums(int crate, int dataID,
+                                       const ConstCmmSumsMap& cmmEtMap) const;
    LVL1::CMMEtSums*  findCmmSums(const CmmSumsData& data, int crate, int dataID) const;
 
+   std::vector<uint32_t> makeSourceIDs() const;
+
    /// Set up jet element map
-   void setupJeMap(const JetElementCollection* jeCollection);
+   void setupJeMap(const JetElementCollection* jeCollection,
+                   ConstJetElementMap& jeMap,
+                   LVL1::JetElementKey& elementKey) const;
    /// Set up jet hits map
-   void setupHitsMap(const JetHitsCollection* hitCollection);
+   void setupHitsMap(const JetHitsCollection* hitCollection,
+                     ConstJetHitsMap& hitsMap) const;
    /// Set up energy sums map
-   void setupEtMap(const EnergySumsCollection* enCollection);
+   void setupEtMap(const EnergySumsCollection* enCollection,
+                   ConstEnergySumsMap& etMap) const;
    /// Set up CMM hits map
-   void setupCmmHitsMap(const CmmHitsCollection* hitCollection);
+   void setupCmmHitsMap(const CmmHitsCollection* hitCollection,
+                        ConstCmmHitsMap& cmmHitsMap) const;
    /// Set up CMM energy sums map
-   void setupCmmEtMap(const CmmSumsCollection* enCollection);
+   void setupCmmEtMap(const CmmSumsCollection* enCollection,
+                      ConstCmmSumsMap& cmmEtMap) const;
 
    /// Get number of slices and triggered slice offset for next slink
    bool slinkSlices(int crate, int module, int modulesPerSlink,
-                    int& timeslices, int& trigJem);
+                    int& timeslices, int& trigJem,
+                    const ConstJetElementMap& jeMap,
+                    const ConstJetHitsMap& hitsMap,
+                    const ConstEnergySumsMap& etMap,
+                    const ConstCmmHitsMap& cmmHitsMap,
+                    const ConstCmmSumsMap& cmmEtMap,
+                    LVL1::JetElementKey& elementKey) const;
 
-   /// Channel mapping tool
+   /// Property: Channel mapping tool
    ToolHandle<LVL1::IL1CaloMappingTool> m_jemMaps;
    /// Error collection tool
    ToolHandle<LVL1BS::L1CaloErrorByteStreamTool> m_errorTool;
 
-   /// Hardware crate number offset
+   /// Property: Hardware crate number offset
    int m_crateOffsetHw;
-   /// Software crate number offset
+   /// Property: Software crate number offset
    int m_crateOffsetSw;
-   /// Sub_block header version
+   /// Property: Sub_block header version
    int m_version;
-   /// Data compression format
+   /// Property: Data compression format
    int m_dataFormat;
    /// Number of channels per module
-   int m_channels;
+   const int m_channels;
    /// Number of crates
-   int m_crates;
+   const int m_crates;
    /// Number of JEM modules per crate
-   int m_modules;
-   /// Number of slinks per crate when writing out bytestream
+   const int m_modules;
+   /// Property: Number of slinks per crate when writing out bytestream
    int m_slinks;
-   /// Default number of slices in simulation
+   /// Property: Default number of slices in simulation
    int m_dfltSlices;
-   /// Force number of slices in bytestream
+   /// Property: Force number of slices in bytestream
    int m_forceSlices;
-   /// Jet elements to accept (0=Core, 1=Overlap)
-   int m_coreOverlap;
-   /// Unpacking error code
-   unsigned int m_rodErr;
-   /// ROB source IDs
-   std::vector<uint32_t> m_sourceIDs;
+   /// Property: ROB source IDs
+   std::vector<uint32_t> m_sourceIDsProp;
    /// Sub-detector type
-   eformat::SubDetector m_subDetector;
+   const eformat::SubDetector m_subDetector;
    /// Source ID converter
-   L1CaloSrcIdMap* m_srcIdMap;
-   /// Jet element key provider
-   LVL1::JetElementKey* m_elementKey;
-   /// JemSubBlock for unpacking
-   JemSubBlock* m_jemSubBlock;
-   /// CmmEnergySubBlock for unpacking
-   CmmEnergySubBlock* m_cmmEnergySubBlock;
-   /// CmmJetSubBlock for unpacking
-   CmmJetSubBlock* m_cmmJetSubBlock;
-   /// Ex vector for unpacking
-   std::vector<unsigned int> m_exVec;
-   /// Ey vector for unpacking
-   std::vector<unsigned int> m_eyVec;
-   /// Et vector for unpacking
-   std::vector<unsigned int> m_etVec;
-   /// Ex error vector for unpacking
-   std::vector<int> m_exErrVec;
-   /// Ex error vector for unpacking
-   std::vector<int> m_eyErrVec;
-   /// Ex error vector for unpacking
-   std::vector<int> m_etErrVec;
-   /// Hits vector for unpacking
-   std::vector<unsigned int> m_hitsVec;
-   /// Error vector for unpacking
-   std::vector<int> m_errVec;
-   /// Vector for current JEM sub-blocks
-   DataVector<JemSubBlock> m_jemBlocks;
-   /// Vector for current CMM-Energy sub-blocks
-   DataVector<CmmEnergySubBlock> m_cmmEnergyBlocks;
-   /// Vector for current CMM-Jet sub-blocks
-   DataVector<CmmJetSubBlock> m_cmmJetBlocks;
-   /// Jet element map
-   ConstJetElementMap m_jeMap;
-   /// Jet hits map
-   ConstJetHitsMap    m_hitsMap;
-   /// Energy sums map
-   ConstEnergySumsMap m_etMap;
-   /// CMM hits map
-   ConstCmmHitsMap    m_cmmHitsMap;
-   /// CMM energy sums map
-   ConstCmmSumsMap    m_cmmEtMap;
-   /// ROD Status words
-   std::vector<uint32_t>* m_rodStatus;
-   /// ROD status map
-   std::map<uint32_t, std::vector<uint32_t>* > m_rodStatusMap;
-   /// Event assembler
-   FullEventAssembler<L1CaloSrcIdMap>* m_fea;
-
+   const L1CaloSrcIdMap m_srcIdMap;
 };
 
 } // end namespace
diff --git a/Trigger/TrigT1/TrigT1CaloByteStream/src/JepByteStreamV1Tool.cxx b/Trigger/TrigT1/TrigT1CaloByteStream/src/JepByteStreamV1Tool.cxx
index 50c664bb8453d85c26b4f27b38179a1e5e98ca9d..bcd54f35fd88d873f03bb62ecf28787cb73b3ef8 100755
--- a/Trigger/TrigT1/TrigT1CaloByteStream/src/JepByteStreamV1Tool.cxx
+++ b/Trigger/TrigT1/TrigT1CaloByteStream/src/JepByteStreamV1Tool.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 
@@ -55,11 +55,8 @@ JepByteStreamV1Tool::JepByteStreamV1Tool(const std::string& type,
   : AthAlgTool(type, name, parent),
     m_jemMaps("LVL1::JemMappingTool/JemMappingTool"),
     m_errorTool("LVL1BS::L1CaloErrorByteStreamTool/L1CaloErrorByteStreamTool"),
-    m_channels(44), m_crates(2), m_modules(16), m_coreOverlap(0),
-    m_subDetector(eformat::TDAQ_CALO_JET_PROC_DAQ),
-    m_srcIdMap(0), m_elementKey(0),
-    m_jemSubBlock(0), m_cmmEnergySubBlock(0), m_cmmJetSubBlock(0),
-    m_rodStatus(0), m_fea(0)
+    m_channels(44), m_crates(2), m_modules(16), 
+    m_subDetector(eformat::TDAQ_CALO_JET_PROC_DAQ)
 {
   declareInterface<JepByteStreamV1Tool>(this);
 
@@ -76,7 +73,7 @@ JepByteStreamV1Tool::JepByteStreamV1Tool(const std::string& type,
                   "The number of S-Links per crate");
 
   // Properties for reading bytestream only
-  declareProperty("ROBSourceIDs",       m_sourceIDs,
+  declareProperty("ROBSourceIDs",       m_sourceIDsProp,
                   "ROB fragment source identifiers");
 
   // Properties for writing bytestream only
@@ -106,28 +103,12 @@ JepByteStreamV1Tool::~JepByteStreamV1Tool()
 
 StatusCode JepByteStreamV1Tool::initialize()
 {
-  msg(MSG::INFO) << "Initializing " << name() << " - package version "
-                 << PACKAGE_VERSION << endmsg;
-
-  StatusCode sc = m_jemMaps.retrieve();
-  if (sc.isFailure()) {
-    msg(MSG::ERROR) << "Failed to retrieve tool " << m_jemMaps << endmsg;
-    return sc;
-  } else msg(MSG::INFO) << "Retrieved tool " << m_jemMaps << endmsg;
-
-  sc = m_errorTool.retrieve();
-  if (sc.isFailure()) {
-    msg(MSG::ERROR) << "Failed to retrieve tool " << m_errorTool << endmsg;
-    return sc;
-  } else msg(MSG::INFO) << "Retrieved tool " << m_errorTool << endmsg;
-
-  m_srcIdMap          = new L1CaloSrcIdMap();
-  m_elementKey        = new LVL1::JetElementKey();
-  m_jemSubBlock       = new JemSubBlockV1();
-  m_cmmEnergySubBlock = new CmmEnergySubBlock();
-  m_cmmJetSubBlock    = new CmmJetSubBlock();
-  m_rodStatus         = new std::vector<uint32_t>(2);
-  m_fea               = new FullEventAssembler<L1CaloSrcIdMap>();
+  ATH_MSG_INFO ("Initializing " << name() << " - package version "
+                 << PACKAGE_VERSION);
+
+  ATH_CHECK( m_jemMaps.retrieve() );
+  ATH_CHECK(  m_errorTool.retrieve() );
+
   return StatusCode::SUCCESS;
 }
 
@@ -135,92 +116,106 @@ StatusCode JepByteStreamV1Tool::initialize()
 
 StatusCode JepByteStreamV1Tool::finalize()
 {
-  delete m_fea;
-  delete m_rodStatus;
-  delete m_cmmJetSubBlock;
-  delete m_cmmEnergySubBlock;
-  delete m_jemSubBlock;
-  delete m_elementKey;
-  delete m_srcIdMap;
   return StatusCode::SUCCESS;
 }
 
 // Conversion bytestream to jet elements
 
 StatusCode JepByteStreamV1Tool::convert(
+  const std::string& sgKey,
   const IROBDataProviderSvc::VROBFRAG& robFrags,
-  DataVector<LVL1::JetElement>* const jeCollection)
+  DataVector<LVL1::JetElement>* const jeCollection) const
 {
   JetElementData data (jeCollection);
-  return convertBs(robFrags, data);
+  return convertBs(sgKey, robFrags, data);
 }
 
 // Conversion bytestream to jet hits
 
 StatusCode JepByteStreamV1Tool::convert(
+  const std::string& sgKey,
   const IROBDataProviderSvc::VROBFRAG& robFrags,
-  DataVector<LVL1::JEMHits>* const hitCollection)
+  DataVector<LVL1::JEMHits>* const hitCollection) const
 {
   JetHitsData data (hitCollection);
-  return convertBs(robFrags, data);
+  return convertBs(sgKey, robFrags, data);
 }
 
 // Conversion bytestream to energy sums
 
 StatusCode JepByteStreamV1Tool::convert(
+  const std::string& sgKey,
   const IROBDataProviderSvc::VROBFRAG& robFrags,
-  DataVector<LVL1::JEMEtSums>* const etCollection)
+  DataVector<LVL1::JEMEtSums>* const etCollection) const
 {
   EnergySumsData data (etCollection);
-  return convertBs(robFrags, data);
+  return convertBs(sgKey, robFrags, data);
 }
 
 // Conversion bytestream to CMM hits
 
 StatusCode JepByteStreamV1Tool::convert(
+  const std::string& sgKey,
   const IROBDataProviderSvc::VROBFRAG& robFrags,
-  DataVector<LVL1::CMMJetHits>* const hitCollection)
+  DataVector<LVL1::CMMJetHits>* const hitCollection) const
 {
   CmmHitsData data (hitCollection);
-  return convertBs(robFrags, data);
+  return convertBs(sgKey, robFrags, data);
 }
 
 // Conversion bytestream to CMM energy sums
 
 StatusCode JepByteStreamV1Tool::convert(
+  const std::string& sgKey,
   const IROBDataProviderSvc::VROBFRAG& robFrags,
-  DataVector<LVL1::CMMEtSums>* const etCollection)
+  DataVector<LVL1::CMMEtSums>* const etCollection) const
 {
   CmmSumsData data (etCollection);
-  return convertBs(robFrags, data);
+  return convertBs(sgKey, robFrags, data);
 }
 
 // Conversion of JEP container to bytestream
 
 StatusCode JepByteStreamV1Tool::convert(const LVL1::JEPBSCollectionV1* const jep,
-                                        RawEventWrite* const re)
+                                        RawEventWrite* const re) const
 {
   const bool debug = msgLvl(MSG::DEBUG);
   if (debug) msg(MSG::DEBUG);
 
   // Clear the event assembler
-
-  m_fea->clear();
-  const uint16_t minorVersion = m_srcIdMap->minorVersionPreLS1();
-  m_fea->setRodMinorVersion(minorVersion);
-  m_rodStatusMap.clear();
+  FullEventAssembler<L1CaloSrcIdMap> fea;
+  fea.clear();
+  const uint16_t minorVersion = m_srcIdMap.minorVersionPreLS1();
+  fea.setRodMinorVersion(minorVersion);
 
   // Pointer to ROD data vector
 
   FullEventAssembler<L1CaloSrcIdMap>::RODDATA* theROD = 0;
 
+  // Jet element key provider
+  LVL1::JetElementKey elementKey;
+
   // Set up the container maps
 
-  setupJeMap(jep->JetElements());
-  setupHitsMap(jep->JetHits());
-  setupEtMap(jep->EnergySums());
-  setupCmmHitsMap(jep->CmmHits());
-  setupCmmEtMap(jep->CmmSums());
+  // Jet element map
+  ConstJetElementMap jeMap;
+  setupJeMap(jep->JetElements(), jeMap, elementKey);
+
+  // Jet hits map
+  ConstJetHitsMap hitsMap;
+  setupHitsMap(jep->JetHits(), hitsMap);
+
+  // Energy sums map
+  ConstEnergySumsMap etMap;
+  setupEtMap(jep->EnergySums(), etMap);
+
+  // CMM hits map
+  ConstCmmHitsMap cmmHitsMap;
+  setupCmmHitsMap(jep->CmmHits(), cmmHitsMap);
+
+  // CMM energy sums map
+  ConstCmmSumsMap cmmEtMap;
+  setupCmmEtMap(jep->CmmSums(), cmmEtMap);
 
   // Loop over data
 
@@ -247,7 +242,14 @@ StatusCode JepByteStreamV1Tool::convert(const LVL1::JEPBSCollectionV1* const jep
         // Get number of JEM slices and triggered slice offset
         // for this slink
         if ( ! slinkSlices(crate, module, modulesPerSlink,
-                           timeslices, trigJem)) {
+                           timeslices, trigJem,
+                           jeMap,
+                           hitsMap,
+                           etMap,
+                           cmmHitsMap,
+                           cmmEtMap,
+                           elementKey))
+        {
           msg(MSG::ERROR) << "Inconsistent number of slices or "
                           << "triggered slice offsets in data for crate "
                           << hwCrate << " slink " << slink << endmsg;
@@ -266,22 +268,23 @@ StatusCode JepByteStreamV1Tool::convert(const LVL1::JEPBSCollectionV1* const jep
         }
         L1CaloUserHeader userHeader;
         userHeader.setJem(trigJemNew);
-        const uint32_t rodIdJem = m_srcIdMap->getRodID(hwCrate, slink, daqOrRoi,
+        const uint32_t rodIdJem = m_srcIdMap.getRodID(hwCrate, slink, daqOrRoi,
                                   m_subDetector);
-        theROD = m_fea->getRodData(rodIdJem);
+        theROD = fea.getRodData(rodIdJem);
         theROD->push_back(userHeader.header());
-        m_rodStatusMap.insert(make_pair(rodIdJem, m_rodStatus));
       }
       if (debug) msg() << "Module " << module << endmsg;
 
       // Create a sub-block for each slice (except Neutral format)
 
-      m_jemBlocks.clear();
+      // Vector for current JEM sub-blocks
+      DataVector<JemSubBlockV1> jemBlocks;
+
       for (int slice = 0; slice < timeslicesNew; ++slice) {
         JemSubBlockV1* const subBlock = new JemSubBlockV1();
         subBlock->setJemHeader(m_version, m_dataFormat, slice,
                                hwCrate, module, timeslicesNew);
-        m_jemBlocks.push_back(subBlock);
+        jemBlocks.push_back(subBlock);
         if (neutralFormat) break;
       }
 
@@ -293,7 +296,7 @@ StatusCode JepByteStreamV1Tool::convert(const LVL1::JEPBSCollectionV1* const jep
         double phi = 0.;
         int layer = 0;
         if (m_jemMaps->mapping(crate, module, chan, eta, phi, layer)) {
-          const LVL1::JetElement* const je = findJetElement(eta, phi);
+          const LVL1::JetElement* const je = findJetElement(eta, phi, jeMap, elementKey);
           if (je ) {
             std::vector<int> emData;
             std::vector<int> hadData;
@@ -307,7 +310,7 @@ StatusCode JepByteStreamV1Tool::convert(const LVL1::JEPBSCollectionV1* const jep
               const LVL1::DataError emErrBits(emErrors[slice]);
               const LVL1::DataError hadErrBits(hadErrors[slice]);
               const int index = ( neutralFormat ) ? 0 : slice;
-              JemSubBlockV1* const subBlock = m_jemBlocks[index];
+              JemSubBlockV1* const subBlock = jemBlocks[index];
               const JemJetElement jetEle(chan, emData[slice], hadData[slice],
                                          emErrBits.get(LVL1::DataError::Parity),
                                          hadErrBits.get(LVL1::DataError::Parity),
@@ -321,17 +324,17 @@ StatusCode JepByteStreamV1Tool::convert(const LVL1::JEPBSCollectionV1* const jep
 
       // Add jet hits and energy subsums
 
-      const LVL1::JEMHits* const hits = findJetHits(crate, module);
+      const LVL1::JEMHits* const hits = findJetHits(crate, module, hitsMap);
       if (hits) {
         std::vector<unsigned int> vec;
         ModifySlices::data(hits->JetHitsVec(), vec, timeslicesNew);
         for (int slice = 0; slice < timeslicesNew; ++slice) {
           const int index = ( neutralFormat ) ? 0 : slice;
-          JemSubBlockV1* const subBlock = m_jemBlocks[index];
+          JemSubBlockV1* const subBlock = jemBlocks[index];
           subBlock->setJetHits(slice, vec[slice]);
         }
       }
-      const LVL1::JEMEtSums* const et = findEnergySums(crate, module);
+      const LVL1::JEMEtSums* const et = findEnergySums(crate, module, etMap);
       if (et) {
         std::vector<unsigned int> exVec;
         std::vector<unsigned int> eyVec;
@@ -341,7 +344,7 @@ StatusCode JepByteStreamV1Tool::convert(const LVL1::JEPBSCollectionV1* const jep
         ModifySlices::data(et->EtVec(), etVec, timeslicesNew);
         for (int slice = 0; slice < timeslicesNew; ++slice) {
           const int index = ( neutralFormat ) ? 0 : slice;
-          JemSubBlockV1* const subBlock = m_jemBlocks[index];
+          JemSubBlockV1* const subBlock = jemBlocks[index];
           subBlock->setEnergySubsums(slice, exVec[slice], eyVec[slice],
                                      etVec[slice]);
         }
@@ -350,7 +353,7 @@ StatusCode JepByteStreamV1Tool::convert(const LVL1::JEPBSCollectionV1* const jep
       // Pack and write the sub-blocks
 
       DataVector<JemSubBlockV1>::iterator pos;
-      for (pos = m_jemBlocks.begin(); pos != m_jemBlocks.end(); ++pos) {
+      for (pos = jemBlocks.begin(); pos != jemBlocks.end(); ++pos) {
         JemSubBlockV1* const subBlock = *pos;
         if ( !subBlock->pack()) {
           msg(MSG::ERROR) << "JEM sub-block packing failed" << endmsg;
@@ -368,8 +371,11 @@ StatusCode JepByteStreamV1Tool::convert(const LVL1::JEPBSCollectionV1* const jep
 
     // Create a sub-block for each slice (except Neutral format)
 
-    m_cmmEnergyBlocks.clear();
-    m_cmmJetBlocks.clear();
+    // Vector for current CMM-Energy sub-blocks
+    DataVector<CmmEnergySubBlock> cmmEnergyBlocks;
+    // Vector for current CMM-Jet sub-blocks
+    DataVector<CmmJetSubBlock> cmmJetBlocks;
+
     const int summing = (crate == m_crates - 1) ? CmmSubBlock::SYSTEM
                         : CmmSubBlock::CRATE;
     for (int slice = 0; slice < timeslicesNew; ++slice) {
@@ -378,12 +384,12 @@ StatusCode JepByteStreamV1Tool::convert(const LVL1::JEPBSCollectionV1* const jep
       enBlock->setCmmHeader(cmmEnergyVersion, m_dataFormat, slice, hwCrate,
                             summing, CmmSubBlock::CMM_ENERGY,
                             CmmSubBlock::LEFT, timeslicesNew);
-      m_cmmEnergyBlocks.push_back(enBlock);
+      cmmEnergyBlocks.push_back(enBlock);
       CmmJetSubBlock* const jetBlock = new CmmJetSubBlock();
       jetBlock->setCmmHeader(m_version, m_dataFormat, slice, hwCrate,
                              summing, CmmSubBlock::CMM_JET,
                              CmmSubBlock::RIGHT, timeslicesNew);
-      m_cmmJetBlocks.push_back(jetBlock);
+      cmmJetBlocks.push_back(jetBlock);
       if (neutralFormat) break;
     }
 
@@ -416,7 +422,7 @@ StatusCode JepByteStreamV1Tool::convert(const LVL1::JEPBSCollectionV1* const jep
           continue;
         }
       }
-      const LVL1::CMMEtSums* const sums = findCmmSums(crate, dataID);
+      const LVL1::CMMEtSums* const sums = findCmmSums(crate, dataID, cmmEtMap);
       if ( sums ) {
         std::vector<unsigned int> ex;
         std::vector<unsigned int> ey;
@@ -445,7 +451,7 @@ StatusCode JepByteStreamV1Tool::convert(const LVL1::JEPBSCollectionV1* const jep
             etError = (etError << 1) + etErrBits.get(LVL1::DataError::Overflow);
           }
           const int index = ( neutralFormat ) ? 0 : slice;
-          CmmEnergySubBlock* const subBlock = m_cmmEnergyBlocks[index];
+          CmmEnergySubBlock* const subBlock = cmmEnergyBlocks[index];
           if (dataID == LVL1::CMMEtSums::MISSING_ET_MAP) {
             subBlock->setMissingEtHits(slice, et[slice]);
           } else if (dataID == LVL1::CMMEtSums::SUM_ET_MAP) {
@@ -461,8 +467,8 @@ StatusCode JepByteStreamV1Tool::convert(const LVL1::JEPBSCollectionV1* const jep
       }
     }
     DataVector<CmmEnergySubBlock>::iterator pos;
-    pos = m_cmmEnergyBlocks.begin();
-    for (; pos != m_cmmEnergyBlocks.end(); ++pos) {
+    pos = cmmEnergyBlocks.begin();
+    for (; pos != cmmEnergyBlocks.end(); ++pos) {
       CmmEnergySubBlock* const subBlock = *pos;
       if ( !subBlock->pack()) {
         msg(MSG::ERROR) << "CMM-Energy sub-block packing failed" << endmsg;
@@ -512,7 +518,7 @@ StatusCode JepByteStreamV1Tool::convert(const LVL1::JEPBSCollectionV1* const jep
           continue;
         }
       }
-      const LVL1::CMMJetHits* const ch = findCmmHits(crate, dataID);
+      const LVL1::CMMJetHits* const ch = findCmmHits(crate, dataID, cmmHitsMap);
       if ( ch ) {
         std::vector<unsigned int> hits;
         std::vector<int> errs;
@@ -521,7 +527,7 @@ StatusCode JepByteStreamV1Tool::convert(const LVL1::JEPBSCollectionV1* const jep
         for (int slice = 0; slice < timeslicesNew; ++slice) {
           const LVL1::DataError errBits(errs[slice]);
           const int index = ( neutralFormat ) ? 0 : slice;
-          CmmJetSubBlock* const subBlock = m_cmmJetBlocks[index];
+          CmmJetSubBlock* const subBlock = cmmJetBlocks[index];
           if (dataID == LVL1::CMMJetHits::ET_MAP) {
             subBlock->setJetEtMap(slice, hits[slice]);
           } else {
@@ -532,8 +538,8 @@ StatusCode JepByteStreamV1Tool::convert(const LVL1::JEPBSCollectionV1* const jep
       }
     }
     DataVector<CmmJetSubBlock>::iterator jos;
-    jos = m_cmmJetBlocks.begin();
-    for (; jos != m_cmmJetBlocks.end(); ++jos) {
+    jos = cmmJetBlocks.begin();
+    for (; jos != cmmJetBlocks.end(); ++jos) {
       CmmJetSubBlock* const subBlock = *jos;
       if ( !subBlock->pack()) {
         msg(MSG::ERROR) << "CMM-Jet sub-block packing failed" << endmsg;
@@ -549,52 +555,70 @@ StatusCode JepByteStreamV1Tool::convert(const LVL1::JEPBSCollectionV1* const jep
 
   // Fill the raw event
 
-  m_fea->fill(re, msg());
-
-  // Set ROD status words
-
-  //L1CaloRodStatus::setStatus(re, m_rodStatusMap, m_srcIdMap);
+  fea.fill(re, msg());
 
   return StatusCode::SUCCESS;
 }
 
 // Return reference to vector with all possible Source Identifiers
 
-const std::vector<uint32_t>& JepByteStreamV1Tool::sourceIDs(
-  const std::string& sgKey)
+std::vector<uint32_t> JepByteStreamV1Tool::makeSourceIDs() const
 {
-  // Check if overlap jet element channels wanted
-  const std::string flag("Overlap");
-  const std::string::size_type pos = sgKey.find(flag);
-  m_coreOverlap =
-    (pos == std::string::npos || pos != sgKey.length() - flag.length()) ? 0 : 1;
+  std::vector<uint32_t> sourceIDs;
 
-  if (m_sourceIDs.empty()) {
+  if (!m_sourceIDsProp.empty()) {
+    sourceIDs = m_sourceIDsProp;
+  }
+  else {
     const int maxCrates = m_crates + m_crateOffsetHw;
-    const int maxSlinks = m_srcIdMap->maxSlinks();
-    for (int hwCrate = m_crateOffsetHw; hwCrate < maxCrates; ++hwCrate) {
-      for (int slink = 0; slink < maxSlinks; ++slink) {
+    const int maxSlinks = m_srcIdMap.maxSlinks();
+    for (int hwCrate = m_crateOffsetHw; hwCrate < maxCrates; ++hwCrate)
+    {
+      for (int slink = 0; slink < maxSlinks; ++slink)
+      {
         const int daqOrRoi = 0;
-        const uint32_t rodId = m_srcIdMap->getRodID(hwCrate, slink, daqOrRoi,
-                               m_subDetector);
-        const uint32_t robId = m_srcIdMap->getRobID(rodId);
-        m_sourceIDs.push_back(robId);
+        const uint32_t rodId = m_srcIdMap.getRodID(hwCrate, slink, daqOrRoi,
+                                                   m_subDetector);
+        const uint32_t robId = m_srcIdMap.getRobID(rodId);
+        sourceIDs.push_back(robId);
       }
     }
   }
-  return m_sourceIDs;
+  return sourceIDs;
+}
+
+const std::vector<uint32_t>& JepByteStreamV1Tool::sourceIDs() const
+{
+  static const std::vector<uint32_t> sourceIDs = makeSourceIDs();
+  return sourceIDs;
 }
 
 // Convert bytestream to given container type
 
 StatusCode JepByteStreamV1Tool::convertBs(
+  const std::string& sgKey,
   const IROBDataProviderSvc::VROBFRAG& robFrags,
-  JepByteStreamToolData& data)
+  JepByteStreamToolData& data) const
 {
+  LocalData ld;
+
+  // Check if overlap jet element channels wanted
+  const std::string flag("Overlap");
+  const std::string::size_type pos = sgKey.find(flag);
+  ld.coreOverlap =
+    (pos == std::string::npos || pos != sgKey.length() - flag.length()) ? 0 : 1;
+
   const bool debug = msgLvl(MSG::DEBUG);
   if (debug) msg(MSG::DEBUG);
 
-  // Loop over ROB fragments
+  // JemSubBlock for unpacking
+  JemSubBlockV1 jemSubBlock;
+  // CmmEnergySubBlock for unpacking
+  CmmEnergySubBlock cmmEnergySubBlock;
+  // CmmJetSubBlock for unpacking
+  CmmJetSubBlock cmmJetSubBlock;
+
+   // Loop over ROB fragments
 
   int robCount = 0;
   std::set<uint32_t> dupCheck;
@@ -643,12 +667,12 @@ StatusCode JepByteStreamV1Tool::convertBs(
 
     // Check identifier
     const uint32_t sourceID = (*rob)->rod_source_id();
-    if (m_srcIdMap->getRobID(sourceID) != robid           ||
-        m_srcIdMap->subDet(sourceID)   != m_subDetector   ||
-        m_srcIdMap->daqOrRoi(sourceID) != 0               ||
-        m_srcIdMap->slink(sourceID)    >= m_slinks        ||
-        m_srcIdMap->crate(sourceID)    <  m_crateOffsetHw ||
-        m_srcIdMap->crate(sourceID)    >= m_crateOffsetHw + m_crates) {
+    if (m_srcIdMap.getRobID(sourceID) != robid           ||
+        m_srcIdMap.subDet(sourceID)   != m_subDetector   ||
+        m_srcIdMap.daqOrRoi(sourceID) != 0               ||
+        m_srcIdMap.slink(sourceID)    >= m_slinks        ||
+        m_srcIdMap.crate(sourceID)    <  m_crateOffsetHw ||
+        m_srcIdMap.crate(sourceID)    >= m_crateOffsetHw + m_crates) {
       m_errorTool->rodError(robid, L1CaloSubBlock::ERROR_ROD_ID);
       if (debug) {
         msg() << "Wrong source identifier in data: ROD "
@@ -660,14 +684,14 @@ StatusCode JepByteStreamV1Tool::convertBs(
 
     // Check minor version
     const int minorVersion = (*rob)->rod_version() & 0xffff;
-    if (minorVersion > m_srcIdMap->minorVersionPreLS1()) {
+    if (minorVersion > m_srcIdMap.minorVersionPreLS1()) {
       if (debug) msg() << "Skipping post-LS1 data" << endmsg;
       continue;
     }
-    const int rodCrate = m_srcIdMap->crate(sourceID);
+    const int rodCrate = m_srcIdMap.crate(sourceID);
     if (debug) {
       msg() << "Treating crate " << rodCrate
-            << " slink " << m_srcIdMap->slink(sourceID) << endmsg;
+            << " slink " << m_srcIdMap.slink(sourceID) << endmsg;
     }
 
     // First word should be User Header
@@ -704,75 +728,75 @@ StatusCode JepByteStreamV1Tool::convertBs(
 
     // Loop over sub-blocks
 
-    m_rodErr = L1CaloSubBlock::ERROR_NONE;
+    ld.rodErr = L1CaloSubBlock::ERROR_NONE;
     while (payload != payloadEnd) {
 
       if (L1CaloSubBlock::wordType(*payload) != L1CaloSubBlock::HEADER) {
         if (debug) msg() << "Unexpected data sequence" << endmsg;
-        m_rodErr = L1CaloSubBlock::ERROR_MISSING_HEADER;
+        ld.rodErr = L1CaloSubBlock::ERROR_MISSING_HEADER;
         break;
       }
       if (CmmSubBlock::cmmBlock(*payload)) {
         // CMMs
         if (CmmSubBlock::cmmType(*payload) == CmmSubBlock::CMM_JET) {
-          m_cmmJetSubBlock->clear();
-          payload = m_cmmJetSubBlock->read(payload, payloadEnd);
-          if (m_cmmJetSubBlock->crate() != rodCrate) {
+          cmmJetSubBlock.clear();
+          payload = cmmJetSubBlock.read(payload, payloadEnd);
+          if (cmmJetSubBlock.crate() != rodCrate) {
             if (debug) msg() << "Inconsistent crate number in ROD source ID"
                                << endmsg;
-            m_rodErr = L1CaloSubBlock::ERROR_CRATE_NUMBER;
+            ld.rodErr = L1CaloSubBlock::ERROR_CRATE_NUMBER;
             break;
           }
           if (data.m_collection == CMM_HITS) {
-            decodeCmmJet(m_cmmJetSubBlock, trigCmm, static_cast<CmmHitsData&>(data));
-            if (m_rodErr != L1CaloSubBlock::ERROR_NONE) {
+            decodeCmmJet(&cmmJetSubBlock, trigCmm, static_cast<CmmHitsData&>(data), ld);
+            if (ld.rodErr != L1CaloSubBlock::ERROR_NONE) {
               if (debug) msg() << "decodeCmmJet failed" << endmsg;
               break;
             }
           }
         } else if (CmmSubBlock::cmmType(*payload) == CmmSubBlock::CMM_ENERGY) {
-          m_cmmEnergySubBlock->clear();
-          payload = m_cmmEnergySubBlock->read(payload, payloadEnd);
-          if (m_cmmEnergySubBlock->crate() != rodCrate) {
+          cmmEnergySubBlock.clear();
+          payload = cmmEnergySubBlock.read(payload, payloadEnd);
+          if (cmmEnergySubBlock.crate() != rodCrate) {
             if (debug) msg() << "Inconsistent crate number in ROD source ID"
                                << endmsg;
-            m_rodErr = L1CaloSubBlock::ERROR_CRATE_NUMBER;
+            ld.rodErr = L1CaloSubBlock::ERROR_CRATE_NUMBER;
             break;
           }
           if (data.m_collection == CMM_SUMS) {
-            decodeCmmEnergy(m_cmmEnergySubBlock, trigCmm, static_cast<CmmSumsData&>(data));
-            if (m_rodErr != L1CaloSubBlock::ERROR_NONE) {
+            decodeCmmEnergy(&cmmEnergySubBlock, trigCmm, static_cast<CmmSumsData&>(data), ld);
+            if (ld.rodErr != L1CaloSubBlock::ERROR_NONE) {
               if (debug) msg() << "decodeCmmEnergy failed" << endmsg;
               break;
             }
           }
         } else {
           if (debug) msg() << "Invalid CMM type in module field" << endmsg;
-          m_rodErr = L1CaloSubBlock::ERROR_MODULE_NUMBER;
+          ld.rodErr = L1CaloSubBlock::ERROR_MODULE_NUMBER;
           break;
         }
       } else {
         // JEM
-        m_jemSubBlock->clear();
-        payload = m_jemSubBlock->read(payload, payloadEnd);
-        if (m_jemSubBlock->crate() != rodCrate) {
+        jemSubBlock.clear();
+        payload = jemSubBlock.read(payload, payloadEnd);
+        if (jemSubBlock.crate() != rodCrate) {
           if (debug) msg() << "Inconsistent crate number in ROD source ID"
                              << endmsg;
-          m_rodErr = L1CaloSubBlock::ERROR_CRATE_NUMBER;
+          ld.rodErr = L1CaloSubBlock::ERROR_CRATE_NUMBER;
           break;
         }
         if (data.m_collection == JET_ELEMENTS || data.m_collection == JET_HITS ||
             data.m_collection == ENERGY_SUMS) {
-          decodeJem(m_jemSubBlock, trigJem, data);
-          if (m_rodErr != L1CaloSubBlock::ERROR_NONE) {
+          decodeJem(&jemSubBlock, trigJem, data, ld);
+          if (ld.rodErr != L1CaloSubBlock::ERROR_NONE) {
             if (debug) msg() << "decodeJem failed" << endmsg;
             break;
           }
         }
       }
     }
-    if (m_rodErr != L1CaloSubBlock::ERROR_NONE)
-      m_errorTool->rodError(robid, m_rodErr);
+    if (ld.rodErr != L1CaloSubBlock::ERROR_NONE)
+      m_errorTool->rodError(robid, ld.rodErr);
   }
 
   return StatusCode::SUCCESS;
@@ -782,7 +806,8 @@ StatusCode JepByteStreamV1Tool::convertBs(
 
 void JepByteStreamV1Tool::decodeCmmEnergy(CmmEnergySubBlock* subBlock,
                                           int trigCmm,
-                                          CmmSumsData& data)
+                                          CmmSumsData& data,
+                                          LocalData& ld) const
 {
   const bool debug = msgLvl(MSG::DEBUG);
   if (debug) msg(MSG::DEBUG);
@@ -805,13 +830,13 @@ void JepByteStreamV1Tool::decodeCmmEnergy(CmmEnergySubBlock* subBlock,
     if (debug) msg() << "Triggered CMM slice from header "
                        << "inconsistent with number of slices: "
                        << trigCmm << ", " << timeslices << endmsg;
-    m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+    ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
     return;
   }
   if (timeslices <= sliceNum) {
     if (debug) msg() << "Total slices inconsistent with slice number: "
                        << timeslices << ", " << sliceNum << endmsg;
-    m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+    ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
     return;
   }
   // Unpack sub-block
@@ -820,7 +845,7 @@ void JepByteStreamV1Tool::decodeCmmEnergy(CmmEnergySubBlock* subBlock,
       std::string errMsg(subBlock->unpackErrorMsg());
       msg() << "CMM-Energy sub-block unpacking failed: " << errMsg << endmsg;
     }
-    m_rodErr = subBlock->unpackErrorCode();
+    ld.rodErr = subBlock->unpackErrorCode();
     return;
   }
 
@@ -887,54 +912,54 @@ void JepByteStreamV1Tool::decodeCmmEnergy(CmmEnergySubBlock* subBlock,
       if (ex || ey || et || exErr || eyErr || etErr) {
         LVL1::CMMEtSums* sums = findCmmSums(data, crate, dataID);
         if ( ! sums ) {   // create new CMM energy sums
-          m_exVec.assign(timeslices, 0);
-          m_eyVec.assign(timeslices, 0);
-          m_etVec.assign(timeslices, 0);
-          m_exErrVec.assign(timeslices, 0);
-          m_eyErrVec.assign(timeslices, 0);
-          m_etErrVec.assign(timeslices, 0);
-          m_exVec[slice] = ex;
-          m_eyVec[slice] = ey;
-          m_etVec[slice] = et;
-          m_exErrVec[slice] = exErr;
-          m_eyErrVec[slice] = eyErr;
-          m_etErrVec[slice] = etErr;
+          ld.exVec.assign(timeslices, 0);
+          ld.eyVec.assign(timeslices, 0);
+          ld.etVec.assign(timeslices, 0);
+          ld.exErrVec.assign(timeslices, 0);
+          ld.eyErrVec.assign(timeslices, 0);
+          ld.etErrVec.assign(timeslices, 0);
+          ld.exVec[slice] = ex;
+          ld.eyVec[slice] = ey;
+          ld.etVec[slice] = et;
+          ld.exErrVec[slice] = exErr;
+          ld.eyErrVec[slice] = eyErr;
+          ld.etErrVec[slice] = etErr;
           auto sumsp =
-            std::make_unique<LVL1::CMMEtSums>(swCrate, dataID, m_etVec, m_exVec, m_eyVec,
-                                              m_etErrVec, m_exErrVec, m_eyErrVec, trigCmm);
+            std::make_unique<LVL1::CMMEtSums>(swCrate, dataID, ld.etVec, ld.exVec, ld.eyVec,
+                                              ld.etErrVec, ld.exErrVec, ld.eyErrVec, trigCmm);
           const int key = crate * 100 + dataID;
           data.m_cmmEtMap.insert(std::make_pair(key, sumsp.get()));
           data.m_cmmEtCollection->push_back(std::move(sumsp));
         } else {
-          m_exVec = sums->ExVec();
-          m_eyVec = sums->EyVec();
-          m_etVec = sums->EtVec();
-          m_exErrVec = sums->ExErrorVec();
-          m_eyErrVec = sums->EyErrorVec();
-          m_etErrVec = sums->EtErrorVec();
-          const int nsl = m_exVec.size();
+          ld.exVec = sums->ExVec();
+          ld.eyVec = sums->EyVec();
+          ld.etVec = sums->EtVec();
+          ld.exErrVec = sums->ExErrorVec();
+          ld.eyErrVec = sums->EyErrorVec();
+          ld.etErrVec = sums->EtErrorVec();
+          const int nsl = ld.exVec.size();
           if (timeslices != nsl) {
             if (debug) msg() << "Inconsistent number of slices in sub-blocks"
                                << endmsg;
-            m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+            ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
             return;
           }
-          if (m_exVec[slice] != 0 || m_eyVec[slice] != 0 || m_etVec[slice] != 0 ||
-              m_exErrVec[slice] != 0 || m_eyErrVec[slice] != 0 ||
-              m_etErrVec[slice] != 0) {
+          if (ld.exVec[slice] != 0 || ld.eyVec[slice] != 0 || ld.etVec[slice] != 0 ||
+              ld.exErrVec[slice] != 0 || ld.eyErrVec[slice] != 0 ||
+              ld.etErrVec[slice] != 0) {
             if (debug) msg() << "Duplicate data for slice " << slice << endmsg;
-            m_rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
+            ld.rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
             return;
           }
-          m_exVec[slice] = ex;
-          m_eyVec[slice] = ey;
-          m_etVec[slice] = et;
-          m_exErrVec[slice] = exErr;
-          m_eyErrVec[slice] = eyErr;
-          m_etErrVec[slice] = etErr;
-          sums->addEx(m_exVec, m_exErrVec);
-          sums->addEy(m_eyVec, m_eyErrVec);
-          sums->addEt(m_etVec, m_etErrVec);
+          ld.exVec[slice] = ex;
+          ld.eyVec[slice] = ey;
+          ld.etVec[slice] = et;
+          ld.exErrVec[slice] = exErr;
+          ld.eyErrVec[slice] = eyErr;
+          ld.etErrVec[slice] = etErr;
+          sums->addEx(ld.exVec, ld.exErrVec);
+          sums->addEy(ld.eyVec, ld.eyErrVec);
+          sums->addEt(ld.etVec, ld.etErrVec);
         }
       }
     }
@@ -947,37 +972,37 @@ void JepByteStreamV1Tool::decodeCmmEnergy(CmmEnergySubBlock* subBlock,
         const int dataID = LVL1::CMMEtSums::MISSING_ET_MAP;
         LVL1::CMMEtSums* map = findCmmSums(data, crate, dataID);
         if ( ! map ) {
-          m_etVec.assign(timeslices, 0);
-          m_etErrVec.assign(timeslices, 0);
-          m_etVec[slice]    = missEt;
-          m_etErrVec[slice] = ssError;
+          ld.etVec.assign(timeslices, 0);
+          ld.etErrVec.assign(timeslices, 0);
+          ld.etVec[slice]    = missEt;
+          ld.etErrVec[slice] = ssError;
           auto mapp =
             std::make_unique<LVL1::CMMEtSums>(swCrate, dataID,
-                                              m_etVec, m_etVec, m_etVec,
-                                              m_etErrVec, m_etErrVec, m_etErrVec, trigCmm);
+                                              ld.etVec, ld.etVec, ld.etVec,
+                                              ld.etErrVec, ld.etErrVec, ld.etErrVec, trigCmm);
           const int key = crate * 100 + dataID;
           data.m_cmmEtMap.insert(std::make_pair(key, mapp.get()));
           data.m_cmmEtCollection->push_back(std::move(mapp));
         } else {
-          m_etVec    = map->EtVec();
-          m_etErrVec = map->EtErrorVec();
-          const int nsl = m_etVec.size();
+          ld.etVec    = map->EtVec();
+          ld.etErrVec = map->EtErrorVec();
+          const int nsl = ld.etVec.size();
           if (timeslices != nsl) {
             if (debug) msg() << "Inconsistent number of slices in sub-blocks"
                                << endmsg;
-            m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+            ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
             return;
           }
-          if (m_etVec[slice] != 0 || m_etErrVec[slice] != 0) {
+          if (ld.etVec[slice] != 0 || ld.etErrVec[slice] != 0) {
             if (debug) msg() << "Duplicate data for slice " << slice << endmsg;
-            m_rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
+            ld.rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
             return;
           }
-          m_etVec[slice]     = missEt;
-          m_etErrVec[slice]  = ssError;
-          map->addEx(m_etVec, m_etErrVec);
-          map->addEy(m_etVec, m_etErrVec);
-          map->addEt(m_etVec, m_etErrVec);
+          ld.etVec[slice]     = missEt;
+          ld.etErrVec[slice]  = ssError;
+          map->addEx(ld.etVec, ld.etErrVec);
+          map->addEy(ld.etVec, ld.etErrVec);
+          map->addEt(ld.etVec, ld.etErrVec);
         }
       }
       const unsigned int sumEt = subBlock->sumEtHits(slice);
@@ -985,37 +1010,37 @@ void JepByteStreamV1Tool::decodeCmmEnergy(CmmEnergySubBlock* subBlock,
         const int dataID = LVL1::CMMEtSums::SUM_ET_MAP;
         LVL1::CMMEtSums* map = findCmmSums(data, crate, dataID);
         if ( ! map ) {
-          m_etVec.assign(timeslices, 0);
-          m_etErrVec.assign(timeslices, 0);
-          m_etVec[slice]    = sumEt;
-          m_etErrVec[slice] = ssError;
+          ld.etVec.assign(timeslices, 0);
+          ld.etErrVec.assign(timeslices, 0);
+          ld.etVec[slice]    = sumEt;
+          ld.etErrVec[slice] = ssError;
           auto mapp =
             std::make_unique<LVL1::CMMEtSums>(swCrate, dataID,
-                                              m_etVec, m_etVec, m_etVec,
-                                              m_etErrVec, m_etErrVec, m_etErrVec, trigCmm);
+                                              ld.etVec, ld.etVec, ld.etVec,
+                                              ld.etErrVec, ld.etErrVec, ld.etErrVec, trigCmm);
           const int key = crate * 100 + dataID;
           data.m_cmmEtMap.insert(std::make_pair(key, mapp.get()));
           data.m_cmmEtCollection->push_back(std::move(mapp));
         } else {
-          m_etVec    = map->EtVec();
-          m_etErrVec = map->EtErrorVec();
-          const int nsl = m_etVec.size();
+          ld.etVec    = map->EtVec();
+          ld.etErrVec = map->EtErrorVec();
+          const int nsl = ld.etVec.size();
           if (timeslices != nsl) {
             if (debug) msg() << "Inconsistent number of slices in sub-blocks"
                                << endmsg;
-            m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+            ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
             return;
           }
-          if (m_etVec[slice] != 0 || m_etErrVec[slice] != 0) {
+          if (ld.etVec[slice] != 0 || ld.etErrVec[slice] != 0) {
             if (debug) msg() << "Duplicate data for slice " << slice << endmsg;
-            m_rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
+            ld.rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
             return;
           }
-          m_etVec[slice]    = sumEt;
-          m_etErrVec[slice] = ssError;
-          map->addEx(m_etVec, m_etErrVec);
-          map->addEy(m_etVec, m_etErrVec);
-          map->addEt(m_etVec, m_etErrVec);
+          ld.etVec[slice]    = sumEt;
+          ld.etErrVec[slice] = ssError;
+          map->addEx(ld.etVec, ld.etErrVec);
+          map->addEy(ld.etVec, ld.etErrVec);
+          map->addEt(ld.etVec, ld.etErrVec);
         }
       }
       if (subBlock->version() > 1) {
@@ -1024,38 +1049,38 @@ void JepByteStreamV1Tool::decodeCmmEnergy(CmmEnergySubBlock* subBlock,
           const int dataID = LVL1::CMMEtSums::MISSING_ET_SIG_MAP;
           LVL1::CMMEtSums* map = findCmmSums(data, crate, dataID);
           if ( ! map ) {
-            m_etVec.assign(timeslices, 0);
-            m_etErrVec.assign(timeslices, 0);
-            m_etVec[slice]    = missEtSig;
-            m_etErrVec[slice] = ssError;
+            ld.etVec.assign(timeslices, 0);
+            ld.etErrVec.assign(timeslices, 0);
+            ld.etVec[slice]    = missEtSig;
+            ld.etErrVec[slice] = ssError;
             auto mapp =
               std::make_unique<LVL1::CMMEtSums>(swCrate, dataID,
-                                                m_etVec, m_etVec, m_etVec,
-                                                m_etErrVec, m_etErrVec, m_etErrVec, trigCmm);
+                                                ld.etVec, ld.etVec, ld.etVec,
+                                                ld.etErrVec, ld.etErrVec, ld.etErrVec, trigCmm);
             const int key = crate * 100 + dataID;
             data.m_cmmEtMap.insert(std::make_pair(key, mapp.get()));
             data.m_cmmEtCollection->push_back(std::move(mapp));
           } else {
-            m_etVec    = map->EtVec();
-            m_etErrVec = map->EtErrorVec();
-            const int nsl = m_etVec.size();
+            ld.etVec    = map->EtVec();
+            ld.etErrVec = map->EtErrorVec();
+            const int nsl = ld.etVec.size();
             if (timeslices != nsl) {
               if (debug) msg() << "Inconsistent number of slices in sub-blocks"
                                  << endmsg;
-              m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+              ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
               return;
             }
-            if (m_etVec[slice] != 0 || m_etErrVec[slice] != 0) {
+            if (ld.etVec[slice] != 0 || ld.etErrVec[slice] != 0) {
               if (debug) msg() << "Duplicate data for slice "
                                  << slice << endmsg;
-              m_rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
+              ld.rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
               return;
             }
-            m_etVec[slice]    = missEtSig;
-            m_etErrVec[slice] = ssError;
-            map->addEx(m_etVec, m_etErrVec);
-            map->addEy(m_etVec, m_etErrVec);
-            map->addEt(m_etVec, m_etErrVec);
+            ld.etVec[slice]    = missEtSig;
+            ld.etErrVec[slice] = ssError;
+            map->addEx(ld.etVec, ld.etErrVec);
+            map->addEy(ld.etVec, ld.etErrVec);
+            map->addEt(ld.etVec, ld.etErrVec);
           }
         }
       }
@@ -1068,7 +1093,8 @@ void JepByteStreamV1Tool::decodeCmmEnergy(CmmEnergySubBlock* subBlock,
 // Unpack CMM-Jet sub-block
 
 void JepByteStreamV1Tool::decodeCmmJet(CmmJetSubBlock* subBlock, int trigCmm,
-                                       CmmHitsData& data)
+                                       CmmHitsData& data,
+                                       LocalData& ld) const
 {
   const bool debug = msgLvl(MSG::DEBUG);
   if (debug) msg(MSG::DEBUG);
@@ -1091,13 +1117,13 @@ void JepByteStreamV1Tool::decodeCmmJet(CmmJetSubBlock* subBlock, int trigCmm,
     if (debug) msg() << "Triggered CMM slice from header "
                        << "inconsistent with number of slices: "
                        << trigCmm << ", " << timeslices << endmsg;
-    m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+    ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
     return;
   }
   if (timeslices <= sliceNum) {
     if (debug) msg() << "Total slices inconsistent with slice number: "
                        << timeslices << ", " << sliceNum << endmsg;
-    m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+    ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
     return;
   }
   // Unpack sub-block
@@ -1106,7 +1132,7 @@ void JepByteStreamV1Tool::decodeCmmJet(CmmJetSubBlock* subBlock, int trigCmm,
       std::string errMsg(subBlock->unpackErrorMsg());
       msg() << "CMM-Jet sub-block unpacking failed: " << errMsg << endmsg;
     }
-    m_rodErr = subBlock->unpackErrorCode();
+    ld.rodErr = subBlock->unpackErrorCode();
     return;
   }
 
@@ -1165,33 +1191,33 @@ void JepByteStreamV1Tool::decodeCmmJet(CmmJetSubBlock* subBlock, int trigCmm,
       if (hits || err) {
         LVL1::CMMJetHits* jh = findCmmHits(data, crate, dataID);
         if ( ! jh ) {   // create new CMM hits
-          m_hitsVec.assign(timeslices, 0);
-          m_errVec.assign(timeslices, 0);
-          m_hitsVec[slice] = hits;
-          m_errVec[slice]  = err;
+          ld.hitsVec.assign(timeslices, 0);
+          ld.errVec.assign(timeslices, 0);
+          ld.hitsVec[slice] = hits;
+          ld.errVec[slice]  = err;
           auto jhp =
-            std::make_unique<LVL1::CMMJetHits>(swCrate, dataID, m_hitsVec, m_errVec, trigCmm);
+            std::make_unique<LVL1::CMMJetHits>(swCrate, dataID, ld.hitsVec, ld.errVec, trigCmm);
           const int key = crate * 100 + dataID;
           data.m_cmmHitsMap.insert(std::make_pair(key, jhp.get()));
           data.m_cmmHitCollection->push_back(std::move(jhp));
         } else {
-          m_hitsVec = jh->HitsVec();
-          m_errVec  = jh->ErrorVec();
-          const int nsl = m_hitsVec.size();
+          ld.hitsVec = jh->HitsVec();
+          ld.errVec  = jh->ErrorVec();
+          const int nsl = ld.hitsVec.size();
           if (timeslices != nsl) {
             if (debug) msg() << "Inconsistent number of slices in sub-blocks"
                                << endmsg;
-            m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+            ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
             return;
           }
-          if (m_hitsVec[slice] != 0 || m_errVec[slice] != 0) {
+          if (ld.hitsVec[slice] != 0 || ld.errVec[slice] != 0) {
             if (debug) msg() << "Duplicate data for slice " << slice << endmsg;
-            m_rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
+            ld.rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
             return;
           }
-          m_hitsVec[slice] = hits;
-          m_errVec[slice]  = err;
-          jh->addHits(m_hitsVec, m_errVec);
+          ld.hitsVec[slice] = hits;
+          ld.errVec[slice]  = err;
+          jh->addHits(ld.hitsVec, ld.errVec);
         }
       }
     }
@@ -1204,33 +1230,33 @@ void JepByteStreamV1Tool::decodeCmmJet(CmmJetSubBlock* subBlock, int trigCmm,
         const int dataID = LVL1::CMMJetHits::ET_MAP;
         LVL1::CMMJetHits* map = findCmmHits(data, crate, dataID);
         if ( ! map ) {
-          m_hitsVec.assign(timeslices, 0);
-          m_errVec.assign(timeslices, 0);
-          m_hitsVec[slice] = etMap;
-          m_errVec[slice]  = ssError;
+          ld.hitsVec.assign(timeslices, 0);
+          ld.errVec.assign(timeslices, 0);
+          ld.hitsVec[slice] = etMap;
+          ld.errVec[slice]  = ssError;
           auto mapp =
-            std::make_unique<LVL1::CMMJetHits>(swCrate, dataID, m_hitsVec, m_errVec, trigCmm);
+            std::make_unique<LVL1::CMMJetHits>(swCrate, dataID, ld.hitsVec, ld.errVec, trigCmm);
           const int key = crate * 100 + dataID;
           data.m_cmmHitsMap.insert(std::make_pair(key, mapp.get()));
           data.m_cmmHitCollection->push_back(std::move(mapp));
         } else {
-          m_hitsVec = map->HitsVec();
-          m_errVec  = map->ErrorVec();
-          const int nsl = m_hitsVec.size();
+          ld.hitsVec = map->HitsVec();
+          ld.errVec  = map->ErrorVec();
+          const int nsl = ld.hitsVec.size();
           if (timeslices != nsl) {
             if (debug) msg() << "Inconsistent number of slices in sub-blocks"
                                << endmsg;
-            m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+            ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
             return;
           }
-          if (m_hitsVec[slice] != 0 || m_errVec[slice] != 0) {
+          if (ld.hitsVec[slice] != 0 || ld.errVec[slice] != 0) {
             if (debug) msg() << "Duplicate data for slice " << slice << endmsg;
-            m_rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
+            ld.rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
             return;
           }
-          m_hitsVec[slice] = etMap;
-          m_errVec[slice]  = ssError;
-          map->addHits(m_hitsVec, m_errVec);
+          ld.hitsVec[slice] = etMap;
+          ld.errVec[slice]  = ssError;
+          map->addHits(ld.hitsVec, ld.errVec);
         }
       }
     }
@@ -1242,7 +1268,8 @@ void JepByteStreamV1Tool::decodeCmmJet(CmmJetSubBlock* subBlock, int trigCmm,
 // Unpack JEM sub-block
 
 void JepByteStreamV1Tool::decodeJem(JemSubBlockV1* subBlock, int trigJem,
-                                    JepByteStreamToolData& data)
+                                    JepByteStreamToolData& data,
+                                    LocalData& ld) const
 {
   const bool debug   = msgLvl(MSG::DEBUG);
   const bool verbose = msgLvl(MSG::VERBOSE);
@@ -1262,13 +1289,13 @@ void JepByteStreamV1Tool::decodeJem(JemSubBlockV1* subBlock, int trigJem,
     if (debug) msg() << "Triggered JEM slice from header "
                        << "inconsistent with number of slices: "
                        << trigJem << ", " << timeslices << endmsg;
-    m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+    ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
     return;
   }
   if (timeslices <= sliceNum) {
     if (debug) msg() << "Total slices inconsistent with slice number: "
                        << timeslices << ", " << sliceNum << endmsg;
-    m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+    ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
     return;
   }
   // Unpack sub-block
@@ -1277,7 +1304,7 @@ void JepByteStreamV1Tool::decodeJem(JemSubBlockV1* subBlock, int trigJem,
       std::string errMsg(subBlock->unpackErrorMsg());
       msg() << "JEM sub-block unpacking failed: " << errMsg << endmsg;
     }
-    m_rodErr = subBlock->unpackErrorCode();
+    ld.rodErr = subBlock->unpackErrorCode();
     return;
   }
 
@@ -1306,10 +1333,10 @@ void JepByteStreamV1Tool::decodeJem(JemSubBlockV1* subBlock, int trigJem,
           double phi = 0.;
           int layer = 0;
           if (m_jemMaps->mapping(crate, module, chan, eta, phi, layer)) {
-            if (layer == m_coreOverlap) {
-	      LVL1::JetElement* je = findJetElement(jedata, eta, phi);
+            if (layer == ld.coreOverlap) {
+	      LVL1::JetElement* je = findJetElement(jedata, eta, phi, ld.elementKey);
               if ( ! je ) {   // create new jet element
-                const unsigned int key = m_elementKey->jeKey(phi, eta);
+                const unsigned int key = ld.elementKey.jeKey(phi, eta);
                 auto jep =
                   std::make_unique<LVL1::JetElement>(phi, eta, dummy, dummy, key,
                                                      dummy, dummy, dummy, trigJem);
@@ -1327,14 +1354,14 @@ void JepByteStreamV1Tool::decodeJem(JemSubBlockV1* subBlock, int trigJem,
                     msg() << "Inconsistent number of slices in sub-blocks"
                           << endmsg;
                   }
-                  m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+                  ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
                   return;
                 }
                 if (emEnergy[slice] != 0 || hadEnergy[slice] != 0 ||
                     emError[slice]  != 0 || hadError[slice]  != 0) {
                   if (debug) msg() << "Duplicate data for slice "
                                      << slice << endmsg;
-                  m_rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
+                  ld.rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
                   return;
                 }
               }
@@ -1369,31 +1396,31 @@ void JepByteStreamV1Tool::decodeJem(JemSubBlockV1* subBlock, int trigJem,
       if (hits) {
         LVL1::JEMHits* jh = findJetHits(jhdata, crate, module);
         if ( ! jh ) {   // create new jet hits
-          m_hitsVec.assign(timeslices, 0);
-          m_hitsVec[slice] = hits;
+          ld.hitsVec.assign(timeslices, 0);
+          ld.hitsVec[slice] = hits;
           auto jhp =
-            std::make_unique<LVL1::JEMHits>(swCrate, module, m_hitsVec, trigJem);
+            std::make_unique<LVL1::JEMHits>(swCrate, module, ld.hitsVec, trigJem);
           jhdata.m_hitsMap.insert(std::make_pair(crate * m_modules + module, jhp.get()));
           jhdata.m_hitCollection->push_back(std::move(jhp));
         } else {
-          m_hitsVec = jh->JetHitsVec();
-          const int nsl = m_hitsVec.size();
+          ld.hitsVec = jh->JetHitsVec();
+          const int nsl = ld.hitsVec.size();
           if (timeslices != nsl) {
             if (debug) {
               msg() << "Inconsistent number of slices in sub-blocks"
                     << endmsg;
             }
-            m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+            ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
             return;
           }
-          if (m_hitsVec[slice] != 0) {
+          if (ld.hitsVec[slice] != 0) {
             if (debug) msg() << "Duplicate data for slice "
                                << slice << endmsg;
-            m_rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
+            ld.rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
             return;
           }
-          m_hitsVec[slice] = hits;
-          jh->addJetHits(m_hitsVec);
+          ld.hitsVec[slice] = hits;
+          jh->addJetHits(ld.hitsVec);
         }
       } else if (verbose) {
         msg(MSG::VERBOSE) << "No jet hits data for crate/module/slice "
@@ -1412,42 +1439,42 @@ void JepByteStreamV1Tool::decodeJem(JemSubBlockV1* subBlock, int trigJem,
       if (ex | ey | et) {
 	LVL1::JEMEtSums* sums = findEnergySums(sumdata, crate, module);
         if ( ! sums ) {   // create new energy sums
-          m_exVec.assign(timeslices, 0);
-          m_eyVec.assign(timeslices, 0);
-          m_etVec.assign(timeslices, 0);
-          m_exVec[slice] = ex;
-          m_eyVec[slice] = ey;
-          m_etVec[slice] = et;
+          ld.exVec.assign(timeslices, 0);
+          ld.eyVec.assign(timeslices, 0);
+          ld.etVec.assign(timeslices, 0);
+          ld.exVec[slice] = ex;
+          ld.eyVec[slice] = ey;
+          ld.etVec[slice] = et;
           auto sumsp =
-            std::make_unique<LVL1::JEMEtSums>(swCrate, module, m_etVec, m_exVec, m_eyVec,
+            std::make_unique<LVL1::JEMEtSums>(swCrate, module, ld.etVec, ld.exVec, ld.eyVec,
                                               trigJem);
           sumdata.m_etMap.insert(std::make_pair(crate * m_modules + module, sumsp.get()));
           sumdata.m_etCollection->push_back(std::move(sumsp));
         } else {
-          m_exVec = sums->ExVec();
-          m_eyVec = sums->EyVec();
-          m_etVec = sums->EtVec();
-          const int nsl = m_exVec.size();
+          ld.exVec = sums->ExVec();
+          ld.eyVec = sums->EyVec();
+          ld.etVec = sums->EtVec();
+          const int nsl = ld.exVec.size();
           if (timeslices != nsl) {
             if (debug) {
               msg() << "Inconsistent number of slices in sub-blocks"
                     << endmsg;
             }
-            m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+            ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
             return;
           }
-          if (m_exVec[slice] != 0 || m_eyVec[slice] != 0 || m_etVec[slice] != 0) {
+          if (ld.exVec[slice] != 0 || ld.eyVec[slice] != 0 || ld.etVec[slice] != 0) {
             if (debug) msg() << "Duplicate data for slice "
                                << slice << endmsg;
-            m_rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
+            ld.rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
             return;
           }
-          m_exVec[slice] = ex;
-          m_eyVec[slice] = ey;
-          m_etVec[slice] = et;
-          sums->addEx(m_exVec);
-          sums->addEy(m_eyVec);
-          sums->addEt(m_etVec);
+          ld.exVec[slice] = ex;
+          ld.eyVec[slice] = ey;
+          ld.etVec[slice] = et;
+          sums->addEx(ld.exVec);
+          sums->addEy(ld.eyVec);
+          sums->addEt(ld.etVec);
         }
       } else if (verbose) {
         msg(MSG::VERBOSE) << "No energy sums data for crate/module/slice "
@@ -1464,19 +1491,22 @@ void JepByteStreamV1Tool::decodeJem(JemSubBlockV1* subBlock, int trigJem,
 
 const 
 LVL1::JetElement* JepByteStreamV1Tool::findJetElement(const double eta,
-                                                      const double phi) const
+                                                      const double phi,
+                                                      const ConstJetElementMap& jeMap,
+                                                      LVL1::JetElementKey& elementKey) const
 {
-  const unsigned int key = m_elementKey->jeKey(phi, eta);
-  ConstJetElementMap::const_iterator mapIter = m_jeMap.find(key);
-  if (mapIter != m_jeMap.end()) return mapIter->second;
+  const unsigned int key = elementKey.jeKey(phi, eta);
+  ConstJetElementMap::const_iterator mapIter = jeMap.find(key);
+  if (mapIter != jeMap.end()) return mapIter->second;
   return nullptr;
 }
 
 LVL1::JetElement* JepByteStreamV1Tool::findJetElement(const JetElementData& data,
                                                       const double eta,
-                                                      const double phi) const
+                                                      const double phi,
+                                                      LVL1::JetElementKey& elementKey) const
 {
-  const unsigned int key = m_elementKey->jeKey(phi, eta);
+  const unsigned int key = elementKey.jeKey(phi, eta);
   JetElementMap::const_iterator mapIter = data.m_jeMap.find(key);
   if (mapIter != data.m_jeMap.end()) return mapIter->second;
   return nullptr;
@@ -1486,10 +1516,11 @@ LVL1::JetElement* JepByteStreamV1Tool::findJetElement(const JetElementData& data
 
 const
 LVL1::JEMHits* JepByteStreamV1Tool::findJetHits(const int crate,
-                                                const int module) const
+                                                const int module,
+                                                const ConstJetHitsMap& hitsMap) const
 {
-  ConstJetHitsMap::const_iterator mapIter = m_hitsMap.find(crate * m_modules + module);
-  if (mapIter != m_hitsMap.end()) return mapIter->second;
+  ConstJetHitsMap::const_iterator mapIter = hitsMap.find(crate * m_modules + module);
+  if (mapIter != hitsMap.end()) return mapIter->second;
   return nullptr;
 }
 
@@ -1506,10 +1537,11 @@ LVL1::JEMHits* JepByteStreamV1Tool::findJetHits(const JetHitsData& data,
 
 const
 LVL1::JEMEtSums* JepByteStreamV1Tool::findEnergySums(const int crate,
-                                                     const int module) const
+                                                     const int module,
+                                                     const ConstEnergySumsMap& etMap) const
 {
-  ConstEnergySumsMap::const_iterator mapIter = m_etMap.find(crate * m_modules + module);
-  if (mapIter != m_etMap.end()) return mapIter->second;
+  ConstEnergySumsMap::const_iterator mapIter = etMap.find(crate * m_modules + module);
+  if (mapIter != etMap.end()) return mapIter->second;
   return nullptr;
 }
 
@@ -1526,10 +1558,11 @@ LVL1::JEMEtSums* JepByteStreamV1Tool::findEnergySums(const EnergySumsData& data,
 
 const
 LVL1::CMMJetHits* JepByteStreamV1Tool::findCmmHits(const int crate,
-                                                   const int dataID) const
+                                                   const int dataID,
+                                                   const ConstCmmHitsMap& cmmHitsMap) const
 {
-  ConstCmmHitsMap::const_iterator mapIter = m_cmmHitsMap.find(crate * 100 + dataID);
-  if (mapIter != m_cmmHitsMap.end()) return mapIter->second;
+  ConstCmmHitsMap::const_iterator mapIter = cmmHitsMap.find(crate * 100 + dataID);
+  if (mapIter != cmmHitsMap.end()) return mapIter->second;
   return nullptr;
 }
 
@@ -1546,10 +1579,11 @@ LVL1::CMMJetHits* JepByteStreamV1Tool::findCmmHits(const CmmHitsData& data,
 
 const
 LVL1::CMMEtSums* JepByteStreamV1Tool::findCmmSums(const int crate,
-                                                  const int dataID) const
+                                                  const int dataID,
+                                                  const ConstCmmSumsMap& cmmEtMap) const
 {
-  ConstCmmSumsMap::const_iterator mapIter = m_cmmEtMap.find(crate * 100 + dataID);
-  if (mapIter != m_cmmEtMap.end()) return mapIter->second;
+  ConstCmmSumsMap::const_iterator mapIter = cmmEtMap.find(crate * 100 + dataID);
+  if (mapIter != cmmEtMap.end()) return mapIter->second;
   return nullptr;
 }
 
@@ -1565,16 +1599,18 @@ LVL1::CMMEtSums* JepByteStreamV1Tool::findCmmSums(const CmmSumsData& data,
 // Set up jet element map
 
 void JepByteStreamV1Tool::setupJeMap(const JetElementCollection*
-                                     const jeCollection)
+                                     const jeCollection,
+                                     ConstJetElementMap& jeMap,
+                                     LVL1::JetElementKey& elementKey) const
 {
-  m_jeMap.clear();
+  jeMap.clear();
   if (jeCollection) {
     JetElementCollection::const_iterator pos  = jeCollection->begin();
     JetElementCollection::const_iterator pose = jeCollection->end();
     for (; pos != pose; ++pos) {
       const LVL1::JetElement* je = *pos;
-      const unsigned int key = m_elementKey->jeKey(je->phi(), je->eta());
-      m_jeMap.insert(std::make_pair(key, je));
+      const unsigned int key = elementKey.jeKey(je->phi(), je->eta());
+      jeMap.insert(std::make_pair(key, je));
     }
   }
 }
@@ -1583,9 +1619,10 @@ void JepByteStreamV1Tool::setupJeMap(const JetElementCollection*
 // Set up jet hits map
 
 void JepByteStreamV1Tool::setupHitsMap(const JetHitsCollection*
-                                       const hitCollection)
+                                       const hitCollection,
+                                       ConstJetHitsMap& hitsMap) const
 {
-  m_hitsMap.clear();
+  hitsMap.clear();
   if (hitCollection) {
     JetHitsCollection::const_iterator pos  = hitCollection->begin();
     JetHitsCollection::const_iterator pose = hitCollection->end();
@@ -1593,7 +1630,7 @@ void JepByteStreamV1Tool::setupHitsMap(const JetHitsCollection*
       const LVL1::JEMHits* const hits = *pos;
       const int crate = hits->crate() - m_crateOffsetSw;
       const int key   = m_modules * crate + hits->module();
-      m_hitsMap.insert(std::make_pair(key, hits));
+      hitsMap.insert(std::make_pair(key, hits));
     }
   }
 }
@@ -1601,9 +1638,10 @@ void JepByteStreamV1Tool::setupHitsMap(const JetHitsCollection*
 // Set up energy sums map
 
 void JepByteStreamV1Tool::setupEtMap(const EnergySumsCollection*
-                                     const etCollection)
+                                     const etCollection,
+                                     ConstEnergySumsMap& etMap) const
 {
-  m_etMap.clear();
+  etMap.clear();
   if (etCollection) {
     EnergySumsCollection::const_iterator pos  = etCollection->begin();
     EnergySumsCollection::const_iterator pose = etCollection->end();
@@ -1611,7 +1649,7 @@ void JepByteStreamV1Tool::setupEtMap(const EnergySumsCollection*
       const LVL1::JEMEtSums* const sums = *pos;
       const int crate = sums->crate() - m_crateOffsetSw;
       const int key   = m_modules * crate + sums->module();
-      m_etMap.insert(std::make_pair(key, sums));
+      etMap.insert(std::make_pair(key, sums));
     }
   }
 }
@@ -1619,9 +1657,10 @@ void JepByteStreamV1Tool::setupEtMap(const EnergySumsCollection*
 // Set up CMM hits map
 
 void JepByteStreamV1Tool::setupCmmHitsMap(const CmmHitsCollection*
-    const hitCollection)
+                                          const hitCollection,
+                                          ConstCmmHitsMap& cmmHitsMap) const
 {
-  m_cmmHitsMap.clear();
+  cmmHitsMap.clear();
   if (hitCollection) {
     CmmHitsCollection::const_iterator pos  = hitCollection->begin();
     CmmHitsCollection::const_iterator pose = hitCollection->end();
@@ -1629,7 +1668,7 @@ void JepByteStreamV1Tool::setupCmmHitsMap(const CmmHitsCollection*
       const LVL1::CMMJetHits* const hits = *pos;
       const int crate = hits->crate() - m_crateOffsetSw;
       const int key   = crate * 100 + hits->dataID();
-      m_cmmHitsMap.insert(std::make_pair(key, hits));
+      cmmHitsMap.insert(std::make_pair(key, hits));
     }
   }
 }
@@ -1637,9 +1676,10 @@ void JepByteStreamV1Tool::setupCmmHitsMap(const CmmHitsCollection*
 // Set up CMM energy sums map
 
 void JepByteStreamV1Tool::setupCmmEtMap(const CmmSumsCollection*
-                                        const etCollection)
+                                        const etCollection,
+                                        ConstCmmSumsMap& cmmEtMap) const
 {
-  m_cmmEtMap.clear();
+  cmmEtMap.clear();
   if (etCollection) {
     CmmSumsCollection::const_iterator pos  = etCollection->begin();
     CmmSumsCollection::const_iterator pose = etCollection->end();
@@ -1647,7 +1687,7 @@ void JepByteStreamV1Tool::setupCmmEtMap(const CmmSumsCollection*
       const LVL1::CMMEtSums* const sums = *pos;
       const int crate = sums->crate() - m_crateOffsetSw;
       const int key   = crate * 100 + sums->dataID();
-      m_cmmEtMap.insert(std::make_pair(key, sums));
+      cmmEtMap.insert(std::make_pair(key, sums));
     }
   }
 }
@@ -1655,7 +1695,15 @@ void JepByteStreamV1Tool::setupCmmEtMap(const CmmSumsCollection*
 // Get number of slices and triggered slice offset for next slink
 
 bool JepByteStreamV1Tool::slinkSlices(const int crate, const int module,
-                                      const int modulesPerSlink, int& timeslices, int& trigJem)
+                                      const int modulesPerSlink,
+                                      int& timeslices,
+                                      int& trigJem,
+                                      const ConstJetElementMap& jeMap,
+                                      const ConstJetHitsMap& hitsMap,
+                                      const ConstEnergySumsMap& etMap,
+                                      const ConstCmmHitsMap& cmmHitsMap,
+                                      const ConstCmmSumsMap& cmmEtMap,
+                                      LVL1::JetElementKey& elementKey) const
 {
   int slices = -1;
   int trigJ  = m_dfltSlices / 2;
@@ -1665,7 +1713,7 @@ bool JepByteStreamV1Tool::slinkSlices(const int crate, const int module,
       double phi = 0.;
       int layer = 0;
       if ( !m_jemMaps->mapping(crate, mod, chan, eta, phi, layer)) continue;
-      const LVL1::JetElement* const je = findJetElement(eta, phi);
+      const LVL1::JetElement* const je = findJetElement(eta, phi, jeMap, elementKey);
       if ( !je ) continue;
       const int numdat = 5;
       std::vector<int> sums(numdat);
@@ -1694,7 +1742,7 @@ bool JepByteStreamV1Tool::slinkSlices(const int crate, const int module,
         } else if (slices != sizes[i] || trigJ != peak) return false;
       }
     }
-    const LVL1::JEMHits* const hits = findJetHits(crate, mod);
+    const LVL1::JEMHits* const hits = findJetHits(crate, mod, hitsMap);
     if (hits) {
       const unsigned int sum = std::accumulate((hits->JetHitsVec()).begin(),
                                (hits->JetHitsVec()).end(), 0);
@@ -1707,7 +1755,7 @@ bool JepByteStreamV1Tool::slinkSlices(const int crate, const int module,
         } else if (slices != size || trigJ != peak) return false;
       }
     }
-    const LVL1::JEMEtSums* const et = findEnergySums(crate, mod);
+    const LVL1::JEMEtSums* const et = findEnergySums(crate, mod, etMap);
     if (et) {
       const int numdat = 3;
       std::vector<unsigned int> sums(numdat);
@@ -1741,7 +1789,7 @@ bool JepByteStreamV1Tool::slinkSlices(const int crate, const int module,
       std::vector<unsigned int> sums(numdat);
       std::vector<int> sizes(numdat);
       const LVL1::CMMJetHits* hits = 0;
-      if (dataID < maxDataID1) hits = findCmmHits(crate, dataID);
+      if (dataID < maxDataID1) hits = findCmmHits(crate, dataID, cmmHitsMap);
       if (hits) {
         sums[0] = std::accumulate((hits->HitsVec()).begin(),
                                   (hits->HitsVec()).end(), 0);
@@ -1759,7 +1807,7 @@ bool JepByteStreamV1Tool::slinkSlices(const int crate, const int module,
         }
       }
       const LVL1::CMMEtSums* et = 0;
-      if (dataID < maxDataID2) et = findCmmSums(crate, dataID);
+      if (dataID < maxDataID2) et = findCmmSums(crate, dataID, cmmEtMap);
       if (et) {
         sums[0] = std::accumulate((et->ExVec()).begin(),
                                   (et->ExVec()).end(), 0);
diff --git a/Trigger/TrigT1/TrigT1CaloByteStream/src/JepByteStreamV1Tool.h b/Trigger/TrigT1/TrigT1CaloByteStream/src/JepByteStreamV1Tool.h
index e32a73bfc5cfa364373fff2161e5f9b7d87cdf46..fc9ebc2a7048c5df1d9c7f1e249c0d6caa57e860 100755
--- a/Trigger/TrigT1/TrigT1CaloByteStream/src/JepByteStreamV1Tool.h
+++ b/Trigger/TrigT1/TrigT1CaloByteStream/src/JepByteStreamV1Tool.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRIGT1CALOBYTESTREAM_JEPBYTESTREAMV1TOOL_H
@@ -11,6 +11,8 @@
 #include <string>
 #include <vector>
 
+#include "L1CaloSrcIdMap.h"
+#include "TrigT1CaloUtils/JetElementKey.h"
 #include "AthenaBaseComps/AthAlgTool.h"
 #include "ByteStreamCnvSvcBase/IROBDataProviderSvc.h"
 #include "ByteStreamData/RawEvent.h"
@@ -61,32 +63,63 @@ class JepByteStreamV1Tool : public AthAlgTool {
    /// AlgTool InterfaceID
    static const InterfaceID& interfaceID();
 
-   virtual StatusCode initialize();
-   virtual StatusCode finalize();
+   virtual StatusCode initialize() override;
+   virtual StatusCode finalize() override;
 
    /// Convert ROB fragments to jet elements
-   StatusCode convert(const IROBDataProviderSvc::VROBFRAG& robFrags,
-                      DataVector<LVL1::JetElement>* jeCollection);
+   StatusCode convert(const std::string& sgKey,
+                      const IROBDataProviderSvc::VROBFRAG& robFrags,
+                      DataVector<LVL1::JetElement>* jeCollection) const;
    /// Convert ROB fragments to jet hits
-   StatusCode convert(const IROBDataProviderSvc::VROBFRAG& robFrags,
-                      DataVector<LVL1::JEMHits>* hitCollection);
+   StatusCode convert(const std::string& sgKey,
+                      const IROBDataProviderSvc::VROBFRAG& robFrags,
+                      DataVector<LVL1::JEMHits>* hitCollection) const;
    /// Convert ROB fragments to energy sums
-   StatusCode convert(const IROBDataProviderSvc::VROBFRAG& robFrags,
-                      DataVector<LVL1::JEMEtSums>* etCollection);
+   StatusCode convert(const std::string& sgKey,
+                      const IROBDataProviderSvc::VROBFRAG& robFrags,
+                      DataVector<LVL1::JEMEtSums>* etCollection) const;
    /// Convert ROB fragments to CMM jet hits
-   StatusCode convert(const IROBDataProviderSvc::VROBFRAG& robFrags,
-                      DataVector<LVL1::CMMJetHits>* hitCollection);
+   StatusCode convert(const std::string& sgKey,
+                      const IROBDataProviderSvc::VROBFRAG& robFrags,
+                      DataVector<LVL1::CMMJetHits>* hitCollection) const;
    /// Convert ROB fragments to CMM energy sums
-   StatusCode convert(const IROBDataProviderSvc::VROBFRAG& robFrags,
-                      DataVector<LVL1::CMMEtSums>* etCollection);
+   StatusCode convert(const std::string& sgKey,
+                      const IROBDataProviderSvc::VROBFRAG& robFrags,
+                      DataVector<LVL1::CMMEtSums>* etCollection) const;
 
    /// Convert JEP Container to bytestream
-   StatusCode convert(const LVL1::JEPBSCollectionV1* jep, RawEventWrite* re);
+   StatusCode convert(const LVL1::JEPBSCollectionV1* jep, RawEventWrite* re) const;
 
    /// Return reference to vector with all possible Source Identifiers
-   const std::vector<uint32_t>& sourceIDs(const std::string& sgKey);
+   const std::vector<uint32_t>& sourceIDs() const;
 
  private:
+   struct LocalData
+   {
+     /// Jet elements to accept (0=Core, 1=Overlap)
+     int coreOverlap = 0;
+     /// Unpacking error code
+     unsigned int rodErr = 0;
+     /// Ex vector for unpacking
+     std::vector<unsigned int> exVec;
+     /// Ey vector for unpacking
+     std::vector<unsigned int> eyVec;
+     /// Et vector for unpacking
+     std::vector<unsigned int> etVec;
+     /// Ex error vector for unpacking
+     std::vector<int> exErrVec;
+     /// Ex error vector for unpacking
+     std::vector<int> eyErrVec;
+     /// Ex error vector for unpacking
+     std::vector<int> etErrVec;
+     /// Hits vector for unpacking
+     std::vector<unsigned int> hitsVec;
+     /// Error vector for unpacking
+     std::vector<int> errVec;
+     /// Jet element key provider
+     LVL1::JetElementKey elementKey;
+   };
+
    enum CollectionType { JET_ELEMENTS, JET_HITS, ENERGY_SUMS,
                                        CMM_HITS, CMM_SUMS };
 
@@ -152,133 +185,107 @@ class JepByteStreamV1Tool : public AthAlgTool {
    };
 
    /// Convert bytestream to given container type
-   StatusCode convertBs(const IROBDataProviderSvc::VROBFRAG& robFrags,
-                        JepByteStreamToolData& data);
+   StatusCode convertBs(const std::string& sgKey,
+                        const IROBDataProviderSvc::VROBFRAG& robFrags,
+                        JepByteStreamToolData& data) const;
    /// Unpack CMM-Energy sub-block
-   void decodeCmmEnergy(CmmEnergySubBlock* subBlock, int trigCmm, CmmSumsData& data);
+   void decodeCmmEnergy(CmmEnergySubBlock* subBlock, int trigCmm, CmmSumsData& data,
+                        LocalData& ld) const;
    /// Unpack CMM-Jet sub-block
-   void decodeCmmJet(CmmJetSubBlock* subBlock, int trigCmm, CmmHitsData& data);
+   void decodeCmmJet(CmmJetSubBlock* subBlock, int trigCmm, CmmHitsData& data,
+                     LocalData& ld) const;
    /// Unpack JEM sub-block
    void decodeJem(JemSubBlockV1* subBlock, int trigJem,
-                  JepByteStreamToolData& data);
+                  JepByteStreamToolData& data,
+                  LocalData& ld) const;
 
    /// Find a jet element given eta, phi
-   const LVL1::JetElement* findJetElement(double eta, double phi) const;
-   LVL1::JetElement* findJetElement(const JetElementData& data, double eta, double phi) const;
+   const LVL1::JetElement* findJetElement(double eta, double phi,
+                                          const ConstJetElementMap& jeMap,
+                                          LVL1::JetElementKey& elementKey) const;
+   LVL1::JetElement* findJetElement(const JetElementData& data, double eta, double phi,
+                                    LVL1::JetElementKey& elementKey) const;
    /// Find jet hits for given crate, module
-   const LVL1::JEMHits*    findJetHits(int crate, int module) const;
+   const LVL1::JEMHits*    findJetHits(int crate, int module,
+                                       const ConstJetHitsMap& hitsMap) const;
    LVL1::JEMHits*    findJetHits(const JetHitsData& data, int crate, int module) const;
    /// Find energy sums for given crate, module
-   const LVL1::JEMEtSums*  findEnergySums(int crate, int module) const;
+   const LVL1::JEMEtSums*  findEnergySums(int crate, int module,
+                                          const ConstEnergySumsMap& etMap) const;
    LVL1::JEMEtSums*  findEnergySums(const EnergySumsData& data, int crate, int module) const;
    /// Find CMM hits for given crate, data ID
-   const LVL1::CMMJetHits* findCmmHits(int crate, int dataID) const;
+   const LVL1::CMMJetHits* findCmmHits(int crate, int dataID,
+                                       const ConstCmmHitsMap& cmmHitsMap) const;
    LVL1::CMMJetHits* findCmmHits(const CmmHitsData& data, int crate, int dataID) const;
    /// Find CMM energy sums for given crate, data ID
-   const LVL1::CMMEtSums*  findCmmSums(int crate, int dataID) const;
+   const LVL1::CMMEtSums*  findCmmSums(int crate, int dataID,
+                                       const ConstCmmSumsMap& cmmEtMap) const;
    LVL1::CMMEtSums*  findCmmSums(const CmmSumsData& data, int crate, int dataID) const;
 
+   std::vector<uint32_t> makeSourceIDs() const;
+
    /// Set up jet element map
-   void setupJeMap(const JetElementCollection* jeCollection);
+   void setupJeMap(const JetElementCollection* jeCollection,
+                   ConstJetElementMap& jeMap,
+                   LVL1::JetElementKey& elementKey) const;
    /// Set up jet hits map
-   void setupHitsMap(const JetHitsCollection* hitCollection);
+   void setupHitsMap(const JetHitsCollection* hitCollection,
+                     ConstJetHitsMap& hitsMap) const;
    /// Set up energy sums map
-   void setupEtMap(const EnergySumsCollection* enCollection);
+   void setupEtMap(const EnergySumsCollection* enCollection,
+                   ConstEnergySumsMap& etMap) const;
    /// Set up CMM hits map
-   void setupCmmHitsMap(const CmmHitsCollection* hitCollection);
+   void setupCmmHitsMap(const CmmHitsCollection* hitCollection,
+                        ConstCmmHitsMap& cmmHitsMap) const;
    /// Set up CMM energy sums map
-   void setupCmmEtMap(const CmmSumsCollection* enCollection);
+   void setupCmmEtMap(const CmmSumsCollection* enCollection,
+                      ConstCmmSumsMap& cmmEtMap) const;
 
    /// Get number of slices and triggered slice offset for next slink
    bool slinkSlices(int crate, int module, int modulesPerSlink,
-                    int& timeslices, int& trigJem);
+                    int& timeslices, int& trigJem,
+                    const ConstJetElementMap& jeMap,
+                    const ConstJetHitsMap& hitsMap,
+                    const ConstEnergySumsMap& etMap,
+                    const ConstCmmHitsMap& cmmHitsMap,
+                    const ConstCmmSumsMap& cmmEtMap,
+                    LVL1::JetElementKey& elementKey) const;
 
-   /// Channel mapping tool
+   /// Property: Channel mapping tool
    ToolHandle<LVL1::IL1CaloMappingTool> m_jemMaps;
-   /// Error collection tool
+   /// Property: Error collection tool
    ToolHandle<LVL1BS::L1CaloErrorByteStreamTool> m_errorTool;
 
-   /// Hardware crate number offset
+   /// Property: Hardware crate number offset
    int m_crateOffsetHw;
-   /// Software crate number offset
+   /// Property: Software crate number offset
    int m_crateOffsetSw;
-   /// Sub_block header version
+   /// Property: Sub_block header version
    int m_version;
-   /// Data compression format
+   /// Property: Data compression format
    int m_dataFormat;
    /// Number of channels per module
-   int m_channels;
+   const int m_channels;
    /// Number of crates
-   int m_crates;
+   const int m_crates;
    /// Number of JEM modules per crate
-   int m_modules;
-   /// Number of slinks per crate when writing out bytestream
+   const int m_modules;
+   /// Property: Number of slinks per crate when writing out bytestream
    int m_slinks;
-   /// Default number of slices in simulation
+   /// Property: Default number of slices in simulation
    int m_dfltSlices;
-   /// Force number of slices in bytestream
+   /// Property: Force number of slices in bytestream
    int m_forceSlices;
-   /// Minimum crate number when writing out bytestream
+   /// Property: Minimum crate number when writing out bytestream
    int m_crateMin;
-   /// Maximum crate number when writing out bytestream
+   /// Property: Maximum crate number when writing out bytestream
    int m_crateMax;
-   /// Jet elements to accept (0=Core, 1=Overlap)
-   int m_coreOverlap;
-   /// Unpacking error code
-   unsigned int m_rodErr;
-   /// ROB source IDs
-   std::vector<uint32_t> m_sourceIDs;
+   /// Property: ROB source IDs
+   std::vector<uint32_t> m_sourceIDsProp;
    /// Sub-detector type
-   eformat::SubDetector m_subDetector;
+   const eformat::SubDetector m_subDetector;
    /// Source ID converter
-   L1CaloSrcIdMap* m_srcIdMap;
-   /// Jet element key provider
-   LVL1::JetElementKey* m_elementKey;
-   /// JemSubBlock for unpacking
-   JemSubBlockV1* m_jemSubBlock;
-   /// CmmEnergySubBlock for unpacking
-   CmmEnergySubBlock* m_cmmEnergySubBlock;
-   /// CmmJetSubBlock for unpacking
-   CmmJetSubBlock* m_cmmJetSubBlock;
-   /// Ex vector for unpacking
-   std::vector<unsigned int> m_exVec;
-   /// Ey vector for unpacking
-   std::vector<unsigned int> m_eyVec;
-   /// Et vector for unpacking
-   std::vector<unsigned int> m_etVec;
-   /// Ex error vector for unpacking
-   std::vector<int> m_exErrVec;
-   /// Ex error vector for unpacking
-   std::vector<int> m_eyErrVec;
-   /// Ex error vector for unpacking
-   std::vector<int> m_etErrVec;
-   /// Hits vector for unpacking
-   std::vector<unsigned int> m_hitsVec;
-   /// Error vector for unpacking
-   std::vector<int> m_errVec;
-   /// Vector for current JEM sub-blocks
-   DataVector<JemSubBlockV1> m_jemBlocks;
-   /// Vector for current CMM-Energy sub-blocks
-   DataVector<CmmEnergySubBlock> m_cmmEnergyBlocks;
-   /// Vector for current CMM-Jet sub-blocks
-   DataVector<CmmJetSubBlock> m_cmmJetBlocks;
-   /// Jet element map
-   ConstJetElementMap m_jeMap;
-   /// Jet hits map
-   ConstJetHitsMap    m_hitsMap;
-   /// Energy sums map
-   ConstEnergySumsMap m_etMap;
-   /// CMM hits map
-   ConstCmmHitsMap    m_cmmHitsMap;
-   /// CMM energy sums map
-   ConstCmmSumsMap    m_cmmEtMap;
-   /// ROD Status words
-   std::vector<uint32_t>* m_rodStatus;
-   /// ROD status map
-   std::map<uint32_t, std::vector<uint32_t>* > m_rodStatusMap;
-   /// Event assembler
-   FullEventAssembler<L1CaloSrcIdMap>* m_fea;
-
+   const L1CaloSrcIdMap m_srcIdMap;
 };
 
 } // end namespace
diff --git a/Trigger/TrigT1/TrigT1CaloByteStream/src/JepByteStreamV2Tool.cxx b/Trigger/TrigT1/TrigT1CaloByteStream/src/JepByteStreamV2Tool.cxx
index 8fc573e0a89d68c70277bef1f62557501c638ba6..1c3bcb9344ff37341b818dc482e79757b325b10e 100755
--- a/Trigger/TrigT1/TrigT1CaloByteStream/src/JepByteStreamV2Tool.cxx
+++ b/Trigger/TrigT1/TrigT1CaloByteStream/src/JepByteStreamV2Tool.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 
@@ -29,7 +29,6 @@
 #include "JemJetElement.h"
 #include "JemSubBlockV2.h"
 #include "L1CaloErrorByteStreamTool.h"
-#include "L1CaloSrcIdMap.h"
 #include "L1CaloSubBlock.h"
 #include "L1CaloUserHeader.h"
 #include "ModifySlices.h"
@@ -57,11 +56,8 @@ JepByteStreamV2Tool::JepByteStreamV2Tool(const std::string& type,
     m_jemMaps("LVL1::JemMappingTool/JemMappingTool"),
     m_errorTool("LVL1BS::L1CaloErrorByteStreamTool/L1CaloErrorByteStreamTool"),
     m_channels(44), m_crates(2), m_modules(16), m_frames(8), m_locations(4),
-    m_maxTobs(4), m_coreOverlap(0),
-    m_subDetector(eformat::TDAQ_CALO_JET_PROC_DAQ),
-    m_srcIdMap(0), m_elementKey(0),
-    m_jemSubBlock(0), m_cmxEnergySubBlock(0), m_cmxJetSubBlock(0),
-    m_rodStatus(0), m_fea(0)
+    m_maxTobs(4), 
+    m_subDetector(eformat::TDAQ_CALO_JET_PROC_DAQ)
 {
   declareInterface<JepByteStreamV2Tool>(this);
 
@@ -78,7 +74,7 @@ JepByteStreamV2Tool::JepByteStreamV2Tool(const std::string& type,
                   "The number of S-Links per crate");
 
   // Properties for reading bytestream only
-  declareProperty("ROBSourceIDs",       m_sourceIDs,
+  declareProperty("ROBSourceIDs",       m_sourceIDsProp,
                   "ROB fragment source identifiers");
 
   // Properties for writing bytestream only
@@ -108,28 +104,12 @@ JepByteStreamV2Tool::~JepByteStreamV2Tool()
 
 StatusCode JepByteStreamV2Tool::initialize()
 {
-  msg(MSG::INFO) << "Initializing " << name() << " - package version "
-                 << PACKAGE_VERSION << endmsg;
-
-  StatusCode sc = m_jemMaps.retrieve();
-  if (sc.isFailure()) {
-    msg(MSG::ERROR) << "Failed to retrieve tool " << m_jemMaps << endmsg;
-    return sc;
-  } else msg(MSG::INFO) << "Retrieved tool " << m_jemMaps << endmsg;
-
-  sc = m_errorTool.retrieve();
-  if (sc.isFailure()) {
-    msg(MSG::ERROR) << "Failed to retrieve tool " << m_errorTool << endmsg;
-    return sc;
-  } else msg(MSG::INFO) << "Retrieved tool " << m_errorTool << endmsg;
-
-  m_srcIdMap          = new L1CaloSrcIdMap();
-  m_elementKey        = new LVL1::JetElementKey();
-  m_jemSubBlock       = new JemSubBlockV2();
-  m_cmxEnergySubBlock = new CmxEnergySubBlock();
-  m_cmxJetSubBlock    = new CmxJetSubBlock();
-  m_rodStatus         = new std::vector<uint32_t>(2);
-  m_fea               = new FullEventAssembler<L1CaloSrcIdMap>();
+  ATH_MSG_INFO ("Initializing " << name() << " - package version "
+                << PACKAGE_VERSION);
+
+  ATH_CHECK( m_jemMaps.retrieve() );
+  ATH_CHECK( m_errorTool.retrieve() );
+
   return StatusCode::SUCCESS;
 }
 
@@ -137,13 +117,6 @@ StatusCode JepByteStreamV2Tool::initialize()
 
 StatusCode JepByteStreamV2Tool::finalize()
 {
-  delete m_fea;
-  delete m_rodStatus;
-  delete m_cmxJetSubBlock;
-  delete m_cmxEnergySubBlock;
-  delete m_jemSubBlock;
-  delete m_elementKey;
-  delete m_srcIdMap;
   return StatusCode::SUCCESS;
 }
 
@@ -151,135 +124,155 @@ StatusCode JepByteStreamV2Tool::finalize()
 
 StatusCode JepByteStreamV2Tool::convert(
     const std::string& sgKey,
-    DataVector<LVL1::JetElement>* collection)
+    DataVector<LVL1::JetElement>* collection) const
 {
- const std::vector<uint32_t>& vID(sourceIDs(sgKey));
+  const std::vector<uint32_t>& vID(sourceIDs());
   // // get ROB fragments
   IROBDataProviderSvc::VROBFRAG robFrags;
   m_robDataProvider->getROBData(vID, robFrags, "JepByteStreamV2Tool");
   ATH_MSG_DEBUG("Number of ROB fragments:" << robFrags.size());
-  return convert(robFrags, collection);
+  return convert(sgKey, robFrags, collection);
 }
 
 StatusCode JepByteStreamV2Tool::convert(
+                            const std::string& sgKey,
                             const IROBDataProviderSvc::VROBFRAG& robFrags,
-                            DataVector<LVL1::JetElement>*  jeCollection)
+                            DataVector<LVL1::JetElement>*  jeCollection) const
 {
   JetElementData data (jeCollection);
-  return convertBs(robFrags, data);
+  return convertBs(sgKey, robFrags, data);
 }
 
 // Conversion bytestream to energy sums
 StatusCode JepByteStreamV2Tool::convert(
     const std::string& sgKey,
-    DataVector<LVL1::JEMEtSums>* collection)
+    DataVector<LVL1::JEMEtSums>* collection) const
 {
- const std::vector<uint32_t>& vID(sourceIDs(sgKey));
+  const std::vector<uint32_t>& vID(sourceIDs());
   // // get ROB fragments
   IROBDataProviderSvc::VROBFRAG robFrags;
   m_robDataProvider->getROBData(vID, robFrags, "JepByteStreamV2Tool");
   ATH_MSG_DEBUG("Number of ROB fragments:" << robFrags.size());
-  return convert(robFrags, collection);
+  return convert(sgKey, robFrags, collection);
 }
 
 StatusCode JepByteStreamV2Tool::convert(
+                            const std::string& sgKey,
                             const IROBDataProviderSvc::VROBFRAG& robFrags,
-                            DataVector<LVL1::JEMEtSums>*  etCollection)
+                            DataVector<LVL1::JEMEtSums>*  etCollection) const
 {
   EnergySumsData data (etCollection);
-  return convertBs(robFrags, data);
+  return convertBs(sgKey, robFrags, data);
 }
 
 // Conversion bytestream to CMX TOBs
 StatusCode JepByteStreamV2Tool::convert(
     const std::string& sgKey,
-    DataVector<LVL1::CMXJetTob>* collection)
+    DataVector<LVL1::CMXJetTob>* collection) const
 {
- const std::vector<uint32_t>& vID(sourceIDs(sgKey));
+  const std::vector<uint32_t>& vID(sourceIDs());
   // // get ROB fragments
   IROBDataProviderSvc::VROBFRAG robFrags;
   m_robDataProvider->getROBData(vID, robFrags, "JepByteStreamV2Tool");
   ATH_MSG_DEBUG("Number of ROB fragments:" << robFrags.size());
-  return convert(robFrags, collection);
+  return convert(sgKey, robFrags, collection);
 }
 
 StatusCode JepByteStreamV2Tool::convert(
+                            const std::string& sgKey,
                             const IROBDataProviderSvc::VROBFRAG& robFrags,
-                            DataVector<LVL1::CMXJetTob>*  tobCollection)
+                            DataVector<LVL1::CMXJetTob>*  tobCollection) const
 {
   CmxTobData data (tobCollection);
-  return convertBs(robFrags, data);
+  return convertBs(sgKey, robFrags, data);
 }
 
 // Conversion bytestream to CMX hits
 StatusCode JepByteStreamV2Tool::convert(
     const std::string& sgKey,
-    DataVector<LVL1::CMXJetHits>* collection)
+    DataVector<LVL1::CMXJetHits>* collection) const
 {
- const std::vector<uint32_t>& vID(sourceIDs(sgKey));
+  const std::vector<uint32_t>& vID(sourceIDs());
   // // get ROB fragments
   IROBDataProviderSvc::VROBFRAG robFrags;
   m_robDataProvider->getROBData(vID, robFrags, "JepByteStreamV2Tool");
   ATH_MSG_DEBUG("Number of ROB fragments:" << robFrags.size());
-  return convert(robFrags, collection);
+  return convert(sgKey, robFrags, collection);
 }
 
 StatusCode JepByteStreamV2Tool::convert(
+                            const std::string& sgKey,
                             const IROBDataProviderSvc::VROBFRAG& robFrags,
-                            DataVector<LVL1::CMXJetHits>*  hitCollection)
+                            DataVector<LVL1::CMXJetHits>*  hitCollection) const
 {
   CmxHitsData data (hitCollection);
-  return convertBs(robFrags, data);
+  return convertBs(sgKey, robFrags, data);
 }
 
 // Conversion bytestream to CMX energy sums
 
 StatusCode JepByteStreamV2Tool::convert(
     const std::string& sgKey,
-    DataVector<LVL1::CMXEtSums>* collection)
+    DataVector<LVL1::CMXEtSums>* collection) const
 {
- const std::vector<uint32_t>& vID(sourceIDs(sgKey));
+  const std::vector<uint32_t>& vID(sourceIDs());
   // // get ROB fragments
   IROBDataProviderSvc::VROBFRAG robFrags;
   m_robDataProvider->getROBData(vID, robFrags, "JepByteStreamV2Tool");
   ATH_MSG_DEBUG("Number of ROB fragments:" << robFrags.size());
-  return convert(robFrags, collection);
+  return convert(sgKey, robFrags, collection);
 }
 
 StatusCode JepByteStreamV2Tool::convert(
+                            const std::string& sgKey,
                             const IROBDataProviderSvc::VROBFRAG& robFrags,
-                            DataVector<LVL1::CMXEtSums>*  etCollection)
+                            DataVector<LVL1::CMXEtSums>*  etCollection) const
 {
   CmxSumsData data (etCollection);
-  return convertBs(robFrags, data);
+  return convertBs(sgKey, robFrags, data);
 }
 
 // Conversion of JEP container to bytestream
 
 StatusCode JepByteStreamV2Tool::convert(const LVL1::JEPBSCollectionV2* const jep,
-                                            RawEventWrite* const re)
+                                        RawEventWrite* const re) const
 {
   const bool debug = msgLvl(MSG::DEBUG);
   if (debug) msg(MSG::DEBUG);
 
   // Clear the event assembler
-
-  m_fea->clear();
-  const uint16_t minorVersion = m_srcIdMap->minorVersion();
-  m_fea->setRodMinorVersion(minorVersion);
-  m_rodStatusMap.clear();
+  FullEventAssembler<L1CaloSrcIdMap> fea;
+  const uint16_t minorVersion = m_srcIdMap.minorVersion();
+  fea.setRodMinorVersion(minorVersion);
 
   // Pointer to ROD data vector
 
   FullEventAssembler<L1CaloSrcIdMap>::RODDATA* theROD = 0;
 
+  // Jet element key provider
+  LVL1::JetElementKey elementKey;
+
   // Set up the container maps
 
-  setupJeMap(jep->JetElements());
-  setupEtMap(jep->EnergySums());
-  setupCmxTobMap(jep->CmxTobs());
-  setupCmxHitsMap(jep->CmxHits());
-  setupCmxEtMap(jep->CmxSums());
+  // Jet element map
+  ConstJetElementMap jeMap;
+  setupJeMap(jep->JetElements(), jeMap, elementKey);
+
+  // Energy sums map
+  ConstEnergySumsMap etMap;
+  setupEtMap(jep->EnergySums(), etMap);
+
+  // CMX TOB map
+  ConstCmxTobMap cmxTobMap;
+  setupCmxTobMap(jep->CmxTobs(), cmxTobMap);
+
+  // CMX hits map
+  ConstCmxHitsMap cmxHitsMap;
+  setupCmxHitsMap(jep->CmxHits(), cmxHitsMap);
+
+  /// CMX energy sums map
+  ConstCmxSumsMap cmxEtMap;
+  setupCmxEtMap(jep->CmxSums(), cmxEtMap);
 
   // Loop over data
 
@@ -306,7 +299,14 @@ StatusCode JepByteStreamV2Tool::convert(const LVL1::JEPBSCollectionV2* const jep
 	// Get number of JEM slices and triggered slice offset
 	// for this slink
 	if ( ! slinkSlices(crate, module, modulesPerSlink,
-	                                  timeslices, trigJem)) {
+                           timeslices, trigJem,
+                           jeMap,
+                           etMap,
+                           cmxTobMap,
+                           cmxHitsMap,
+                           cmxEtMap,
+                           elementKey))
+        {
 	  msg(MSG::ERROR) << "Inconsistent number of slices or "
 	                  << "triggered slice offsets in data for crate "
 	                  << hwCrate << " slink " << slink << endmsg;
@@ -325,22 +325,22 @@ StatusCode JepByteStreamV2Tool::convert(const LVL1::JEPBSCollectionV2* const jep
         }
         L1CaloUserHeader userHeader;
         userHeader.setJem(trigJemNew);
-	const uint32_t rodIdJem = m_srcIdMap->getRodID(hwCrate, slink, daqOrRoi,
+	const uint32_t rodIdJem = m_srcIdMap.getRodID(hwCrate, slink, daqOrRoi,
 	                                                        m_subDetector);
-	theROD = m_fea->getRodData(rodIdJem);
+	theROD = fea.getRodData(rodIdJem);
 	theROD->push_back(userHeader.header());
-	m_rodStatusMap.insert(make_pair(rodIdJem, m_rodStatus));
       }
       if (debug) msg() << "Module " << module << endmsg;
 
       // Create a sub-block for each slice (except Neutral format)
 
-      m_jemBlocks.clear();
+      // Vector for current JEM sub-blocks
+      DataVector<JemSubBlockV2> jemBlocks;
       for (int slice = 0; slice < timeslicesNew; ++slice) {
         JemSubBlockV2* const subBlock = new JemSubBlockV2();
 	subBlock->setJemHeader(m_version, m_dataFormat, slice,
 	                       hwCrate, module, timeslicesNew);
-        m_jemBlocks.push_back(subBlock);
+        jemBlocks.push_back(subBlock);
 	if (neutralFormat) break;
       }
 
@@ -352,7 +352,8 @@ StatusCode JepByteStreamV2Tool::convert(const LVL1::JEPBSCollectionV2* const jep
 	double phi = 0.;
 	int layer = 0;
 	if (m_jemMaps->mapping(crate, module, chan, eta, phi, layer)) {
-          const LVL1::JetElement* const je = findJetElement(eta, phi);
+          const LVL1::JetElement* const je = findJetElement(eta, phi, jeMap,
+                                                            elementKey);
 	  if (je ) {
 	    std::vector<int> emData;
 	    std::vector<int> hadData;
@@ -366,7 +367,7 @@ StatusCode JepByteStreamV2Tool::convert(const LVL1::JEPBSCollectionV2* const jep
 	      const LVL1::DataError emErrBits(emErrors[slice]);
 	      const LVL1::DataError hadErrBits(hadErrors[slice]);
 	      const int index = ( neutralFormat ) ? 0 : slice;
-              JemSubBlockV2* const subBlock = m_jemBlocks[index];
+              JemSubBlockV2* const subBlock = jemBlocks[index];
 	      const JemJetElement jetEle(chan, emData[slice], hadData[slice],
 	                  emErrBits.get(LVL1::DataError::Parity),
 	                  hadErrBits.get(LVL1::DataError::Parity),
@@ -393,7 +394,7 @@ StatusCode JepByteStreamV2Tool::convert(const LVL1::JEPBSCollectionV2* const jep
 
       // Add energy subsums
 
-      const LVL1::JEMEtSums* const et = findEnergySums(crate, module);
+      const LVL1::JEMEtSums* const et = findEnergySums(crate, module, etMap);
       if (et) {
         std::vector<unsigned int> exVec;
         std::vector<unsigned int> eyVec;
@@ -403,7 +404,7 @@ StatusCode JepByteStreamV2Tool::convert(const LVL1::JEPBSCollectionV2* const jep
 	ModifySlices::data(et->EtVec(), etVec, timeslicesNew);
 	for (int slice = 0; slice < timeslicesNew; ++slice) {
 	  const int index = ( neutralFormat ) ? 0 : slice;
-	  JemSubBlockV2* const subBlock = m_jemBlocks[index];
+	  JemSubBlockV2* const subBlock = jemBlocks[index];
 	  subBlock->setEnergySubsums(slice, exVec[slice], eyVec[slice],
 	                                                  etVec[slice]);
         }
@@ -412,7 +413,7 @@ StatusCode JepByteStreamV2Tool::convert(const LVL1::JEPBSCollectionV2* const jep
       // Pack and write the sub-blocks
 
       DataVector<JemSubBlockV2>::iterator pos;
-      for (pos = m_jemBlocks.begin(); pos != m_jemBlocks.end(); ++pos) {
+      for (pos = jemBlocks.begin(); pos != jemBlocks.end(); ++pos) {
         JemSubBlockV2* const subBlock = *pos;
 	if ( !subBlock->pack()) {
 	  msg(MSG::ERROR) << "JEM sub-block packing failed" << endmsg;
@@ -430,8 +431,11 @@ StatusCode JepByteStreamV2Tool::convert(const LVL1::JEPBSCollectionV2* const jep
 
     // Create a sub-block for each slice (except Neutral format)
 
-    m_cmxEnergyBlocks.clear();
-    m_cmxJetBlocks.clear();
+    // Vector for current CMX-Energy sub-blocks
+    DataVector<CmxEnergySubBlock> cmxEnergyBlocks;
+    // Vector for current CMX-Jet sub-blocks
+    DataVector<CmxJetSubBlock> cmxJetBlocks;
+
     const int summing = (crate == m_crates - 1) ? CmxSubBlock::SYSTEM
                                                 : CmxSubBlock::CRATE;
     for (int slice = 0; slice < timeslicesNew; ++slice) {
@@ -440,12 +444,12 @@ StatusCode JepByteStreamV2Tool::convert(const LVL1::JEPBSCollectionV2* const jep
       enBlock->setCmxHeader(cmxEnergyVersion, m_dataFormat, slice, hwCrate,
                             summing, CmxSubBlock::CMX_ENERGY,
 			    CmxSubBlock::LEFT, timeslicesNew);
-      m_cmxEnergyBlocks.push_back(enBlock);
+      cmxEnergyBlocks.push_back(enBlock);
       CmxJetSubBlock* const jetBlock = new CmxJetSubBlock();
       jetBlock->setCmxHeader(m_version, m_dataFormat, slice, hwCrate,
                              summing, CmxSubBlock::CMX_JET,
 			     CmxSubBlock::RIGHT, timeslicesNew);
-      m_cmxJetBlocks.push_back(jetBlock);
+      cmxJetBlocks.push_back(jetBlock);
       if (neutralFormat) break;
     }
 
@@ -458,7 +462,7 @@ StatusCode JepByteStreamV2Tool::convert(const LVL1::JEPBSCollectionV2* const jep
 	    source != LVL1::CMXEtSums::LOCAL_STANDARD &&
 	    source != LVL1::CMXEtSums::LOCAL_RESTRICTED) continue;
       }
-      const LVL1::CMXEtSums* const sums = findCmxSums(crate, source);
+      const LVL1::CMXEtSums* const sums = findCmxSums(crate, source, cmxEtMap);
       if ( sums ) {
         std::vector<unsigned int> ex;
         std::vector<unsigned int> ey;
@@ -485,7 +489,7 @@ StatusCode JepByteStreamV2Tool::convert(const LVL1::JEPBSCollectionV2* const jep
 	    etError += etErrBits.get(LVL1::DataError::Overflow);
 	  }
 	  const int index = ( neutralFormat ) ? 0 : slice;
-	  CmxEnergySubBlock* const subBlock = m_cmxEnergyBlocks[index];
+	  CmxEnergySubBlock* const subBlock = cmxEnergyBlocks[index];
 	  if (source < m_modules) {
 	    subBlock->setSubsums(slice, source,
 	                         ex[slice], ey[slice], et[slice],
@@ -507,8 +511,8 @@ StatusCode JepByteStreamV2Tool::convert(const LVL1::JEPBSCollectionV2* const jep
       }
     }
     DataVector<CmxEnergySubBlock>::iterator pos;
-    pos = m_cmxEnergyBlocks.begin();
-    for (; pos != m_cmxEnergyBlocks.end(); ++pos) {
+    pos = cmxEnergyBlocks.begin();
+    for (; pos != cmxEnergyBlocks.end(); ++pos) {
       CmxEnergySubBlock* const subBlock = *pos;
       if ( !subBlock->pack()) {
         msg(MSG::ERROR) << "CMX-Energy sub-block packing failed" << endmsg;
@@ -527,7 +531,7 @@ StatusCode JepByteStreamV2Tool::convert(const LVL1::JEPBSCollectionV2* const jep
       for (int frame = 0; frame < m_frames; ++frame) {
         for (int loc = 0; loc < m_locations; ++loc) {
 	  const int key = tobKey(crate, jem, frame, loc);
-          const LVL1::CMXJetTob* const ct = findCmxTob(key);
+          const LVL1::CMXJetTob* const ct = findCmxTob(key, cmxTobMap);
           if ( ct ) {
             std::vector<int> energyLarge;
             std::vector<int> energySmall;
@@ -545,7 +549,7 @@ StatusCode JepByteStreamV2Tool::convert(const LVL1::JEPBSCollectionV2* const jep
               err1 |= (errBits.get(LVL1::DataError::ParityPhase2))<<2;
               err1 |= (errBits.get(LVL1::DataError::ParityPhase3))<<3;
               const int index = ( neutralFormat ) ? 0 : slice;
-              CmxJetSubBlock* const subBlock = m_cmxJetBlocks[index];
+              CmxJetSubBlock* const subBlock = cmxJetBlocks[index];
               subBlock->setTob(slice, jem, frame, loc, energyLarge[slice],
                                                   energySmall[slice], err0);
 	      subBlock->setParityBits(slice, jem, err1); // for neutral format
@@ -567,7 +571,7 @@ StatusCode JepByteStreamV2Tool::convert(const LVL1::JEPBSCollectionV2* const jep
 	   source == LVL1::CMXJetHits::TOTAL_FORWARD)) continue;
       int sourceId = jetSubBlockSourceId(source);
       if (sourceId == CmxJetSubBlock::MAX_SOURCE_ID) continue;
-      const LVL1::CMXJetHits* const ch = findCmxHits(crate, source);
+      const LVL1::CMXJetHits* const ch = findCmxHits(crate, source, cmxHitsMap);
       if ( ch ) {
         std::vector<unsigned int> hits0;
         std::vector<unsigned int> hits1;
@@ -593,7 +597,7 @@ StatusCode JepByteStreamV2Tool::convert(const LVL1::JEPBSCollectionV2* const jep
 	    }
 	  }
 	  const int index = ( neutralFormat ) ? 0 : slice;
-	  CmxJetSubBlock* const subBlock = m_cmxJetBlocks[index];
+	  CmxJetSubBlock* const subBlock = cmxJetBlocks[index];
 	  subBlock->setHits(slice, sourceId, 0, hits0[slice], error);
 	  if (source != LVL1::CMXJetHits::TOPO_CHECKSUM &&
 	      source != LVL1::CMXJetHits::TOPO_OCCUPANCY_MAP) {
@@ -603,8 +607,8 @@ StatusCode JepByteStreamV2Tool::convert(const LVL1::JEPBSCollectionV2* const jep
       }
     }
     DataVector<CmxJetSubBlock>::iterator jos;
-    jos = m_cmxJetBlocks.begin();
-    for (; jos != m_cmxJetBlocks.end(); ++jos) {
+    jos = cmxJetBlocks.begin();
+    for (; jos != cmxJetBlocks.end(); ++jos) {
       CmxJetSubBlock* const subBlock = *jos;
       if ( !subBlock->pack()) {
         msg(MSG::ERROR) << "CMX-Jet sub-block packing failed" << endmsg;
@@ -620,51 +624,69 @@ StatusCode JepByteStreamV2Tool::convert(const LVL1::JEPBSCollectionV2* const jep
 
   // Fill the raw event
 
-  m_fea->fill(re, msg());
-
-  // Set ROD status words
-
-  //L1CaloRodStatus::setStatus(re, m_rodStatusMap, m_srcIdMap);
+  fea.fill(re, msg());
 
   return StatusCode::SUCCESS;
 }
 
 // Return reference to vector with all possible Source Identifiers
 
-const std::vector<uint32_t>& JepByteStreamV2Tool::sourceIDs(
-                                                const std::string& sgKey)
+std::vector<uint32_t> JepByteStreamV2Tool::makeSourceIDs() const
 {
-  // Check if overlap jet element channels wanted
-  const std::string flag("Overlap");
-  const std::string::size_type pos = sgKey.find(flag);
-  m_coreOverlap =
-   (pos == std::string::npos || pos != sgKey.length() - flag.length()) ? 0 : 1;
+  std::vector<uint32_t> sourceIDs;
 
-  if (m_sourceIDs.empty()) {
+  if (!m_sourceIDsProp.empty()) {
+    sourceIDs = m_sourceIDsProp;
+  }
+  else {
     const int maxCrates = m_crates + m_crateOffsetHw;
-    const int maxSlinks = m_srcIdMap->maxSlinks();
-    for (int hwCrate = m_crateOffsetHw; hwCrate < maxCrates; ++hwCrate) {
-      for (int slink = 0; slink < maxSlinks; ++slink) {
+    const int maxSlinks = m_srcIdMap.maxSlinks();
+    for (int hwCrate = m_crateOffsetHw; hwCrate < maxCrates; ++hwCrate)
+    {
+      for (int slink = 0; slink < maxSlinks; ++slink)
+      {
         const int daqOrRoi = 0;
-        const uint32_t rodId = m_srcIdMap->getRodID(hwCrate, slink, daqOrRoi,
-                                                             m_subDetector);
-        const uint32_t robId = m_srcIdMap->getRobID(rodId);
-        m_sourceIDs.push_back(robId);
+        const uint32_t rodId = m_srcIdMap.getRodID(hwCrate, slink, daqOrRoi,
+                                                   m_subDetector);
+        const uint32_t robId = m_srcIdMap.getRobID(rodId);
+        sourceIDs.push_back(robId);
       }
     }
   }
-  return m_sourceIDs;
+  return sourceIDs;
+}
+
+const std::vector<uint32_t>& JepByteStreamV2Tool::sourceIDs() const
+{
+  static const std::vector<uint32_t> sourceIDs = makeSourceIDs();
+  return sourceIDs;
 }
 
 // Convert bytestream to given container type
 
 StatusCode JepByteStreamV2Tool::convertBs(
+                            const std::string& sgKey,
                             const IROBDataProviderSvc::VROBFRAG& robFrags,
-                            JepByteStreamToolData& data)
+                            JepByteStreamToolData& data) const
 {
+  LocalData ld;
+
+  // Check if overlap jet element channels wanted
+  const std::string flag("Overlap");
+  const std::string::size_type pos = sgKey.find(flag);
+  ld.coreOverlap =
+   (pos == std::string::npos || pos != sgKey.length() - flag.length()) ? 0 : 1;
+
   const bool debug = msgLvl(MSG::DEBUG);
   if (debug) msg(MSG::DEBUG);
 
+  // JemSubBlock for unpacking
+  JemSubBlockV2 jemSubBlock;
+  // CmxEnergySubBlock for unpacking
+  CmxEnergySubBlock cmxEnergySubBlock;
+  // CmxJetSubBlock for unpacking
+  CmxJetSubBlock cmxJetSubBlock;
+
   // Loop over ROB fragments
 
   int robCount = 0;
@@ -714,12 +736,12 @@ StatusCode JepByteStreamV2Tool::convertBs(
 
     // Check identifier
     const uint32_t sourceID = (*rob)->rod_source_id();
-    if (m_srcIdMap->getRobID(sourceID) != robid           ||
-        m_srcIdMap->subDet(sourceID)   != m_subDetector   ||
-	m_srcIdMap->daqOrRoi(sourceID) != 0               ||
-	m_srcIdMap->slink(sourceID)    >= m_slinks        ||
-	m_srcIdMap->crate(sourceID)    <  m_crateOffsetHw ||
-	m_srcIdMap->crate(sourceID)    >= m_crateOffsetHw + m_crates) {
+    if (m_srcIdMap.getRobID(sourceID) != robid           ||
+        m_srcIdMap.subDet(sourceID)   != m_subDetector   ||
+	m_srcIdMap.daqOrRoi(sourceID) != 0               ||
+	m_srcIdMap.slink(sourceID)    >= m_slinks        ||
+	m_srcIdMap.crate(sourceID)    <  m_crateOffsetHw ||
+	m_srcIdMap.crate(sourceID)    >= m_crateOffsetHw + m_crates) {
       m_errorTool->rodError(robid, L1CaloSubBlock::ERROR_ROD_ID);
       if (debug) {
         msg() << "Wrong source identifier in data: ROD "
@@ -731,14 +753,14 @@ StatusCode JepByteStreamV2Tool::convertBs(
 
     // Check minor version
     const int minorVersion = (*rob)->rod_version() & 0xffff;
-    if (minorVersion <= m_srcIdMap->minorVersionPreLS1()) {
+    if (minorVersion <= m_srcIdMap.minorVersionPreLS1()) {
       if (debug) msg() << "Skipping pre-LS1 data" << endmsg;
       continue;
     }
-    const int rodCrate = m_srcIdMap->crate(sourceID);
+    const int rodCrate = m_srcIdMap.crate(sourceID);
     if (debug) {
       msg() << "Treating crate " << rodCrate 
-            << " slink " << m_srcIdMap->slink(sourceID) << endmsg;
+            << " slink " << m_srcIdMap.slink(sourceID) << endmsg;
     }
 
     // First word should be User Header
@@ -767,74 +789,74 @@ StatusCode JepByteStreamV2Tool::convertBs(
 
     // Loop over sub-blocks
 
-    m_rodErr = L1CaloSubBlock::ERROR_NONE;
+    ld.rodErr = L1CaloSubBlock::ERROR_NONE;
     while (payload != payloadEnd) {
       
       if (L1CaloSubBlock::wordType(*payload) != L1CaloSubBlock::HEADER) {
         if (debug) msg() << "Unexpected data sequence" << endmsg;
-	m_rodErr = L1CaloSubBlock::ERROR_MISSING_HEADER;
+	ld.rodErr = L1CaloSubBlock::ERROR_MISSING_HEADER;
 	break;
       }
       if (CmxSubBlock::cmxBlock(*payload)) {
         // CMXs
 	if (CmxSubBlock::cmxType(*payload) == CmxSubBlock::CMX_JET) {
-	  m_cmxJetSubBlock->clear();
-          payload = m_cmxJetSubBlock->read(payload, payloadEnd);
-	  if (m_cmxJetSubBlock->crate() != rodCrate) {
+	  cmxJetSubBlock.clear();
+          payload = cmxJetSubBlock.read(payload, payloadEnd);
+	  if (cmxJetSubBlock.crate() != rodCrate) {
 	    if (debug) msg() << "Inconsistent crate number in ROD source ID"
 	                     << endmsg;
-	    m_rodErr = L1CaloSubBlock::ERROR_CRATE_NUMBER;
+	    ld.rodErr = L1CaloSubBlock::ERROR_CRATE_NUMBER;
 	    break;
           }
 	  if (data.m_collection == CMX_HITS || data.m_collection == CMX_TOBS) {
-	    decodeCmxJet(m_cmxJetSubBlock, trigJem, data);
-	    if (m_rodErr != L1CaloSubBlock::ERROR_NONE) {
+	    decodeCmxJet(&cmxJetSubBlock, trigJem, data, ld);
+	    if (ld.rodErr != L1CaloSubBlock::ERROR_NONE) {
 	      if (debug) msg() << "decodeCmxJet failed" << endmsg;
 	      break;
 	    }
           }
         } else if (CmxSubBlock::cmxType(*payload) == CmxSubBlock::CMX_ENERGY) {
-	  m_cmxEnergySubBlock->clear();
-	  payload = m_cmxEnergySubBlock->read(payload, payloadEnd);
-	  if (m_cmxEnergySubBlock->crate() != rodCrate) {
+	  cmxEnergySubBlock.clear();
+	  payload = cmxEnergySubBlock.read(payload, payloadEnd);
+	  if (cmxEnergySubBlock.crate() != rodCrate) {
 	    if (debug) msg() << "Inconsistent crate number in ROD source ID"
 	                     << endmsg;
-	    m_rodErr = L1CaloSubBlock::ERROR_CRATE_NUMBER;
+	    ld.rodErr = L1CaloSubBlock::ERROR_CRATE_NUMBER;
 	    break;
           }
 	  if (data.m_collection == CMX_SUMS) {
-	    decodeCmxEnergy(m_cmxEnergySubBlock, trigJem, static_cast<CmxSumsData&>(data));
-	    if (m_rodErr != L1CaloSubBlock::ERROR_NONE) {
+	    decodeCmxEnergy(&cmxEnergySubBlock, trigJem, static_cast<CmxSumsData&>(data), ld);
+	    if (ld.rodErr != L1CaloSubBlock::ERROR_NONE) {
 	      if (debug) msg() << "decodeCmxEnergy failed" << endmsg;
 	      break;
 	    }
           }
 	} else {
 	  if (debug) msg() << "Invalid CMX type in module field" << endmsg;
-	  m_rodErr = L1CaloSubBlock::ERROR_MODULE_NUMBER;
+	  ld.rodErr = L1CaloSubBlock::ERROR_MODULE_NUMBER;
 	  break;
         }
       } else {
         // JEM
-	m_jemSubBlock->clear();
-        payload = m_jemSubBlock->read(payload, payloadEnd);
-	if (m_jemSubBlock->crate() != rodCrate) {
+	jemSubBlock.clear();
+        payload = jemSubBlock.read(payload, payloadEnd);
+	if (jemSubBlock.crate() != rodCrate) {
 	  if (debug) msg() << "Inconsistent crate number in ROD source ID"
 	                   << endmsg;
-	  m_rodErr = L1CaloSubBlock::ERROR_CRATE_NUMBER;
+	  ld.rodErr = L1CaloSubBlock::ERROR_CRATE_NUMBER;
 	  break;
         }
 	if (data.m_collection == JET_ELEMENTS || data.m_collection == ENERGY_SUMS) {
-	  decodeJem(m_jemSubBlock, trigJem, data);
-	  if (m_rodErr != L1CaloSubBlock::ERROR_NONE) {
+	  decodeJem(&jemSubBlock, trigJem, data, ld);
+	  if (ld.rodErr != L1CaloSubBlock::ERROR_NONE) {
 	    if (debug) msg() << "decodeJem failed" << endmsg;
 	    break;
 	  }
         }
       }
     }
-    if (m_rodErr != L1CaloSubBlock::ERROR_NONE)
-                                       m_errorTool->rodError(robid, m_rodErr);
+    if (ld.rodErr != L1CaloSubBlock::ERROR_NONE)
+                                       m_errorTool->rodError(robid, ld.rodErr);
   }
 
   return StatusCode::SUCCESS;
@@ -844,7 +866,8 @@ StatusCode JepByteStreamV2Tool::convertBs(
 
 void JepByteStreamV2Tool::decodeCmxEnergy(CmxEnergySubBlock* subBlock,
                                           int trigJem,
-                                          CmxSumsData& data)
+                                          CmxSumsData& data,
+                                          LocalData& ld) const
 {
   const bool debug = msgLvl(MSG::DEBUG);
   if (debug) msg(MSG::DEBUG);
@@ -867,13 +890,13 @@ void JepByteStreamV2Tool::decodeCmxEnergy(CmxEnergySubBlock* subBlock,
     if (debug) msg() << "Triggered CMX slice from header "
                      << "inconsistent with number of slices: "
                      << trigJem << ", " << timeslices << endmsg;
-    m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+    ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
     return;
   }
   if (timeslices <= sliceNum) {
     if (debug) msg() << "Total slices inconsistent with slice number: "
                      << timeslices << ", " << sliceNum << endmsg;
-    m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+    ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
     return;
   }
   // Unpack sub-block
@@ -882,7 +905,7 @@ void JepByteStreamV2Tool::decodeCmxEnergy(CmxEnergySubBlock* subBlock,
       std::string errMsg(subBlock->unpackErrorMsg());
       msg() << "CMX-Energy sub-block unpacking failed: " << errMsg << endmsg;
     }
-    m_rodErr = subBlock->unpackErrorCode();
+    ld.rodErr = subBlock->unpackErrorCode();
     return;
   }
 
@@ -892,12 +915,12 @@ void JepByteStreamV2Tool::decodeCmxEnergy(CmxEnergySubBlock* subBlock,
   const int crate     = hwCrate - m_crateOffsetHw;
   const int swCrate   = crate   + m_crateOffsetSw;
   const int maxSource = static_cast<int>(LVL1::CMXEtSums::MAX_SOURCE);
-  std::vector<unsigned int>& exVec(m_uintVec0);
-  std::vector<unsigned int>& eyVec(m_uintVec1);
-  std::vector<unsigned int>& etVec(m_uintVec2);
-  std::vector<int>& exErrVec(m_intVec0);
-  std::vector<int>& eyErrVec(m_intVec1);
-  std::vector<int>& etErrVec(m_intVec2);
+  std::vector<unsigned int>& exVec(ld.uintVec0);
+  std::vector<unsigned int>& eyVec(ld.uintVec1);
+  std::vector<unsigned int>& etVec(ld.uintVec2);
+  std::vector<int>& exErrVec(ld.intVec0);
+  std::vector<int>& eyErrVec(ld.intVec1);
+  std::vector<int>& etErrVec(ld.intVec2);
   LVL1::DataError derr;
   derr.set(LVL1::DataError::SubStatusWord, subBlock->subStatus());
   const int ssError = derr.error();
@@ -994,14 +1017,14 @@ void JepByteStreamV2Tool::decodeCmxEnergy(CmxEnergySubBlock* subBlock,
 	  if (timeslices != nsl) {
 	    if (debug) msg() << "Inconsistent number of slices in sub-blocks"
 	                     << endmsg;
-            m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+            ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
 	    return;
           }
 	  if (exVec[slice] != 0 || eyVec[slice] != 0 || etVec[slice] != 0 ||
 	      exErrVec[slice] != 0 || eyErrVec[slice] != 0 ||
               etErrVec[slice] != 0) {
             if (debug) msg() << "Duplicate data for slice " << slice << endmsg;
-	    m_rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
+	    ld.rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
 	    return;
           }
 	  exVec[slice] = ex;
@@ -1024,7 +1047,8 @@ void JepByteStreamV2Tool::decodeCmxEnergy(CmxEnergySubBlock* subBlock,
 // Unpack CMX-Jet sub-block
 
 void JepByteStreamV2Tool::decodeCmxJet(CmxJetSubBlock* subBlock, int trigJem,
-                                       JepByteStreamToolData& data)
+                                       JepByteStreamToolData& data,
+                                       LocalData& ld) const
 {
   const bool debug = msgLvl(MSG::DEBUG);
   if (debug) msg(MSG::DEBUG);
@@ -1047,13 +1071,13 @@ void JepByteStreamV2Tool::decodeCmxJet(CmxJetSubBlock* subBlock, int trigJem,
     if (debug) msg() << "Triggered CMX slice from header "
                      << "inconsistent with number of slices: "
                      << trigJem << ", " << timeslices << endmsg;
-    m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+    ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
     return;
   }
   if (timeslices <= sliceNum) {
     if (debug) msg() << "Total slices inconsistent with slice number: "
                      << timeslices << ", " << sliceNum << endmsg;
-    m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+    ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
     return;
   }
   // Unpack sub-block
@@ -1062,7 +1086,7 @@ void JepByteStreamV2Tool::decodeCmxJet(CmxJetSubBlock* subBlock, int trigJem,
       std::string errMsg(subBlock->unpackErrorMsg());
       msg() << "CMX-Jet sub-block unpacking failed: " << errMsg << endmsg;
     }
-    m_rodErr = subBlock->unpackErrorCode();
+    ld.rodErr = subBlock->unpackErrorCode();
     return;
   }
 
@@ -1072,14 +1096,14 @@ void JepByteStreamV2Tool::decodeCmxJet(CmxJetSubBlock* subBlock, int trigJem,
   const int crate     = hwCrate - m_crateOffsetHw;
   const int swCrate   = crate   + m_crateOffsetSw;
   const int maxSource = static_cast<int>(LVL1::CMXJetHits::MAX_SOURCE);
-  std::vector<int>& energyLgVec(m_intVec0);
-  std::vector<int>& energySmVec(m_intVec1);
-  std::vector<int>& errorVec(m_intVec2);
-  std::vector<unsigned int>& presenceMapVec(m_uintVec0);
-  std::vector<unsigned int>& hit0Vec(m_uintVec0);
-  std::vector<unsigned int>& hit1Vec(m_uintVec1);
-  std::vector<int>& err0Vec(m_intVec0);
-  std::vector<int>& err1Vec(m_intVec1);
+  std::vector<int>& energyLgVec(ld.intVec0);
+  std::vector<int>& energySmVec(ld.intVec1);
+  std::vector<int>& errorVec(ld.intVec2);
+  std::vector<unsigned int>& presenceMapVec(ld.uintVec0);
+  std::vector<unsigned int>& hit0Vec(ld.uintVec0);
+  std::vector<unsigned int>& hit1Vec(ld.uintVec1);
+  std::vector<int>& err0Vec(ld.intVec0);
+  std::vector<int>& err1Vec(ld.intVec1);
   LVL1::DataError derr;
   derr.set(LVL1::DataError::SubStatusWord, subBlock->subStatus());
   const int ssError = derr.error();
@@ -1139,13 +1163,13 @@ void JepByteStreamV2Tool::decodeCmxJet(CmxJetSubBlock* subBlock, int trigJem,
 	    if (timeslices != nsl) {
 	      if (debug) msg() << "Inconsistent number of slices in sub-blocks"
 	                       << endmsg;
-              m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+              ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
 	      return;
             }
 	    if (energyLgVec[slice] != 0 || energySmVec[slice] != 0 ||
 	        errorVec[slice]  != 0 || presenceMapVec[slice] != 0) {
               if (debug) msg() << "Duplicate data for slice " << slice << endmsg;
-	      m_rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
+	      ld.rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
 	      return;
             }
 	    energyLgVec[slice] = energyLarge;
@@ -1209,13 +1233,13 @@ void JepByteStreamV2Tool::decodeCmxJet(CmxJetSubBlock* subBlock, int trigJem,
 	    if (timeslices != nsl) {
 	      if (debug) msg() << "Inconsistent number of slices in sub-blocks"
 	                       << endmsg;
-              m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+              ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
 	      return;
             }
 	    if (hit0Vec[slice] != 0 || hit1Vec[slice] != 0 ||
 	        err0Vec[slice] != 0 || err1Vec[slice] != 0) {
 	      if (debug) msg() << "Duplicate data for slice " << slice << endmsg;
-	      m_rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
+	      ld.rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
 	      return;
             }
 	    hit0Vec[slice] = hit0;
@@ -1235,7 +1259,8 @@ void JepByteStreamV2Tool::decodeCmxJet(CmxJetSubBlock* subBlock, int trigJem,
 // Unpack JEM sub-block
 
 void JepByteStreamV2Tool::decodeJem(JemSubBlockV2* subBlock, int trigJem,
-                                    JepByteStreamToolData& data)
+                                    JepByteStreamToolData& data,
+                                    LocalData& ld) const
 {
   const bool debug   = msgLvl(MSG::DEBUG);
   const bool verbose = msgLvl(MSG::VERBOSE);
@@ -1255,13 +1280,13 @@ void JepByteStreamV2Tool::decodeJem(JemSubBlockV2* subBlock, int trigJem,
     if (debug) msg() << "Triggered JEM slice from header "
                      << "inconsistent with number of slices: "
                      << trigJem << ", " << timeslices << endmsg;
-    m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+    ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
     return;
   }
   if (timeslices <= sliceNum) {
     if (debug) msg() << "Total slices inconsistent with slice number: "
                      << timeslices << ", " << sliceNum << endmsg;
-    m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+    ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
     return;
   }
   // Unpack sub-block
@@ -1270,7 +1295,7 @@ void JepByteStreamV2Tool::decodeJem(JemSubBlockV2* subBlock, int trigJem,
       std::string errMsg(subBlock->unpackErrorMsg());
       msg() << "JEM sub-block unpacking failed: " << errMsg << endmsg;
     }
-    m_rodErr = subBlock->unpackErrorCode();
+    ld.rodErr = subBlock->unpackErrorCode();
     return;
   }
 
@@ -1279,9 +1304,9 @@ void JepByteStreamV2Tool::decodeJem(JemSubBlockV2* subBlock, int trigJem,
   const bool neutralFormat = subBlock->format() == L1CaloSubBlock::NEUTRAL;
   const int crate    = hwCrate - m_crateOffsetHw;
   const int swCrate  = crate   + m_crateOffsetSw;
-  std::vector<unsigned int>& exVec(m_uintVec0);
-  std::vector<unsigned int>& eyVec(m_uintVec1);
-  std::vector<unsigned int>& etVec(m_uintVec2);
+  std::vector<unsigned int>& exVec(ld.uintVec0);
+  std::vector<unsigned int>& eyVec(ld.uintVec1);
+  std::vector<unsigned int>& etVec(ld.uintVec2);
   LVL1::DataError derr;
   derr.set(LVL1::DataError::SubStatusWord, subBlock->subStatus());
   const int ssError = derr.error();
@@ -1302,10 +1327,11 @@ void JepByteStreamV2Tool::decodeJem(JemSubBlockV2* subBlock, int trigJem,
 	  double phi = 0.;
 	  int layer = 0;
 	  if (m_jemMaps->mapping(crate, module, chan, eta, phi, layer)) {
-	    if (layer == m_coreOverlap) {
-	      LVL1::JetElement* je = findJetElement(jedata, eta, phi);
+	    if (layer == ld.coreOverlap) {
+	      LVL1::JetElement* je = findJetElement(jedata, eta, phi,
+                                                    ld.elementKey);
 	      if ( ! je ) {   // create new jet element
-	        const unsigned int key = m_elementKey->jeKey(phi, eta);
+	        const unsigned int key = ld.elementKey.jeKey(phi, eta);
                 auto jep =
                   std::make_unique<LVL1::JetElement>(phi, eta, dummy, dummy, key,
                                                      dummy, dummy, dummy, trigJem);
@@ -1323,14 +1349,14 @@ void JepByteStreamV2Tool::decodeJem(JemSubBlockV2* subBlock, int trigJem,
 		    msg() << "Inconsistent number of slices in sub-blocks"
 		          << endmsg;
                   }
-		  m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+		  ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
 		  return;
                 }
 		if (emEnergy[slice] != 0 || hadEnergy[slice] != 0 ||
 		    emError[slice]  != 0 || hadError[slice]  != 0) {
                   if (debug) msg() << "Duplicate data for slice "
 		                   << slice << endmsg;
-                  m_rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
+                  ld.rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
 		  return;
                 }
               }
@@ -1388,13 +1414,13 @@ void JepByteStreamV2Tool::decodeJem(JemSubBlockV2* subBlock, int trigJem,
 	      msg() << "Inconsistent number of slices in sub-blocks"
 	            << endmsg;
 	    }
-            m_rodErr = L1CaloSubBlock::ERROR_SLICES;
+            ld.rodErr = L1CaloSubBlock::ERROR_SLICES;
 	    return;
           }
 	  if (exVec[slice] != 0 || eyVec[slice] != 0 || etVec[slice] != 0) {
 	    if (debug) msg() << "Duplicate data for slice "
 	                     << slice << endmsg;
-            m_rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
+            ld.rodErr = L1CaloSubBlock::ERROR_DUPLICATE_DATA;
 	    return;
           }
 	  exVec[slice] = ex;
@@ -1418,7 +1444,7 @@ void JepByteStreamV2Tool::decodeJem(JemSubBlockV2* subBlock, int trigJem,
 // Find TOB map key for given crate, jem, frame, loc
 
 int JepByteStreamV2Tool::tobKey(const int crate, const int jem,
-                                const int frame, const int loc)
+                                const int frame, const int loc) const
 {
   return ((((((crate<<4)+jem)<<3)+frame)<<2)+loc);
 }
@@ -1427,19 +1453,22 @@ int JepByteStreamV2Tool::tobKey(const int crate, const int jem,
 
 const
 LVL1::JetElement* JepByteStreamV2Tool::findJetElement(const double eta,
-                                                      const double phi) const
+                                                      const double phi,
+                                                      const ConstJetElementMap& jeMap,
+                                                      LVL1::JetElementKey& elementKey) const
 {
-  const unsigned int key = m_elementKey->jeKey(phi, eta);
-  ConstJetElementMap::const_iterator mapIter = m_jeMap.find(key);
-  if (mapIter != m_jeMap.end()) return mapIter->second;
+  const unsigned int key = elementKey.jeKey(phi, eta);
+  ConstJetElementMap::const_iterator mapIter = jeMap.find(key);
+  if (mapIter != jeMap.end()) return mapIter->second;
   return nullptr;
 }
 
 LVL1::JetElement* JepByteStreamV2Tool::findJetElement(const JetElementData& data,
                                                       const double eta,
-                                                      const double phi) const
+                                                      const double phi,
+                                                      LVL1::JetElementKey& elementKey) const
 {
-  const unsigned int key = m_elementKey->jeKey(phi, eta);
+  const unsigned int key = elementKey.jeKey(phi, eta);
   JetElementMap::const_iterator mapIter = data.m_jeMap.find(key);
   if (mapIter != data.m_jeMap.end()) return mapIter->second;
   return nullptr;
@@ -1449,10 +1478,11 @@ LVL1::JetElement* JepByteStreamV2Tool::findJetElement(const JetElementData& data
 
 const
 LVL1::JEMEtSums* JepByteStreamV2Tool::findEnergySums(const int crate,
-                                                     const int module) const
+                                                     const int module,
+                                                     const ConstEnergySumsMap& etMap) const
 {
-  ConstEnergySumsMap::const_iterator mapIter = m_etMap.find(crate*m_modules + module);
-  if (mapIter != m_etMap.end()) return mapIter->second;
+  ConstEnergySumsMap::const_iterator mapIter = etMap.find(crate*m_modules + module);
+  if (mapIter != etMap.end()) return mapIter->second;
   return nullptr;
 }
 
@@ -1468,10 +1498,11 @@ LVL1::JEMEtSums* JepByteStreamV2Tool::findEnergySums(const EnergySumsData& data,
 // Find CMX TOB for given crate, jem, frame, loc
 
 const
-LVL1::CMXJetTob* JepByteStreamV2Tool::findCmxTob(const int key) const
+LVL1::CMXJetTob* JepByteStreamV2Tool::findCmxTob(const int key,
+                                                 const ConstCmxTobMap& cmxTobMap) const
 {
-  ConstCmxTobMap::const_iterator mapIter = m_cmxTobMap.find(key);
-  if (mapIter != m_cmxTobMap.end()) return mapIter->second;
+  ConstCmxTobMap::const_iterator mapIter = cmxTobMap.find(key);
+  if (mapIter != cmxTobMap.end()) return mapIter->second;
   return nullptr;
 }
 
@@ -1487,10 +1518,11 @@ LVL1::CMXJetTob* JepByteStreamV2Tool::findCmxTob(const CmxTobData& data,
 
 const
 LVL1::CMXJetHits* JepByteStreamV2Tool::findCmxHits(const int crate,
-                                                   const int source) const
+                                                   const int source,
+                                                   const ConstCmxHitsMap& cmxHitsMap) const
 {
-  ConstCmxHitsMap::const_iterator mapIter = m_cmxHitsMap.find(crate*100 + source);
-  if (mapIter != m_cmxHitsMap.end()) return mapIter->second;
+  ConstCmxHitsMap::const_iterator mapIter = cmxHitsMap.find(crate*100 + source);
+  if (mapIter != cmxHitsMap.end()) return mapIter->second;
   return nullptr;
 }
 
@@ -1507,10 +1539,11 @@ LVL1::CMXJetHits* JepByteStreamV2Tool::findCmxHits(const CmxHitsData& data,
 
 const
 LVL1::CMXEtSums* JepByteStreamV2Tool::findCmxSums(const int crate,
-                                                  const int source) const
+                                                  const int source,
+                                                  const ConstCmxSumsMap& cmxEtMap) const
 {
-  ConstCmxSumsMap::const_iterator mapIter = m_cmxEtMap.find(crate*100 + source);
-  if (mapIter != m_cmxEtMap.end()) return mapIter->second;
+  ConstCmxSumsMap::const_iterator mapIter = cmxEtMap.find(crate*100 + source);
+  if (mapIter != cmxEtMap.end()) return mapIter->second;
   return nullptr;
 }
 
@@ -1526,16 +1559,18 @@ LVL1::CMXEtSums* JepByteStreamV2Tool::findCmxSums(const CmxSumsData& data,
 // Set up jet element map
 
 void JepByteStreamV2Tool::setupJeMap(const JetElementCollection*
-                                                        const jeCollection)
+                                                        const jeCollection,
+                                     ConstJetElementMap& jeMap,
+                                     LVL1::JetElementKey& elementKey) const
 {
-  m_jeMap.clear();
+  jeMap.clear();
   if (jeCollection) {
     JetElementCollection::const_iterator pos  = jeCollection->begin();
     JetElementCollection::const_iterator pose = jeCollection->end();
     for (; pos != pose; ++pos) {
       const LVL1::JetElement* const je = *pos;
-      const unsigned int key = m_elementKey->jeKey(je->phi(), je->eta());
-      m_jeMap.insert(std::make_pair(key, je));
+      const unsigned int key = elementKey.jeKey(je->phi(), je->eta());
+      jeMap.insert(std::make_pair(key, je));
     }
   }
 }
@@ -1543,9 +1578,10 @@ void JepByteStreamV2Tool::setupJeMap(const JetElementCollection*
 // Set up energy sums map
 
 void JepByteStreamV2Tool::setupEtMap(const EnergySumsCollection*
-                                                         const etCollection)
+                                                         const etCollection,
+                                     ConstEnergySumsMap& etMap) const
 {
-  m_etMap.clear();
+  etMap.clear();
   if (etCollection) {
     EnergySumsCollection::const_iterator pos  = etCollection->begin();
     EnergySumsCollection::const_iterator pose = etCollection->end();
@@ -1553,7 +1589,7 @@ void JepByteStreamV2Tool::setupEtMap(const EnergySumsCollection*
       const LVL1::JEMEtSums* const sums = *pos;
       const int crate = sums->crate() - m_crateOffsetSw;
       const int key   = m_modules * crate + sums->module();
-      m_etMap.insert(std::make_pair(key, sums));
+      etMap.insert(std::make_pair(key, sums));
     }
   }
 }
@@ -1561,9 +1597,10 @@ void JepByteStreamV2Tool::setupEtMap(const EnergySumsCollection*
 // Set up CMX TOB map
 
 void JepByteStreamV2Tool::setupCmxTobMap(const CmxTobCollection*
-                                                         const tobCollection)
+                                                         const tobCollection,
+                                         ConstCmxTobMap& cmxTobMap) const
 {
-  m_cmxTobMap.clear();
+  cmxTobMap.clear();
   if (tobCollection) {
     CmxTobCollection::const_iterator pos  = tobCollection->begin();
     CmxTobCollection::const_iterator pose = tobCollection->end();
@@ -1574,7 +1611,7 @@ void JepByteStreamV2Tool::setupCmxTobMap(const CmxTobCollection*
       const int frame = tob->frame();
       const int loc   = tob->location();
       const int key   = tobKey(crate, jem, frame, loc);
-      m_cmxTobMap.insert(std::make_pair(key, tob));
+      cmxTobMap.insert(std::make_pair(key, tob));
     }
   }
 }
@@ -1582,9 +1619,10 @@ void JepByteStreamV2Tool::setupCmxTobMap(const CmxTobCollection*
 // Set up CMX hits map
 
 void JepByteStreamV2Tool::setupCmxHitsMap(const CmxHitsCollection*
-                                                         const hitCollection)
+                                                         const hitCollection,
+                                          ConstCmxHitsMap& cmxHitsMap) const
 {
-  m_cmxHitsMap.clear();
+  cmxHitsMap.clear();
   if (hitCollection) {
     CmxHitsCollection::const_iterator pos  = hitCollection->begin();
     CmxHitsCollection::const_iterator pose = hitCollection->end();
@@ -1592,7 +1630,7 @@ void JepByteStreamV2Tool::setupCmxHitsMap(const CmxHitsCollection*
       const LVL1::CMXJetHits* const hits = *pos;
       const int crate = hits->crate() - m_crateOffsetSw;
       const int key   = crate*100 + hits->source();
-      m_cmxHitsMap.insert(std::make_pair(key, hits));
+      cmxHitsMap.insert(std::make_pair(key, hits));
     }
   }
 }
@@ -1600,9 +1638,10 @@ void JepByteStreamV2Tool::setupCmxHitsMap(const CmxHitsCollection*
 // Set up CMX energy sums map
 
 void JepByteStreamV2Tool::setupCmxEtMap(const CmxSumsCollection*
-                                                         const etCollection)
+                                                         const etCollection,
+                                        ConstCmxSumsMap& cmxEtMap) const
 {
-  m_cmxEtMap.clear();
+  cmxEtMap.clear();
   if (etCollection) {
     CmxSumsCollection::const_iterator pos  = etCollection->begin();
     CmxSumsCollection::const_iterator pose = etCollection->end();
@@ -1610,7 +1649,7 @@ void JepByteStreamV2Tool::setupCmxEtMap(const CmxSumsCollection*
       const LVL1::CMXEtSums* const sums = *pos;
       const int crate = sums->crate() - m_crateOffsetSw;
       const int key   = crate*100 + sums->source();
-      m_cmxEtMap.insert(std::make_pair(key, sums));
+      cmxEtMap.insert(std::make_pair(key, sums));
     }
   }
 }
@@ -1618,7 +1657,15 @@ void JepByteStreamV2Tool::setupCmxEtMap(const CmxSumsCollection*
 // Get number of slices and triggered slice offset for next slink
 
 bool JepByteStreamV2Tool::slinkSlices(const int crate, const int module,
-                  const int modulesPerSlink, int& timeslices, int& trigJem)
+                                      const int modulesPerSlink,
+                                      int& timeslices,
+                                      int& trigJem,
+                                      const ConstJetElementMap& jeMap,
+                                      const ConstEnergySumsMap& etMap,
+                                      const ConstCmxTobMap& cmxTobMap,
+                                      const ConstCmxHitsMap& cmxHitsMap,
+                                      const ConstCmxSumsMap& cmxEtMap,
+                                      LVL1::JetElementKey& elementKey) const
 {
   int slices = -1;
   int trigJ  = m_dfltSlices/2;
@@ -1628,7 +1675,8 @@ bool JepByteStreamV2Tool::slinkSlices(const int crate, const int module,
       double phi = 0.;
       int layer = 0;
       if ( !m_jemMaps->mapping(crate, mod, chan, eta, phi, layer)) continue;
-      const LVL1::JetElement* const je = findJetElement(eta, phi);
+      const LVL1::JetElement* const je = findJetElement(eta, phi, jeMap,
+                                                        elementKey);
       if ( !je ) continue;
       const int numdat = 5;
       std::vector<int> sums(numdat);
@@ -1657,7 +1705,7 @@ bool JepByteStreamV2Tool::slinkSlices(const int crate, const int module,
 	} else if (slices != sizes[i] || trigJ != peak) return false;
       }
     }
-    const LVL1::JEMEtSums* const et = findEnergySums(crate, mod);
+    const LVL1::JEMEtSums* const et = findEnergySums(crate, mod, etMap);
     if (et) {
       const int numdat = 3;
       std::vector<unsigned int> sums(numdat);
@@ -1687,7 +1735,7 @@ bool JepByteStreamV2Tool::slinkSlices(const int crate, const int module,
       for (int frame = 0; frame < m_frames; ++frame) {
         for (int loc = 0; loc < m_locations; ++loc) {
 	  const int key = tobKey(crate, jem, frame, loc);
-	  const LVL1::CMXJetTob* tob = findCmxTob(key);
+	  const LVL1::CMXJetTob* tob = findCmxTob(key, cmxTobMap);
 	  if (tob) {
 	    const int numdat = 4;
             std::vector<int> sums(numdat);
@@ -1724,7 +1772,7 @@ bool JepByteStreamV2Tool::slinkSlices(const int crate, const int module,
       std::vector<unsigned int> sums(numdat);
       std::vector<int> sizes(numdat);
       const LVL1::CMXJetHits* hits = 0;
-      if (source < maxDataID1) hits = findCmxHits(crate, source);
+      if (source < maxDataID1) hits = findCmxHits(crate, source, cmxHitsMap);
       if (hits) {
         sums[0] = std::accumulate((hits->hitsVec0()).begin(),
                                              (hits->hitsVec0()).end(), 0);
@@ -1747,8 +1795,7 @@ bool JepByteStreamV2Tool::slinkSlices(const int crate, const int module,
           } else if (slices != sizes[i] || trigJ != peak) return false;
         }
       }
-      const LVL1::CMXEtSums* et = 0;
-      if (source < maxDataID2) et = findCmxSums(crate, source);
+      const LVL1::CMXEtSums* et = 0;      if (source < maxDataID2) et = findCmxSums(crate, source, cmxEtMap);
       if (et) {
         sums[0] = std::accumulate((et->ExVec()).begin(),
   				  (et->ExVec()).end(), 0);
@@ -1790,7 +1837,7 @@ bool JepByteStreamV2Tool::slinkSlices(const int crate, const int module,
 void JepByteStreamV2Tool::energySubBlockTypes(const int source,
                           CmxEnergySubBlock::SourceType& srcType,
 			  CmxEnergySubBlock::SumType&    sumType,
-			  CmxEnergySubBlock::HitsType&   hitType)
+			  CmxEnergySubBlock::HitsType&   hitType) const
 {
   switch (source) {
     case LVL1::CMXEtSums::REMOTE_STANDARD:
@@ -1844,7 +1891,7 @@ void JepByteStreamV2Tool::energySubBlockTypes(const int source,
 
 // Get jet hits subBlock source ID from CMXJetHits source type
 
-int JepByteStreamV2Tool::jetSubBlockSourceId(const int source)
+int JepByteStreamV2Tool::jetSubBlockSourceId(const int source) const
 {
   int sourceId = CmxJetSubBlock::MAX_SOURCE_ID;
   switch (source) {
diff --git a/Trigger/TrigT1/TrigT1CaloByteStream/src/JepByteStreamV2Tool.h b/Trigger/TrigT1/TrigT1CaloByteStream/src/JepByteStreamV2Tool.h
index 89c9431a3b79c778394da09b2f11cd7e67f6f016..efeeeb3fece44681adde463795f2d5b8f0816f6f 100755
--- a/Trigger/TrigT1/TrigT1CaloByteStream/src/JepByteStreamV2Tool.h
+++ b/Trigger/TrigT1/TrigT1CaloByteStream/src/JepByteStreamV2Tool.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRIGT1CALOBYTESTREAM_JEPBYTESTREAMV2TOOL_H
@@ -11,6 +11,8 @@
 #include <string>
 #include <vector>
 
+#include "L1CaloSrcIdMap.h"
+#include "TrigT1CaloUtils/JetElementKey.h"
 #include "AthenaBaseComps/AthAlgTool.h"
 #include "ByteStreamCnvSvcBase/IROBDataProviderSvc.h"
 #include "ByteStreamData/RawEvent.h"
@@ -62,43 +64,70 @@ class JepByteStreamV2Tool : public AthAlgTool {
    /// AlgTool InterfaceID
    static const InterfaceID& interfaceID();
 
-   virtual StatusCode initialize();
-   virtual StatusCode finalize();
+   virtual StatusCode initialize() override;
+   virtual StatusCode finalize() override;
 
    /// Convert ROB fragments to jet elements
    StatusCode convert(const std::string& name,
-                      DataVector<LVL1::JetElement>* jeCollection);
-   StatusCode convert(const IROBDataProviderSvc::VROBFRAG& robFrags,
-                      DataVector<LVL1::JetElement>* jeCollection);
+                      DataVector<LVL1::JetElement>* jeCollection) const;
+   StatusCode convert(const std::string& sgKey,
+                      const IROBDataProviderSvc::VROBFRAG& robFrags,
+                      DataVector<LVL1::JetElement>* jeCollection) const;
    /// Convert ROB fragments to energy sums
    StatusCode convert(const std::string& name,
-                      DataVector<LVL1::JEMEtSums>* etCollection);
-   StatusCode convert(const IROBDataProviderSvc::VROBFRAG& robFrags,
-                      DataVector<LVL1::JEMEtSums>* etCollection);
+                      DataVector<LVL1::JEMEtSums>* etCollection) const;
+   StatusCode convert(const std::string& sgKey,
+                      const IROBDataProviderSvc::VROBFRAG& robFrags,
+                      DataVector<LVL1::JEMEtSums>* etCollection) const;
    /// Convert ROB fragments to CMX TOBs
    StatusCode convert(const std::string& name,
-                      DataVector<LVL1::CMXJetTob>* tobCollection);
-   StatusCode convert(const IROBDataProviderSvc::VROBFRAG& robFrags,
-                      DataVector<LVL1::CMXJetTob>* tobCollection);
+                      DataVector<LVL1::CMXJetTob>* tobCollection) const;
+   StatusCode convert(const std::string& sgKey,
+                      const IROBDataProviderSvc::VROBFRAG& robFrags,
+                      DataVector<LVL1::CMXJetTob>* tobCollection) const;
    /// Convert ROB fragments to CMX jet hits
    StatusCode convert(const std::string& name,
-                      DataVector<LVL1::CMXJetHits>* hitCollection);
-   StatusCode convert(const IROBDataProviderSvc::VROBFRAG& robFrags,
-                      DataVector<LVL1::CMXJetHits>* hitCollection);
+                      DataVector<LVL1::CMXJetHits>* hitCollection) const;
+   StatusCode convert(const std::string& sgKey,
+                      const IROBDataProviderSvc::VROBFRAG& robFrags,
+                      DataVector<LVL1::CMXJetHits>* hitCollection) const;
    /// Convert ROB fragments to CMX energy sums
    StatusCode convert(const std::string& name,
-                      DataVector<LVL1::CMXEtSums>* etCollection);
-   StatusCode convert(const IROBDataProviderSvc::VROBFRAG& robFrags,
-                      DataVector<LVL1::CMXEtSums>* etCollection);
+                      DataVector<LVL1::CMXEtSums>* etCollection) const;
+   StatusCode convert(const std::string& sgKey,
+                      const IROBDataProviderSvc::VROBFRAG& robFrags,
+                      DataVector<LVL1::CMXEtSums>* etCollection) const;
 
    /// Convert JEP Container to bytestream
-   StatusCode convert(const LVL1::JEPBSCollectionV2* jep, RawEventWrite* re);
+   StatusCode convert(const LVL1::JEPBSCollectionV2* jep, RawEventWrite* re) const;
 
    /// Return reference to vector with all possible Source Identifiers
-   const std::vector<uint32_t>& sourceIDs(const std::string& sgKey);
+   const std::vector<uint32_t>& sourceIDs() const;
 
  private:
-   enum CollectionType { JET_ELEMENTS, ENERGY_SUMS, CMX_TOBS,
+  struct LocalData
+  {
+    /// Jet elements to accept (0=Core, 1=Overlap)
+    int coreOverlap = 0;
+    // Unpacking error code
+    unsigned int rodErr = 0;
+    /// Unsigned int unpacking vector 0
+    std::vector<unsigned int> uintVec0;
+    /// Unsigned int unpacking vector 1
+    std::vector<unsigned int> uintVec1;
+    /// Unsigned int unpacking vector 2
+    std::vector<unsigned int> uintVec2;
+    /// Int unpacking vector 0
+    std::vector<int> intVec0;
+    /// Int unpacking vector 1
+    std::vector<int> intVec1;
+    /// Int unpacking vector 2
+    std::vector<int> intVec2;
+    // Jet element key provider
+    LVL1::JetElementKey elementKey;
+  };
+
+  enum CollectionType { JET_ELEMENTS, ENERGY_SUMS, CMX_TOBS,
                                        CMX_HITS, CMX_SUMS };
 
    typedef DataVector<LVL1::JetElement>                  JetElementCollection;
@@ -164,146 +193,124 @@ class JepByteStreamV2Tool : public AthAlgTool {
    };
 
    /// Convert bytestream to given container type
-   StatusCode convertBs(const IROBDataProviderSvc::VROBFRAG& robFrags,
-                        JepByteStreamToolData& data);
+   StatusCode convertBs(const std::string& sgKey,
+                        const IROBDataProviderSvc::VROBFRAG& robFrags,
+                        JepByteStreamToolData& data) const;
    /// Unpack CMX-Energy sub-block
-   void decodeCmxEnergy(CmxEnergySubBlock* subBlock, int trigJem, CmxSumsData& data);
+   void decodeCmxEnergy(CmxEnergySubBlock* subBlock, int trigJem, CmxSumsData& data,
+                        LocalData& ld) const;
    /// Unpack CMX-Jet sub-block
    void decodeCmxJet(CmxJetSubBlock* subBlock, int trigJem,
-                     JepByteStreamToolData& data);
+                     JepByteStreamToolData& data,
+                     LocalData& ld) const;
    /// Unpack JEM sub-block
    void decodeJem(JemSubBlockV2* subBlock, int trigJem,
-                  JepByteStreamToolData& data);
+                  JepByteStreamToolData& data,
+                  LocalData& ld) const;
 
    /// Find TOB map key for given crate, jem, frame, loc
-   int tobKey(int crate, int jem, int frame, int loc);
+   int tobKey(int crate, int jem, int frame, int loc) const;
    /// Find a jet element given eta, phi
-   const LVL1::JetElement* findJetElement(double eta, double phi) const;
-   LVL1::JetElement* findJetElement(const JetElementData& data, double eta, double phi) const;
+   const LVL1::JetElement* findJetElement(double eta, double phi,
+                                          const ConstJetElementMap& jeMap,
+                                          LVL1::JetElementKey& elementKey) const;
+   LVL1::JetElement* findJetElement(const JetElementData& data, double eta, double phi,
+                                    LVL1::JetElementKey& elementKey) const;
    /// Find energy sums for given crate, module
-   const LVL1::JEMEtSums*  findEnergySums(int crate, int module) const;
+   const LVL1::JEMEtSums*  findEnergySums(int crate, int module,
+                                          const ConstEnergySumsMap& etMap) const;
    LVL1::JEMEtSums*  findEnergySums(const EnergySumsData& data, int crate, int module) const;
    /// Find CMX TOB for given key
-   const LVL1::CMXJetTob*  findCmxTob(int key) const;
+   const LVL1::CMXJetTob*  findCmxTob(int key,
+                                      const ConstCmxTobMap& cmxTobMap) const;
    LVL1::CMXJetTob*  findCmxTob(const CmxTobData& data, int key) const;
    /// Find CMX hits for given crate, source
-   const LVL1::CMXJetHits* findCmxHits(int crate, int source) const;
+   const LVL1::CMXJetHits* findCmxHits(int crate, int source,
+                                       const ConstCmxHitsMap& cmxHitsMap) const;
    LVL1::CMXJetHits* findCmxHits(const CmxHitsData& data, int crate, int source) const;
    /// Find CMX energy sums for given crate, source
-   const LVL1::CMXEtSums*  findCmxSums(int crate, int source) const;
+   const LVL1::CMXEtSums*  findCmxSums(int crate, int source,
+                                       const ConstCmxSumsMap& cmxEtMap) const;
    LVL1::CMXEtSums*  findCmxSums(const CmxSumsData& data, int crate, int source) const;
 
+   std::vector<uint32_t> makeSourceIDs() const;
+
    /// Set up jet element map
-   void setupJeMap(const JetElementCollection* jeCollection);
+   void setupJeMap(const JetElementCollection* jeCollection,
+                   ConstJetElementMap& jeMap,
+                   LVL1::JetElementKey& elementKey) const;
    /// Set up energy sums map
-   void setupEtMap(const EnergySumsCollection* enCollection);
+   void setupEtMap(const EnergySumsCollection* enCollection,
+                   ConstEnergySumsMap& etMap) const;
    /// Set up CMX TOB map
-   void setupCmxTobMap(const CmxTobCollection* tobCollection);
+   void setupCmxTobMap(const CmxTobCollection* tobCollection,
+                       ConstCmxTobMap& cmxTobMap) const;
    /// Set up CMX hits map
-   void setupCmxHitsMap(const CmxHitsCollection* hitCollection);
+   void setupCmxHitsMap(const CmxHitsCollection* hitCollection,
+                        ConstCmxHitsMap& cmxHitsMap) const;
    /// Set up CMX energy sums map
-   void setupCmxEtMap(const CmxSumsCollection* enCollection);
+   void setupCmxEtMap(const CmxSumsCollection* enCollection,
+                      ConstCmxSumsMap& cmxEtMap) const;
 
    /// Get number of slices and triggered slice offset for next slink
    bool slinkSlices(int crate, int module, int modulesPerSlink,
-                    int& timeslices, int& trigJem);
+                    int& timeslices, int& trigJem,
+                    const ConstJetElementMap& jeMap,
+                    const ConstEnergySumsMap& etMap,
+                    const ConstCmxTobMap& cmxTobMap,
+                    const ConstCmxHitsMap& cmxHitsMap,
+                    const ConstCmxSumsMap& cmxEtMap,
+                    LVL1::JetElementKey& elementKey) const;
    /// Get energy subBlock types from CMXEtSums source type
    void energySubBlockTypes(int source,
                             CmxEnergySubBlock::SourceType& srcType,
 			    CmxEnergySubBlock::SumType&    sumType,
-			    CmxEnergySubBlock::HitsType&   hitType);
+			    CmxEnergySubBlock::HitsType&   hitType) const;
    /// Get jet hits subBlock source ID from CMXJetHits source type
-   int jetSubBlockSourceId(int source);
+   int jetSubBlockSourceId(int source) const;
 
    ServiceHandle<IROBDataProviderSvc> m_robDataProvider;
-   /// Channel mapping tool
+   /// Property: Channel mapping tool
    ToolHandle<LVL1::IL1CaloMappingTool> m_jemMaps;
-   /// Error collection tool
+   /// Property:Error collection tool
    ToolHandle<LVL1BS::L1CaloErrorByteStreamTool> m_errorTool;
 
-   /// Hardware crate number offset
+   /// Property:Hardware crate number offset
    int m_crateOffsetHw;
-   /// Software crate number offset
+   /// Property:Software crate number offset
    int m_crateOffsetSw;
-   /// Sub_block header version
+   /// Property:Sub_block header version
    int m_version;
-   /// Data compression format
+   /// Property:Data compression format
    int m_dataFormat;
    /// Number of channels per module
-   int m_channels;
+   const int m_channels;
    /// Number of crates
-   int m_crates;
+   const int m_crates;
    /// Number of JEM modules per crate
-   int m_modules;
+   const int m_modules;
    /// Number of RoI frames
-   int m_frames;
+   const int m_frames;
    /// Number of RoI locations
-   int m_locations;
+   const int m_locations;
    /// Maximum number of TOBs per module
-   int m_maxTobs;
-   /// Number of slinks per crate when writing out bytestream
+   const int m_maxTobs;
+   /// Property: Number of slinks per crate when writing out bytestream
    int m_slinks;
-   /// Default number of slices in simulation
+   /// Property: Default number of slices in simulation
    int m_dfltSlices;
-   /// Force number of slices in bytestream
+   /// Property: Force number of slices in bytestream
    int m_forceSlices;
-   /// Minimum crate number when writing out bytestream
+   /// Property: Minimum crate number when writing out bytestream
    int m_crateMin;
-   /// Maximum crate number when writing out bytestream
+   /// Property: Maximum crate number when writing out bytestream
    int m_crateMax;
-   /// Jet elements to accept (0=Core, 1=Overlap)
-   int m_coreOverlap;
-   /// Unpacking error code
-   unsigned int m_rodErr;
-   /// ROB source IDs
-   std::vector<uint32_t> m_sourceIDs;
+   /// Property:ROB source IDs
+   std::vector<uint32_t> m_sourceIDsProp;
    /// Sub-detector type
-   eformat::SubDetector m_subDetector;
+   const eformat::SubDetector m_subDetector;
    /// Source ID converter
-   L1CaloSrcIdMap* m_srcIdMap;
-   /// Jet element key provider
-   LVL1::JetElementKey* m_elementKey;
-   /// JemSubBlock for unpacking
-   JemSubBlockV2* m_jemSubBlock;
-   /// CmxEnergySubBlock for unpacking
-   CmxEnergySubBlock* m_cmxEnergySubBlock;
-   /// CmxJetSubBlock for unpacking
-   CmxJetSubBlock* m_cmxJetSubBlock;
-   /// Unsigned int unpacking vector 0
-   std::vector<unsigned int> m_uintVec0;
-   /// Unsigned int unpacking vector 1
-   std::vector<unsigned int> m_uintVec1;
-   /// Unsigned int unpacking vector 2
-   std::vector<unsigned int> m_uintVec2;
-   /// Int unpacking vector 0
-   std::vector<int> m_intVec0;
-   /// Int unpacking vector 1
-   std::vector<int> m_intVec1;
-   /// Int unpacking vector 2
-   std::vector<int> m_intVec2;
-   /// Vector for current JEM sub-blocks
-   DataVector<JemSubBlockV2> m_jemBlocks;
-   /// Vector for current CMX-Energy sub-blocks
-   DataVector<CmxEnergySubBlock> m_cmxEnergyBlocks;
-   /// Vector for current CMX-Jet sub-blocks
-   DataVector<CmxJetSubBlock> m_cmxJetBlocks;
-   /// Jet element map
-   ConstJetElementMap m_jeMap;
-   /// Energy sums map
-   ConstEnergySumsMap m_etMap;
-   /// CMX TOB map
-   ConstCmxTobMap     m_cmxTobMap;
-   /// CMX hits map
-   ConstCmxHitsMap    m_cmxHitsMap;
-   /// CMX energy sums map
-   ConstCmxSumsMap    m_cmxEtMap;
-   /// ROD Status words
-   std::vector<uint32_t>* m_rodStatus;
-   /// ROD status map
-   std::map<uint32_t, std::vector<uint32_t>* > m_rodStatusMap;
-   /// Event assembler
-   FullEventAssembler<L1CaloSrcIdMap>* m_fea;
-
+   const L1CaloSrcIdMap m_srcIdMap;
 };
 
 } // end namespace
diff --git a/Trigger/TrigT1/TrigT1CaloByteStream/src/JepReadByteStreamV1Cnv.icc b/Trigger/TrigT1/TrigT1CaloByteStream/src/JepReadByteStreamV1Cnv.icc
index 788491d1ab5492397c48ca56f48f3f9fd016d372..ac6ea86a60b886b8a25737eed2ce86e59ad519fc 100644
--- a/Trigger/TrigT1/TrigT1CaloByteStream/src/JepReadByteStreamV1Cnv.icc
+++ b/Trigger/TrigT1/TrigT1CaloByteStream/src/JepReadByteStreamV1Cnv.icc
@@ -90,7 +90,7 @@ StatusCode JepReadByteStreamV1Cnv<Container>::createObj( IOpaqueAddress* pAddr,
   }
 
   // get SourceIDs
-  const std::vector<uint32_t>& vID(m_tool->sourceIDs(nm));
+  const std::vector<uint32_t>& vID(m_tool->sourceIDs());
 
   // get ROB fragments
   IROBDataProviderSvc::VROBFRAG robFrags;
@@ -106,7 +106,7 @@ StatusCode JepReadByteStreamV1Cnv<Container>::createObj( IOpaqueAddress* pAddr,
     return StatusCode::SUCCESS;
   }
 
-  ATH_CHECK( m_tool->convert(robFrags, collection.get()) );
+  ATH_CHECK( m_tool->convert(nm, robFrags, collection.get()) );
 
   pObj = SG::asStorable(std::move(collection));
 
diff --git a/Trigger/TrigT1/TrigT1CaloByteStream/src/JepReadByteStreamV1V2Cnv.icc b/Trigger/TrigT1/TrigT1CaloByteStream/src/JepReadByteStreamV1V2Cnv.icc
index 2b32a33b6796e7769e300a0ef79dcfb57120eb76..069c4810f6897805960da4ccb6957813dacf95e0 100644
--- a/Trigger/TrigT1/TrigT1CaloByteStream/src/JepReadByteStreamV1V2Cnv.icc
+++ b/Trigger/TrigT1/TrigT1CaloByteStream/src/JepReadByteStreamV1V2Cnv.icc
@@ -96,8 +96,8 @@ StatusCode JepReadByteStreamV1V2Cnv<Container>::createObj( IOpaqueAddress* pAddr
   }
 
   // get SourceIDs
-  const std::vector<uint32_t>& vID1(m_tool1->sourceIDs(nm));
-  const std::vector<uint32_t>& vID2(m_tool2->sourceIDs(nm));
+  const std::vector<uint32_t>& vID1(m_tool1->sourceIDs());
+  const std::vector<uint32_t>& vID2(m_tool2->sourceIDs());
 
   // get ROB fragments
   IROBDataProviderSvc::VROBFRAG robFrags1;
@@ -118,11 +118,11 @@ StatusCode JepReadByteStreamV1V2Cnv<Container>::createObj( IOpaqueAddress* pAddr
 
   // Pre-LS1 data
   if (robFrags1.size() > 0) {
-    ATH_CHECK( m_tool1->convert(robFrags1, collection.get()) );
+    ATH_CHECK( m_tool1->convert(nm, robFrags1, collection.get()) );
   }
   // Post-LS1 data
   if (robFrags2.size() > 0) {
-    ATH_CHECK( m_tool2->convert(robFrags2, collection.get()) );
+    ATH_CHECK( m_tool2->convert(nm, robFrags2, collection.get()) );
   }
 
   pObj = SG::asStorable(std::move(collection));
diff --git a/Trigger/TrigT1/TrigT1CaloByteStream/src/TrigT1CaloDataAccess.cxx b/Trigger/TrigT1/TrigT1CaloByteStream/src/TrigT1CaloDataAccess.cxx
index c2a5a9b4ba211c5ca56a857c7712b6506432b48e..8ec61a69de35d41757742336ffe05af8599d24a9 100644
--- a/Trigger/TrigT1/TrigT1CaloByteStream/src/TrigT1CaloDataAccess.cxx
+++ b/Trigger/TrigT1/TrigT1CaloByteStream/src/TrigT1CaloDataAccess.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 
@@ -198,7 +198,8 @@ StatusCode TrigT1CaloDataAccess::loadCollection(
   m_robDataProvider->getROBData(m_robs_full_je, m_robFrags);
 
   m_jetCol->clear();
-  StatusCode sc = m_JetConverter->convert(m_robFrags, m_jetCol);
+  // FIXME: Assuming not Overlap.
+  StatusCode sc = m_JetConverter->convert("", m_robFrags, m_jetCol);
   if (sc.isFailure() ) {
     msg(MSG::ERROR) << "JET bytestream conversion failed" << endmsg;
     return sc;