diff --git a/Control/AthenaCommon/python/BeamFlags.py b/Control/AthenaCommon/python/BeamFlags.py
index fd0316389ae695f5562b8f8a6ab8b77cea950470..2207f037980ed682974bd6f19d11ce3c936862c0 100644
--- a/Control/AthenaCommon/python/BeamFlags.py
+++ b/Control/AthenaCommon/python/BeamFlags.py
@@ -91,6 +91,7 @@ for j in _list_Beam:
     jobproperties.Beam.add_JobProperty(j)
 del _list_Beam
 
+# For convenience, a shorthand alias to the beam flags
+beamFlags = jobproperties.Beam
 
 #=======================================================================
-
diff --git a/Simulation/G4Atlas/G4AtlasAlg/src/AthenaStackingAction.h b/Simulation/G4Atlas/G4AtlasAlg/src/AthenaStackingAction.h
index cf2f9cf29d4ed06b082da3bc5c674188f657f448..646c5ef93b51cb459e04ca7af295afdd5f13c5ed 100644
--- a/Simulation/G4Atlas/G4AtlasAlg/src/AthenaStackingAction.h
+++ b/Simulation/G4Atlas/G4AtlasAlg/src/AthenaStackingAction.h
@@ -2,9 +2,8 @@
   Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 */
 
-
-#ifndef G4ATLASALG_G4UA_ATHENASTACKINGACTION_H
-#define G4ATLASALG_G4UA_ATHENASTACKINGACTION_H
+#ifndef G4ATLASALG_ATHENASTACKINGACTION_H
+#define G4ATLASALG_ATHENASTACKINGACTION_H
 
 #include "G4UserStackingAction.hh"
 
diff --git a/Simulation/G4Atlas/G4AtlasAlg/src/AthenaStackingActionTool.cxx b/Simulation/G4Atlas/G4AtlasAlg/src/AthenaStackingActionTool.cxx
index 26ebfcb6fa5ae9400a29a07255187490f6b8a55b..ff89e06d37f6656fdd3cbc61ec272f16c16b8b12 100644
--- a/Simulation/G4Atlas/G4AtlasAlg/src/AthenaStackingActionTool.cxx
+++ b/Simulation/G4Atlas/G4AtlasAlg/src/AthenaStackingActionTool.cxx
@@ -13,10 +13,9 @@ namespace G4UA
   AthenaStackingActionTool::
   AthenaStackingActionTool(const std::string& type, const std::string& name,
                            const IInterface* parent)
