diff --git a/Calorimeter/CaloEvent/CaloEvent/CaloEnergyCluster.h b/Calorimeter/CaloEvent/CaloEvent/CaloEnergyCluster.h
index 67791a8919305f4c68f33888be6fe8cc6c7032b4..19d2f6b2c2c7145e705d77028efbc08e3ea9c742 100644
--- a/Calorimeter/CaloEvent/CaloEvent/CaloEnergyCluster.h
+++ b/Calorimeter/CaloEvent/CaloEvent/CaloEnergyCluster.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 CALOEVENT_CALOENERGYCLUSTER_H
@@ -136,6 +136,24 @@ class CaloEnergyCluster : public Navigable<CaloCellContainer,double>,
                            double weight,
                            size_t size_hint = 0);
 
+
+  /*! \brief Add a cell (very fast)
+   * 
+   *  \overload
+   * 
+   *  \param theContainer  input pointer to a \a CaloCellContainer (unchanged)
+   *  \param theIndex      input index of \a CaloCell in \a CaloCellConatiner 
+   *                       (unchanged)
+   *  \param sg            current event store instance
+   *  \param weight        signal weight asociated with this cell
+   *
+   *  client has to provide the correct (and valid) index.
+   *
+   *  The caller also guarantees that the cell is not already
+   *  in the cluster.
+   * 
+   *  The caller MUST update Kinematics by himself
+   */
   void addUniqueCellNoKine(const CaloCellContainer* theContainer,
                            index_type theIndex,
                            IProxyDict* sg,
@@ -143,6 +161,34 @@ class CaloEnergyCluster : public Navigable<CaloCellContainer,double>,
                            size_t size_hint = 0);
 
 
+  /*! \brief Add a cell (fastest)
+   * 
+   *  \overload
+   * 
+   *  \param theContainer  link pointing to some element of a \a CaloCellContainer (unchanged)
+   *                       The element index is ignored; this is only to
+   *                       identify the container.
+   *  \param theIndex      input index of \a CaloCell in \a CaloCellConatiner 
+   *                       (unchanged)
+   *  \param sg            current event store instance
+   *  \param weight        signal weight asociated with this cell
+   *
+   *  client has to provide the correct (and valid) index.
+   *
+   *  The caller also guarantees that the cell is not already
+   *  in the cluster.
+   *
+   *  Using this method avoids having to look up the container
+   *  in the event store.
+   * 
+   *  The caller MUST update Kinematics by himself
+   */
+  void addUniqueCellNoKine(const ElementLink<CaloCellContainer>& theContainer,
+                           index_type theIndex,
+                           double weight,
+                           size_t size_hint = 0);
+
+
   /*! \brief Reweight a cell with kinematic update
    *
    *  \param theCell input pointer to a \a CaloCell object (unchanged)
diff --git a/Calorimeter/CaloEvent/src/CaloEnergyCluster.cxx b/Calorimeter/CaloEvent/src/CaloEnergyCluster.cxx
index 2c3e5fe28933b3643d659de60bbaff0dd23da81a..3b471224eb56667ebf56aec022d70e9e6ddc458c 100644
--- a/Calorimeter/CaloEvent/src/CaloEnergyCluster.cxx
+++ b/Calorimeter/CaloEvent/src/CaloEnergyCluster.cxx
@@ -145,6 +145,18 @@ CaloEnergyCluster::addUniqueCellNoKine(const CaloCellContainer* theContainer,
 }
 
 
+void
+CaloEnergyCluster::addUniqueCellNoKine(const ElementLink<CaloCellContainer>& theContainer,
+                                       index_type theIndex,
+                                       double weight,
+                                       size_t size_hint)
+{
+  if ((int)theIndex < 0) abort();
+  ElementLink<CaloCellContainer> el (theContainer, theIndex);
+  this->insertElement(el,weight,size_hint);
+}
+
+
 void 
 CaloEnergyCluster::removeCell(/*CaloCellContainer::const_reference*/
 			      const CaloCell* theCell)
