diff --git a/Control/PileUpTools/CMakeLists.txt b/Control/PileUpTools/CMakeLists.txt
index 87e1bc3a80e5d686b60ac4e288502d252d7218c0..7c6e59914072d7ecd7d4e8ccccff469a9825f20a 100644
--- a/Control/PileUpTools/CMakeLists.txt
+++ b/Control/PileUpTools/CMakeLists.txt
@@ -12,7 +12,7 @@ atlas_add_library( PileUpToolsLib
                    LINK_LIBRARIES AthenaBaseComps AthenaKernel
                    AthLinks SGTools
                    EventInfo xAODEventInfo xAODCnvInterfaces
-                   GaudiKernel StoreGateLib )
+                   GaudiKernel StoreGateLib CxxUtils )
 
 atlas_add_component( PileUpTools
                      src/components/*.cxx
diff --git a/Control/PileUpTools/PileUpTools/ATLAS_CHECK_THREAD_SAFETY b/Control/PileUpTools/PileUpTools/ATLAS_CHECK_THREAD_SAFETY
new file mode 100644
index 0000000000000000000000000000000000000000..1570454f5ecc547d4c270112ca078d3d546d386d
--- /dev/null
+++ b/Control/PileUpTools/PileUpTools/ATLAS_CHECK_THREAD_SAFETY
@@ -0,0 +1 @@
+Control/PileUpTools
diff --git a/Control/PileUpTools/PileUpTools/PileUpMergeSvc.h b/Control/PileUpTools/PileUpTools/PileUpMergeSvc.h
index 9561b3cdd582ba0187c7da2320f92fa564620c26..facff856ad6ded09ef6665929c21dd38c8b28bd3 100755
--- a/Control/PileUpTools/PileUpTools/PileUpMergeSvc.h
+++ b/Control/PileUpTools/PileUpTools/PileUpMergeSvc.h
@@ -1,7 +1,7 @@
 /* -*- C++ -*- */
 
 /*
-  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 /** @file PileUpMergeSvc.h
@@ -29,6 +29,7 @@
 #include "AthenaKernel/SlotSpecificObj.h"
 
 #include "PileUpTools/IPileUpXingFolder.h"
+#include "CxxUtils/checker_macros.h"
 
 #include <cassert>
 
@@ -127,7 +128,7 @@ private:
 
   // Protect against multiple threads trying to make EventInfo
   // for the same slot.
-  mutable SG::SlotSpecificObj<std::mutex> m_slotMutex;
+  mutable SG::SlotSpecificObj<std::mutex> m_slotMutex ATLAS_THREAD_SAFE;
 
   template <typename DATA, typename KEY>
   bool isLive(const KEY& key, int iXing);   ///< is iXing live for DATA/key?
diff --git a/Control/PileUpTools/PileUpTools/PileUpStream.h b/Control/PileUpTools/PileUpTools/PileUpStream.h
index 1bba5bdf86324968ec43c1dd44956cb377313d4c..52ac99859896fbbc54d977c4224d677deacbbe9b 100755
--- a/Control/PileUpTools/PileUpTools/PileUpStream.h
+++ b/Control/PileUpTools/PileUpTools/PileUpStream.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef PILEUPSTREAM_PILEUPSTREAM_H
@@ -14,7 +14,7 @@
 
 // Framework include files
 #include "GaudiKernel/IEvtSelector.h"
-#include "AthenaKernel/MsgStreamMember.h"
+#include "AthenaBaseComps/AthMessaging.h"
 
 #include "xAODEventInfo/EventInfo.h"
 
@@ -28,15 +28,19 @@ class PileUpMergeSvc;
 /** @class PileUpStream
  * @brief a triple selector/context/store defines a stream
  */
-class PileUpStream {
+class PileUpStream
+  : public AthMessaging
+{
 public:
   typedef IEvtSelector::Context EvtIterator;
 
   /// @name Structors
   //@{
   PileUpStream();
-  PileUpStream(const PileUpStream& rhs);
-  PileUpStream& operator=(const PileUpStream& rhs);
+  PileUpStream(const PileUpStream& rhs) = delete;
+  PileUpStream& operator=(const PileUpStream& rhs) = delete;
+  PileUpStream(PileUpStream&& rhs);
+  PileUpStream& operator=(PileUpStream&& rhs);
   PileUpStream(const std::string& name, 
 	       IEvtSelector* sel, 
 	       StoreGateSvc* store);
@@ -88,11 +92,7 @@ public:
     }
   }
 
-  /// Log a message using the Athena controlled logging system
-  MsgStream& msg( MSG::Level lvl ) const { return m_msg << lvl; }
-  /// Check whether the logging system is active at the provided verbosity level
-  bool msgLvl( MSG::Level lvl ) { return m_msg.get().level() <= lvl; }
-  
+
 private:
   ISvcLocator* serviceLocator() { return p_svcLoc; }
 
@@ -126,12 +126,10 @@ private:
   
   ActiveStoreSvc* p_activeStore;
 
-  //mutable so that ownership can be passed upon copy
-  mutable bool m_ownEvtIterator; ///> do we own p_iter? 
+  bool m_ownEvtIterator; ///> do we own p_iter? 
   /// Private message stream member
-  mutable Athena::MsgStreamMember m_msg;
   bool m_neverLoaded;  ///> has an event been loaded into this stream?
-  mutable bool m_ownStore;  ///> is p_SG a store we cloned from the master one?
+  bool m_ownStore;  ///> is p_SG a store we cloned from the master one?
 
   bool m_used; ///has this stream already been used? (for the current event)
   bool m_hasRing;
diff --git a/Control/PileUpTools/src/PileUpMergeSvc.cxx b/Control/PileUpTools/src/PileUpMergeSvc.cxx
index ad28ff2952f22c1649702206f8d1f8247d56cb94..7fa9881b396d58cda2238cae0b6468411c28961e 100755
--- a/Control/PileUpTools/src/PileUpMergeSvc.cxx
+++ b/Control/PileUpTools/src/PileUpMergeSvc.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "PileUpTools/PileUpMergeSvc.h"
@@ -137,15 +137,8 @@ const xAOD::EventInfo* PileUpMergeSvc::getPileUpEvent( StoreGateSvc* sg, const s
    if( xAODEventInfo ) {
       ATH_MSG_DEBUG("Found xAOD::EventInfo");
       ATH_MSG_DEBUG(" EventInfo has " <<   xAODEventInfo->subEvents().size() << " subevents" );
-      if( xAODEventInfo->evtStore() == nullptr ) {
-         // SG is 0 only when the xAODEventInfo is first read
-         const_cast<xAOD::EventInfo*>(xAODEventInfo)->setEvtStore( sg );
-         // the loop below serves 2 purposes: to recreate subevent links cache
-         // and set SG pointer in subevents 
-         for( auto& subev : xAODEventInfo->subEvents() ) {
-            const_cast<xAOD::EventInfo*>( subev.ptr() )->setEvtStore( sg );
-         }
-      }
+      // recreate subevent links cache
+      xAODEventInfo->subEvents();
    } else {
       // Don't allow more than one thread per slot through here.
       // Otherwise, we can get errors with multiple threads trying
@@ -179,21 +172,20 @@ const xAOD::EventInfo* PileUpMergeSvc::getPileUpEvent( StoreGateSvc* sg, const s
             std::vector< xAOD::EventInfo::SubEvent > subEvents;
 
             // A map translating between the AOD and xAOD pileup event types:
-            static std::map< PileUpEventInfo::SubEvent::pileup_type,
-               xAOD::EventInfo::PileUpType > pileupTypeMap;
-            if( ! pileupTypeMap.size() ) {
+            static const std::map< PileUpEventInfo::SubEvent::pileup_type,
+               xAOD::EventInfo::PileUpType > pileupTypeMap = {
 #define DECLARE_SE_TYPE( TYPE )                                         \
-               pileupTypeMap[ PileUpTimeEventIndex::TYPE ] = xAOD::EventInfo::TYPE
+              { PileUpTimeEventIndex::TYPE, xAOD::EventInfo::TYPE },
 
-               DECLARE_SE_TYPE( Unknown );
-               DECLARE_SE_TYPE( Signal );
-               DECLARE_SE_TYPE( MinimumBias );
-               DECLARE_SE_TYPE( Cavern );
-               DECLARE_SE_TYPE( HaloGas );
-               DECLARE_SE_TYPE( ZeroBias );
+               DECLARE_SE_TYPE( Unknown )
+               DECLARE_SE_TYPE( Signal )
+               DECLARE_SE_TYPE( MinimumBias )
+               DECLARE_SE_TYPE( Cavern )
+               DECLARE_SE_TYPE( HaloGas )
+               DECLARE_SE_TYPE( ZeroBias )
 
 #undef DECLARE_SE_TYPE
-            }
+            };
 
             // A convenience type declaration:
             typedef ElementLink< xAOD::EventInfoContainer > EiLink;
diff --git a/Control/PileUpTools/src/PileUpStream.cxx b/Control/PileUpTools/src/PileUpStream.cxx
index 06dbf5aa9a38bc5fa59235137ba4cbd396079e05..c08b98969e11fa866e51504c9d0e7a874d37dd6d 100755
--- a/Control/PileUpTools/src/PileUpStream.cxx
+++ b/Control/PileUpTools/src/PileUpStream.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "PileUpTools/PileUpStream.h"
@@ -13,7 +13,7 @@
 #include "GaudiKernel/ISvcManager.h"
 #include "AthenaKernel/CloneService.h"
 #include "AthenaKernel/IAddressProvider.h"
-#include "AthenaKernel/IProxyProviderSvc.h"
+#include "AthenaKernel/getMessageSvc.h"
 #include "StoreGate/StoreGateSvc.h"
 
 #include "SGTools/DataProxy.h"
@@ -28,17 +28,19 @@ class IOpaqueAddress;
 
 /// Structors
 PileUpStream::PileUpStream():
+  AthMessaging (Athena::getMessageSvc(), "PileUpStream"),
   m_name("INVALID"), p_svcLoc(0), p_sel(0), p_SG(0), p_iter(0), 
   p_mergeSvc(nullptr), p_activeStore(0), m_ownEvtIterator(false),
-  m_msg("PileUpStream"), m_neverLoaded(true), m_ownStore(false),
+  m_neverLoaded(true), m_ownStore(false),
   m_used(false), m_hasRing(false), m_iOriginalRing(0)
 { 
 }
 
-PileUpStream::PileUpStream(const PileUpStream& rhs):
+PileUpStream::PileUpStream(PileUpStream&& rhs):
+  AthMessaging (Athena::getMessageSvc(), rhs.m_name),
   m_name(rhs.m_name), p_svcLoc(rhs.p_svcLoc), p_sel(rhs.p_sel), 
   p_SG(rhs.p_SG), p_iter(rhs.p_iter), p_mergeSvc(rhs.p_mergeSvc), p_activeStore(rhs.p_activeStore),
-  m_ownEvtIterator(rhs.m_ownEvtIterator), m_msg(rhs.m_msg),
+  m_ownEvtIterator(rhs.m_ownEvtIterator),
   m_neverLoaded(rhs.m_neverLoaded), m_ownStore(rhs.m_ownStore),
   m_used(rhs.m_used), m_hasRing(rhs.m_hasRing), m_iOriginalRing(rhs.m_iOriginalRing)
 { 
@@ -48,7 +50,7 @@ PileUpStream::PileUpStream(const PileUpStream& rhs):
 }
 
 PileUpStream&
-PileUpStream::operator=(const PileUpStream& rhs) {
+PileUpStream::operator=(PileUpStream&& rhs) {
   if (this != &rhs) {
     m_name=rhs.m_name;
     p_svcLoc=rhs.p_svcLoc;
@@ -59,7 +61,6 @@ PileUpStream::operator=(const PileUpStream& rhs) {
     p_activeStore=rhs.p_activeStore;
     m_ownEvtIterator=rhs.m_ownEvtIterator;
     rhs.m_ownEvtIterator=false;
-    m_msg=rhs.m_msg;
     m_neverLoaded=rhs.m_neverLoaded;
     m_ownStore=rhs.m_ownStore;
     rhs.m_ownStore=false;
@@ -73,8 +74,9 @@ PileUpStream::operator=(const PileUpStream& rhs) {
 PileUpStream::PileUpStream(const std::string& name, 
 			   ISvcLocator* svcLoc,
 			   IEvtSelector* sel):
+  AthMessaging (Athena::getMessageSvc(), name),
   m_name(name), p_svcLoc(svcLoc), p_sel(sel), p_SG(0), p_iter(0), 
-  m_ownEvtIterator(false), m_msg("PileUpStream"),
+  m_ownEvtIterator(false), 
   m_neverLoaded(true), m_ownStore(false),
   m_used(false), m_hasRing(false), m_iOriginalRing(0)
 { 
@@ -93,8 +95,9 @@ PileUpStream::PileUpStream(const std::string& name,
 PileUpStream::PileUpStream(const std::string& name, 
 			   ISvcLocator* svcLoc,
 			   const std::string& selecName):
+  AthMessaging (Athena::getMessageSvc(), name),
   m_name(name), p_svcLoc(svcLoc), p_sel(0), p_SG(0), p_iter(0),
-  m_ownEvtIterator(false), m_msg("PileUpStream"), 
+  m_ownEvtIterator(false), 
   m_neverLoaded(true), m_ownStore(false),
   m_used(false), m_hasRing(false), m_iOriginalRing(0)