-    : ActionToolBase<AthenaStackingAction>(type, name, parent),
+    : UserActionToolBase<AthenaStackingAction>(type, name, parent),
       m_config { /*killAllNeutrinos*/ false, /*photonEnergyCut*/ -1., /*isISFJob*/ false}
   {
-    declareInterface<IG4StackingActionTool>(this);
     declareProperty("KillAllNeutrinos", m_config.killAllNeutrinos,
                     "Toggle killing of all neutrinos");
     declareProperty("PhotonEnergyCut", m_config.photonEnergyCut,
@@ -37,11 +36,13 @@ namespace G4UA
   // Create the action on request
   //---------------------------------------------------------------------------
   std::unique_ptr<AthenaStackingAction>
-  AthenaStackingActionTool::makeAction()
+  AthenaStackingActionTool::makeAndFillAction(G4AtlasUserActions& actionLists)
   {
     ATH_MSG_DEBUG("Creating an AthenaStackingAction");
     // Create and configure the action plugin.
-    return std::make_unique<AthenaStackingAction>(m_config);
+    auto action = std::make_unique<AthenaStackingAction>(m_config);
+    actionLists.stackingActions.push_back( action.get() );
+    return action;
   }
 
 }
diff --git a/Simulation/G4Atlas/G4AtlasAlg/src/AthenaStackingActionTool.h b/Simulation/G4Atlas/G4AtlasAlg/src/AthenaStackingActionTool.h
index 5dcbc00ad57adf9ad1b8bc1c12bd9dc21c4ecb09..55a52fc7e04d292582182753d254597c77a0265f 100644
--- a/Simulation/G4Atlas/G4AtlasAlg/src/AthenaStackingActionTool.h
+++ b/Simulation/G4Atlas/G4AtlasAlg/src/AthenaStackingActionTool.h
@@ -8,13 +8,13 @@
 // STL includes
 #include <string>
 
+// G4Atlas includes
+#include "G4AtlasInterfaces/IUserActionTool.h"
+#include "G4AtlasTools/UserActionToolBase.h"
+
 // Local includes
 #include "AthenaStackingAction.h"
 
-// Infrastructure includes
-#include "G4AtlasInterfaces/IG4StackingActionTool.h"
-#include "G4AtlasTools/ActionToolBase.h"
-
 
 namespace G4UA
 {
@@ -24,8 +24,7 @@ namespace G4UA
   ///
   /// @author Steve Farrell <Steven.Farrell@cern.ch>
   ///
-  class AthenaStackingActionTool : public ActionToolBase<AthenaStackingAction>,
-                                   public IG4StackingActionTool
+  class AthenaStackingActionTool : public UserActionToolBase<AthenaStackingAction>
   {
 
     public:
@@ -37,14 +36,11 @@ namespace G4UA
       /// Initialize the tool
       virtual StatusCode initialize() override final;
 
-      /// Retrieve the stepping action
-      virtual G4UserStackingAction* getStackingAction() override final
-      { return static_cast<G4UserStackingAction*>( getAction() ); }
-
     protected:
 
-      /// Create an action for this thread
-      virtual std::unique_ptr<AthenaStackingAction> makeAction() override final;
+      // Setup the user action for current thread
+      virtual std::unique_ptr<AthenaStackingAction>
+      makeAndFillAction(G4AtlasUserActions& actionLists) override final;
 
     private:
 
diff --git a/Simulation/G4Atlas/G4AtlasAlg/src/AthenaTrackingAction.h b/Simulation/G4Atlas/G4AtlasAlg/src/AthenaTrackingAction.h
index 26adb304dc84c9c2d47d7d4af3caf9674e752936..3c120bc6617948df3d70ec51a1752cc2841829a1 100644
--- a/Simulation/G4Atlas/G4AtlasAlg/src/AthenaTrackingAction.h
+++ b/Simulation/G4Atlas/G4AtlasAlg/src/AthenaTrackingAction.h
@@ -21,7 +21,7 @@ namespace G4UA
     public:
 
       /// Constructor
-    AthenaTrackingAction(MSG::Level lvl, int secondarySavingLevel, int subDetVolLevel);
+      AthenaTrackingAction(MSG::Level lvl, int secondarySavingLevel, int subDetVolLevel);
 
       /// @brief Called before tracking a new particle.
       ///
diff --git a/Simulation/G4Atlas/G4AtlasAlg/src/AthenaTrackingActionTool.cxx b/Simulation/G4Atlas/G4AtlasAlg/src/AthenaTrackingActionTool.cxx
index dee88dac7cc086c84b6339f76caeb5f236a93e94..95dec5fecccb792429aee3ca4617d10d7645bc73 100644
--- a/Simulation/G4Atlas/G4AtlasAlg/src/AthenaTrackingActionTool.cxx
+++ b/Simulation/G4Atlas/G4AtlasAlg/src/AthenaTrackingActionTool.cxx
@@ -13,11 +13,10 @@ namespace G4UA
   AthenaTrackingActionTool::
   AthenaTrackingActionTool(const std::string& type, const std::string& name,
                            const IInterface* parent)
-    : ActionToolBase<AthenaTrackingAction>(type, name, parent)
+    : UserActionToolBase<AthenaTrackingAction>(type, name, parent)
     , m_secondarySavingLevel(2)
     , m_subDetVolLevel(1)
   {
-    declareInterface<IG4TrackingActionTool>(this);
     declareProperty("SecondarySavingLevel", m_secondarySavingLevel,
       "Three valid options: 1 - Primaries; 2 - StoredSecondaries(default); 3 - All");
     declareProperty("SubDetVolumeLevel", m_subDetVolLevel,
@@ -37,12 +36,14 @@ namespace G4UA
   // Create the action on request
   //---------------------------------------------------------------------------
   std::unique_ptr<AthenaTrackingAction>
-  AthenaTrackingActionTool::makeAction()
+  AthenaTrackingActionTool::makeAndFillAction(G4AtlasUserActions& actionLists)
   {
     ATH_MSG_DEBUG("Constructing an AthenaTrackingAction");
     // Create and configure the action plugin.
-    return std::make_unique<AthenaTrackingAction>( msg().level(),
-                                                   m_secondarySavingLevel, m_subDetVolLevel );
+    auto action = std::make_unique<AthenaTrackingAction>(
+        msg().level(), m_secondarySavingLevel, m_subDetVolLevel );
+    actionLists.trackingActions.push_back( action.get() );
+    return action;
   }
 
 }
diff --git a/Simulation/G4Atlas/G4AtlasAlg/src/AthenaTrackingActionTool.h b/Simulation/G4Atlas/G4AtlasAlg/src/AthenaTrackingActionTool.h
index a21fdf141c9d1407e5ab16cda37e987b136c2f01..431f8ee22259c914ef3ce765eb5855bbe5310582 100644
--- a/Simulation/G4Atlas/G4AtlasAlg/src/AthenaTrackingActionTool.h
+++ b/Simulation/G4Atlas/G4AtlasAlg/src/AthenaTrackingActionTool.h
@@ -5,9 +5,9 @@
 #ifndef G4AtlasAlg_AthenaTrackingActionTool_H
 #define G4AtlasAlg_AthenaTrackingActionTool_H
 
-// Infrastructure includes
-#include "G4AtlasInterfaces/IG4TrackingActionTool.h"
-#include "G4AtlasTools/ActionToolBase.h"
+// G4Atlas includes
+#include "G4AtlasInterfaces/IUserActionTool.h"
+#include "G4AtlasTools/UserActionToolBase.h"
 
 // Local includes
 #include "AthenaTrackingAction.h"
@@ -20,8 +20,7 @@ namespace G4UA
   ///
   /// @author Steve Farrell <Steven.Farrell@cern.ch>
   ///
-  class AthenaTrackingActionTool : public ActionToolBase<AthenaTrackingAction>,
-                                   public IG4TrackingActionTool
+  class AthenaTrackingActionTool : public UserActionToolBase<AthenaTrackingAction>
   {
 
     public:
@@ -33,14 +32,11 @@ namespace G4UA
       /// Initialize the tool (just for debugging printout)
       virtual StatusCode initialize() override;
 
-      /// Retrieve the tracking action
-      virtual G4UserTrackingAction* getTrackingAction() override final
-      { return static_cast<G4UserTrackingAction*>( getAction() ); }
-
     protected:
 
-      /// Create an action for this thread
-      virtual std::unique_ptr<AthenaTrackingAction> makeAction() override final;
+      /// Setup the user action for current thread
+      virtual std::unique_ptr<AthenaTrackingAction>
+      makeAndFillAction(G4AtlasUserActions& actionLists) override final;
 
     private:
 
diff --git a/Simulation/G4Atlas/G4AtlasApps/python/SimFlags.py b/Simulation/G4Atlas/G4AtlasApps/python/SimFlags.py
index 3f0bdc324585f7b78c51fd372f73d7effad4db13..4c3b9c857d2cf177cb4acbb47ae9cc7c43b29192 100644
--- a/Simulation/G4Atlas/G4AtlasApps/python/SimFlags.py
+++ b/Simulation/G4Atlas/G4AtlasApps/python/SimFlags.py
@@ -659,11 +659,13 @@ class RecordFlux(JobProperty):
 class OptionalUserActionList(JobProperty):
     """Configuration for Optional UserActions
       The name of the action must be a name retrievable through the ConfigurableFactory"""
-
     statusOn = True
     allowedTypes = ['dict']
-    # not allowing stacking actions to be modified this way
-    StoredValue = {'Run':[], 'Event':[], 'Tracking':[], 'Step':['G4UA::LooperKillerTool']}
+    # not allowing stacking actions to be modified this way.
+    # 'General' refers to new common-interface tools.
+    # FIXME: why do we add the LoopKillerTool here???
+    StoredValue = {'Run':[], 'Event':[], 'Tracking':[], 'Step':[],
+                   'General':['G4UA::LooperKillerTool']}
     def addAction(self,actionTool,roles=[]):
         #Add the action to the end of the list of actions for each role.
         for role in roles:
diff --git a/Simulation/G4Atlas/G4AtlasServices/python/G4AtlasUserActionConfig.py b/Simulation/G4Atlas/G4AtlasServices/python/G4AtlasUserActionConfig.py
index 75fc32cf155988e8611177d7d509115acd593b9d..73f1858fbab1dce52e55e1f32c927a0d7b606729 100644
--- a/Simulation/G4Atlas/G4AtlasServices/python/G4AtlasUserActionConfig.py
+++ b/Simulation/G4Atlas/G4AtlasServices/python/G4AtlasUserActionConfig.py
@@ -6,32 +6,13 @@ from AthenaCommon import CfgGetter,CfgMgr,Logging
 
 # actions to be run at begin/end of run
 def getDefaultRunActions():
-    from G4AtlasApps.SimFlags import simFlags
     defaultUA=[]
-    #if not  simFlags.ISFRun:
-    #    defaultUA+=['G4UA::G4SimTimerTool']
-    if hasattr(simFlags, 'StoppedParticleFile') and simFlags.StoppedParticleFile.statusOn:
-        defaultUA+=['G4UA::StoppedParticleActionTool']
     return defaultUA
 
 # begin of event
 def getDefaultEventActions():
     from G4AtlasApps.SimFlags import simFlags
-    from AthenaCommon.BeamFlags import jobproperties
     defaultUA=[]
-    if not simFlags.ISFRun:
-        defaultUA+=['G4UA::G4SimTimerTool']
-        defaultUA+=['G4UA::MCTruthSteppingActionTool']
-    defaultUA+=['G4UA::G4TrackCounterTool']
-    if hasattr(simFlags, 'CavernBG') and simFlags.CavernBG.statusOn and simFlags.CavernBG.get_Value() == 'Read':
-        defaultUA+=['G4UA::HitWrapperTool']
-    if jobproperties.Beam.beamType() == 'cosmics' and hasattr(simFlags, 'CavernBG') and not simFlags.CavernBG.statusOn:
-        defaultUA+=['G4UA::CosmicPerigeeActionTool']
-    if hasattr(simFlags, 'StoppedParticleFile') and simFlags.StoppedParticleFile.statusOn:
-        defaultUA+=['G4UA::StoppedParticleActionTool']
-        defaultUA+=['G4UA::G4CosmicFilterTool']
-    if jobproperties.Beam.beamType() == 'cosmics' and not simFlags.ISFRun:
-        defaultUA+=['G4UA::G4CosmicFilterTool']
     if hasattr(simFlags, 'CalibrationRun') and simFlags.CalibrationRun() == 'LAr+Tile':
         defaultUA+=['G4UA::CaloG4::CalibrationDefaultProcessingTool']
     return defaultUA
@@ -39,33 +20,66 @@ def getDefaultEventActions():
 # stepping
 def getDefaultSteppingActions():
     from G4AtlasApps.SimFlags import simFlags
-    from AthenaCommon.BeamFlags import jobproperties
     defaultUA=[]
-    if not simFlags.ISFRun:
-        defaultUA+=['G4UA::MCTruthSteppingActionTool']
-    if jobproperties.Beam.beamType() == 'cosmics' and hasattr(simFlags, 'CavernBG') and not simFlags.CavernBG.statusOn:
-        defaultUA+=['G4UA::CosmicPerigeeActionTool']
     if hasattr(simFlags, 'CalibrationRun') and simFlags.CalibrationRun() == 'LAr+Tile':
         defaultUA+=['G4UA::CaloG4::CalibrationDefaultProcessingTool']
-    if simFlags.PhysicsList == 'QGSP_BERT_HP':
-        defaultUA+=['G4UA::PhotonKillerTool']
     return defaultUA
 
 # tracking
 def getDefaultTrackingActions():
-    from G4AtlasApps.SimFlags import simFlags
     defaultUA=[]
-    if not simFlags.ISFRun:
-        defaultUA+=['G4UA::AthenaTrackingActionTool']
-    defaultUA+=['G4UA::G4TrackCounterTool']
     return defaultUA
 
 # Stacking Classification
 def getDefaultStackingActions():
     defaultUA=[]
-    defaultUA+=['G4UA::AthenaStackingActionTool']
     return defaultUA
 
+def flag_on(name):
+    from G4AtlasApps.SimFlags import simFlags
+    return hasattr(simFlags, name) and getattr(simFlags, name).statusOn
+
+def flag_off(name):
+    from G4AtlasApps.SimFlags import simFlags
+    return hasattr(simFlags, name) and not getattr(simFlags, name).statusOn
+
+# New function for all user action types
+def getDefaultActions():
+    from G4AtlasApps.SimFlags import simFlags
+    from AthenaCommon.BeamFlags import beamFlags
+
+    actions = []
+
+    # System stacking action
+    actions += ['G4UA::AthenaStackingActionTool']
+
+    # Some truth handling actions (and timing)
+    if not simFlags.ISFRun:
+        actions += ['G4UA::AthenaTrackingActionTool',
+                    'G4UA::MCTruthSteppingActionTool',
+                    'G4UA::G4SimTimerTool',
+                    ]
+    # Track counter
+    actions += ['G4UA::G4TrackCounterTool']
+    # Cosmic Perigee action
+    if beamFlags.beamType() == 'cosmics' and flag_off('CavernBG'):
+        actions += ['G4UA::CosmicPerigeeActionTool']
+    # Stopped particle action
+    if flag_on('StoppedParticleFile'):
+        actions += ['G4UA::StoppedParticleActionTool']
+    # Hit wrapper action
+    if flag_on('CavernBG') and simFlags.CavernBG.get_Value() == 'Read':
+        actions += ['G4UA::HitWrapperTool']
+    # Cosmic filter
+    if flag_on('StoppedParticleFile') or (
+       beamFlags.beamType() == 'cosmics' and not simFlags.ISFRun):
+        actions += ['G4UA::G4CosmicFilterTool']
+    # Photon killer
+    if simFlags.PhysicsList == 'QGSP_BERT_HP':
+        actions += ['G4UA::PhotonKillerTool']
+
+    return actions
+
 def getUserActionSvc(name="G4UA::UserActionSvc", **kwargs):
     """
     Get the standard UA svc configurable with all default actions added.
@@ -74,29 +88,34 @@ def getUserActionSvc(name="G4UA::UserActionSvc", **kwargs):
 
     from G4AtlasApps.SimFlags import simFlags
 
-    optionalActions = simFlags.OptionalUserActionList
+    optActions = simFlags.OptionalUserActionList.get_Value()
     kwargs.setdefault('RunActionTools',
-        getDefaultRunActions() + optionalActions.get_Value()['Run'])
+                      getDefaultRunActions() + optActions['Run'])
     kwargs.setdefault('EventActionTools',
-        getDefaultEventActions() + optionalActions.get_Value()['Event'])
+                      getDefaultEventActions() + optActions['Event'])
     kwargs.setdefault('SteppingActionTools',
-        getDefaultSteppingActions() + optionalActions.get_Value()['Step'])
+                      getDefaultSteppingActions() + optActions['Step'])
     kwargs.setdefault('TrackingActionTools',
-        getDefaultTrackingActions() + optionalActions.get_Value()['Tracking'])
+                      getDefaultTrackingActions() + optActions['Tracking'])
     # no optional actions for stacking
     kwargs.setdefault('StackingActionTools', getDefaultStackingActions())
 
+    # new user action tools
+    kwargs.setdefault('UserActionTools',
+                      getDefaultActions() + optActions['General'])
+
     # placeholder for more advanced config, if needed
     return CfgMgr.G4UA__UserActionSvc(name, **kwargs)
 
 def getCTBUserActionSvc(name="G4UA::CTBUserActionSvc", **kwargs):
     from G4AtlasApps.SimFlags import simFlags
-    optionalActions = simFlags.OptionalUserActionList
-    run = getDefaultRunActions() + optionalActions.get_Value()['Run']
-    event = getDefaultEventActions() + optionalActions.get_Value()['Event']
-    tracking = getDefaultTrackingActions() + optionalActions.get_Value()['Tracking']
-    stepping = getDefaultSteppingActions() + optionalActions.get_Value()['Step']
+    optActions = simFlags.OptionalUserActionList.get_Value()
+    run = getDefaultRunActions() + optActions['Run']
+    event = getDefaultEventActions() + optActions['Event']
+    tracking = getDefaultTrackingActions() + optActions['Tracking']
+    stepping = getDefaultSteppingActions() + optActions['Step']
     stacking = getDefaultStackingActions()
+    generalActions = getDefaultActions() + optActions['General']
 
     # FIXME: ADS these actions are not yet migrated to Hive
     #if simFlags.SimLayout.get_Value()=='tb_LArH6_2004':
@@ -115,27 +134,34 @@ def getCTBUserActionSvc(name="G4UA::CTBUserActionSvc", **kwargs):
     kwargs.setdefault('TrackingActionTools', tracking)
     kwargs.setdefault('StackingActionTools', stacking)
 
+    # New user action tools
+    kwargs.setdefault('UserActionTools', generalActions)
+
     # placeholder for more advanced config, if needed
     return CfgMgr.G4UA__UserActionSvc(name, **kwargs)
 
-
 def getISFUserActionSvc(name="G4UA::ISFUserActionSvc", **kwargs):
     TrackProcessorUserAction = kwargs.pop('TrackProcessorUserAction',[])
     PhysicsValidationUserAction = kwargs.pop('PhysicsValidationUserAction',[])
     MCTruthUserAction = kwargs.pop('MCTruthUserAction',['ISFMCTruthUserActionTool'])
 
     from G4AtlasApps.SimFlags import simFlags
-    optionalActions = simFlags.OptionalUserActionList
-    run = (getDefaultRunActions() + optionalActions.get_Value()['Run'] +
-           PhysicsValidationUserAction)
-    event = (getDefaultEventActions() + optionalActions.get_Value()['Event'] +
-             TrackProcessorUserAction + PhysicsValidationUserAction)
-    tracking = (TrackProcessorUserAction + MCTruthUserAction +
-                getDefaultTrackingActions() + optionalActions.get_Value()['Tracking'] +
-                PhysicsValidationUserAction)
-    stepping = (getDefaultSteppingActions() + optionalActions.get_Value()['Step'] +
-                TrackProcessorUserAction + PhysicsValidationUserAction)
+    optActions = simFlags.OptionalUserActionList.get_Value()
+    run = (
+        getDefaultRunActions() + optActions['Run'] +
+        PhysicsValidationUserAction)
+    event = (
+        getDefaultEventActions() + optActions['Event'] +
+        TrackProcessorUserAction + PhysicsValidationUserAction)
+    tracking = (
+        TrackProcessorUserAction + MCTruthUserAction +
+        getDefaultTrackingActions() + optActions['Tracking'] +
+        PhysicsValidationUserAction)
+    stepping = (
+        getDefaultSteppingActions() + optActions['Step'] +
+        TrackProcessorUserAction + PhysicsValidationUserAction)
     stacking = getDefaultStackingActions()
+    generalActions = getDefaultActions() + optActions['General']
 
     kwargs.setdefault('RunActionTools', run)
     kwargs.setdefault('EventActionTools', event)
@@ -143,6 +169,9 @@ def getISFUserActionSvc(name="G4UA::ISFUserActionSvc", **kwargs):
     kwargs.setdefault('TrackingActionTools', tracking)
     kwargs.setdefault('StackingActionTools', stacking)
 
+    # New user action tools
+    kwargs.setdefault('UserActionTools', generalActions)
+
     return CfgMgr.G4UA__UserActionSvc(name, **kwargs)
 
 def getISFFullUserActionSvc(name="G4UA::ISFFullUserActionSvc", **kwargs):
diff --git a/Simulation/G4Sim/MCTruthBase/src/MCTruthSteppingActionTool.cxx b/Simulation/G4Sim/MCTruthBase/src/MCTruthSteppingActionTool.cxx
index f99c60a74c6093d30e68427141384b1471f46721..8e8ce2d791b8562dccf8c9c49decffafeb943b44 100644
--- a/Simulation/G4Sim/MCTruthBase/src/MCTruthSteppingActionTool.cxx
+++ b/Simulation/G4Sim/MCTruthBase/src/MCTruthSteppingActionTool.cxx
@@ -15,10 +15,8 @@ namespace G4UA
   MCTruthSteppingActionTool::
   MCTruthSteppingActionTool(const std::string& type, const std::string& name,
                             const IInterface* parent)
-    : ActionToolBase<MCTruthSteppingAction>(type, name, parent)
+    : UserActionToolBase<MCTruthSteppingAction>(type, name, parent)
   {
-    declareInterface<IG4EventActionTool>(this);
-    declareInterface<IG4SteppingActionTool>(this);
     declareProperty("VolumeCollectionMap", m_volumeCollectionMap,
                     "Map of volume name to output collection name");
   }
@@ -36,12 +34,14 @@ namespace G4UA
   // Create an MCTruthSteppingAction
   //---------------------------------------------------------------------------
   std::unique_ptr<MCTruthSteppingAction>
-  MCTruthSteppingActionTool::makeAction()
+  MCTruthSteppingActionTool::makeAndFillAction(G4AtlasUserActions& actionLists)
   {
     ATH_MSG_DEBUG("Constructing an MCTruthSteppingAction");
-    return
-      std::make_unique<MCTruthSteppingAction>
-        ( m_volumeCollectionMap, msgSvc(), msg().level() );
+    auto action = std::make_unique<MCTruthSteppingAction> (
+        m_volumeCollectionMap, msgSvc(), msg().level() );
+    actionLists.eventActions.push_back( action.get() );
+    actionLists.steppingActions.push_back( action.get() );
+    return action;
   }
 
 } // namespace G4UA
diff --git a/Simulation/G4Sim/MCTruthBase/src/MCTruthSteppingActionTool.h b/Simulation/G4Sim/MCTruthBase/src/MCTruthSteppingActionTool.h
index ab9a09972f950fcfb1bcceb887e09fae3724e248..4b7574c26959fd2df487276577c6502bba5f3aca 100644
--- a/Simulation/G4Sim/MCTruthBase/src/MCTruthSteppingActionTool.h
+++ b/Simulation/G4Sim/MCTruthBase/src/MCTruthSteppingActionTool.h
@@ -9,9 +9,7 @@
 #include "MCTruthSteppingAction.h"
 
 // Infrastructure includes
-#include "G4AtlasTools/ActionToolBase.h"
-#include "G4AtlasInterfaces/IG4EventActionTool.h"
-#include "G4AtlasInterfaces/IG4SteppingActionTool.h"
+#include "G4AtlasTools/UserActionToolBase.h"
 
 // STL includes
 #include <string>
@@ -25,9 +23,7 @@ namespace G4UA
   ///
   /// @author Steve Farrell <Steven.Farrell@cern.ch>
   ///
-  class MCTruthSteppingActionTool : public ActionToolBase<MCTruthSteppingAction>,
-                                    public IG4EventActionTool,
-                                    public IG4SteppingActionTool
+  class MCTruthSteppingActionTool : public UserActionToolBase<MCTruthSteppingAction>
   {
 
     public:
@@ -39,19 +35,14 @@ namespace G4UA
       /// Initialize the tool
       virtual StatusCode initialize() override final;
 
-      /// Retrieve the begin-event action
-      virtual G4UserEventAction* getEventAction() override final
-      { return static_cast<G4UserEventAction*>( getAction() ); }
+    protected:
 
-      /// Retrieve the stepping action
-      virtual G4UserSteppingAction* getSteppingAction() override final
-      { return static_cast<G4UserSteppingAction*>( getAction() ); }
+      /// Setup the user action for current thread
+      virtual std::unique_ptr<MCTruthSteppingAction>
+      makeAndFillAction(G4AtlasUserActions&) override final;
 
     private:
 
-      /// Create an action for the current thread
-      virtual std::unique_ptr<MCTruthSteppingAction> makeAction() override final;
-
       /// Map of volume name to output collection name
       std::map<std::string, std::string> m_volumeCollectionMap;
 
diff --git a/Simulation/G4Utilities/G4UserActions/G4UserActions/CosmicPerigeeActionTool.h b/Simulation/G4Utilities/G4UserActions/G4UserActions/CosmicPerigeeActionTool.h
index a74cfb697bca3ad9b989f833e2cd5fd4b1a39125..10e120674de2e7b32f92b204c8e635a0d9b75381 100644
--- a/Simulation/G4Utilities/G4UserActions/G4UserActions/CosmicPerigeeActionTool.h
+++ b/Simulation/G4Utilities/G4UserActions/G4UserActions/CosmicPerigeeActionTool.h
@@ -12,7 +12,7 @@
 #include "G4AtlasInterfaces/IG4SteppingActionTool.h"
 #include "G4AtlasInterfaces/IG4EventActionTool.h"
 #include "G4AtlasInterfaces/IG4TrackingActionTool.h"
-#include "G4AtlasTools/ActionToolBase.h"
+#include "G4AtlasTools/UserActionToolBase.h"
 
 // Local includes
 #include "G4UserActions/CosmicPerigeeAction.h"
@@ -27,10 +27,7 @@ namespace G4UA
   ///
   /// @author Andrea Di Simone
   ///
-  class CosmicPerigeeActionTool : public ActionToolBase<CosmicPerigeeAction>,
-                                  public IG4SteppingActionTool,
-                                  public IG4EventActionTool,
-                                  public IG4TrackingActionTool
+  class CosmicPerigeeActionTool : public UserActionToolBase<CosmicPerigeeAction>
   {
 
     public:
@@ -39,23 +36,11 @@ namespace G4UA
       CosmicPerigeeActionTool(const std::string& type, const std::string& name,
 		              const IInterface* parent);
 
-
-      /// Retrieve the stepping action interface
-      virtual G4UserSteppingAction* getSteppingAction() override final
-      { return static_cast<G4UserSteppingAction*>( getAction() ); }
-
-      /// Retrieve the event action interface
-      virtual G4UserEventAction* getEventAction() override final
-      { return static_cast<G4UserEventAction*>( getAction() ); }
-
-      /// Retrieve the preTracking action interface
-      virtual G4UserTrackingAction* getTrackingAction() override final
-      { return static_cast<G4UserTrackingAction*>( getAction() ); }
-
     protected:
 
       /// Create action for this thread
-      virtual std::unique_ptr<CosmicPerigeeAction> makeAction() override final;
+      virtual std::unique_ptr<CosmicPerigeeAction>
+      makeAndFillAction(G4AtlasUserActions&) override final;
 
     private:
 
diff --git a/Simulation/G4Utilities/G4UserActions/G4UserActions/FastIDKillerTool.h b/Simulation/G4Utilities/G4UserActions/G4UserActions/FastIDKillerTool.h
index 075f8ce7e8a8c5a4d46eb1d76ff5623c85b62bb0..1361eda2313b1daa4c90c30b0a940e21495e724a 100644
--- a/Simulation/G4Utilities/G4UserActions/G4UserActions/FastIDKillerTool.h
+++ b/Simulation/G4Utilities/G4UserActions/G4UserActions/FastIDKillerTool.h
@@ -7,16 +7,14 @@
 
 #include "G4AtlasInterfaces/IG4RunActionTool.h"
 #include "G4AtlasInterfaces/IG4SteppingActionTool.h"
-#include "G4AtlasTools/ActionToolBase.h"
+#include "G4AtlasTools/UserActionToolBase.h"
 #include "G4UserActions/FastIDKiller.h"
 
 namespace G4UA
 {
 
   /// @brief NEEDS DOCUMENTATION
-  class FastIDKillerTool: public ActionToolBaseReport<FastIDKiller>,
-                          public IG4RunActionTool,
-                          public IG4SteppingActionTool
+  class FastIDKillerTool: public UserActionToolBase<FastIDKiller>
   {
 
     public:
@@ -25,22 +23,17 @@ namespace G4UA
       FastIDKillerTool(const std::string& type, const std::string& name,
                        const IInterface* parent);
 
-      virtual G4UserRunAction* getRunAction() override final
-      { return static_cast<G4UserRunAction*>( getAction() ); }
-
-      virtual G4UserSteppingAction* getSteppingAction() override final
-      { return static_cast<G4UserSteppingAction*>( getAction() ); }
-
       virtual StatusCode finalize() override;
 
     protected:
 
-      virtual std::unique_ptr<FastIDKiller> makeAction() override final;
+      /// Create the action for the current thread
+      virtual std::unique_ptr<FastIDKiller>
+      makeAndFillAction(G4AtlasUserActions&) override final;
 
     private:
 
       FastIDKiller::Config m_config;
-      //FastIDKiller::Report m_report;
 
   }; // class FastIDKillerTool
 
diff --git a/Simulation/G4Utilities/G4UserActions/G4UserActions/FluxRecorderTool.h b/Simulation/G4Utilities/G4UserActions/G4UserActions/FluxRecorderTool.h
index 8fa62f0cdb9d768d1cf24373f58b6a1f54d49da6..20dfa91bb50463672e81388ed4f68a5be7bf1d75 100644
--- a/Simulation/G4Utilities/G4UserActions/G4UserActions/FluxRecorderTool.h
+++ b/Simulation/G4Utilities/G4UserActions/G4UserActions/FluxRecorderTool.h
@@ -8,13 +8,12 @@
 #include "G4AtlasInterfaces/IG4RunActionTool.h"
 #include "G4AtlasInterfaces/IG4EventActionTool.h"
 #include "G4AtlasInterfaces/IG4SteppingActionTool.h"
-#include "G4AtlasTools/ActionToolBase.h"
+#include "G4AtlasTools/UserActionToolBase.h"
 #include "G4UserActions/FluxRecorder.h"
 
 namespace G4UA
 {
 
-  /// 	
   /// @class FluxRecorderTool
   /// @brief Tool which manages the FluxRecorder action.
   ///
@@ -22,29 +21,20 @@ namespace G4UA
   ///
   /// @author Andrea Di Simone
   ///
-  class FluxRecorderTool : public ActionToolBase<FluxRecorder>,
-                           public IG4RunActionTool, public IG4EventActionTool,
-                           public IG4SteppingActionTool
+  class FluxRecorderTool : public UserActionToolBase<FluxRecorder>
   {
 
     public:
 
-      /// standard tool ctor
-      FluxRecorderTool(const std::string& type, const std::string& name,const IInterface* parent);
-      /// retrieves the run action
-      virtual G4UserRunAction* getRunAction() override final
-      { return static_cast<G4UserRunAction*>( getAction() ); }
-      /// retrieves the event action
-      virtual G4UserEventAction* getEventAction() override final
-      { return static_cast<G4UserEventAction*>( getAction() ); }
-      /// retrieves the stepping action
-      virtual G4UserSteppingAction* getSteppingAction() override final
-      { return static_cast<G4UserSteppingAction*>( getAction() ); }
+      /// Standard tool ctor
+      FluxRecorderTool(const std::string& type, const std::string& name,
+                       const IInterface* parent);
 
     protected:
 
       /// create action for this thread
-      virtual std::unique_ptr<FluxRecorder> makeAction() override final;
+      virtual std::unique_ptr<FluxRecorder>
+      makeAndFillAction(G4AtlasUserActions&) override final;
 
   }; // class FluxRecorderTool
 
diff --git a/Simulation/G4Utilities/G4UserActions/G4UserActions/G4SimTimerTool.h b/Simulation/G4Utilities/G4UserActions/G4UserActions/G4SimTimerTool.h
index b734a014ecee4a2f6c54f69e741d2f37b6221e26..9f2e1729160f8c1a431b476416a6b86e883f5588 100644
--- a/Simulation/G4Utilities/G4UserActions/G4UserActions/G4SimTimerTool.h
+++ b/Simulation/G4Utilities/G4UserActions/G4UserActions/G4SimTimerTool.h
@@ -10,7 +10,7 @@
 
 // Infrastructure includes
 #include "G4AtlasInterfaces/IG4EventActionTool.h"
-#include "G4AtlasTools/ActionToolBase.h"
+#include "G4AtlasTools/UserActionToolBase.h"
 
 // Local includes
 #include "G4UserActions/G4SimTimer.h"
@@ -26,8 +26,7 @@ namespace G4UA
   ///
   /// @author Steve Farrell <Steven.Farrell@cern.ch>
   ///
-  class G4SimTimerTool : public ActionToolBaseReport<G4SimTimer>,
-                         public IG4EventActionTool
+  class G4SimTimerTool : public UserActionToolBase<G4SimTimer>
   {
 
     public:
@@ -36,20 +35,17 @@ namespace G4UA
       G4SimTimerTool(const std::string& type, const std::string& name,
                      const IInterface* parent);
 
-      /// Temporary, just for debugging
+      /// Initialize the tool
       virtual StatusCode initialize() override;
 
       /// Finalize and merge results from all worker threads
       virtual StatusCode finalize() override;
 
-      /// Retrieve the begin-event action interface
-      virtual G4UserEventAction* getEventAction() override final
-      { return static_cast<G4UserEventAction*>( getAction() ); }
-
     protected:
 
       /// Create aciton for this thread
-      virtual std::unique_ptr<G4SimTimer> makeAction() override final;
+      virtual std::unique_ptr<G4SimTimer>
+      makeAndFillAction(G4AtlasUserActions&) override final;
 
   }; // class G4SimTimerTool
 
diff --git a/Simulation/G4Utilities/G4UserActions/G4UserActions/G4TrackCounterTool.h b/Simulation/G4Utilities/G4UserActions/G4UserActions/G4TrackCounterTool.h
index 5fd9d688a7a70d65b8b1cb78c35a23ea3813e610..fdd5df27e6322487df8d1b585277379635871186 100644
--- a/Simulation/G4Utilities/G4UserActions/G4UserActions/G4TrackCounterTool.h
+++ b/Simulation/G4Utilities/G4UserActions/G4UserActions/G4TrackCounterTool.h
@@ -8,7 +8,7 @@
 // Infrastructure includes
 #include "G4AtlasInterfaces/IG4EventActionTool.h"
 #include "G4AtlasInterfaces/IG4TrackingActionTool.h"
-#include "G4AtlasTools/ActionToolBase.h"
+#include "G4AtlasTools/UserActionToolBase.h"
 
 // Local includes
 #include "G4TrackCounter.h"
@@ -23,9 +23,7 @@ namespace G4UA
   ///
   /// @author Steve Farrell <Steven.Farrell@cern.ch>
   ///
-  class G4TrackCounterTool : public ActionToolBaseReport<G4TrackCounter>,
-                             public IG4EventActionTool,
-                             public IG4TrackingActionTool
+  class G4TrackCounterTool : public UserActionToolBase<G4TrackCounter>
   {
 
     public:
@@ -40,18 +38,11 @@ namespace G4UA
       /// Finalize and merge results from all threads
       virtual StatusCode finalize() override final;
 
-      /// Retrieve the event action interface
-      virtual G4UserEventAction* getEventAction() override final
-      { return static_cast<G4UserEventAction*>( getAction() ); }
-
-      /// Retrieve the tracking action interface
-      virtual G4UserTrackingAction* getTrackingAction() override final
-      { return static_cast<G4UserTrackingAction*>( getAction() ); }
-
     protected:
 
       /// Create action for this thread
-      virtual std::unique_ptr<G4TrackCounter> makeAction() override final;
+      virtual std::unique_ptr<G4TrackCounter>
+      makeAndFillAction(G4AtlasUserActions&) override final;
 
   }; // class G4TrackCounterTool
 
diff --git a/Simulation/G4Utilities/G4UserActions/G4UserActions/HIPKillerTool.h b/Simulation/G4Utilities/G4UserActions/G4UserActions/HIPKillerTool.h
index 2fbc4bac1b5f35cdbefaf50a7e367b61b6ae79ae..01a1e031c5a6b9194dfa6c717983031086d99c7a 100644
--- a/Simulation/G4Utilities/G4UserActions/G4UserActions/HIPKillerTool.h
+++ b/Simulation/G4Utilities/G4UserActions/G4UserActions/HIPKillerTool.h
@@ -5,7 +5,7 @@
 #ifndef G4USERACTIONS_G4UA__HIPKILLERTOOL_H
 #define G4USERACTIONS_G4UA__HIPKILLERTOOL_H
 #include "G4AtlasInterfaces/IG4SteppingActionTool.h"
-#include "G4AtlasTools/ActionToolBase.h"
+#include "G4AtlasTools/UserActionToolBase.h"
 #include "G4UserActions/HIPKiller.h"
 
 namespace G4UA
@@ -13,7 +13,7 @@ namespace G4UA
 
   /// @brief Tool which manages the HIPKiller user action.
   ///
-  class HIPKillerTool: public ActionToolBase<HIPKiller>, public IG4SteppingActionTool
+  class HIPKillerTool : public UserActionToolBase<HIPKiller>
   {
 
     public:
@@ -22,12 +22,11 @@ namespace G4UA
       HIPKillerTool(const std::string& type, const std::string& name,
                     const IInterface* parent);
 
-      virtual G4UserSteppingAction* getSteppingAction() override final
-      { return static_cast<G4UserSteppingAction*>( getAction() ); }
-
     protected:
 
-      virtual std::unique_ptr<HIPKiller> makeAction() override final;
+      /// Create the action for the current thread
+      virtual std::unique_ptr<HIPKiller>
+      makeAndFillAction(G4AtlasUserActions&) override final;
 
   }; // class HIPKillerTool
 
diff --git a/Simulation/G4Utilities/G4UserActions/G4UserActions/HIPLArVolumeAcceptTool.h b/Simulation/G4Utilities/G4UserActions/G4UserActions/HIPLArVolumeAcceptTool.h
index a6544d213f0d2254b57c07181875642c8c067f1d..9dfcb916dac6c520728aecc932fee62ebc1b0a06 100644
--- a/Simulation/G4Utilities/G4UserActions/G4UserActions/HIPLArVolumeAcceptTool.h
+++ b/Simulation/G4Utilities/G4UserActions/G4UserActions/HIPLArVolumeAcceptTool.h
@@ -7,7 +7,7 @@
 
 #include "G4AtlasInterfaces/IG4SteppingActionTool.h"
 #include "G4AtlasInterfaces/IG4EventActionTool.h"
-#include "G4AtlasTools/ActionToolBase.h"
+#include "G4AtlasTools/UserActionToolBase.h"
 #include "G4UserActions/HIPLArVolumeAccept.h"
 
 namespace G4UA
@@ -15,9 +15,7 @@ namespace G4UA
 
   /// Tool which manages the HIPLArVolumeAccept action
   ///
-  class HIPLArVolumeAcceptTool : public ActionToolBaseReport<HIPLArVolumeAccept>,
-                                 public IG4SteppingActionTool,
-                                 public IG4EventActionTool
+  class HIPLArVolumeAcceptTool : public UserActionToolBase<HIPLArVolumeAccept>
   {
 
     public:
@@ -26,21 +24,14 @@ namespace G4UA
       HIPLArVolumeAcceptTool(const std::string& type, const std::string& name,
                              const IInterface* parent);
 
-      virtual G4UserSteppingAction* getSteppingAction() override final
-      { return static_cast<G4UserSteppingAction*>( getAction() ); }
-
-      virtual G4UserEventAction* getEventAction() override final
-      { return static_cast<G4UserEventAction*>( getAction() ); }
-
+      /// Finalize the tool
       virtual StatusCode finalize() override;
 
     protected:
 
-      virtual std::unique_ptr<HIPLArVolumeAccept> makeAction() override final;
-
-    //private:
-
-    //  HIPLArVolumeAccept::Report m_report;
+      /// Create the action for the current thread
+      virtual std::unique_ptr<HIPLArVolumeAccept>
+      makeAndFillAction(G4AtlasUserActions&) override final;
 
   }; // class HIPLArVolumeAcceptTool
 
diff --git a/Simulation/G4Utilities/G4UserActions/G4UserActions/HitWrapperTool.h b/Simulation/G4Utilities/G4UserActions/G4UserActions/HitWrapperTool.h
index 52054f8764b3369c67ab0cdbb480bd028a769089..8a4b42bf77eb2bad1115868efd5181614df3e177 100644
--- a/Simulation/G4Utilities/G4UserActions/G4UserActions/HitWrapperTool.h
+++ b/Simulation/G4Utilities/G4UserActions/G4UserActions/HitWrapperTool.h
@@ -6,28 +6,30 @@
 #define G4USERACTIONS_G4UA__HITWRAPPERTOOL_H
 
 #include "G4AtlasInterfaces/IG4EventActionTool.h"
-#include  "G4AtlasTools/ActionToolBase.h"
+#include  "G4AtlasTools/UserActionToolBase.h"
 #include "G4UserActions/HitWrapper.h"
 
 namespace G4UA
 {
 
   /// @brief A tool which manages the HitWrapper user action.
-  class HitWrapperTool : public ActionToolBase<HitWrapper>,
-                         public IG4EventActionTool
+  class HitWrapperTool : public UserActionToolBase<HitWrapper>
   {
+
     public:
+
       /// Standard constructor
       HitWrapperTool(const std::string& type, const std::string& name,
                      const IInterface* parent);
 
-      virtual G4UserEventAction* getEventAction() override final
-      { return static_cast<G4UserEventAction*>( getAction() ); }
-
     protected:
-      virtual std::unique_ptr<HitWrapper> makeAction() override final;
+
+      /// Create the action for the current thread
+      virtual std::unique_ptr<HitWrapper>
+      makeAndFillAction(G4AtlasUserActions&) override final;
 
     private:
+
       HitWrapper::Config m_config;
 
   }; // class HitWrapperTool
diff --git a/Simulation/G4Utilities/G4UserActions/G4UserActions/LengthIntegratorTool.h b/Simulation/G4Utilities/G4UserActions/G4UserActions/LengthIntegratorTool.h
index b1489cd892687605c4dd01a270997d4446b6d132..c1045fe060e2abbc37e6615a35acd32a1b1bd8e9 100644
--- a/Simulation/G4Utilities/G4UserActions/G4UserActions/LengthIntegratorTool.h
+++ b/Simulation/G4Utilities/G4UserActions/G4UserActions/LengthIntegratorTool.h
@@ -12,7 +12,7 @@
 // User action infrastructure includes
 #include "G4AtlasInterfaces/IG4EventActionTool.h"
 #include "G4AtlasInterfaces/IG4SteppingActionTool.h"
-#include "G4AtlasTools/ActionToolBase.h"
+#include "G4AtlasTools/UserActionToolBase.h"
 
 // Local includes
 #include "G4UserActions/LengthIntegrator.h"
@@ -25,9 +25,7 @@ namespace G4UA
   ///
   /// Creates the LengthIntegrator for each worker thread.
   ///
-  class LengthIntegratorTool : public ActionToolBase<LengthIntegrator>,
-                               public IG4EventActionTool,
-                               public IG4SteppingActionTool
+  class LengthIntegratorTool : public UserActionToolBase<LengthIntegrator>
   {
 
     public:
@@ -39,18 +37,11 @@ namespace G4UA
       /// Initialize the tool
       virtual StatusCode initialize() override;
 
-      /// Retrieve the event action interface
-      virtual G4UserEventAction* getEventAction() override final
-      { return static_cast<G4UserEventAction*>( getAction() ); }
-
-      /// Retrieve the stepping action interface
-      virtual G4UserSteppingAction* getSteppingAction() override final
-      { return static_cast<G4UserSteppingAction*>( getAction() ); }
-
     protected:
 
       /// Create aciton for this thread
-      virtual std::unique_ptr<LengthIntegrator> makeAction() override final;
+      virtual std::unique_ptr<LengthIntegrator>
+      makeAndFillAction(G4AtlasUserActions&) override final;
 
     private:
 
diff --git a/Simulation/G4Utilities/G4UserActions/G4UserActions/LooperKillerTool.h b/Simulation/G4Utilities/G4UserActions/G4UserActions/LooperKillerTool.h
index b8c923590c66e671f1e602f3d9f6fb17d16f187b..f2ba54111bfe5c3eec613a9c0e2066b02191258b 100644
--- a/Simulation/G4Utilities/G4UserActions/G4UserActions/LooperKillerTool.h
+++ b/Simulation/G4Utilities/G4UserActions/G4UserActions/LooperKillerTool.h
@@ -10,7 +10,7 @@
 
 // Infrastructure includes
 #include "G4AtlasInterfaces/IG4SteppingActionTool.h"
-#include "G4AtlasTools/ActionToolBase.h"
+#include "G4AtlasTools/UserActionToolBase.h"
 
 // Local includes
 #include "G4UserActions/LooperKiller.h"
@@ -25,8 +25,7 @@ namespace G4UA
   ///
   /// @author Andrea Di Simone
   ///
-  class LooperKillerTool : public ActionToolBaseReport<LooperKiller>,
-                           public IG4SteppingActionTool
+  class LooperKillerTool : public UserActionToolBase<LooperKiller>
   {
 
     public:
@@ -35,20 +34,17 @@ namespace G4UA
       LooperKillerTool(const std::string& type, const std::string& name,
 		       const IInterface* parent);
 
-
       virtual StatusCode initialize() override;
       virtual StatusCode finalize() override;
 
-      /// Retrieve the begin-event action interface
-      virtual G4UserSteppingAction* getSteppingAction() override final
-      { return static_cast<G4UserSteppingAction*>( getAction() ); }
-
     protected:
 
       /// Create action for this thread
-      virtual std::unique_ptr<LooperKiller> makeAction() override final;
+      virtual std::unique_ptr<LooperKiller>
+      makeAndFillAction(G4AtlasUserActions&) override final;
 
     private:
+
       /// Configuration parameters
       G4UA::LooperKiller::Config m_config;
 
diff --git a/Simulation/G4Utilities/G4UserActions/G4UserActions/MomentumConservationTool.h b/Simulation/G4Utilities/G4UserActions/G4UserActions/MomentumConservationTool.h
index 4cf2c23352884f541433c3a7652083db6734bd29..05b835821bf6f0946ce8f8683b1f78f1717b24c8 100644
--- a/Simulation/G4Utilities/G4UserActions/G4UserActions/MomentumConservationTool.h
+++ b/Simulation/G4Utilities/G4UserActions/G4UserActions/MomentumConservationTool.h
@@ -7,7 +7,7 @@
 
 #include "G4AtlasInterfaces/IG4EventActionTool.h"
 #include "G4AtlasInterfaces/IG4SteppingActionTool.h"
-#include "G4AtlasTools/ActionToolBase.h"
+#include "G4AtlasTools/UserActionToolBase.h"
 #include "G4UserActions/MomentumConservation.h"
 
 namespace G4UA
@@ -15,9 +15,7 @@ namespace G4UA
 
   /// @brief Tool which manages the MomentumConservation user action.
   ///
-  class MomentumConservationTool : public ActionToolBase<MomentumConservation>,
-                                   public IG4EventActionTool,
-                                   public IG4SteppingActionTool
+  class MomentumConservationTool : public UserActionToolBase<MomentumConservation>
   {
 
     public:
@@ -26,15 +24,11 @@ namespace G4UA
       MomentumConservationTool(const std::string& type, const std::string& name,
                                const IInterface* parent);
 
-      virtual G4UserEventAction* getEventAction() override final
-      { return static_cast<G4UserEventAction*>( getAction() ); }
-
-      virtual G4UserSteppingAction* getSteppingAction() override final
-      { return static_cast<G4UserSteppingAction*>( getAction() ); }
-
     protected:
 
-      virtual std::unique_ptr<MomentumConservation> makeAction() override final;
+      /// Create the action for the current thread
+      virtual std::unique_ptr<MomentumConservation>
+      makeAndFillAction(G4AtlasUserActions&) override final;
 
   }; // class MomentumConservationTool
 
diff --git a/Simulation/G4Utilities/G4UserActions/G4UserActions/PhotonKillerTool.h b/Simulation/G4Utilities/G4UserActions/G4UserActions/PhotonKillerTool.h
index 0cfc6998bd9892f9e677a9c6c8d49a5899c77d89..007cce2ab29ae841dfdf22a40f5e65d8f7a617c1 100644
--- a/Simulation/G4Utilities/G4UserActions/G4UserActions/PhotonKillerTool.h
+++ b/Simulation/G4Utilities/G4UserActions/G4UserActions/PhotonKillerTool.h
@@ -7,7 +7,7 @@
 
 #include "G4AtlasInterfaces/IG4SteppingActionTool.h"
 #include "G4AtlasInterfaces/IG4TrackingActionTool.h"
-#include "G4AtlasTools/ActionToolBase.h"
+#include "G4AtlasTools/UserActionToolBase.h"
 #include "G4UserActions/PhotonKiller.h"
 
 namespace G4UA
@@ -15,8 +15,7 @@ namespace G4UA
 
   /// @brief Tool which manages the PhotonKiller user action.
   ///
-  class PhotonKillerTool : public ActionToolBase<PhotonKiller>,
-                           public IG4SteppingActionTool, public IG4TrackingActionTool
+  class PhotonKillerTool : public UserActionToolBase<PhotonKiller>
   {
 
     public:
@@ -25,15 +24,11 @@ namespace G4UA
       PhotonKillerTool(const std::string& type, const std::string& name,
                        const IInterface* parent);
 
-      virtual G4UserSteppingAction* getSteppingAction() override final
-      { return static_cast<G4UserSteppingAction*>( getAction() ); }
-
-      virtual G4UserTrackingAction* getTrackingAction() override final
-      { return static_cast<G4UserTrackingAction*>( getAction() ); }
-
     protected:
 
-      virtual std::unique_ptr<PhotonKiller> makeAction() override final;
+      /// Create the action for the current thread
+      virtual std::unique_ptr<PhotonKiller>
+      makeAndFillAction(G4AtlasUserActions&) override final;
 
   }; // class PhotonKillerTool
 
diff --git a/Simulation/G4Utilities/G4UserActions/G4UserActions/ScoringPlaneTool.h b/Simulation/G4Utilities/G4UserActions/G4UserActions/ScoringPlaneTool.h
index 2cb591aefd4dc3ae252a17a19d387cc78ca00e4a..e0b54fdf81a02045333dddb4ef8686ca0206dccc 100644
--- a/Simulation/G4Utilities/G4UserActions/G4UserActions/ScoringPlaneTool.h
+++ b/Simulation/G4Utilities/G4UserActions/G4UserActions/ScoringPlaneTool.h
@@ -4,10 +4,11 @@
 
 #ifndef G4USERACTIONS_G4UA__SCORINGPLANETOOL_H
 #define G4USERACTIONS_G4UA__SCORINGPLANETOOL_H
+
 #include "G4AtlasInterfaces/IG4RunActionTool.h"
 #include "G4AtlasInterfaces/IG4SteppingActionTool.h"
 #include "G4AtlasInterfaces/IG4EventActionTool.h"
-#include "G4AtlasTools/ActionToolBase.h"
+#include "G4AtlasTools/UserActionToolBase.h"
 #include "G4UserActions/ScoringPlane.h"
 
 
@@ -20,30 +21,20 @@ namespace G4UA
   /// creates one ScoprinPlane instance per thread
   /// @author Andrea Di Simone
   ///
-  class ScoringPlaneTool : public ActionToolBase<ScoringPlane>,
-                           public IG4RunActionTool,
-                           public IG4SteppingActionTool,
-                           public IG4EventActionTool
+  class ScoringPlaneTool : public UserActionToolBase<ScoringPlane>
   {
 
     public:
 
-      /// standard tool ctor
-      ScoringPlaneTool(const std::string& type, const std::string& name,const IInterface* parent);
-      /// retrieves run action
-      virtual G4UserRunAction* getRunAction() override final
-      { return static_cast<G4UserRunAction*>( getAction() ); }
-      /// retrieves stepping action
-      virtual G4UserSteppingAction* getSteppingAction() override final
-      { return static_cast<G4UserSteppingAction*>( getAction() ); }
-      /// retrieves event action
-      virtual G4UserEventAction* getEventAction() override final
-      { return static_cast<G4UserEventAction*>( getAction() ); }
+      /// Standard tool ctor
+      ScoringPlaneTool(const std::string& type, const std::string& name,
+                       const IInterface* parent);
 
     protected:
 
       /// creates the action instances
-      virtual std::unique_ptr<ScoringPlane> makeAction() override final;
+      virtual std::unique_ptr<ScoringPlane>
+      makeAndFillAction(G4AtlasUserActions&) override final;
 
     private:
 
@@ -53,4 +44,5 @@ namespace G4UA
   }; // class ScoringPlaneTool
 
 } // namespace G4UA
+
 #endif
diff --git a/Simulation/G4Utilities/G4UserActions/G4UserActions/ScoringVolumeTrackKillerTool.h b/Simulation/G4Utilities/G4UserActions/G4UserActions/ScoringVolumeTrackKillerTool.h
index bd9102806dcbfd54ca07fddfba460c3dfdbc83da..c901b11c8f8e325dda090b9b413ed0f975ecd596 100644
--- a/Simulation/G4Utilities/G4UserActions/G4UserActions/ScoringVolumeTrackKillerTool.h
+++ b/Simulation/G4Utilities/G4UserActions/G4UserActions/ScoringVolumeTrackKillerTool.h
@@ -4,9 +4,10 @@
 
 #ifndef G4USERACTIONS_G4UA__SCORINGVOLUMETRACKKILLERTOOL_H
 #define G4USERACTIONS_G4UA__SCORINGVOLUMETRACKKILLERTOOL_H
+
 #include "G4AtlasInterfaces/IG4EventActionTool.h"
 #include "G4AtlasInterfaces/IG4SteppingActionTool.h"
-#include "G4AtlasTools/ActionToolBase.h"
+#include "G4AtlasTools/UserActionToolBase.h"
 #include "G4UserActions/ScoringVolumeTrackKiller.h"
 
 namespace G4UA
@@ -14,9 +15,8 @@ namespace G4UA
 
   /// @brief Tool which manages the ScoringVolumeTrackKiller user action.
   ///
-  class ScoringVolumeTrackKillerTool : public ActionToolBase<ScoringVolumeTrackKiller>,
-                                       public IG4EventActionTool,
-                                       public IG4SteppingActionTool
+  class ScoringVolumeTrackKillerTool
+    : public UserActionToolBase<ScoringVolumeTrackKiller>
   {
 
     public:
@@ -25,14 +25,11 @@ namespace G4UA
       ScoringVolumeTrackKillerTool(const std::string& type, const std::string& name,
                                    const IInterface* parent);
 
-      virtual G4UserEventAction* getEventAction() override final
-      { return static_cast<G4UserEventAction*>( getAction() ); }
-      virtual G4UserSteppingAction* getSteppingAction() override final
-      { return static_cast<G4UserSteppingAction*>( getAction() ); }
-
     protected:
 
-      virtual std::unique_ptr<ScoringVolumeTrackKiller> makeAction() override final;
+      /// Create the action for the current thread
+      virtual std::unique_ptr<ScoringVolumeTrackKiller>
+      makeAndFillAction(G4AtlasUserActions&) override final;
 
   }; // class ScoringVolumeTrackKillerTool
 
diff --git a/Simulation/G4Utilities/G4UserActions/G4UserActions/StoppedParticleActionTool.h b/Simulation/G4Utilities/G4UserActions/G4UserActions/StoppedParticleActionTool.h
index ea14a25da1e9d06ecbe96e752d2c0d5d796a295d..6620ccf2361ad414b6120bf67d8528ea4777f5d1 100644
--- a/Simulation/G4Utilities/G4UserActions/G4UserActions/StoppedParticleActionTool.h
+++ b/Simulation/G4Utilities/G4UserActions/G4UserActions/StoppedParticleActionTool.h
@@ -6,7 +6,7 @@
 #define G4USERACTIONS_G4UA__STOPPEDPARTICLEACTIONTOOL_H
 
 #include "G4AtlasInterfaces/IG4SteppingActionTool.h"
-#include "G4AtlasTools/ActionToolBase.h"
+#include "G4AtlasTools/UserActionToolBase.h"
 #include "G4UserActions/StoppedParticleAction.h"
 
 namespace G4UA
@@ -14,8 +14,7 @@ namespace G4UA
 
   /// @brief Tool which manages the StoppedParticleAction
   ///
-  class StoppedParticleActionTool: public ActionToolBase<StoppedParticleAction>,
-                                   public IG4SteppingActionTool
+  class StoppedParticleActionTool: public UserActionToolBase<StoppedParticleAction>
   {
 
     public:
@@ -24,12 +23,11 @@ namespace G4UA
       StoppedParticleActionTool(const std::string& type, const std::string& name,
                                 const IInterface* parent);
 
-      virtual G4UserSteppingAction* getSteppingAction() override final
-      { return static_cast<G4UserSteppingAction*>( getAction() ); }
-
     protected:
 
-      virtual std::unique_ptr<StoppedParticleAction> makeAction() override final;
+      /// Create the action for the current thread
+      virtual std::unique_ptr<StoppedParticleAction>
+      makeAndFillAction(G4AtlasUserActions&) override final;
 
   }; // class StoppedParticleActionTool
 
diff --git a/Simulation/G4Utilities/G4UserActions/src/CosmicPerigeeActionTool.cxx b/Simulation/G4Utilities/G4UserActions/src/CosmicPerigeeActionTool.cxx
index 84ed3d8f2c677f803708f067fda9e8d3b12bea56..a2b71cd315206721a260b742f771256a52631917 100644
--- a/Simulation/G4Utilities/G4UserActions/src/CosmicPerigeeActionTool.cxx
+++ b/Simulation/G4Utilities/G4UserActions/src/CosmicPerigeeActionTool.cxx
@@ -13,21 +13,23 @@ namespace G4UA
   CosmicPerigeeActionTool::CosmicPerigeeActionTool(const std::string& type,
                                                    const std::string& name,
                                                    const IInterface* parent)
-    : ActionToolBase<CosmicPerigeeAction>(type, name, parent)
+    : UserActionToolBase<CosmicPerigeeAction>(type, name, parent)
   {
-    declareInterface<IG4SteppingActionTool>(this);
-    declareInterface<IG4EventActionTool>(this);
-    declareInterface<IG4TrackingActionTool>(this);
     declareProperty("pMinPrimary", m_config.pMinPrimary);
   }
 
   //---------------------------------------------------------------------------
   // Create the action on request
   //---------------------------------------------------------------------------
-  std::unique_ptr<CosmicPerigeeAction> CosmicPerigeeActionTool::makeAction()
+  std::unique_ptr<CosmicPerigeeAction>
+  CosmicPerigeeActionTool::makeAndFillAction(G4AtlasUserActions& actionList)
   {
-    ATH_MSG_DEBUG("makeAction");
-    return std::make_unique<CosmicPerigeeAction>(m_config);
+    ATH_MSG_DEBUG("Creating CosmicPerigeeAction");
+    auto action = std::make_unique<CosmicPerigeeAction>(m_config);
+    actionList.eventActions.push_back( action.get() );
+    actionList.trackingActions.push_back( action.get() );
+    actionList.steppingActions.push_back( action.get() );
+    return action;
   }
 
 }
diff --git a/Simulation/G4Utilities/G4UserActions/src/FastIDKillerTool.cxx b/Simulation/G4Utilities/G4UserActions/src/FastIDKillerTool.cxx
index 35ebcd12f3f8124d7128c6bb1b21384f2d71d5aa..6358290c0bfa2ac5f78a51337b3b97e82bd5c5fb 100644
--- a/Simulation/G4Utilities/G4UserActions/src/FastIDKillerTool.cxx
+++ b/Simulation/G4Utilities/G4UserActions/src/FastIDKillerTool.cxx
@@ -7,28 +7,35 @@
 namespace G4UA
 {
 
+  //---------------------------------------------------------------------------
   FastIDKillerTool::FastIDKillerTool(const std::string& type,
                                      const std::string& name,
                                      const IInterface* parent)
-    : ActionToolBaseReport<FastIDKiller>(type, name, parent)
+    : UserActionToolBase<FastIDKiller>(type, name, parent)
   {
-    declareInterface<IG4RunActionTool>(this);
-    declareInterface<IG4SteppingActionTool>(this);
-
     declareProperty("R", m_config.R);
     declareProperty("Z", m_config.Z);
   }
 
-  std::unique_ptr<FastIDKiller> FastIDKillerTool::makeAction()
+  //---------------------------------------------------------------------------
+  std::unique_ptr<FastIDKiller>
+  FastIDKillerTool::makeAndFillAction(G4AtlasUserActions& actionList)
   {
-    ATH_MSG_DEBUG("makeAction");
-    return std::make_unique<FastIDKiller>(m_config);
+    ATH_MSG_DEBUG("Constructing a FastIDKiller action");
+    auto action = std::make_unique<FastIDKiller>(m_config);
+    actionList.runActions.push_back( action.get() );
+    actionList.steppingActions.push_back( action.get() );
+    return action;
   }
 
+  //---------------------------------------------------------------------------
   StatusCode FastIDKillerTool::finalize()
   {
-    mergeReports();
-    ATH_MSG_INFO( "Fast Inner Detector Killer killed " << m_report.killCount <<
+    // Accumulate results across threads
+    FastIDKiller::Report report;
+    m_actions.accumulate(report, &FastIDKiller::getReport,
+                         &FastIDKiller::Report::merge);
+    ATH_MSG_INFO( "Fast Inner Detector Killer killed " << report.killCount <<
                   " particles during this run." );
     return StatusCode::SUCCESS;
   }
diff --git a/Simulation/G4Utilities/G4UserActions/src/FluxRecorderTool.cxx b/Simulation/G4Utilities/G4UserActions/src/FluxRecorderTool.cxx
index 57340673d127c08fdbc931b7c3a6a04e51604e26..a660c8754e960e1205ecc9eef4a06da9f77ac91f 100644
--- a/Simulation/G4Utilities/G4UserActions/src/FluxRecorderTool.cxx
+++ b/Simulation/G4Utilities/G4UserActions/src/FluxRecorderTool.cxx
@@ -10,17 +10,19 @@ namespace G4UA
   FluxRecorderTool::FluxRecorderTool(const std::string& type,
                                      const std::string& name,
                                      const IInterface* parent)
-    : ActionToolBase<FluxRecorder>(type, name, parent)
+    : UserActionToolBase<FluxRecorder>(type, name, parent)
   {
-    declareInterface<IG4RunActionTool>(this);
-    declareInterface<IG4EventActionTool>(this);
-    declareInterface<IG4SteppingActionTool>(this);
   }
 
-  std::unique_ptr<FluxRecorder> FluxRecorderTool::makeAction()
+  std::unique_ptr<FluxRecorder>
+  FluxRecorderTool::makeAndFillAction(G4AtlasUserActions& actionList)
   {
-    ATH_MSG_DEBUG("makeAction");
-    return std::make_unique<FluxRecorder>();
+    ATH_MSG_DEBUG("Constructing a FluxRecorder action");
+    auto action = std::make_unique<FluxRecorder>();
+    actionList.runActions.push_back( action.get() );
+    actionList.eventActions.push_back( action.get() );
+    actionList.steppingActions.push_back( action.get() );
+    return action;
   }
 
 } // namespace G4UA
diff --git a/Simulation/G4Utilities/G4UserActions/src/G4SimTimerTool.cxx b/Simulation/G4Utilities/G4UserActions/src/G4SimTimerTool.cxx
index c449fe576d8ad3fc76cb2b9ed69b3bbf57ced3cd..7198259e5d14bf88fa4ba32102eaae630e9a2000 100644
--- a/Simulation/G4Utilities/G4UserActions/src/G4SimTimerTool.cxx
+++ b/Simulation/G4Utilities/G4UserActions/src/G4SimTimerTool.cxx
@@ -13,9 +13,8 @@ namespace G4UA
   G4SimTimerTool::G4SimTimerTool(const std::string& type,
                                  const std::string& name,
                                  const IInterface* parent)
-    : ActionToolBaseReport<G4SimTimer>(type, name, parent)
+    : UserActionToolBase<G4SimTimer>(type, name, parent)
   {
-    declareInterface<IG4EventActionTool>(this);
   }
 
   //---------------------------------------------------------------------------
@@ -34,11 +33,14 @@ namespace G4UA
   {
     ATH_MSG_DEBUG( "Finalizing " << name() );
 
-    mergeReports();
+    // Accumulate results across threads
+    G4SimTimer::Report report;
+    m_actions.accumulate(report, &G4SimTimer::getReport,
+                         &G4SimTimer::Report::merge);
 
     // Report the results
-    auto meanSigma = m_report.meanAndSigma();
-    ATH_MSG_INFO("Finalized timing results for " << m_report.nEvent <<
+    auto meanSigma = report.meanAndSigma();
+    ATH_MSG_INFO("Finalized timing results for " << report.nEvent <<
                  " events (not all events used)");
     ATH_MSG_INFO("Average time per event was " <<
                  std::setprecision(4) << meanSigma.first << " +- " <<
@@ -50,10 +52,12 @@ namespace G4UA
   // Create the action on request
   //---------------------------------------------------------------------------
   std::unique_ptr<G4SimTimer>
-  G4SimTimerTool::makeAction()
+  G4SimTimerTool::makeAndFillAction(G4AtlasUserActions& actionList)
   {
     ATH_MSG_DEBUG("Making a G4SimTimer action");
-    return std::make_unique<G4SimTimer>();
+    auto action = std::make_unique<G4SimTimer>();
+    actionList.eventActions.push_back( action.get() );
+    return action;
   }
 
 }
diff --git a/Simulation/G4Utilities/G4UserActions/src/G4TrackCounterTool.cxx b/Simulation/G4Utilities/G4UserActions/src/G4TrackCounterTool.cxx
index cdbd563400c13bf18800760e0404c639d04894a9..b2ff125c0c7bd3ce52c728da74d472dd78e6e784 100644
--- a/Simulation/G4Utilities/G4UserActions/src/G4TrackCounterTool.cxx
+++ b/Simulation/G4Utilities/G4UserActions/src/G4TrackCounterTool.cxx
@@ -13,10 +13,8 @@ namespace G4UA
   G4TrackCounterTool::
   G4TrackCounterTool(const std::string& type, const std::string& name,
                      const IInterface* parent)
-    : ActionToolBaseReport<G4TrackCounter>(type, name, parent)
+    : UserActionToolBase<G4TrackCounter>(type, name, parent)
   {
-    declareInterface<IG4EventActionTool>(this);
-    declareInterface<IG4TrackingActionTool>(this);
   }
 
   //---------------------------------------------------------------------------
@@ -35,13 +33,16 @@ namespace G4UA
   {
     ATH_MSG_DEBUG( "Finalizing " << name() );
 
-    mergeReports();
+    // Accumulate the results across threads
+    G4TrackCounter::Report report;
+    m_actions.accumulate(report, &G4TrackCounter::getReport,
+                         &G4TrackCounter::Report::merge);
 
     // Report the totals
-    ATH_MSG_INFO("nEvents          " << m_report.nEvents);
-    ATH_MSG_INFO("nPrimaryTracks   " << m_report.nPrimaryTracks);
-    ATH_MSG_INFO("nSecondaryTracks " << m_report.nSecondaryTracks);
-    ATH_MSG_INFO("n50MeVTracks     " << m_report.n50MeVTracks);
+    ATH_MSG_INFO("nEvents          " << report.nEvents);
+    ATH_MSG_INFO("nPrimaryTracks   " << report.nPrimaryTracks);
+    ATH_MSG_INFO("nSecondaryTracks " << report.nSecondaryTracks);
+    ATH_MSG_INFO("n50MeVTracks     " << report.n50MeVTracks);
 
     return StatusCode::SUCCESS;
   }
@@ -50,10 +51,13 @@ namespace G4UA
   // Create the action on request
   //---------------------------------------------------------------------------
   std::unique_ptr<G4TrackCounter>
-  G4TrackCounterTool::makeAction()
+  G4TrackCounterTool::makeAndFillAction(G4AtlasUserActions& actionList)
   {
     ATH_MSG_DEBUG("Making a G4TrackCounter action");
-    return std::make_unique<G4TrackCounter>();
+    auto action = std::make_unique<G4TrackCounter>();
+    actionList.eventActions.push_back( action.get() );
+    actionList.trackingActions.push_back( action.get() );
+    return action;
   }
 
 }
diff --git a/Simulation/G4Utilities/G4UserActions/src/HIPKillerTool.cxx b/Simulation/G4Utilities/G4UserActions/src/HIPKillerTool.cxx
index 5bd1dd4bff6a0b9c251e03ac09464c992d7bca06..020b4b42ce3a7c315f5b05aaa571bdf3954c12e4 100644
--- a/Simulation/G4Utilities/G4UserActions/src/HIPKillerTool.cxx
+++ b/Simulation/G4Utilities/G4UserActions/src/HIPKillerTool.cxx
@@ -10,16 +10,18 @@ namespace G4UA
   //---------------------------------------------------------------------------
   HIPKillerTool::HIPKillerTool(const std::string& type, const std::string& name,
                                const IInterface* parent)
-    : ActionToolBase<HIPKiller>(type, name, parent)
+    : UserActionToolBase<HIPKiller>(type, name, parent)
   {
-    declareInterface<IG4SteppingActionTool>(this);
   }
 
   //---------------------------------------------------------------------------
-  std::unique_ptr<HIPKiller>  HIPKillerTool::makeAction()
+  std::unique_ptr<HIPKiller>
+  HIPKillerTool::makeAndFillAction(G4AtlasUserActions& actionList)
   {
-    ATH_MSG_DEBUG("makeAction");
-    return std::make_unique<HIPKiller>();
+    ATH_MSG_DEBUG("Making a HIPKiller action");
+    auto action = std::make_unique<HIPKiller>();
+    actionList.steppingActions.push_back( action.get() );
+    return action;
   }
 
 } // namespace G4UA
diff --git a/Simulation/G4Utilities/G4UserActions/src/HIPLArVolumeAcceptTool.cxx b/Simulation/G4Utilities/G4UserActions/src/HIPLArVolumeAcceptTool.cxx
index e5b3836afd8f75906a49631f42a954c2a69cb8db..3eb42b63d4e57c43fe6a53b9c48a2cfb854bb9ba 100644
--- a/Simulation/G4Utilities/G4UserActions/src/HIPLArVolumeAcceptTool.cxx
+++ b/Simulation/G4Utilities/G4UserActions/src/HIPLArVolumeAcceptTool.cxx
@@ -11,32 +11,37 @@ namespace G4UA
   HIPLArVolumeAcceptTool::HIPLArVolumeAcceptTool(const std::string& type,
                                                  const std::string& name,
                                                  const IInterface* parent)
-    : ActionToolBaseReport<HIPLArVolumeAccept>(type, name, parent)
+    : UserActionToolBase<HIPLArVolumeAccept>(type, name, parent)
   {
-    declareInterface<IG4SteppingActionTool>(this);
-    declareInterface<IG4EventActionTool>(this);
   }
 
   //---------------------------------------------------------------------------
-  std::unique_ptr<HIPLArVolumeAccept> HIPLArVolumeAcceptTool::makeAction()
+  std::unique_ptr<HIPLArVolumeAccept>
+  HIPLArVolumeAcceptTool::makeAndFillAction(G4AtlasUserActions& actionList)
   {
-    ATH_MSG_DEBUG("makeAction");
-    return std::make_unique<HIPLArVolumeAccept>();
+    ATH_MSG_DEBUG("Making a HIPLArVolumeAccept action");
+    auto action = std::make_unique<HIPLArVolumeAccept>();
+    actionList.eventActions.push_back( action.get() );
+    actionList.steppingActions.push_back( action.get() );
+    return action;
   }
 
   //---------------------------------------------------------------------------
   StatusCode HIPLArVolumeAcceptTool::finalize()
   {
-    mergeReports();
+    // Accumulate the results across threads
+    HIPLArVolumeAccept::Report report;
+    m_actions.accumulate(report, &HIPLArVolumeAccept::getReport,
+                         &HIPLArVolumeAccept::Report::merge);
 
     ATH_MSG_INFO("#########################################");
     ATH_MSG_INFO("##                                     ##");
     ATH_MSG_INFO( "##    HIPLArVolumeAccept - EndOfRun    ##");
     ATH_MSG_INFO( "##                                     ##");
     ATH_MSG_INFO( "#########################################");
-    ATH_MSG_INFO(m_report.HIPevts       <<" events were processed by HIPLArVolumeAccept");
-    ATH_MSG_INFO(m_report.HIPevts_failed<<" events were killed because they had no HIP in EMB or EMEC");
-    double HIPfraction=1.*(m_report.HIPevts-m_report.HIPevts_failed)/m_report.HIPevts;
+    ATH_MSG_INFO(report.HIPevts       <<" events were processed by HIPLArVolumeAccept");
+    ATH_MSG_INFO(report.HIPevts_failed<<" events were killed because they had no HIP in EMB or EMEC");
+    double HIPfraction=1.*(report.HIPevts-report.HIPevts_failed)/report.HIPevts;
     ATH_MSG_INFO("HIP Acceptance: "<<HIPfraction);
 
     return StatusCode::SUCCESS;
diff --git a/Simulation/G4Utilities/G4UserActions/src/HitWrapperTool.cxx b/Simulation/G4Utilities/G4UserActions/src/HitWrapperTool.cxx
index 0ce2be8c3b9d4d9da04a836f9e1a8a6bf6f10d06..11c296787f786a8074eb82783432c3df3b6220d8 100644
--- a/Simulation/G4Utilities/G4UserActions/src/HitWrapperTool.cxx
+++ b/Simulation/G4Utilities/G4UserActions/src/HitWrapperTool.cxx
@@ -10,16 +10,19 @@ namespace G4UA
   //---------------------------------------------------------------------------
   HitWrapperTool::HitWrapperTool(const std::string& type, const std::string& name,
                                  const IInterface* parent)
-    : ActionToolBase<HitWrapper>(type, name, parent)
+    : UserActionToolBase<HitWrapper>(type, name, parent)
   {
-    declareInterface<IG4EventActionTool>(this);
     declareProperty("Time", m_config.time);
   }
 
   //---------------------------------------------------------------------------
-  std::unique_ptr<HitWrapper> HitWrapperTool::makeAction(){
-    ATH_MSG_DEBUG("makeAction");
-    return std::make_unique<HitWrapper>(m_config);
+  std::unique_ptr<HitWrapper>
+  HitWrapperTool::makeAndFillAction(G4AtlasUserActions& actionList)
+  {
+    ATH_MSG_DEBUG("Making a HitWrapper action");
+    auto action = std::make_unique<HitWrapper>(m_config);
+    actionList.eventActions.push_back( action.get() );
+    return action;
   }
 
 } // namespace G4UA
diff --git a/Simulation/G4Utilities/G4UserActions/src/LengthIntegratorTool.cxx b/Simulation/G4Utilities/G4UserActions/src/LengthIntegratorTool.cxx
index 61befb4572797d07fc276c376d2550af297153ab..bde908c79b4fb7133de556cbcfac863b611fb741 100644
--- a/Simulation/G4Utilities/G4UserActions/src/LengthIntegratorTool.cxx
+++ b/Simulation/G4Utilities/G4UserActions/src/LengthIntegratorTool.cxx
@@ -13,11 +13,9 @@ namespace G4UA
   LengthIntegratorTool::LengthIntegratorTool(const std::string& type,
                                              const std::string& name,
                                              const IInterface* parent)
-    : ActionToolBase<LengthIntegrator>(type, name, parent),
+    : UserActionToolBase<LengthIntegrator>(type, name, parent),
       m_hSvc("THistSvc", name)
   {
-    declareInterface<IG4EventActionTool>(this);
-    declareInterface<IG4SteppingActionTool>(this);
     declareProperty("HistoSvc", m_hSvc);
   }
 
@@ -37,10 +35,13 @@ namespace G4UA
   // Create the action on request
   //---------------------------------------------------------------------------
   std::unique_ptr<LengthIntegrator>
-  LengthIntegratorTool::makeAction()
+  LengthIntegratorTool::makeAndFillAction(G4AtlasUserActions& actionList)
   {
-    ATH_MSG_DEBUG("makeAction");
-    return std::make_unique<LengthIntegrator>( m_hSvc.name() );
+    ATH_MSG_DEBUG("Making a LengthIntegrator action");
+    auto action = std::make_unique<LengthIntegrator>( m_hSvc.name() );
+    actionList.eventActions.push_back( action.get() );
+    actionList.steppingActions.push_back( action.get() );
+    return action;
   }
 
 }
diff --git a/Simulation/G4Utilities/G4UserActions/src/LooperKillerTool.cxx b/Simulation/G4Utilities/G4UserActions/src/LooperKillerTool.cxx
index ee46aa9d43175bbdd30e6b3ea36d41b4275239de..5ff279a9fd9c4c62d113e5185ad21347952c8b19 100644
--- a/Simulation/G4Utilities/G4UserActions/src/LooperKillerTool.cxx
+++ b/Simulation/G4Utilities/G4UserActions/src/LooperKillerTool.cxx
@@ -12,9 +12,8 @@ namespace G4UA
   //---------------------------------------------------------------------------
   LooperKillerTool::LooperKillerTool(const std::string& type, const std::string& name,
                                  const IInterface* parent)
-    : ActionToolBaseReport<LooperKiller>(type, name, parent)
+    : UserActionToolBase<LooperKiller>(type, name, parent)
   {
-    declareInterface<IG4SteppingActionTool>(this);
     declareProperty("MaxSteps", m_config.MaxSteps);
     declareProperty("PrintSteps",m_config.PrintSteps);
     declareProperty("VerboseLevel", m_config.VerboseLevel);
@@ -35,12 +34,15 @@ namespace G4UA
   {
     ATH_MSG_DEBUG("finalize");
 
-    mergeReports();
+    // Accumulate the results across threads
+    LooperKiller::Report report;
+    m_actions.accumulate(report, &LooperKiller::getReport,
+                         &LooperKiller::Report::merge);
 
     ATH_MSG_INFO( "******* Report from "<< name()<< " *******");
     ATH_MSG_INFO(" Set to kill tracks over " << m_config.MaxSteps << " steps");
     ATH_MSG_INFO(" and give " << m_config.PrintSteps << " steps of verbose output");
-    ATH_MSG_INFO(" We killed " << m_report.killed_tracks << " tracks this run.");
+    ATH_MSG_INFO(" We killed " << report.killed_tracks << " tracks this run.");
     ATH_MSG_INFO(" Was set to " << (m_config.AbortEvent?"":"not ") << "abort events and ");
     ATH_MSG_INFO( (m_config.SetError?"":"not ") << "set an error state." );
 
@@ -52,10 +54,12 @@ namespace G4UA
   // Create the action on request
   //---------------------------------------------------------------------------
   std::unique_ptr<LooperKiller>
-  LooperKillerTool::makeAction()
+  LooperKillerTool::makeAndFillAction(G4AtlasUserActions& actionList)
   {
-    ATH_MSG_DEBUG("makeAction");
-    return std::make_unique<LooperKiller>(m_config);
+    ATH_MSG_DEBUG("Making a LooperKiller action");
+    auto action =  std::make_unique<LooperKiller>(m_config);
+    actionList.steppingActions.push_back( action.get() );
+    return action;
   }
 
 }
diff --git a/Simulation/G4Utilities/G4UserActions/src/MomentumConservationTool.cxx b/Simulation/G4Utilities/G4UserActions/src/MomentumConservationTool.cxx
index c11db30199282b8d79a56f23c509c711d33b7c42..1f6776449c298b34fa85c91074b526462727c18f 100644
--- a/Simulation/G4Utilities/G4UserActions/src/MomentumConservationTool.cxx
+++ b/Simulation/G4Utilities/G4UserActions/src/MomentumConservationTool.cxx
@@ -11,16 +11,19 @@ namespace G4UA
   MomentumConservationTool::MomentumConservationTool(const std::string& type,
                                                      const std::string& name,
                                                      const IInterface* parent)
-    : ActionToolBase<MomentumConservation>(type, name, parent)
+    : UserActionToolBase<MomentumConservation>(type, name, parent)
   {
-    declareInterface<IG4EventActionTool>(this);
-    declareInterface<IG4SteppingActionTool>(this);
   }
 
   //---------------------------------------------------------------------------
-  std::unique_ptr<MomentumConservation>  MomentumConservationTool::makeAction(){
-    ATH_MSG_DEBUG("makeAction");
-    return std::make_unique<MomentumConservation>();
+  std::unique_ptr<MomentumConservation>
+  MomentumConservationTool::makeAndFillAction(G4AtlasUserActions& actionList)
+  {
+    ATH_MSG_DEBUG("Making a MomentumConservation action");
+    auto action = std::make_unique<MomentumConservation>();
+    actionList.eventActions.push_back( action.get() );
+    actionList.steppingActions.push_back( action.get() );
+    return action;
   }
 
 } // namespace G4UA
diff --git a/Simulation/G4Utilities/G4UserActions/src/PhotonKillerTool.cxx b/Simulation/G4Utilities/G4UserActions/src/PhotonKillerTool.cxx
index aae9470c18ed5141a6e37a81202a02717b8a93ac..7529549f82b865a22a761050e6c897897166c082 100644
--- a/Simulation/G4Utilities/G4UserActions/src/PhotonKillerTool.cxx
+++ b/Simulation/G4Utilities/G4UserActions/src/PhotonKillerTool.cxx
@@ -11,17 +11,19 @@ namespace G4UA
   PhotonKillerTool::PhotonKillerTool(const std::string& type,
                                      const std::string& name,
                                      const IInterface* parent)
-    : ActionToolBase<PhotonKiller>(type, name, parent)
+    : UserActionToolBase<PhotonKiller>(type, name, parent)
   {
-    declareInterface<IG4SteppingActionTool>(this);
-    declareInterface<IG4TrackingActionTool>(this);
   }
 
   //---------------------------------------------------------------------------
-  std::unique_ptr<PhotonKiller> PhotonKillerTool::makeAction()
+  std::unique_ptr<PhotonKiller>
+  PhotonKillerTool::makeAndFillAction(G4AtlasUserActions& actionList)
   {
     ATH_MSG_DEBUG("Making a PhotonKiller action");
-    return std::make_unique<PhotonKiller>();
+    auto action = std::make_unique<PhotonKiller>();
+    actionList.trackingActions.push_back( action.get() );
+    actionList.steppingActions.push_back( action.get() );
+    return action;
   }
 
 } // namespace G4UA
diff --git a/Simulation/G4Utilities/G4UserActions/src/ScoringPlaneTool.cxx b/Simulation/G4Utilities/G4UserActions/src/ScoringPlaneTool.cxx
index 073c72ebc4b167cac68faf9ebe3b5ca943292a9c..c3692a0722899a3b76f5d81f6b12ff4e74347b5a 100644
--- a/Simulation/G4Utilities/G4UserActions/src/ScoringPlaneTool.cxx
+++ b/Simulation/G4Utilities/G4UserActions/src/ScoringPlaneTool.cxx
@@ -11,20 +11,22 @@ namespace G4UA
   ScoringPlaneTool::ScoringPlaneTool(const std::string& type,
                                      const std::string& name,
                                      const IInterface* parent)
-    : ActionToolBase<ScoringPlane>(type, name, parent)
+    : UserActionToolBase<ScoringPlane>(type, name, parent)
   {
-    declareInterface<IG4RunActionTool>(this);
-    declareInterface<IG4SteppingActionTool>(this);
-    declareInterface<IG4EventActionTool>(this);
     declareProperty("Plane", m_config.plane);
     declareProperty("PKill", m_config.pkill);
     declareProperty("FName", m_config.fname);
   }
 
-  std::unique_ptr<ScoringPlane> ScoringPlaneTool::makeAction()
+  std::unique_ptr<ScoringPlane>
+  ScoringPlaneTool::makeAndFillAction(G4AtlasUserActions& actionList)
   {
-    ATH_MSG_DEBUG("makeAction");
-    return std::make_unique<ScoringPlane>(m_config);
+    ATH_MSG_DEBUG("Making a ScoringPlane action");
+    auto action = std::make_unique<ScoringPlane>(m_config);
+    actionList.runActions.push_back( action.get() );
+    actionList.eventActions.push_back( action.get() );
+    actionList.steppingActions.push_back( action.get() );
+    return action;
   }
 
 } // namespace G4UA
diff --git a/Simulation/G4Utilities/G4UserActions/src/ScoringVolumeTrackKillerTool.cxx b/Simulation/G4Utilities/G4UserActions/src/ScoringVolumeTrackKillerTool.cxx
index 48ffecba065a478ac3f9a8876885ce8143533c08..c1659f9273817eb0e29cc77903d55ccc010a6c88 100644
--- a/Simulation/G4Utilities/G4UserActions/src/ScoringVolumeTrackKillerTool.cxx
+++ b/Simulation/G4Utilities/G4UserActions/src/ScoringVolumeTrackKillerTool.cxx
@@ -11,18 +11,19 @@ namespace G4UA
   ScoringVolumeTrackKillerTool::ScoringVolumeTrackKillerTool(const std::string& type,
                                                              const std::string& name,
                                                              const IInterface* parent)
-    : ActionToolBase<ScoringVolumeTrackKiller>(type, name, parent)
+    : UserActionToolBase<ScoringVolumeTrackKiller>(type, name, parent)
   {
-    declareInterface<IG4EventActionTool>(this);
-    declareInterface<IG4SteppingActionTool>(this);
   }
 
   //---------------------------------------------------------------------------
   std::unique_ptr<ScoringVolumeTrackKiller>
-  ScoringVolumeTrackKillerTool::makeAction()
+  ScoringVolumeTrackKillerTool::makeAndFillAction(G4AtlasUserActions& actionList)
   {
-    ATH_MSG_DEBUG("makeAction");
-    return std::make_unique<ScoringVolumeTrackKiller>();
+    ATH_MSG_DEBUG("Making a ScoringVolumeTrackKiller action");
+    auto action = std::make_unique<ScoringVolumeTrackKiller>();
+    actionList.eventActions.push_back( action.get() );
+    actionList.steppingActions.push_back( action.get() );
+    return action;
   }
 
 } // namespace G4UA
diff --git a/Simulation/G4Utilities/G4UserActions/src/StoppedParticleActionTool.cxx b/Simulation/G4Utilities/G4UserActions/src/StoppedParticleActionTool.cxx
index 937926e4aee427c732fb3036d09453283137ee42..b0c95ae15962e1a6bdec7b65b1f8f1a74f0587c7 100644
--- a/Simulation/G4Utilities/G4UserActions/src/StoppedParticleActionTool.cxx
+++ b/Simulation/G4Utilities/G4UserActions/src/StoppedParticleActionTool.cxx
@@ -11,16 +11,18 @@ namespace G4UA
   StoppedParticleActionTool::StoppedParticleActionTool(const std::string& type,
                                                        const std::string& name,
                                                        const IInterface* parent)
-    : ActionToolBase<StoppedParticleAction>(type, name, parent)
+    : UserActionToolBase<StoppedParticleAction>(type, name, parent)
   {
-    declareInterface<IG4SteppingActionTool>(this);
   }
 
   //---------------------------------------------------------------------------
-  std::unique_ptr<StoppedParticleAction> StoppedParticleActionTool::makeAction()
+  std::unique_ptr<StoppedParticleAction>
+  StoppedParticleActionTool::makeAndFillAction(G4AtlasUserActions& actionList)
   {
-    ATH_MSG_DEBUG("makeAction");
-    return std::make_unique<StoppedParticleAction>();
+    ATH_MSG_DEBUG("Making a StoppedParticleAction");
+    auto action = std::make_unique<StoppedParticleAction>();
+    actionList.steppingActions.push_back( action.get() );
+    return action;
   }
 
 } // namespace G4UA
diff --git a/Simulation/G4Utilities/G4UserActions/src/TestActionTool.cxx b/Simulation/G4Utilities/G4UserActions/src/TestActionTool.cxx
index 0f6eae841c7544a1d9e924bfd68e8a2ab4ddc42b..0e5c53aea3d2210db2eb3b317a5d9cc8a54569db 100644
--- a/Simulation/G4Utilities/G4UserActions/src/TestActionTool.cxx
+++ b/Simulation/G4Utilities/G4UserActions/src/TestActionTool.cxx
@@ -89,7 +89,8 @@ namespace G4UA
 
     // Accumulate results across threads
     TestAction::Report results;
-    m_actions.accumulate(results, &TestAction::getReport, &TestAction::Report::merge);
+    m_actions.accumulate(results, &TestAction::getReport,
+                         &TestAction::Report::merge);
     ATH_MSG_INFO("Final accumulated results: " <<
                  results.numEvent << " events processed, " <<
                  results.numStep << " steps processed");