diff --git a/Calorimeter/CaloRec/src/CaloTopoTowerAlg.cxx b/Calorimeter/CaloRec/src/CaloTopoTowerAlg.cxx
index b25a6edfb302b183f69f21a21b2ca0273ce701bb..bc7e48bae2f8f088da5315c389feb21a12096e1b 100644
--- a/Calorimeter/CaloRec/src/CaloTopoTowerAlg.cxx
+++ b/Calorimeter/CaloRec/src/CaloTopoTowerAlg.cxx
@@ -155,6 +155,9 @@ StatusCode CaloTopoTowerAlg::execute (const EventContext& ctx) const
      return StatusCode::SUCCESS;
   }
 
+  // EL to the container, to allow making other ELs quickly.
+  ElementLink<CaloCellContainer> theCellsEL (m_cellContainerKey.key(), 0, ctx);
+
   ///+++ pick up CaloCell2ClusterMap from StoreGate
   const CaloClusterContainer* clusterContainer = nullptr;
   
@@ -312,7 +315,7 @@ StatusCode CaloTopoTowerAlg::execute (const EventContext& ctx) const
               energyTower += cellEnergy;
               numberOfClustersInTower++;           
 
-              newTower->addUniqueCellNoKine(theCells.cptr(),globalIndex,weight, 10);
+              newTower->addUniqueCellNoKine(theCellsEL,globalIndex,weight, 10);
             
               // now that we found the cell in at least one cluster above threshold, stop looking at associated clusters
               ATH_MSG_VERBOSE( " -- Found at least one cluster passing cuts. 'break'"  );
diff --git a/Calorimeter/CaloUtils/CaloUtils/CaloTowerBuilderTool.h b/Calorimeter/CaloUtils/CaloUtils/CaloTowerBuilderTool.h
index 5553571ae5673a06d75e9f8647d5ef931bea470f..bd361a2b4b8826fde4566cffa6ea74dbe0026105 100644
--- a/Calorimeter/CaloUtils/CaloUtils/CaloTowerBuilderTool.h
+++ b/Calorimeter/CaloUtils/CaloUtils/CaloTowerBuilderTool.h
@@ -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
 */
 
 #ifndef CALOREC_CALOTOWERBUILDERTOOL_H
@@ -107,15 +107,12 @@ private:
 
   virtual StatusCode checkSetup(MsgStream& log);
   void addTower (const CaloTowerStore::tower_iterator tower_it,
-                 const CaloCellContainer* cells,
-                 IProxyDict* sg,
+                 const ElementLink<CaloCellContainer>& cellsEL,
                  CaloTower* tower) const;
   void iterateFull (CaloTowerContainer* towers,
-                    const CaloCellContainer* cells,
-                    IProxyDict* sg) const;
+                    const ElementLink<CaloCellContainer>& cellsEL) const;
   void iterateSubSeg (CaloTowerContainer* towers,
-                      const CaloCellContainer* cells,
-                      IProxyDict* sg,
+                      const ElementLink<CaloCellContainer>& cellsEL,
                       const CaloTowerSeg::SubSeg* subseg) const;
 
 
diff --git a/Calorimeter/CaloUtils/src/CaloTopoTowerBuilderTool.cxx b/Calorimeter/CaloUtils/src/CaloTopoTowerBuilderTool.cxx
index 77180f903dcd2b0439811df7ec4dd550811f34b4..9ba135cf120ca0dc3de18fbc3a13767dc7d5132b 100644
--- a/Calorimeter/CaloUtils/src/CaloTopoTowerBuilderTool.cxx
+++ b/Calorimeter/CaloUtils/src/CaloTopoTowerBuilderTool.cxx
@@ -85,6 +85,9 @@ StatusCode CaloTopoTowerBuilderTool::execute(CaloTopoTowerContainer* theTowers,
     msg(MSG::WARNING) << "  .. no CaloTopoTowers are made " << endmsg;
     return StatusCode::SUCCESS;
   }
+
+  const ElementLink<CaloCellContainer> CellsEL (*Cells, 0);
+
   const CaloCell2ClusterMap*  cellToClusterMap=theTowers->GetCellToClusterMap();
   bool delete_cellToClusterMap=false;
   if(cellToClusterMap==nullptr  ){
@@ -274,7 +277,7 @@ StatusCode CaloTopoTowerBuilderTool::execute(CaloTopoTowerContainer* theTowers,
 		energyTower += cellEnergy;
 		numberOfClustersInTower++;
 		
-		newTower->addUniqueCellNoKine(Cells,globalIndex,weight, 10);
+		newTower->addUniqueCellNoKine(CellsEL,globalIndex,weight, 10);
 		
 		// now that we found the cell in at least one cluster above threshold, stop looking at associated clusters
 		ATH_MSG_VERBOSE(" -- Found at least one cluster passing cuts. 'break'");
diff --git a/Calorimeter/CaloUtils/src/CaloTowerBuilderTool.cxx b/Calorimeter/CaloUtils/src/CaloTowerBuilderTool.cxx
index 780313ae9b71eed219b88ff5532f89e16a23dd9e..60a6ff739993c89b4e513898f98d4b85d13b1c1c 100644
--- a/Calorimeter/CaloUtils/src/CaloTowerBuilderTool.cxx
+++ b/Calorimeter/CaloUtils/src/CaloTowerBuilderTool.cxx
@@ -63,14 +63,14 @@ StatusCode CaloTowerBuilderTool::initializeTool() {
 inline
 void
 CaloTowerBuilderTool::addTower (const CaloTowerStore::tower_iterator tower_it,
-                                const CaloCellContainer* cells,
-                                IProxyDict* sg,
+                                const ElementLink<CaloCellContainer>& cellsEL,
                                 CaloTower* tower) const
 {
   CaloTowerStore::cell_iterator firstC = tower_it.firstCell();
   CaloTowerStore::cell_iterator lastC = tower_it.lastCell();
   int ts = tower_it.size();
   double wsumE = tower->getBasicEnergy(); // this is not 0 since some towers already have cells from other calos.
+  const CaloCellContainer* cells = cellsEL.getDataPtr();
   for (; firstC != lastC; ++firstC) {
 
     unsigned int ci = firstC.hash();
@@ -82,7 +82,7 @@ CaloTowerBuilderTool::addTower (const CaloTowerStore::tower_iterator tower_it,
     // get weights
     if (cellPtr) {
       wsumE += weightC * cellPtr->e();					// Summ up weighted energies .
-      tower->addUniqueCellNoKine(cells, cndx, sg, weightC, ts); // add cells to tower.
+      tower->addUniqueCellNoKine(cellsEL, cndx, weightC, ts); // add cells to tower.
     }
     /* for debugging em+hec
        if (t==5214) std::cout<<"N14\tc:"<<ci<<"\tw:"<<weightC<<"\te:"<<cellPtr->e()<<"\teta:"<<cellPtr->eta()<<"\td:"<<cellPtr->caloDDE()<<std::endl;
@@ -97,8 +97,7 @@ CaloTowerBuilderTool::addTower (const CaloTowerStore::tower_iterator tower_it,
 inline
 void
 CaloTowerBuilderTool::iterateFull (CaloTowerContainer* towers,
-                                   const CaloCellContainer* cells,
-                                   IProxyDict* sg) const
+                                   const ElementLink<CaloCellContainer>& cellsEL) const
 {
   size_t sz = towers->size();
   assert(m_cellStore.size() ==  sz);
@@ -106,7 +105,7 @@ CaloTowerBuilderTool::iterateFull (CaloTowerContainer* towers,
 
   for (unsigned int t = 0; t < sz; ++t, ++tower_it) {
     CaloTower* aTower = towers->getTower(t);
-    addTower (tower_it, cells, sg, aTower);
+    addTower (tower_it, cellsEL, aTower);
   }
 }
 
@@ -114,8 +113,7 @@ CaloTowerBuilderTool::iterateFull (CaloTowerContainer* towers,
 inline
 void
 CaloTowerBuilderTool::iterateSubSeg (CaloTowerContainer* towers,
-                                     const CaloCellContainer* cells,
-                                     IProxyDict* sg,
+                                     const ElementLink<CaloCellContainer>& cellsEL,
                                      const CaloTowerSeg::SubSeg* subseg) const
 {
   size_t sz = towers->size();
@@ -125,7 +123,7 @@ CaloTowerBuilderTool::iterateSubSeg (CaloTowerContainer* towers,
 #if 0
   for (unsigned int t = 0; t < sz; ++t, ++tower_it) {
     CaloTower* aTower = towers->getTower(tower_it.itower());
-    addTower (tower_it, cells, aTower);
+    addTower (tower_it, cellsEL, aTower);
   }
 #endif
   // This loop was originally written as above.  However, if we increment
@@ -136,7 +134,7 @@ CaloTowerBuilderTool::iterateSubSeg (CaloTowerContainer* towers,
   unsigned int t = 0;
   while (true) {
     CaloTower* aTower = towers->getTower(tower_it.itower());
-    addTower (tower_it, cells, sg, aTower);
+    addTower (tower_it, cellsEL, aTower);
     ++t;
     if (t >= sz) break;
     ++tower_it;
@@ -181,11 +179,11 @@ CaloTowerBuilderTool::execute(CaloTowerContainer* theTowers,
     }
   }
 
-  IProxyDict* sg = SG::CurrentEventStore::store();
+  const ElementLink<CaloCellContainer> cellsEL (*theCells, 0);
   if (subseg)
-    iterateSubSeg (theTowers, theCells, sg, subseg);
+    iterateSubSeg (theTowers, cellsEL, subseg);
   else
-    iterateFull (theTowers, theCells, sg);
+    iterateFull (theTowers, cellsEL);
 
   for (unsigned int i = 0; i < m_caloIndices.size(); i++) {
     theTowers->setCalo(m_caloIndices[i]);
diff --git a/LArCalorimeter/LArRecUtils/src/LArFCalTowerBuilderTool.cxx b/LArCalorimeter/LArRecUtils/src/LArFCalTowerBuilderTool.cxx
index 16111c893386e9562f964dece89e42ca435acaa0..60a29da2467c82125fb97944a3d382fe3ada9469 100644
--- a/LArCalorimeter/LArRecUtils/src/LArFCalTowerBuilderTool.cxx
+++ b/LArCalorimeter/LArRecUtils/src/LArFCalTowerBuilderTool.cxx
@@ -60,7 +60,7 @@ StatusCode LArFCalTowerBuilderTool::initializeTool(){
 inline
 void
 LArFCalTowerBuilderTool::addTower (const tower_iterator& t,
-                                   const CaloCellContainer* cells,
+                                   const ElementLink<CaloCellContainer>& cellsEL,
                                    CaloTower* tower) const
 {
   LArFCalTowerStore::cell_iterator firstC = m_cellStore.firstCellofTower(t);
@@ -68,6 +68,7 @@ LArFCalTowerBuilderTool::addTower (const tower_iterator& t,
   // here get needed size of this vector and use it to reserve tower size.
   int ts=  m_cellStore.towerSize(t);
   double wsumE = tower->getBasicEnergy(); // this is not 0 since some towers already have cells from other calos.
+  const CaloCellContainer* cells = cellsEL.getDataPtr();
   for (; firstC != lastC; ++firstC) {
 
     unsigned int ci = firstC->first;
@@ -79,7 +80,7 @@ LArFCalTowerBuilderTool::addTower (const tower_iterator& t,
     // get weights
     if (cellPtr) {
       wsumE += weightC * cellPtr->e();					// Summ up weighted energies .
-      tower->addUniqueCellNoKine(cells, cndx, weightC, ts); // add cells to tower.
+      tower->addUniqueCellNoKine(cellsEL, cndx, weightC, ts); // add cells to tower.
     }
   }
   tower->setE(wsumE);  // update tower kinematics.
@@ -89,7 +90,7 @@ LArFCalTowerBuilderTool::addTower (const tower_iterator& t,
 inline
 void
 LArFCalTowerBuilderTool::iterateFull (CaloTowerContainer* towers,
-                                      const CaloCellContainer* cells) const
+                                      const ElementLink<CaloCellContainer>& cellsEL) const
 {
   size_t sz = towers->size();
   assert(m_cellStore.size() ==  sz);
@@ -97,7 +98,7 @@ LArFCalTowerBuilderTool::iterateFull (CaloTowerContainer* towers,
 
   for (unsigned int t = 0; t < sz; ++t, ++tower_it) {
     CaloTower* aTower = towers->getTower(t);
-    addTower (tower_it, cells, aTower);
+    addTower (tower_it, cellsEL, aTower);
   }
 }
 
@@ -105,7 +106,7 @@ LArFCalTowerBuilderTool::iterateFull (CaloTowerContainer* towers,
 inline
 void
 LArFCalTowerBuilderTool::iterateSubSeg (CaloTowerContainer* towers,
-                                        const CaloCellContainer* cells,
+                                        const ElementLink<CaloCellContainer>& cellsEL,
                                         const CaloTowerSeg::SubSeg* subseg) const
 {
   size_t sz = towers->size();
@@ -114,7 +115,7 @@ LArFCalTowerBuilderTool::iterateSubSeg (CaloTowerContainer* towers,
 
   for (unsigned int t = 0; t < sz; ++t, ++tower_it) {
     CaloTower* aTower = towers->getTower(tower_it.itower());
-    addTower (tower_it, cells, aTower);
+    addTower (tower_it, cellsEL, aTower);
   }
 }
 
@@ -154,11 +155,11 @@ LArFCalTowerBuilderTool::execute(CaloTowerContainer* theTowers,
   // register this calorimeter
   theTowers->setCalo(m_caloIndex);
 
-  
+  const ElementLink<CaloCellContainer> cellsEL (*theCells, 0);
   if (subseg)
-    iterateSubSeg (theTowers, theCells, subseg);
+    iterateSubSeg (theTowers, cellsEL, subseg);
   else
-    iterateFull (theTowers, theCells);
+    iterateFull (theTowers, cellsEL);
 
   return StatusCode::SUCCESS;
 }
diff --git a/LArCalorimeter/LArRecUtils/src/LArFCalTowerBuilderTool.h b/LArCalorimeter/LArRecUtils/src/LArFCalTowerBuilderTool.h
index b15765434b1fb5a7f58312a712875c8ea3264baf..306a3f0bd7307ce7ceb1cdfef0e0de8d89c63265 100644
--- a/LArCalorimeter/LArRecUtils/src/LArFCalTowerBuilderTool.h
+++ b/LArCalorimeter/LArRecUtils/src/LArFCalTowerBuilderTool.h
@@ -72,12 +72,12 @@ private:
   typedef LArFCalTowerStore::tower_iterator tower_iterator;
 
   void addTower (const tower_iterator& t,
-                 const CaloCellContainer* cells,
+                 const ElementLink<CaloCellContainer>& cellsEL,
                  CaloTower* tower) const;
   void iterateFull (CaloTowerContainer* towers,
-                    const CaloCellContainer* cells) const;
+                    const ElementLink<CaloCellContainer>& cellsEL) const;
   void iterateSubSeg (CaloTowerContainer* towers,
-                      const CaloCellContainer* cells,
+                      const ElementLink<CaloCellContainer>& cellsEL,
                       const CaloTowerSeg::SubSeg* subseg) const;