diff --git a/Simulation/G4Atlas/G4AtlasApps/python/SimConfigFlags.py b/Simulation/G4Atlas/G4AtlasApps/python/SimConfigFlags.py
index 51d3efbd297b60bc56119c115a2dcab55b54a7fc..e807a507c54dec12c50b788ed6bed0d62acd665d 100644
--- a/Simulation/G4Atlas/G4AtlasApps/python/SimConfigFlags.py
+++ b/Simulation/G4Atlas/G4AtlasApps/python/SimConfigFlags.py
@@ -95,5 +95,15 @@ def createSimConfigFlags():
     scf.addFlag("Sim.FastChain.PUWeights_lar_hec", [1.0]) # LAr HEC
     scf.addFlag("Sim.FastChain.PUWeights_lar_bapre", [1.0]) # LAr Barrel presampler
     scf.addFlag("Sim.FastChain.PUWeights_tile", [1.0]) # Tile
+    
+    # Fatras
+    scf.addFlag("Sim.Fatras.RandomStreamName", "FatrasRnd")
+    scf.addFlag("Sim.Fatras.G4RandomStreamName", "FatrasG4")
+    scf.addFlag("Sim.Fatras.TrkExRandomStreamName", "TrkExRnd")
+    # Fatras fine tuning
+    scf.addFlag("Sim.Fatras.MomCutOffSec", 50.) # common momentum cut-off for secondaries
+    scf.addFlag("Sim.Fatras.HadronIntProb", 1.) # hadronic interaction scale factor
+    scf.addFlag("Sim.Fatras.GaussianMixtureModel", True) # use Gaussian mixture model for Multiple Scattering
+    scf.addFlag("Sim.Fatras.BetheHeitlerScale", 1.) # scale to Bethe-Heitler contribution
 
     return scf
diff --git a/Simulation/ISF/ISF_Core/ISF_Tools/python/ISF_ToolsConfigNew.py b/Simulation/ISF/ISF_Core/ISF_Tools/python/ISF_ToolsConfigNew.py
index b985690499a3fa81502c990370cb3ef0d3709ee2..a06608032d58c8ef9e501ca75e392a37dfb4c844 100644
--- a/Simulation/ISF/ISF_Core/ISF_Tools/python/ISF_ToolsConfigNew.py
+++ b/Simulation/ISF/ISF_Core/ISF_Tools/python/ISF_ToolsConfigNew.py
@@ -11,7 +11,7 @@ from BarcodeServices.BarcodeServicesConfigNew import BarcodeSvcCfg
 def ParticleHelperCfg(flags, name="ISF_ParticleHelper", **kwargs):
     acc = BarcodeSvcCfg(flags)
     kwargs.setdefault("BarcodeSvc", acc.getPrimary())
-    acc.setPrivateTools(CompFactory.ISF.ParticleHelper(name, **kwargs))
+    acc.addPublicTool(CompFactory.ISF.ParticleHelper(name, **kwargs))
     return acc
 
 
diff --git a/Simulation/ISF/ISF_Fatras/ISF_FatrasServices/python/ISF_FatrasConfig.py b/Simulation/ISF/ISF_Fatras/ISF_FatrasServices/python/ISF_FatrasConfig.py
index 8916d22761bad1fd1257aa56ba2717ac34b4707b..5444dd2e3555772700b37ed5d1f75f1ba3343750 100644
--- a/Simulation/ISF/ISF_Fatras/ISF_FatrasServices/python/ISF_FatrasConfig.py
+++ b/Simulation/ISF/ISF_Fatras/ISF_FatrasServices/python/ISF_FatrasConfig.py
@@ -6,6 +6,12 @@ from AthenaCommon.Logging import logging
 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
 from AthenaConfiguration.ComponentFactory import CompFactory
 from ISF_Algorithms.collection_merger_helpers import generate_mergeable_collection_name
+from ISF_Tools.ISF_ToolsConfigNew import ParticleHelperCfg
+from ISF_Services.ISF_ServicesCoreConfigNew import (
+    ParticleBrokerSvcCfg, TruthServiceCfg,
+)
+from RngComps.RandomServices import RNG
+from TrkConfig.AtlasTrackingGeometrySvcConfig import TrackingGeometrySvcCfg
 
 ################################################################################
 # HIT CREATION SECTION
@@ -20,12 +26,15 @@ def fatrasHitCreatorPixelCfg(flags, name="ISF_FatrasHitCreatorPixel", **kwargs):
     mlog = logging.getLogger(name)
     mlog.debug('Start configuration')
 
-    acc = ComponentAccumulator()
+    result = ComponentAccumulator()
 
     hits_collection_name = generate_mergeable_collection_name(bare_collection_name="PixelHits",
                                                               mergeable_collection_suffix="_Fatras",
                                                               merger_input_property="PixelHits")
 
+    result.merge(RNG(flags.Random.Engine))
+    kwargs.setdefault("RandomNumberService", result.getService("AthRNGSvc"))
+    kwargs.setdefault("RandomStreamName", flags.Sim.Fatras.RandomStreamName)
     kwargs.setdefault("IdHelperName", 'PixelID')
     kwargs.setdefault("CollectionName", hits_collection_name)
 
@@ -34,8 +43,8 @@ def fatrasHitCreatorPixelCfg(flags, name="ISF_FatrasHitCreatorPixel", **kwargs):
     kwargs.setdefault("UseConditionsTool", False)
 
     iFatras__HitCreatorSilicon = CompFactory.iFatras.HitCreatorSilicon
-    acc.addPublicTool(iFatras__HitCreatorSilicon(name=name, **kwargs))
-    return acc
+    result.addPublicTool(iFatras__HitCreatorSilicon(name=name, **kwargs))
+    return result
 
 
 def fatrasHitCreatorSCTCfg(flags, name="ISF_FatrasHitCreatorSCT", **kwargs):
@@ -43,34 +52,59 @@ def fatrasHitCreatorSCTCfg(flags, name="ISF_FatrasHitCreatorSCT", **kwargs):
     mlog = logging.getLogger(name)
     mlog.debug('Start configuration')
 
-    acc = ComponentAccumulator()
+    result = ComponentAccumulator()
 
     hits_collection_name = generate_mergeable_collection_name(bare_collection_name="SCT_Hits",
                                                               mergeable_collection_suffix="_Fatras",
                                                               merger_input_property="SCTHits")
+    result.merge(RNG(flags.Random.Engine))
+    kwargs.setdefault("RandomNumberService", result.getService("AthRNGSvc"))
+    kwargs.setdefault("RandomStreamName", flags.Sim.Fatras.RandomStreamName)
     kwargs.setdefault("IdHelperName", 'SCT_ID')
     kwargs.setdefault("CollectionName", hits_collection_name)
     kwargs.setdefault("UseConditionsTool", False)
 
     iFatras__HitCreatorSilicon = CompFactory.iFatras.HitCreatorSilicon
-    acc.addPublicTool(iFatras__HitCreatorSilicon(name=name, **kwargs))
-    return acc
+    result.addPublicTool(iFatras__HitCreatorSilicon(name=name, **kwargs))
+    return result
 
 
 def fatrasHitCreatorTRTCfg(flags, name="ISF_FatrasHitCreatorTRT", **kwargs):
+    """Return ISF_FatrasHitCreatorTRT configured with ComponentAccumulator"""
     mlog = logging.getLogger(name)
     mlog.debug('Start configuration')
 
-    acc = ComponentAccumulator()
+    result = ComponentAccumulator()
 
     hits_collection_name = generate_mergeable_collection_name(bare_collection_name="TRTUncompressedHits",
                                                               mergeable_collection_suffix="_Fatras",
                                                               merger_input_property="TRTUncompressedHits")
+    result.merge(RNG(flags.Random.Engine))
+    kwargs.setdefault("RandomNumberService", result.getService("AthRNGSvc"))
+    kwargs.setdefault("RandomStreamName", flags.Sim.Fatras.RandomStreamName)
     kwargs.setdefault("CollectionName", hits_collection_name)
 
     iFatras__HitCreatorTRT = CompFactory.iFatras.HitCreatorTRT
-    acc.addPublicTool(iFatras__HitCreatorTRT(name=name, **kwargs))
-    return acc
+    result.addPublicTool(iFatras__HitCreatorTRT(name=name, **kwargs))
+    return result
+
+
+def fatrasPileupHitCreatorPixelCfg(flags, name="ISF_FatrasPileupHitCreatorPixel", **kwargs):
+    """Return ISF_FatrasHitCreatorPixel configured for pileup with ComponentAccumulator"""
+    kwargs.setdefault("CollectionName", "PileupPixelHits")
+    return fatrasHitCreatorPixelCfg(flags, name, **kwargs)
+
+
+def fatrasPileupHitCreatorSCTCfg(flags, name="ISF_FatrasPileupHitCreatorSCT", **kwargs):
+    """Return ISF_FatrasHitCreatorSCT configured for pileup with ComponentAccumulator"""
+    kwargs.setdefault("CollectionName", "PileupSCT_Hits")
+    return fatrasHitCreatorSCTCfg(flags, name, **kwargs)
+
+
+def fatrasPileupHitCreatorTRTCfg(flags, name="ISF_FatrasPileupHitCreatorTRT", **kwargs):
+    """Return ISF_FatrasHitCreatorTRT configured with ComponentAccumulator"""
+    kwargs.setdefault("CollectionName", "PileupTRTUncompressedHits")
+    return fatrasHitCreatorTRTCfg(flags, name, **kwargs)
 
 
 ################################################################################
@@ -100,13 +134,39 @@ def fatrasSimHitCreatorIDCfg(flags, name="ISF_FatrasSimHitCreatorID", **kwargs):
     result.merge(acc)
     kwargs.setdefault("TrtHitCreator", trt_hit_cfg)
 
-    kwargs.setdefault("OutputLevel", 3)
+    kwargs.setdefault("OutputLevel", flags.Exec.OutputLevel)
 
     iFatras__SimHitCreatorID = CompFactory.iFatras.SimHitCreatorID
     result.addPublicTool(iFatras__SimHitCreatorID(name=name, **kwargs))
     return result
 
 
+def fatrasPileupSimHitCreatorIDCfg(flags, name="ISF_FatrasPileupSimHitCreatorID", **kwargs):
+    """Return ISF_FatrasSimHitCreatorID configured for pileup with ComponentAccumulator"""
+
+    mlog = logging.getLogger(name)
+    mlog.debug('Start configuration')
+
+    result = ComponentAccumulator()
+
+    acc = fatrasPileupHitCreatorPixelCfg(flags)
+    pixel_hit_cfg = acc.getPublicTool('ISF_FatrasHitCreatorPixel')
+    result.merge(acc)
+    kwargs.setdefault("PixelHitCreator", pixel_hit_cfg)
+
+    acc = fatrasPileupHitCreatorSCTCfg(flags)
+    sct_hit_cfg = acc.getPublicTool('ISF_FatrasHitCreatorSCT')
+    result.merge(acc)
+    kwargs.setdefault("SctHitCreator", sct_hit_cfg)
+
+    acc = fatrasPileupHitCreatorTRTCfg(flags)
+    trt_hit_cfg = acc.getPublicTool("ISF_FatrasHitCreatorTRT")
+    result.merge(acc)
+    kwargs.setdefault("TrtHitCreator", trt_hit_cfg)
+
+    return fatrasSimHitCreatorIDCfg(flags, name, **kwargs)
+
+
 def fatrasSimHitCreatorMSCfg(flags, name="ISF_FatrasSimHitCreatorMS", **kwargs):
     """Return ISF_FatrasSimHitCreatorMS configured with ComponentAccumulator"""
 
@@ -132,9 +192,11 @@ def fatrasSimHitCreatorMSCfg(flags, name="ISF_FatrasSimHitCreatorMS", **kwargs):
     csc_hits_collection_name = generate_mergeable_collection_name(bare_collection_name="CSC_Hits",
                                                                   mergeable_collection_suffix=mergeable_collection_suffix,
                                                                   merger_input_property="CSCHits")
-
+    result.merge(RNG(flags.Random.Engine))
+    kwargs.setdefault("RandomNumberService", result.getService("AthRNGSvc"))
+    kwargs.setdefault("RandomStreamName", flags.Sim.Fatras.RandomStreamName)
     #####
-    # Extrapolator from ACTS to be added
+    # Extrapolator from ACTS to be added TODO
     # kwargs.setdefault("Extrapolator" , getPublicTool('ISF_FatrasExtrapolator'))
     #####
     kwargs.setdefault("MDTCollectionName", mdt_hits_collection_name)
@@ -192,23 +254,20 @@ def G4RunManagerHelperCfg(flags, name="ISF_G4RunManagerHelper", **kwargs):
     return result
 
 
-def fatrasParticleHelperCfg(flags, name="ISF_ParticleHelper", **kwargs):
+def fatrasParticleDecayHelperCfg(flags, name="ISF_FatrasParticleDecayHelper", **kwargs):
     mlog = logging.getLogger(name)
     mlog.debug('Start configuration')
 
     result = ComponentAccumulator()
 
-    ISF__ParticleHelper = CompFactory.ISF.ParticleHelper
-    result.addPublicTool(ISF__ParticleHelper(name=name, **kwargs))
-
-    return result
+    result.merge(RNG(flags.Random.Engine))
+    kwargs.setdefault("RandomNumberService", result.getService("AthRNGSvc"))
+    kwargs.setdefault("RandomStreamName", flags.Sim.Fatras.RandomStreamName)
+    kwargs.setdefault("G4RandomStreamName", flags.Sim.Fatras.G4RandomStreamName)
+    kwargs.setdefault("ValidationMode", flags.Sim.ISF.ValidationMode)
 
-
-def fatrasParticleDecayHelperCfg(flags, name="ISF_FatrasParticleDecayHelper", **kwargs):
-    mlog = logging.getLogger(name)
-    mlog.debug('Start configuration')
-
-    result = ComponentAccumulator()
+    result.merge(ParticleBrokerSvcCfg(flags))
+    kwargs.setdefault("ParticleBroker", result.getService("ISF_ParticleBrokerSvc"))
 
     acc = fatrasPdgG4ParticleCfg(flags)
     pdg_g4part_cfg = acc.getPublicTool('ISF_FatrasPdgG4Particle')
@@ -223,13 +282,14 @@ def fatrasParticleDecayHelperCfg(flags, name="ISF_FatrasParticleDecayHelper", **
     acc = G4RunManagerHelperCfg(flags)
     g4run_man_cfg = acc.getPublicTool('ISF_G4RunManagerHelper')
     result.merge(acc)
-    kwargs.setdefault("PDGToG4ParticleConverter", g4run_man_cfg)
+    kwargs.setdefault("G4RunManagerHelper", g4run_man_cfg)
 
     iFatras__G4ParticleDecayHelper = CompFactory.iFatras.G4ParticleDecayHelper
     result.addPublicTool(iFatras__G4ParticleDecayHelper(name=name, **kwargs))
 
     return result
 
+
 ################################################################################
 # Extrapolator
 ################################################################################
@@ -238,9 +298,8 @@ def fatrasNavigatorCfg(flags, name="ISF_FatrasNavigator", **kwargs):
     mlog = logging.getLogger(name)
     mlog.debug('Start configuration')
 
-    result = ComponentAccumulator()    
+    result = ComponentAccumulator()
 
-    from TrkConfig.AtlasTrackingGeometrySvcConfig import TrackingGeometrySvcCfg
     acc = TrackingGeometrySvcCfg(flags)
     kwargs.setdefault("TrackingGeometrySvc", acc.getPrimary())
     result.merge(acc)
@@ -250,32 +309,178 @@ def fatrasNavigatorCfg(flags, name="ISF_FatrasNavigator", **kwargs):
 
     return result
 
+
+def fatrasNeutralPropagatorIDCfg(flags, name="ISF_FatrasNeutralPropagatorID", **kwargs):
+    mlog = logging.getLogger(name)
+    mlog.debug('Start configuration')
+
+    result = ComponentAccumulator()
+    
+    Trk__StraightLinePropagator = CompFactory.Trk.StraightLinePropagator
+    result.addPublicTool(Trk__StraightLinePropagator(name=name, **kwargs))
+    
+    return result
+
+
+def fatrasPropagatorCfg(flags, name="ISF_FatrasPropagator", **kwargs):
+    mlog = logging.getLogger(name)
+    mlog.debug('Start configuration')
+
+    result = ComponentAccumulator()
+    
+    Trk__RungeKuttaPropagator = CompFactory.Trk.RungeKuttaPropagator
+    result.addPublicTool(Trk__RungeKuttaPropagator(name=name, **kwargs))
+    
+    return result
+
+
+# from the Propagator create a Propagation engine to handle path length
+def fatrasStaticPropagatorCfg(flags, name="ISF_FatrasStaticPropagator", **kwargs):
+    mlog = logging.getLogger(name)
+    mlog.debug('Start configuration')
+
+    result = ComponentAccumulator()
+    
+    result.merge(fatrasPropagatorCfg(flags))
+    kwargs.setdefault("Propagator", result.getPublicTool("ISF_FatrasPropagator"))
+    
+    # configure output formatting
+    kwargs.setdefault("OutputPrefix", "[SP] - ")
+    kwargs.setdefault("OutputPostfix", " - ")
+    kwargs.setdefault("OutputLevel", flags.Exec.OutputLevel)
+    
+    Trk__PropagationEngine = CompFactory.Trk.PropagationEngine
+    result.addPublicTool(Trk__PropagationEngine(name, **kwargs))
+    
+    return result
+
+
+# load the static navigation engine
+def fatrasStaticNavigationEngineCfg(flags, name="ISF_FatrasStaticNavigationEngine", **kwargs):
+    mlog = logging.getLogger(name)
+    mlog.debug('Start configuration')
+
+    result = ComponentAccumulator()
+
+    result.merge(fatrasStaticPropagatorCfg(flags))
+    kwargs.setdefault("PropagationEngine", result.getPublicTool("ISF_FatrasStaticPropagator"))
+    result.merge(fatrasMaterialEffectsEngineCfg(flags))
+    kwargs.setdefault("MaterialEffectsEngine", result.getPublicTool("ISF_FatrasMaterialEffectsEngine"))
+    acc = TrackingGeometrySvcCfg(flags)
+    kwargs.setdefault("TrackingGeometrySvc", acc.getPrimary())
+    result.merge(acc)
+    
+    # configure output formatting
+    kwargs.setdefault("OutputPrefix", "[SN] - ")
+    kwargs.setdefault("OutputPostfix", " - ")
+    kwargs.setdefault("OutputLevel", flags.Exec.OutputLevel)
+    Trk__StaticNavigationEngine = CompFactory.Trk.StaticNavigationEngine
+    acc.setPrivateTools(Trk__StaticNavigationEngine(name, **kwargs))
+    return acc
+
+
 def fatrasEnergyLossUpdatorCfg(flags, name="ISF_FatrasEnergyLossUpdator", **kwargs):
     mlog = logging.getLogger(name)
     mlog.debug('Start configuration')
 
     result = ComponentAccumulator()
 
+    result.merge(RNG(flags.Random.Engine))
+    kwargs.setdefault("RandomNumberService", result.getService("AthRNGSvc"))
+    kwargs.setdefault("RandomStreamName", flags.Sim.Fatras.RandomStreamName)
+
     kwargs.setdefault("UsePDG_EnergyLossFormula", True)
     kwargs.setdefault("EnergyLossDistribution", 2)
-    
+
     iFatras__McEnergyLossUpdator = CompFactory.iFatras.McEnergyLossUpdator
     result.addPublicTool(iFatras__McEnergyLossUpdator(name=name, **kwargs))
 
     return result
 
+
+def fatrasEnergyLossSamplerBetheHeitlerCfg(flags, name="ISF_FatrasEnergyLossSamplerBetheHeitler", **kwargs):
+    mlog = logging.getLogger(name)
+    mlog.debug('Start configuration')
+
+    result = ComponentAccumulator()
+
+    result.merge(RNG(flags.Random.Engine))
+    kwargs.setdefault("RandomNumberService", result.getService("AthRNGSvc"))
+    kwargs.setdefault("RandomStreamName", flags.Sim.Fatras.RandomStreamName)
+
+    kwargs.setdefault("ScaleFactor", flags.Sim.Fatras.BetheHeitlerScale)
+
+    iFatras__EnergyLossSamplerBetheHeitler = CompFactory.iFatras.EnergyLossSamplerBetheHeitler
+    result.addPublicTool(iFatras__EnergyLossSamplerBetheHeitler(name=name, **kwargs))
+
+    return result
+
+
 def fatrasMultipleScatteringUpdatorCfg(flags, name="ISF_FatrasMultipleScatteringUpdator", **kwargs):
     mlog = logging.getLogger(name)
     mlog.debug('Start configuration')
 
     result = ComponentAccumulator()
-    kwargs.setdefault("GaussianMixtureModel", True)
+
+    result.merge(RNG(flags.Random.Engine))
+    kwargs.setdefault("RandomNumberService", result.getService("AthRNGSvc"))
+    kwargs.setdefault("RandomStreamName", flags.Sim.Fatras.TrkExRandomStreamName)
+    kwargs.setdefault("GaussianMixtureModel", flags.Sim.Fatras.GaussianMixtureModel)
 
     Trk__MultipleScatteringUpdator = CompFactory.Trk.MultipleScatteringUpdator
     result.addPublicTool(Trk__MultipleScatteringUpdator(name=name, **kwargs))
 
     return result
 
+
+def fatrasMultipleScatteringSamplerHighlandCfg(flags, name="ISF_MultipleScatteringSamplerHighland", **kwargs):
+    mlog = logging.getLogger(name)
+    mlog.debug('Start configuration')
+
+    result = ComponentAccumulator()
+
+    result.merge(RNG(flags.Random.Engine))
+    kwargs.setdefault("RandomNumberService", result.getService("AthRNGSvc"))
+    kwargs.setdefault("RandomStreamName", flags.Sim.Fatras.TrkExRandomStreamName)
+
+    Trk__MultipleScatteringSamplerHighland = CompFactory.Trk.MultipleScatteringSamplerHighland
+    result.addPublicTool(Trk__MultipleScatteringSamplerHighland(name=name, **kwargs))
+
+    return result
+
+
+def fatrasMultipleScatteringSamplerGaussianMixtureCfg(flags, name="ISF_MultipleScatteringSamplerGaussianMixture", **kwargs):
+    mlog = logging.getLogger(name)
+    mlog.debug('Start configuration')
+
+    result = ComponentAccumulator()
+
+    result.merge(RNG(flags.Random.Engine))
+    kwargs.setdefault("RandomNumberService", result.getService("AthRNGSvc"))
+    kwargs.setdefault("RandomStreamName", flags.Sim.Fatras.TrkExRandomStreamName)
+
+    Trk__MultipleScatteringSamplerGaussianMixture = CompFactory.Trk.MultipleScatteringSamplerGaussianMixture
+    result.addPublicTool(Trk__MultipleScatteringSamplerGaussianMixture(name=name, **kwargs))
+
+    return result
+
+
+def fatrasMultipleScatteringSamplerGeneralMixtureCfg(flags, name="ISF_MultipleScatteringSamplerGeneralMixture", **kwargs):
+    mlog = logging.getLogger(name)
+    mlog.debug('Start configuration')
+
+    result = ComponentAccumulator()
+
+    result.merge(RNG(flags.Random.Engine))
+    kwargs.setdefault("RandomNumberService", result.getService("AthRNGSvc"))
+    kwargs.setdefault("RandomStreamName", flags.Sim.Fatras.TrkExRandomStreamName)
+
+    Trk__MultipleScatteringSamplerGeneralMixture = CompFactory.Trk.MultipleScatteringSamplerGeneralMixture
+    result.addPublicTool(Trk__MultipleScatteringSamplerGeneralMixture(name=name, **kwargs))
+
+    return result
+
+
 # Combining all in the MaterialEffectsUpdator
 def fatrasMaterialUpdatorCfg(flags, name="ISF_FatrasMaterialUpdator", **kwargs):
     mlog = logging.getLogger(name)
@@ -283,12 +488,15 @@ def fatrasMaterialUpdatorCfg(flags, name="ISF_FatrasMaterialUpdator", **kwargs):
 
     result = ComponentAccumulator()
 
+    result.merge(RNG(flags.Random.Engine))
+    kwargs.setdefault("RandomNumberService", result.getService("AthRNGSvc"))
+    kwargs.setdefault("RandomStreamName", flags.Sim.Fatras.RandomStreamName)
+
     # Geometry Svc
-    from TrkConfig.AtlasTrackingGeometrySvcConfig import TrackingGeometrySvcCfg
     acc = TrackingGeometrySvcCfg(flags)
     kwargs.setdefault("TrackingGeometrySvc", acc.getPrimary())
     result.merge(acc)
-    
+
     # hadronic interactions
     kwargs.setdefault("HadronicInteraction", True)
     acc = fatrasG4HadIntProcessorCfg(flags)
@@ -315,10 +523,14 @@ def fatrasMaterialUpdatorCfg(flags, name="ISF_FatrasMaterialUpdator", **kwargs):
     ph_conv_cfg = acc.getPublicTool('ISF_FatrasConversionCreator')
     result.merge(acc)
     kwargs.setdefault("PhotonConversionTool", ph_conv_cfg)
-  
+
     # the validation output
-    ##  NOTE to be checked
-    ###  kwargs.setdefault("ValidationMode", ISF_Flags.ValidationMode())
+    kwargs.setdefault("ValidationMode", flags.Sim.ISF.ValidationMode)
+    kwargs.setdefault("BremPhotonValidation", False)
+    kwargs.setdefault("EnergyDepositValidation", False)
+
+    kwargs.setdefault("MomentumCut", flags.Sim.Fatras.MomCutOffSec)
+    kwargs.setdefault("MinimumBremPhotonMomentum", flags.Sim.Fatras.MomCutOffSec)
 
     acc = fatrasPhysicsValidationToolCfg(flags)
     phys_val_cfg = acc.getPublicTool('ISF_FatrasPhysicsValidationTool')
@@ -335,12 +547,82 @@ def fatrasMaterialUpdatorCfg(flags, name="ISF_FatrasMaterialUpdator", **kwargs):
     result.merge(acc)
     kwargs.setdefault("ParticleDecayHelper", pdhelper_cfg)
 
+    # MCTruth Process Code
+    kwargs.setdefault("BremProcessCode", 3) # TODO: to be taken from central definition
+    acc = TrackingGeometrySvcCfg(flags)
+    kwargs.setdefault("TrackingGeometrySvc", acc.getPrimary())
+    result.merge(acc)
 
     iFatras__McMaterialEffectsUpdator = CompFactory.iFatras.McMaterialEffectsUpdator
     result.addPublicTool(iFatras__McMaterialEffectsUpdator(name=name, **kwargs))
 
     return result
 
+
+
+def fatrasMaterialEffectsEngineCfg(flags, name="ISF_FatrasMaterialEffectsEngine", **kwargs):
+    mlog = logging.getLogger(name)
+    mlog.debug('Start configuration')
+
+    result = ComponentAccumulator()
+
+    result.merge(RNG(flags.Random.Engine))
+    kwargs.setdefault("RandomNumberService", result.getService("AthRNGSvc"))
+    kwargs.setdefault("RandomStreamName", flags.Sim.Fatras.RandomStreamName)
+
+    result.merge(ParticleBrokerSvcCfg(flags))
+    kwargs.setdefault("ParticleBroker", result.getService("ISF_ParticleBrokerSvc"))
+    
+    acc = TruthServiceCfg(flags)
+    kwargs.setdefault("TruthRecordSvc", acc.getPrimary())
+    result.merge(acc)
+    
+    result.merge(fatrasProcessSamplingToolCfg(flags))
+    kwargs.setdefault("ProcessSamplingTool", result.getPublicTool("ISF_FatrasProcessSamplingTool"))
+    
+    result.merge(fatrasParticleDecayHelperCfg(flags))
+    kwargs.setdefault("ParticleDecayHelper", result.getPublicTool("ISF_FatrasParticleDecayHelper"))
+    
+    # energy loss
+    result.merge(fatrasEnergyLossUpdatorCfg(flags))
+    kwargs.setdefault("EnergyLossSampler", result.getPublicTool("ISF_FatrasEnergyLossUpdator"))
+    kwargs.setdefault("EnergyLoss", True)
+    
+    result.merge(fatrasEnergyLossSamplerBetheHeitlerCfg(flags))
+    tool = result.getPublicTool("ISF_FatrasEnergyLossSamplerBetheHeitler")
+    kwargs.setdefault("ElectronEnergyLossSampler", tool)
+    kwargs.setdefault("UseElectronSampler", True)
+    kwargs.setdefault("CreateBremPhotons", True)
+    
+    # multiple scattering
+    result.merge(fatrasMultipleScatteringSamplerHighlandCfg(flags))
+    tool = result.getPublicTool("ISF_MultipleScatteringSamplerHighland")
+    kwargs.setdefault("MultipleScatteringSampler", tool)
+    kwargs.setdefault("MultipleScattering", True)
+    
+    # the properties given throuth the JobProperties interface
+    kwargs.setdefault("MomentumCut", flags.Sim.Fatras.MomCutOffSec)
+    kwargs.setdefault("MinimumBremPhotonMomentum", flags.Sim.Fatras.MomCutOffSec)
+    
+    # MCTruth Process Code
+    kwargs.setdefault("BremProcessCode", 3) # TODO: to be taken from central definition
+    
+    # the validation output
+    result.merge(fatrasPhysicsValidationToolCfg(flags))
+    tool = acc.getPublicTool('ISF_FatrasPhysicsValidationTool')
+    kwargs.setdefault("PhysicsValidationTool", tool)
+    kwargs.setdefault("ValidationMode", flags.Sim.ISF.ValidationMode)
+    
+    kwargs.setdefault("OutputPrefix", "[McME] - ")
+    kwargs.setdefault("OutputPostfix", " - ")
+    kwargs.setdefault("OutputLevel", flags.Exec.OutputLevel)
+    
+    iFatras__McMaterialEffectsEngine = CompFactory.iFatras.McMaterialEffectsEngine
+    result.setPublicTool(iFatras__McMaterialEffectsEngine(name, **kwargs))
+    
+    return result
+
+
 def fatrasChargedPropagatorCfg(flags, name="ISF_FatrasChargedPropagator", **kwargs):
     mlog = logging.getLogger(name)
     mlog.debug('Start configuration')
@@ -357,6 +639,7 @@ def fatrasSTEP_PropagatorCfg(flags, name="ISF_FatrasSTEP_Propagator", **kwargs):
     mlog.debug('Start configuration')
 
     result = ComponentAccumulator()
+    kwargs.setdefault("MomentumCutOff", flags.Sim.Fatras.MomCutOffSec)
     kwargs.setdefault("SimulationMode", True)
 
     acc = fatrasMaterialUpdatorCfg(flags)
@@ -402,6 +685,7 @@ def fatrasExtrapolatorCfg(flags, name="ISF_FatrasExtrapolator", **kwargs):
     # Fatras specific: stop the trajectory
     kwargs.setdefault("StopWithNavigationBreak", True)
     kwargs.setdefault("StopWithUpdateKill", True)
+    kwargs.setdefault("RobustSampling", True)
     kwargs.setdefault("ResolveMuonStation", True)
     kwargs.setdefault("UseMuonMatApproximation", True)
 
@@ -410,6 +694,56 @@ def fatrasExtrapolatorCfg(flags, name="ISF_FatrasExtrapolator", **kwargs):
 
     return result
 
+
+def fatrasStaticExtrapolatorCfg(flags, name="ISF_FatrasStaticExEngine", **kwargs):
+    mlog = logging.getLogger(name)
+    mlog.debug('Start configuration')
+
+    result = ComponentAccumulator()
+    
+    result.merge(fatrasStaticPropagatorCfg(flags))
+    kwargs.setdefault("PropagationEngine", result.getPublicTool("ISF_FatrasStaticPropagator"))
+    result.merge(fatrasMaterialEffectsEngineCfg(flags))
+    kwargs.setdefault("MaterialEffectsEngine", result.getPublicTool("ISF_FatrasMaterialEffectsEngine"))
+    result.merge(fatrasStaticNavigationEngineCfg(flags))
+    kwargs.setdefault("NavigationEngine", result.getPublicTool("ISF_FatrasStaticNavigationEngine"))
+    
+    # configure output formatting
+    kwargs.setdefault("OutputPrefix", "[SE] - ")
+    kwargs.setdefault("OutputPostfix", " - ")
+    kwargs.setdefault("OutputLevel", flags.Exec.OutputLevel)
+    
+    Trk__StaticEngine = CompFactory.Trk.StaticEngine
+    result.setPrivateTools(Trk__StaticEngine(name, **kwargs))
+    return result
+
+
+def fatrasExEngineCfg(flags, name="ISF_FatrasExEngine", **kwargs):
+    # load the tracking geometry service
+    mlog = logging.getLogger(name)
+    mlog.debug('Start configuration')
+
+    result = ComponentAccumulator()
+    
+    # assign the tools
+    result.merge(fatrasStaticExtrapolatorCfg(flags))
+    tool = result.getPublicTool("ISF_FatrasStaticExEngine")
+    kwargs.setdefault("ExtrapolationEngines", [tool])
+    acc = TrackingGeometrySvcCfg(flags)
+    kwargs.setdefault("TrackingGeometrySvc", acc.getPrimary())
+    result.merge(acc)
+    result.merge(fatrasStaticPropagatorCfg(flags))
+    kwargs.setdefault("PropagationEngine", result.getPublicTool("ISF_FatrasStaticPropagator"))
+    
+    # configure output formatting
+    kwargs.setdefault("OutputPrefix", "[ME] - ")
+    kwargs.setdefault("OutputPostfix", " - ")
+    kwargs.setdefault("OutputLevel", flags.Exec.OutputLevel)
+    
+    Trk__ExtrapolationEngine = CompFactory.Trk.ExtrapolationEngine
+    result.setPrivateTools(Trk__ExtrapolationEngine(name, **kwargs))
+    return result
+
 ################################################################################
 # SIMULATION TOOL and SERVICE
 ################################################################################
@@ -421,6 +755,7 @@ def fatrasKinematicFilterCfg(flags, name="ISF_FatrasKinematicFilter", **kwargs):
     result = ComponentAccumulator()
 
     kwargs.setdefault("MaxEtaSymmetric", 10.)
+    kwargs.setdefault("MinMomentum", flags.Sim.Fatras.MomCutOffSec)
 
     ISF__KinematicParticleFilter = CompFactory.ISF.KinematicParticleFilter
     result.addPublicTool(ISF__KinematicParticleFilter(name=name, **kwargs))
@@ -435,11 +770,21 @@ def fatrasConversionCreatorCfg(flags, name="ISF_FatrasConversionCreator", **kwar
 
     result = ComponentAccumulator()
 
+    result.merge(RNG(flags.Random.Engine))
+    kwargs.setdefault("RandomNumberService", result.getService("AthRNGSvc"))
+    kwargs.setdefault("RandomStreamName", flags.Sim.Fatras.RandomStreamName)
+
+    result.merge(ParticleBrokerSvcCfg(flags))
+    kwargs.setdefault("ParticleBroker", result.getService("ISF_ParticleBrokerSvc"))
+
     acc = fatrasPhysicsValidationToolCfg(flags)
     phys_val_cfg = acc.getPublicTool('ISF_FatrasPhysicsValidationTool')
     result.merge(acc)
     kwargs.setdefault("PhysicsValidationTool", phys_val_cfg)
 
+    kwargs.setdefault("PhysicsProcessCode", 14) # TODO: to be taken from central definition
+    kwargs.setdefault("ValidationMode", flags.Sim.ISF.ValidationMode)
+
     iFatras__PhotonConversionTool = CompFactory.iFatras.PhotonConversionTool
     result.addPublicTool(iFatras__PhotonConversionTool(name=name, **kwargs))
 
@@ -452,23 +797,79 @@ def fatrasG4HadIntProcessorCfg(flags, name="ISF_FatrasG4HadIntProcessor", **kwar
 
     result = ComponentAccumulator()
 
-    acc = fatrasPhysicsValidationToolCfg(flags)
-    phys_val_cfg = acc.getPublicTool('ISF_FatrasPhysicsValidationTool')
+    result.merge(RNG(flags.Random.Engine))
+    kwargs.setdefault("RandomNumberService", result.getService("AthRNGSvc"))
+    kwargs.setdefault("RandomStreamName", flags.Sim.Fatras.RandomStreamName)
+
+    result.merge(ParticleBrokerSvcCfg(flags))
+    kwargs.setdefault("ParticleBroker", result.getService("ISF_ParticleBrokerSvc"))
+    
+    acc = TruthServiceCfg(flags)
+    kwargs.setdefault("TruthRecordSvc", acc.getPrimary())
     result.merge(acc)
+
+    result.merge(fatrasPhysicsValidationToolCfg(flags))
+    phys_val_cfg = acc.getPublicTool('ISF_FatrasPhysicsValidationTool')
     kwargs.setdefault("PhysicsValidationTool", phys_val_cfg)
 
+    kwargs.setdefault("ValidationMode", flags.Sim.ISF.ValidationMode)
+    kwargs.setdefault("MomentumCut", flags.Sim.Fatras.MomCutOffSec)
+
     iFatras__G4HadIntProcessor = CompFactory.iFatras.G4HadIntProcessor
     result.addPublicTool(iFatras__G4HadIntProcessor(name=name, **kwargs))
 
     return result
 
 
+#   Fatras Hadronic Interaction Processor
+def fatrasParametricHadIntProcessorCfg(flags, name="ISF_FatrasParametricHadIntProcessor", **kwargs):
+    mlog = logging.getLogger(name)
+    mlog.debug('Start configuration')
+
+    result = ComponentAccumulator()
+
+    result.merge(RNG(flags.Random.Engine))
+    kwargs.setdefault("RandomNumberService", result.getService("AthRNGSvc"))
+    kwargs.setdefault("RandomStreamName", flags.Sim.Fatras.RandomStreamName)
+    
+    result.merge(ParticleBrokerSvcCfg(flags))
+    kwargs.setdefault("ParticleBroker", result.getService("ISF_ParticleBrokerSvc"))
+    
+    acc = TruthServiceCfg(flags)
+    kwargs.setdefault("TruthRecordSvc", acc.getPrimary())
+    result.merge(acc)
+    
+    kwargs.setdefault("HadronicInteractionScaleFactor", flags.Sim.Fatras.HadronIntProb)
+    kwargs.setdefault("MinimumHadronicInitialEnergy", flags.Sim.Fatras.MomCutOffSec)
+    kwargs.setdefault("MinimumHadronicOutEnergy", flags.Sim.Fatras.MomCutOffSec)
+    kwargs.setdefault("HadronicInteractionValidation", False)
+    kwargs.setdefault("PhysicsProcessCode", 121) # TODO: to be taken from central definition
+    
+    result.merge(fatrasPhysicsValidationToolCfg(flags))
+    phys_val_cfg = acc.getPublicTool('ISF_FatrasPhysicsValidationTool')
+    kwargs.setdefault("PhysicsValidationTool", phys_val_cfg)
+    kwargs.setdefault("ValidationMode", flags.Sim.ISF.ValidationMode)
+    
+    iFatras__HadIntProcessorParametric = CompFactory.iFatras.HadIntProcessorParametric
+    result.setPrivateTools(iFatras__HadIntProcessorParametric(name, **kwargs))
+    
+    return result
+
+
 def fatrasProcessSamplingToolCfg(flags, name="ISF_FatrasProcessSamplingTool", **kwargs):
     mlog = logging.getLogger(name)
     mlog.debug('Start configuration')
 
     result = ComponentAccumulator()
 
+    result.merge(RNG(flags.Random.Engine))
+    kwargs.setdefault("RandomNumberService", result.getService("AthRNGSvc"))
+
+    # truth record
+    acc = TruthServiceCfg(flags)
+    kwargs.setdefault("TruthRecordSvc", acc.getPrimary())
+    result.merge(acc)
+
     # decays
     acc = fatrasParticleDecayHelperCfg(flags)
     pd_helper_cfg = acc.getPublicTool('ISF_FatrasParticleDecayHelper')
@@ -486,12 +887,14 @@ def fatrasProcessSamplingToolCfg(flags, name="ISF_FatrasProcessSamplingTool", **
     g4had_proc_cfg = acc.getPublicTool('ISF_FatrasG4HadIntProcessor')
     result.merge(acc)
     kwargs.setdefault("HadronicInteractionProcessor", g4had_proc_cfg)
+    kwargs.setdefault("HadronicInteraction", True)
 
     # Validation Tool
     acc = fatrasPhysicsValidationToolCfg(flags)
     phys_val_cfg = acc.getPublicTool('ISF_FatrasPhysicsValidationTool')
     result.merge(acc)
     kwargs.setdefault("PhysicsValidationTool", phys_val_cfg)
+    kwargs.setdefault("ValidationMode", flags.Sim.ISF.ValidationMode)
 
     iFatras__ProcessSamplingTool = CompFactory.iFatras.ProcessSamplingTool
     result.addPublicTool(iFatras__ProcessSamplingTool(name=name, **kwargs))
@@ -505,10 +908,11 @@ def fatrasSimToolCfg(flags, name="ISF_FatrasSimTool", **kwargs):
 
     result = ComponentAccumulator()
 
-    acc = fatrasSimHitCreatorIDCfg(flags)
-    id_cfg = acc.getPublicTool('ISF_FatrasSimHitCreatorID')
-    result.merge(acc)
-    kwargs.setdefault("SimHitCreatorID", id_cfg)
+    if "SimHitCreatorID" not in kwargs:
+        acc = fatrasSimHitCreatorIDCfg(flags)
+        id_cfg = acc.getPublicTool('ISF_FatrasSimHitCreatorID')
+        result.merge(acc)
+        kwargs.setdefault("SimHitCreatorID", id_cfg)
 
     acc = fatrasSimHitCreatorMSCfg(flags)
     ms_cfg = acc.getPublicTool('ISF_FatrasSimHitCreatorMS')
@@ -520,7 +924,7 @@ def fatrasSimToolCfg(flags, name="ISF_FatrasSimTool", **kwargs):
     result.merge(acc)
     kwargs.setdefault("ParticleDecayHelper", pdhelper_cfg)
 
-    acc = fatrasParticleHelperCfg(flags)
+    acc = ParticleHelperCfg(flags)
     part_helper_cfg = acc.getPublicTool('ISF_ParticleHelper')
     result.merge(acc)
     kwargs.setdefault("ParticleHelper", part_helper_cfg)
@@ -547,6 +951,188 @@ def fatrasSimToolCfg(flags, name="ISF_FatrasSimTool", **kwargs):
     result.merge(acc)
     kwargs.setdefault("ProcessSamplingTool", proc_samp_cfg)
 
+    kwargs.setdefault("OutputLevel", flags.Exec.OutputLevel)
+    kwargs.setdefault("ValidationOutput", flags.Sim.ISF.ValidationMode)
+    
+    result.merge(RNG(flags.Random.Engine))
+    kwargs.setdefault("RandomNumberService", result.getService("AthRNGSvc"))
+    
     iFatras__TransportTool = CompFactory.iFatras.TransportTool
-    result.setPrivateTools(iFatras__TransportTool(name=name, **kwargs))
+    result.addPublicTool(iFatras__TransportTool(name=name, **kwargs))
+    return result
+
+
+def fatrasSimEngineCfg(flags, name="ISF_FatrasSimEngine", **kwargs):
+    mlog = logging.getLogger(name)
+    mlog.debug('Start configuration')
+
+    result = ComponentAccumulator()
+
+    acc = fatrasSimHitCreatorIDCfg(flags)
+    id_cfg = acc.getPublicTool('ISF_FatrasSimHitCreatorID')
+    result.merge(acc)
+    kwargs.setdefault("SimHitCreatorID", id_cfg)
+    
+    acc = fatrasParticleDecayHelperCfg(flags)
+    pdhelper_cfg = acc.getPublicTool('ISF_FatrasParticleDecayHelper')
+    result.merge(acc)
+    kwargs.setdefault("ParticleDecayHelper", pdhelper_cfg)
+
+    acc = fatrasKinematicFilterCfg(flags)
+    kin_filter_cfg = acc.getPublicTool('ISF_FatrasKinematicFilter')
+    result.merge(acc)
+    kwargs.setdefault("TrackFilter", kin_filter_cfg)
+    kwargs.setdefault("NeutralFilter", kin_filter_cfg)
+    kwargs.setdefault("PhotonFilter", kin_filter_cfg)
+    
+    acc = fatrasExEngineCfg(flags)
+    extrapolator_cfg = acc.getPublicTool('ISF_FatrasExEngine')
+    kwargs.setdefault("Extrapolator", extrapolator_cfg)
+    result.merge(acc)
+
+    acc = fatrasProcessSamplingToolCfg(flags)
+    proc_samp_cfg = acc.getPublicTool('ISF_FatrasProcessSamplingTool')
+    result.merge(acc)
+    kwargs.setdefault("ProcessSamplingTool", proc_samp_cfg)
+    
+    kwargs.setdefault("OutputLevel", flags.Exec.OutputLevel)
+    kwargs.setdefault("ValidationOutput", flags.Sim.ISF.ValidationMode)
+    
+    result.merge(fatrasPhysicsValidationToolCfg(flags))
+    tool = result.getPublicTool("ISF_FatrasPhysicsValidationTool")
+    kwargs.setdefault("PhysicsValidationTool", tool)
+    
+    result.merge(RNG(flags.Random.Engine))
+    kwargs.setdefault("RandomNumberService", result.getService("AthRNGSvc"))
+    
+    iFatras__TransportEngine = CompFactory.iFatras.TransportEngine
+    result.addPublicTool(iFatras__TransportEngine(name=name, **kwargs))
+    return result
+
+
+def fatrasPileupSimToolCfg(flags, name="ISF_FatrasPileupSimTool", **kwargs):
+    mlog = logging.getLogger(name)
+    mlog.debug('Start configuration')
+
+    result = ComponentAccumulator()
+
+    result.merge(fatrasPileupSimHitCreatorIDCfg(flags))
+    tool = result.getPublicTool("ISF_FatrasPileupSimHitCreatorID")
+    kwargs.setdefault("SimHitCreatorID", tool)
+    
+    result.merge(fatrasSimToolCfg(flags, name, **kwargs))
+    return result
+
+
+# FatrasSimulatorTool
+def fatrasSimulatorToolSTCfg(flags, name="ISF_FatrasSimulatorToolST", **kwargs):
+    mlog = logging.getLogger(name)
+    mlog.debug('Start configuration')
+
+    result = ComponentAccumulator()
+
+    result.merge(fatrasSimToolCfg(flags))
+    tool = result.getPublicTool("ISF_FatrasSimTool")
+    kwargs.setdefault("IDSimulationTool", tool)
+    kwargs.setdefault("SimulationTool", tool)
+    
+    kwargs.setdefault("OutputLevel", flags.Exec.OutputLevel)
+    
+    ISF__FatrasSimTool = CompFactory.ISF.FatrasSimTool
+    result.addPublicTool(ISF__FatrasSimTool(name, **kwargs))
+    return result
+
+
+def fatrasNewExtrapolationSimulatorToolSTCfg(flags, name="ISF_FatrasNewExtrapolationSimulatorToolST", **kwargs):
+    mlog = logging.getLogger(name)
+    mlog.debug('Start configuration')
+
+    result = ComponentAccumulator()
+
+    result.merge(fatrasSimEngineCfg(flags))
+    tool = result.getPrivateTool("ISF_FatrasSimEngine")
+    kwargs.setdefault("IDSimulationTool", tool)
+    kwargs.setdefault("UseSimulationTool", True)
+    
+    result.merge(fatrasSimulatorToolSTCfg(flags, name, **kwargs))
+    return result
+
+
+def fatrasPileupSimulatorToolSTCfg(flags, name="ISF_FatrasPileupSimulatorToolST", **kwargs):
+    mlog = logging.getLogger(name)
+    mlog.debug('Start configuration')
+
+    result = ComponentAccumulator()
+
+    result.merge(fatrasPileupSimToolCfg(flags))
+    tool = result.getPrivateTool("ISF_FatrasPileupSimTool")
+    kwargs.setdefault("IDSimulationTool", tool)
+    
+    result.merge(fatrasSimToolCfg(flags))
+    tool = result.getPrivateTool("ISF_FatrasSimTool")
+    kwargs.setdefault("SimulationTool", tool)
+    
+    result.merge(fatrasSimulatorToolSTCfg(flags, name, **kwargs))
+    return result
+
+
+# FatrasSimulationSvc
+def fatrasSimServiceIDCfg(flags, name="ISF_FatrasSimSvc", **kwargs):
+    mlog = logging.getLogger(name)
+    mlog.debug('Start configuration')
+
+    result = ComponentAccumulator()
+
+    kwargs.setdefault("Identifier", "Fatras")
+    
+    result.merge(fatrasSimulatorToolSTCfg(flags))
+    tool = result.getPublicTool("ISF_FatrasSimulatorToolST")
+    kwargs.setdefault("SimulatorTool", tool)
+    
+    result.addService(CompFactory.ISF.LegacySimSvc(name, **kwargs))
+    
+    return result
+
+
+def fatrasNewExtrapolationSimServiceIDCfg(flags, name="ISF_FatrasNewExtrapolationSimSvc", **kwargs):
+    mlog = logging.getLogger(name)
+    mlog.debug('Start configuration')
+
+    result = ComponentAccumulator()
+
+    result.merge(fatrasNewExtrapolationSimulatorToolSTCfg(flags))
+    tool = result.getPublicTool("ISF_FatrasNewExtrapolationSimulatorToolST")
+    kwargs.setdefault("SimulatorTool", tool)
+    
+    result.merge(fatrasSimServiceIDCfg(flags, name, **kwargs))
+    
+    return result
+
+
+def fatrasGeoIDFixSimServiceIDCfg(flags, name="ISF_FatrasGeoIDFixSimSvc", **kwargs):
+    mlog = logging.getLogger(name)
+    mlog.debug('Start configuration')
+
+    result = ComponentAccumulator()
+
+    kwargs.setdefault("EnableGeoIDOverride", True)
+    kwargs.setdefault("GeoIDOverrideZ", 3150.)
+    kwargs.setdefault("GeoIDOverride", 3) # ISF::fAtlasCalo
+    
+    result.merge(fatrasSimServiceIDCfg(flags, name, **kwargs))
+    
+    return result
+
+
+def fatrasPileupSimServiceIDCfg(flags, name="ISF_FatrasPileupSimSvc", **kwargs):
+    mlog = logging.getLogger(name)
+    mlog.debug('Start configuration')
+
+    result = ComponentAccumulator()
+
+    result.merge(fatrasPileupSimulatorToolSTCfg(flags))
+    tool = result.getPublicTool("ISF_FatrasPileupSimulatorToolST")
+    kwargs.setdefault("SimulatorTool", tool)
+    
+    result.merge(fatrasSimServiceIDCfg(flags, name, **kwargs))
     return result
diff --git a/Simulation/ISF/ISF_Fatras/ISF_FatrasServices/python/ISF_FatrasServicesSimConfigNew.py b/Simulation/ISF/ISF_Fatras/ISF_FatrasServices/python/ISF_FatrasServicesSimConfigNew.py
new file mode 100644
index 0000000000000000000000000000000000000000..dfb396b461341e785188ac3e99fd0a90dc985545
--- /dev/null
+++ b/Simulation/ISF/ISF_Fatras/ISF_FatrasServices/python/ISF_FatrasServicesSimConfigNew.py
@@ -0,0 +1,49 @@
+"""
+ComponentAccumulator service configuration for ISF_Fatras simulator tool FatrasSimTool
+Separated from main config to avoid circular dependences
+
+Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+"""
+from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
+from ISF_FatrasServices.ISF_FatrasServicesConfigNew import (
+    FatrasSimulatorToolSTCfg,
+    FatrasNewExtrapolationSimulatorToolSTCfg,
+    FatrasPileupSimulatorToolSTCfg,
+)
+from ISF_SimulationSelectors.ISF_SimulationSelectorsConfigNew import (
+    DefaultFatrasSelectorCfg, MuonFatrasSelectorCfg,
+)
+
+def FatrasSimulatorToolCfg(flags, name="ISF_FatrasSimulatorTool", **kwargs):
+    acc = ComponentAccumulator()
+    deftool = acc.popToolsAndMerge(DefaultFatrasSelectorCfg(flags))
+    muontool = acc.popToolsAndMerge(MuonFatrasSelectorCfg(flags))
+    kwargs.setdefault("IDSimulationSelectors", [deftool])
+    kwargs.setdefault("CaloSimulationSelectors", [muontool])
+    kwargs.setdefault("MSSimulationSelectors", [deftool])
+    tool = acc.popToolsAndMerge(FatrasSimulatorToolSTCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
+    return acc
+
+
+def FatrasNewExtrapolationSimulatorToolCfg(flags, name="ISF_FatrasSNewExtrapolationimulatorTool", **kwargs):
+    acc = ComponentAccumulator()
+    deftool = acc.popToolsAndMerge(DefaultFatrasSelectorCfg(flags))
+    muontool = acc.popToolsAndMerge(MuonFatrasSelectorCfg(flags))
+    kwargs.setdefault("IDSimulationSelectors", [deftool])
+    kwargs.setdefault("CaloSimulationSelectors", [muontool])
+    kwargs.setdefault("MSSimulationSelectors", [deftool])
+    tool = acc.popToolsAndMerge(FatrasNewExtrapolationSimulatorToolSTCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
+    return tool
+
+def FatrasPileupSimulatorToolCfg(flags, name="ISF_FatrasPileupSimulatorTool", **kwargs):
+    acc = ComponentAccumulator()
+    deftool = acc.popToolsAndMerge(DefaultFatrasSelectorCfg(flags))
+    muontool = acc.popToolsAndMerge(MuonFatrasSelectorCfg(flags))
+    kwargs.setdefault("IDSimulationSelectors", [deftool])
+    kwargs.setdefault("CaloSimulationSelectors", [muontool])
+    kwargs.setdefault("MSSimulationSelectors", [deftool])
+    tool = acc.popToolsAndMerge(FatrasPileupSimulatorToolSTCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
+    return tool
diff --git a/Simulation/ISF/ISF_SimulationSelectors/CMakeLists.txt b/Simulation/ISF/ISF_SimulationSelectors/CMakeLists.txt
index c45118e877e807a7f3c8c74598fdf6d69aa81a02..9aea9edd2017c1d57320aa97605bbf4d3f2ccee1 100644
--- a/Simulation/ISF/ISF_SimulationSelectors/CMakeLists.txt
+++ b/Simulation/ISF/ISF_SimulationSelectors/CMakeLists.txt
@@ -17,5 +17,5 @@ atlas_add_component( ISF_SimulationSelectors
                      LINK_LIBRARIES ${ROOT_LIBRARIES} ${HEPPDT_LIBRARIES} AtlasHepMCLib GaudiKernel BarcodeServicesLib ISF_Event ISF_InterfacesLib ISF_TrackingInterfacesLib )
 
 # Install files from the package:
-atlas_install_python_modules( python/*.py )
+atlas_install_python_modules( python/*.py POST_BUILD_CMD ${ATLAS_FLAKE8} )
 
diff --git a/Simulation/ISF/ISF_SimulationSelectors/python/ISF_SimulationSelectorsConfig.py b/Simulation/ISF/ISF_SimulationSelectors/python/ISF_SimulationSelectorsConfig.py
index ac7fb2086c9dca5953dc68ecb5b35450bb095c2a..f253c348e765ed0f8327ab9b5f3cf511a1e25971 100644
--- a/Simulation/ISF/ISF_SimulationSelectors/python/ISF_SimulationSelectorsConfig.py
+++ b/Simulation/ISF/ISF_SimulationSelectors/python/ISF_SimulationSelectorsConfig.py
@@ -6,8 +6,6 @@ Elmar Ritsch, 04/02/2013
 
 from AthenaCommon import CfgMgr
 
-from AthenaCommon.Constants import *  # FATAL,ERROR etc.
-from AthenaCommon.SystemOfUnits import *
 from ISF_SimulationSelectors import SimulationFlavor
 ### DefaultSimSelector configurations
 
diff --git a/Simulation/ISF/ISF_SimulationSelectors/python/ISF_SimulationSelectorsConfigNew.py b/Simulation/ISF/ISF_SimulationSelectors/python/ISF_SimulationSelectorsConfigNew.py
index fde6340e3d45cb4c6cfd7d46ca7c1f6fc28c72a2..2901ef2bf103d99c6d6d1f55b4377fb3fa5feef3 100644
--- a/Simulation/ISF/ISF_SimulationSelectors/python/ISF_SimulationSelectorsConfigNew.py
+++ b/Simulation/ISF/ISF_SimulationSelectors/python/ISF_SimulationSelectorsConfigNew.py
@@ -10,7 +10,18 @@ from ISF_SimulationSelectors import SimulationFlavor
 from ISF_Services.ISF_ServicesConfigNew import ParticleKillerSvcCfg
 from ISF_Geant4Services.ISF_Geant4ServicesConfigNew import (
     Geant4SimCfg, AFIIGeant4SimCfg, LongLivedGeant4SimCfg, AFII_QS_Geant4SimCfg,
-    FullGeant4SimCfg, PassBackGeant4SimCfg
+    FullGeant4SimCfg, PassBackGeant4SimCfg,
+)
+from ISF_FastCaloSimServices.ISF_FastCaloSimServicesConfigNew import (
+    FastCaloSimSvcCfg, LegacyAFIIFastCaloSimSvcCfg,
+    FastCaloSimSvcV2Cfg, DNNCaloSimSvcCfg,
+    FastHitConvAlgFastCaloSimSvcCfg,
+    FastHitConvAlgLegacyAFIIFastCaloSimSvcCfg,
+    FastCaloSimPileupSvcCfg, FastCaloSimPileupOTSvcCfg,
+)
+from ISF_FatrasServices.ISF_FatrasServicesConfigNew import (
+    FatrasSimServiceIDCfg, FatrasNewExtrapolationSimServiceIDCfg,
+    FatrasPileupSimServiceIDCfg, 
 )
 
 
@@ -22,16 +33,19 @@ def DefaultSimSelectorCfg(flags, name="ISF_DefaultSimSelector", **kwargs):
 
 def DefaultParticleKillerSelectorCfg(flags, name="ISF_DefaultParticleKillerSelector", **kwargs):
     acc = ParticleKillerSvcCfg(flags)
-    kwargs.setdefault("Simulator", acc.getService("ISF_ParticleKillerSvc"))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_ParticleKillerSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.ParticleKiller)
-    acc.merge(DefaultSimSelectorCfg(flags, name, **kwargs))
+    tool = acc.popToolsAndMerge(DefaultSimSelectorCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
     return acc
 
 
 def PileupParticleKillerSelectorCfg(flags, name="ISF_PileupParticleKillerSelector", **kwargs):
     acc = ParticleKillerSvcCfg(flags)
     kwargs.setdefault("PileupBCID", [1])
-    kwargs.setdefault("Simulator", acc.getService("ISF_ParticleKillerSvc"))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_ParticleKillerSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.ParticleKiller)
     acc.setPrivateTools(CompFactory.ISF.KinematicPileupSimSelector(name, **kwargs))
     return acc
@@ -39,99 +53,151 @@ def PileupParticleKillerSelectorCfg(flags, name="ISF_PileupParticleKillerSelecto
 
 def DefaultGeant4SelectorCfg(flags, name="ISF_DefaultGeant4Selector", **kwargs):
     acc = Geant4SimCfg(flags)
-    kwargs.setdefault("Simulator", acc.getService("ISFG4SimSvc"))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISFG4SimSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.Geant4)
-    acc.merge(DefaultSimSelectorCfg(flags, name, **kwargs))
+    tool = acc.popToolsAndMerge(DefaultSimSelectorCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
     return acc
 
 
 def DefaultAFIIGeant4SelectorCfg(flags, name="ISF_DefaultAFIIGeant4Selector", **kwargs):
     acc = AFIIGeant4SimCfg(flags)
-    kwargs.setdefault("Simulator", acc.getService("ISF_AFIIGeant4SimSvc"))
-    acc.merge(DefaultGeant4SelectorCfg(flags, name, **kwargs))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_AFIIGeant4SimSvc"))
+    tool = acc.popToolsAndMerge(DefaultGeant4SelectorCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
     return acc
 
 
 def DefaultLongLivedGeant4SelectorCfg(flags, name="ISF_DefaultLongLivedGeant4Selector", **kwargs):
     acc = LongLivedGeant4SimCfg(flags)
-    kwargs.setdefault("Simulator", acc.getService("ISF_LongLivedGeant4SimSvc"))
-    acc.merge(DefaultGeant4SelectorCfg(flags, name, **kwargs))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_LongLivedGeant4SimSvc"))
+    tool = acc.popToolsAndMerge(DefaultGeant4SelectorCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
     return acc
 
 
 def DefaultAFII_QS_Geant4SelectorCfg(flags, name="ISF_DefaultAFII_QS_Geant4Selector", **kwargs):
     acc = AFII_QS_Geant4SimCfg(flags)
-    kwargs.setdefault("Simulator", acc.getService("ISF_AFII_QS_Geant4SimSvc"))
-    acc.merge(DefaultGeant4SelectorCfg(flags, name, **kwargs))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_AFII_QS_Geant4SimSvc"))
+    tool = acc.popToolsAndMerge(DefaultGeant4SelectorCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
     return acc
 
 
 def FullGeant4SelectorCfg(flags, name="ISF_FullGeant4Selector", **kwargs):
     acc = FullGeant4SimCfg(flags)
-    kwargs.setdefault("Simulator", acc.getService("ISF_FullGeant4SimSvc"))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_FullGeant4SimSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.Geant4)
-    acc.merge(DefaultSimSelectorCfg(flags, name, **kwargs))
+    tool = acc.popToolsAndMerge(DefaultSimSelectorCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
     return acc
 
 
 def PassBackGeant4SelectorCfg(flags, name="ISF_PassBackGeant4Selector", **kwargs):
     acc = PassBackGeant4SimCfg(flags)
-    kwargs.setdefault("Simulator", acc.getService("ISF_PassBackGeant4SimSvc"))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_PassBackGeant4SimSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.Geant4)
-    acc.merge(DefaultSimSelectorCfg(flags, name, **kwargs))
+    tool = acc.popToolsAndMerge(DefaultSimSelectorCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
     return acc
 
 
 def DefaultFastCaloSimSelectorCfg(flags, name="ISF_DefaultFastCaloSimSelector", **kwargs):
-    kwargs.setdefault("Simulator", "ISF_FastCaloSimSvc") # TODO
+    acc = FastCaloSimSvcCfg(flags)
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_FastCaloSimSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.FastCaloSim)
-    return DefaultSimSelectorCfg(flags, name, **kwargs)
+    tool = acc.popToolsAndMerge(DefaultSimSelectorCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
+    return acc
 
 
 def DefaultLegacyAFIIFastCaloSimSelectorCfg(flags, name="ISF_DefaultLegacyAFIIFastCaloSimSelector", **kwargs):
-    kwargs.setdefault("Simulator", "ISF_LegacyAFIIFastCaloSimSvc") # TODO
+    acc = LegacyAFIIFastCaloSimSvcCfg(flags)
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_LegacyAFIIFastCaloSimSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.FastCaloSim)
-    return DefaultSimSelectorCfg(flags, name, **kwargs)
+    tool = acc.popToolsAndMerge(DefaultSimSelectorCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
+    return acc
 
 
 def DefaultFastCaloSimV2SelectorCfg(flags, name="ISF_DefaultFastCaloSimV2Selector", **kwargs):
-    kwargs.setdefault("Simulator", "ISF_FastCaloSimSvcV2") # TODO
+    acc = FastCaloSimSvcV2Cfg(flags)
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_FastCaloSimSvcV2"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.FastCaloSimV2)
-    return DefaultSimSelectorCfg(flags, name, **kwargs)
+    tool = acc.popToolsAndMerge(DefaultSimSelectorCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
+    return acc
 
 
 def DefaultDNNCaloSimSelectorCfg(flags, name="ISF_DefaultDNNCaloSimSelector", **kwargs):
-    kwargs.setdefault("Simulator", "ISF_DNNCaloSimSvc") # TODO
-    return DefaultSimSelectorCfg(flags, name, **kwargs)
+    acc = DNNCaloSimSvcCfg(flags)
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_DNNCaloSimSvc"))
+    tool = acc.popToolsAndMerge(DefaultSimSelectorCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
+    return acc
 
 
 def FastHitConvAlgFastCaloSimSelectorCfg(flags, name="ISF_FastHitConvAlgFastCaloSimSelector", **kwargs):
-    kwargs.setdefault("Simulator", "ISF_FastHitConvAlgFastCaloSimSvc") # TODO
+    acc = ComponentAccumulator()
+    acc.merge(FastHitConvAlgFastCaloSimSvcCfg(flags))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_FastHitConvAlgFastCaloSimSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.FastCaloSim)
-    return DefaultSimSelectorCfg(flags, name, **kwargs)
+    tool = acc.popToolsAndMerge(DefaultSimSelectorCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
+    return acc
+
 
 def FastHitConvAlgLegacyAFIIFastCaloSimSelectorCfg(flags, name="ISF_FastHitConvAlgLegacyAFIIFastCaloSimSelector", **kwargs):
-    kwargs.setdefault("Simulator", "ISF_FastHitConvAlgLegacyAFIIFastCaloSimSvc") # TODO
+    acc = ComponentAccumulator()
+    acc.merge(FastHitConvAlgLegacyAFIIFastCaloSimSvcCfg(flags))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_FastHitConvAlgLegacyAFIIFastCaloSimSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.FastCaloSim)
-    return DefaultSimSelectorCfg(flags, name, **kwargs)
+    tool = acc.popToolsAndMerge(DefaultSimSelectorCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
+    return acc
 
 
 def DefaultFatrasSelectorCfg(flags, name="ISF_DefaultFatrasSelector", **kwargs):
-    kwargs.setdefault("Simulator", "ISF_FatrasSimSvc") # TODO
+    acc = FatrasSimServiceIDCfg(flags)
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_FatrasSimSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.Fatras)
-    return DefaultSimSelectorCfg(flags, name, **kwargs)
+    tool = acc.popToolsAndMerge(DefaultSimSelectorCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
+    return acc
 
 
 def DefaultFatrasNewExtrapolationSelectorCfg(flags, name="ISF_DefaultFatrasNewExtrapolationSelector", **kwargs):
-    kwargs.setdefault("Simulator", "ISF_FatrasNewExtrapolationSimSvc") # TODO
+    acc = ComponentAccumulator()
+    acc.merge(FatrasNewExtrapolationSimServiceIDCfg(flags))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_FatrasNewExtrapolationSimSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.Fatras)
-    return DefaultSimSelectorCfg(flags, name, **kwargs)
+    tool = acc.popToolsAndMerge(DefaultSimSelectorCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
+    return acc
 
 
 def DefaultParametricSimulationSelectorCfg(flags, name="ISF_DefaultParametricSimulationSelector", **kwargs):
-    kwargs.setdefault("Simulator", "ISF_ParametricSimSvc") # TODO
+    acc = ComponentAccumulator()
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", "ISF_ParametricSimSvc") # TODO
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.Parametric)
-    return DefaultSimSelectorCfg(flags, name, **kwargs)
+    tool = acc.popToolsAndMerge(DefaultSimSelectorCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
+    return acc
 
 
 # PileUpSimSelector Configurations
@@ -142,38 +208,50 @@ def PileupSimSelectorCfg(flags, name="ISF_PileupSimSelector", **kwargs):
 
 
 def FatrasPileupSelectorCfg(flags, name="ISF_FatrasPileupSelector", **kwargs):
+    acc = ComponentAccumulator()
+    acc.merge(FatrasPileupSimServiceIDCfg(flags))
     kwargs.setdefault("PileupBCID", [1])
-    kwargs.setdefault("Simulator", "ISF_FatrasPileupSimSvc") # TODO
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_FatrasPileupSimSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.FatrasPileup)
-    return PileupSimSelectorCfg(flags, name, **kwargs)
+    tool = acc.popToolsAndMerge(PileupSimSelectorCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
+    return acc
 
 
-def FatrasPileupSelector_noHits(flags, name="ISF_FatrasPileupSelector_noHits", **kwargs):
-    kwargs.setdefault("PileupBCID", [2])
-    kwargs.setdefault("Simulator", "ISF_FatrasPileupSimSvc_noHits") # TODO
-    kwargs.setdefault("SimulationFlavor", SimulationFlavor.FatrasPileup)
-    return PileupSimSelectorCfg(flags, name, **kwargs)
+# FatrasPileupSelector_noHits not migrated
+# due to missing getter for Simulator "ISF_FatrasPileupSimSvc_noHits"
 
 
 def FastCaloSimPileupSelectorCfg(flags, name="ISF_FastCaloSimPileupSelector", **kwargs):
+    acc = FastCaloSimPileupSvcCfg(flags)
     kwargs.setdefault("PileupBCID"  , flags.Sim.FastChain.BCID)
-    kwargs.setdefault("Simulator", "ISF_FastCaloSimPileupSvc") # TODO
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_FastCaloSimPileupSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.FastCaloSimPileup)
-    return PileupSimSelectorCfg(flags, name, **kwargs)
+    acc.merge(PileupSimSelectorCfg(flags, name, **kwargs))
+    tool = acc.popToolsAndMerge(PileupSimSelectorCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
+    return acc
 
 
 def FastCaloSimPileupOTSelectorCfg(flags, name="ISF_FastCaloSimPileupOTSelector", **kwargs):
+    acc = FastCaloSimPileupOTSvcCfg(flags)
     kwargs.setdefault("PileupBCID", flags.Sim.FastChain.BCID)
-    kwargs.setdefault("Simulator", "ISF_FastCaloSimPileupOTSvc") # TODO
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_FastCaloSimPileupOTSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.FastCaloSimPileup)
-    return PileupSimSelectorCfg(flags, name, **kwargs)
+    tool = acc.popToolsAndMerge(PileupSimSelectorCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
+    return acc
 
 
 # KinematicSimSelector Configurations
 def ElectronGeant4SelectorCfg(flags, name="ISF_ElectronGeant4Selector", **kwargs):
     acc = Geant4SimCfg(flags)
     kwargs.setdefault("ParticlePDG", 11)
-    kwargs.setdefault("Simulator", acc.getService("ISFG4SimSvc"))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISFG4SimSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.Geant4)
     acc.setPrivateTools(CompFactory.ISF.KinematicSimSelector(name, **kwargs))
     return acc
@@ -182,7 +260,8 @@ def ElectronGeant4SelectorCfg(flags, name="ISF_ElectronGeant4Selector", **kwargs
 def NeutralGeant4SelectorCfg(flags, name="ISF_NeutralGeant4Selector", **kwargs):
     acc = Geant4SimCfg(flags)
     kwargs.setdefault("Charge", 0)
-    kwargs.setdefault("Simulator", acc.getService("ISFG4SimSvc"))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISFG4SimSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.Geant4)
     acc.setPrivateTools(CompFactory.ISF.KinematicSimSelector(name, **kwargs))
     return acc
@@ -192,7 +271,8 @@ def ProtonAFIIGeant4SelectorCfg(flags, name="ISF_ProtonAFIIGeant4Selector", **kw
     acc = AFIIGeant4SimCfg(flags)
     kwargs.setdefault("MaxMom", 750)
     kwargs.setdefault("ParticlePDG", 2212)
-    kwargs.setdefault("Simulator", acc.getService("ISF_AFIIGeant4SimSvc"))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_AFIIGeant4SimSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.Geant4)
     acc.setPrivateTools(CompFactory.ISF.KinematicSimSelector(name, **kwargs))
     return acc
@@ -200,7 +280,8 @@ def ProtonAFIIGeant4SelectorCfg(flags, name="ISF_ProtonAFIIGeant4Selector", **kw
 
 def ProtonAFII_QS_Geant4SelectorCfg(flags, name="ISF_ProtonAFII_QS_Geant4Selector", **kwargs):
     acc = AFII_QS_Geant4SimCfg(flags)
-    kwargs.setdefault("Simulator", acc.getService("ISF_AFII_QS_Geant4SimSvc"))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_AFII_QS_Geant4SimSvc"))
     acc.merge(ProtonAFIIGeant4SelectorCfg(flags, name, **kwargs))
     return acc
 
@@ -209,7 +290,8 @@ def PionAFIIGeant4SelectorCfg(flags, name="ISF_PionAFIIGeant4Selector", **kwargs
     acc = AFIIGeant4SimCfg(flags)
     kwargs.setdefault("MaxMom", 200)
     kwargs.setdefault("ParticlePDG", 211)
-    kwargs.setdefault("Simulator", acc.getService("ISF_AFIIGeant4SimSvc"))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_AFIIGeant4SimSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.Geant4)
     acc.setPrivateTools(CompFactory.ISF.KinematicSimSelector(name, **kwargs))
     return acc
@@ -217,7 +299,8 @@ def PionAFIIGeant4SelectorCfg(flags, name="ISF_PionAFIIGeant4Selector", **kwargs
 
 def PionAFII_QS_Geant4SelectorCfg(flags, name="ISF_PionAFII_QS_Geant4Selector", **kwargs):
     acc = AFII_QS_Geant4SimCfg(flags)
-    kwargs.setdefault("Simulator", acc.getService("ISF_AFII_QS_Geant4SimSvc"))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_AFII_QS_Geant4SimSvc"))
     acc.merge(PionAFIIGeant4SelectorCfg(flags, name, **kwargs))
     return acc
 
@@ -226,7 +309,8 @@ def ChargedKaonAFIIGeant4SelectorCfg(flags, name="ISF_ChargedKaonAFIIGeant4Selec
     acc = AFIIGeant4SimCfg(flags)
     kwargs.setdefault("MaxMom", 750)
     kwargs.setdefault("ParticlePDG", 321)
-    kwargs.setdefault("Simulator", acc.getService("ISF_AFIIGeant4SimSvc"))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_AFIIGeant4SimSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.Geant4)
     acc.setPrivateTools(CompFactory.ISF.KinematicSimSelector(name, **kwargs))
     return acc
@@ -234,7 +318,8 @@ def ChargedKaonAFIIGeant4SelectorCfg(flags, name="ISF_ChargedKaonAFIIGeant4Selec
 
 def ChargedKaonAFII_QS_Geant4SelectorCfg(flags, name="ISF_ChargedKaonAFII_QS_Geant4Selector", **kwargs):
     acc = AFII_QS_Geant4SimCfg(flags)
-    kwargs.setdefault("Simulator", acc.getService("ISF_AFII_QS_Geant4SimSvc"))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_AFII_QS_Geant4SimSvc"))
     acc.merge(ChargedKaonAFIIGeant4SelectorCfg(flags, name, **kwargs))
     return acc
 
@@ -243,7 +328,8 @@ def KLongAFIIGeant4SelectorCfg(flags, name="ISF_KLongAFIIGeant4Selector", **kwar
     acc = AFIIGeant4SimCfg(flags)
     kwargs.setdefault("MaxMom", 750)
     kwargs.setdefault("ParticlePDG", 130)
-    kwargs.setdefault("Simulator", acc.getService("ISF_AFIIGeant4SimSvc"))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_AFIIGeant4SimSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.Geant4)
     acc.setPrivateTools(CompFactory.ISF.KinematicSimSelector(name, **kwargs))
     return acc
@@ -251,7 +337,8 @@ def KLongAFIIGeant4SelectorCfg(flags, name="ISF_KLongAFIIGeant4Selector", **kwar
 
 def KLongAFII_QS_Geant4SelectorCfg(flags, name="ISF_KLongAFII_QS_Geant4Selector", **kwargs):
     acc = AFII_QS_Geant4SimCfg(flags)
-    kwargs.setdefault("Simulator", acc.getService("ISF_AFII_QS_Geant4SimSvc"))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_AFII_QS_Geant4SimSvc"))
     acc.merge(KLongAFIIGeant4SelectorCfg(flags, name, **kwargs))
     return acc
 
@@ -262,46 +349,63 @@ def MuonSelectorCfg(flags, name="ISF_MuonSelector", **kwargs):
     acc.setPrivateTools(CompFactory.ISF.KinematicSimSelector(name, **kwargs))
     return acc
 
+
 def MuonGeant4SelectorCfg(flags, name="ISF_MuonGeant4Selector", **kwargs):
     acc = Geant4SimCfg(flags)
-    kwargs.setdefault("Simulator", acc.getService("ISFG4SimSvc"))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISFG4SimSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.Geant4)
-    acc.merge(MuonSelectorCfg(flags, name, **kwargs))
+    tool = acc.popToolsAndMerge(MuonSelectorCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
     return acc
 
 
 def MuonAFIIGeant4SelectorCfg(flags, name="ISF_MuonAFIIGeant4Selector", **kwargs):
     acc = AFIIGeant4SimCfg(flags)
-    kwargs.setdefault("Simulator", acc.getService("ISF_AFIIGeant4SimSvc"))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_AFIIGeant4SimSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.Geant4)
-    acc.merge(MuonGeant4SelectorCfg(flags, name, **kwargs))
+    tool = acc.popToolsAndMerge(MuonGeant4SelectorCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
     return acc
 
 
 def MuonAFII_QS_Geant4SelectorCfg(flags, name="ISF_MuonAFII_QS_Geant4Selector", **kwargs):
     acc = AFII_QS_Geant4SimCfg(flags)
-    kwargs.setdefault("Simulator", acc.getService("ISF_AFII_QS_Geant4SimSvc"))
-    acc.merge(MuonGeant4SelectorCfg(flags, name, **kwargs))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_AFII_QS_Geant4SimSvc"))
+    tool = acc.popToolsAndMerge(MuonGeant4SelectorCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
     return acc
 
 
 def MuonFatrasSelectorCfg(flags, name="ISF_MuonFatrasSelector", **kwargs):
-    kwargs.setdefault("Simulator", "ISF_FatrasSimSvc") # TODO
+    acc = FatrasSimServiceIDCfg(flags)
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_FatrasSimSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.Fatras)
-    return MuonSelectorCfg(flags, name, **kwargs)
+    tool = acc.popToolsAndMerge(MuonSelectorCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
+    return acc
 
 
 def MuonFatrasPileupSelectorCfg(flags, name="ISF_MuonFatrasPileupSelector", **kwargs):
-    kwargs.setdefault("Simulator", "ISF_FatrasPileupSimSvc") # TODO
+    acc = ComponentAccumulator()
+    acc.merge(FatrasPileupSimServiceIDCfg(flags))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_FatrasPileupSimSvc"))
     kwargs.setdefault("PileupBCID", [1])
     kwargs.setdefault("ParticlePDG", 13)
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.Fatras)
-    return PileupSimSelectorCfg(flags, name, **kwargs)
+    tool = acc.popToolsAndMerge(PileupSimSelectorCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
+    return acc
 
 
 def WithinEta5FastCaloSimSelectorCfg(flags, name="ISF_WithinEta5FastCaloSimSelector", **kwargs):
-    acc = ComponentAccumulator()
-    kwargs.setdefault("Simulator", "ISF_FastCaloSimSvc") # TODO
+    acc = FastCaloSimSvcCfg(flags)
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_FastCaloSimSvc"))
     kwargs.setdefault("MinPosEta", -5.0)
     kwargs.setdefault("MaxPosEta",  5.0)
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.FastCaloSim)
@@ -311,7 +415,8 @@ def WithinEta5FastCaloSimSelectorCfg(flags, name="ISF_WithinEta5FastCaloSimSelec
 
 def EtaGreater5ParticleKillerSimSelectorCfg(flags, name="ISF_EtaGreater5ParticleKillerSimSelector", **kwargs):
     acc = ParticleKillerSvcCfg(flags)
-    kwargs.setdefault("Simulator", acc.getService("ISF_ParticleKillerSvc"))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_ParticleKillerSvc"))
     kwargs.setdefault("MinPosEta", -5.0)
     kwargs.setdefault("MaxPosEta",  5.0)
     kwargs.setdefault("InvertCuts", True)
@@ -322,7 +427,8 @@ def EtaGreater5ParticleKillerSimSelectorCfg(flags, name="ISF_EtaGreater5Particle
 
 def EtaGreater5PileupParticleKillerSimSelectorCfg(flags, name="ISF_EtaGreater5PileupParticleKillerSimSelector", **kwargs):
     acc = ParticleKillerSvcCfg(flags)
-    kwargs.setdefault("Simulator", acc.getService("ISF_ParticleKillerSvc"))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_ParticleKillerSvc"))
     kwargs.setdefault("MinPosEta", -5.0)
     kwargs.setdefault("MaxPosEta",  5.0)
     kwargs.setdefault("InvertCuts", True)
@@ -343,14 +449,19 @@ def PhotonConeSelectorCfg(flags, name="ISF_PhotonConeSelector", **kwargs):
 
 
 def PhotonConeFatrasSelectorCfg(flags, name="ISF_PhotonConeFatrasSelector", **kwargs):
-    kwargs.setdefault("Simulator", "ISF_FatrasSimSvc") # TODO
+    acc = FatrasSimServiceIDCfg(flags)
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_FatrasSimSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.Fatras)
-    return PhotonConeSelectorCfg(flags, name, **kwargs)
+    tool = acc.popToolsAndMerge(PhotonConeSelectorCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
+    return acc
 
 
 def PhotonConeGeant4SelectorCfg(flags, name="ISF_PhotonConeGeant4Selector", **kwargs):
     acc = Geant4SimCfg(flags)
-    kwargs.setdefault("Simulator", acc.getService("ISFG4SimSvc"))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISFG4SimSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.Geant4)
     acc.merge(PhotonConeSelectorCfg(flags, name, **kwargs))
     return acc
@@ -372,7 +483,8 @@ def HiggsLeptonsConeSimSelectorCfg(flags, name="ISF_HiggsLeptonsConeSimSelector"
 
 def HiggsLeptonsConeGeant4SelectorCfg(flags, name="ISF_HiggsLeptonsConeGeant4Selector", **kwargs):
     acc = Geant4SimCfg(flags)
-    kwargs.setdefault("Simulator", acc.getService("ISFG4SimSvc"))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISFG4SimSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.Geant4)
     acc.merge(HiggsLeptonsConeSimSelectorCfg(flags, name, **kwargs))
     return acc
@@ -393,7 +505,8 @@ def HiggsLeptonsConeGeant4CaloSelectorCfg(flags, name="ISF_HiggsLeptonsConeGeant
 
 def WLeptonsConeGeant4SelectorCfg(flags, name="ISF_WLeptonsConeGeant4Selector", **kwargs):
     acc = Geant4SimCfg(flags)
-    kwargs.setdefault("Simulator", acc.getService("ISFG4SimSvc"))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISFG4SimSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.Geant4)
     kwargs.setdefault("ConeCreatorMinPt", 0.)
     kwargs.setdefault("ConeSize", 0.4)
@@ -410,7 +523,8 @@ def ZLeptonsDirectionConeGeant4SelectorCfg(flags, name="ISF_ZLeptonsDirectionCon
     # this selector picks all particles with a mometum direction
     # within DeltaR<ConeSize relative to the Z decay lepton directions
     acc = Geant4SimCfg(flags)
-    kwargs.setdefault("Simulator", acc.getService("ISFG4SimSvc"))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISFG4SimSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.Geant4)
     kwargs.setdefault("ConeCreatorMinPt", 0.)
     kwargs.setdefault("ConeSize", 0.4)
@@ -432,7 +546,8 @@ def ZLeptonsPositionConeGeant4SelectorCfg(flags, name="ISF_ZLeptonsPositionConeG
 
 def JPsiLeptonsConeGeant4SelectorCfg(flags, name="ISF_JPsiLeptonsConeGeant4Selector", **kwargs):
     acc = Geant4SimCfg(flags)
-    kwargs.setdefault("Simulator", acc.getService("ISFG4SimSvc"))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISFG4SimSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.Geant4)
     kwargs.setdefault("ConeCreatorMinPt", 0.)
     kwargs.setdefault("ConeSize", 0.4)
@@ -463,16 +578,22 @@ def BHadronProductsSimSelectorCfg(flags, name="ISF_BHadronProductsSimSelector",
 
 def BHadronProductsGeant4SelectorCfg(flags, name="ISF_BHadronProductsGeant4Selector", **kwargs):
     acc = Geant4SimCfg(flags)
-    kwargs.setdefault("Simulator", acc.getService("ISFG4SimSvc"))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISFG4SimSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.Geant4)
-    acc.merge(BHadronProductsSimSelectorCfg(flags, name, **kwargs))
+    tool = acc.popToolsAndMerge(BHadronProductsSimSelectorCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
     return acc
 
 
 def BHadronProductsFatrasSelectorCfg(flags, name="ISF_BHadronProductsFatrasSelector", **kwargs):
-    kwargs.setdefault("Simulator", "ISF_FatrasSimSvc") # TODO
+    acc = FatrasSimServiceIDCfg(flags)
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISF_FatrasSimSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.Fatras)
-    return BHadronProductsSimSelectorCfg(flags, name, **kwargs)
+    tool = acc.popToolsAndMerge(BHadronProductsSimSelectorCfg(flags, name, **kwargs))
+    acc.setPrivateTools(tool)
+    return acc
 
 
 def TauProductsSimSelectorCfg(flags, name="ISF_TauProductsSimSelector", **kwargs):
@@ -487,7 +608,8 @@ def TauProductsSimSelectorCfg(flags, name="ISF_TauProductsSimSelector", **kwargs
 
 def TauProductsGeant4SelectorCfg(flags, name="ISF_TauProductsGeant4Selector", **kwargs):
     acc = Geant4SimCfg(flags)
-    kwargs.setdefault("Simulator", acc.getService("ISFG4SimSvc"))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISFG4SimSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.Geant4)
     acc.merge(TauProductsSimSelectorCfg(flags, name, **kwargs))
     return acc
@@ -505,7 +627,8 @@ def ZProductsSimSelectorCfg(flags, name="ISF_ZProductsSimSelector", **kwargs):
 
 def ZProductsGeant4SelectorCfg(flags, name="ISF_ZProductsGeant4Selector", **kwargs):
     acc = Geant4SimCfg(flags)
-    kwargs.setdefault("Simulator", acc.getService("ISFG4SimSvc"))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISFG4SimSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.Geant4)
     acc.merge(ZProductsSimSelectorCfg(flags, name, **kwargs))
     return acc
@@ -514,10 +637,10 @@ def ZProductsGeant4SelectorCfg(flags, name="ISF_ZProductsGeant4Selector", **kwar
 # HistorySimSelector Configurations
 def SubDetStickyGeant4SimSelectorCfg(flags, name="ISF_SubDetStickyGeant4SimSelector", **kwargs):
     acc = Geant4SimCfg(flags)
-    kwargs.setdefault("PrevSimSvc", acc.getService("ISFG4SimSvc"))
     kwargs.setdefault("RequiresUnchangedGeoID", True)
-    kwargs.setdefault("Simulator", "ISF_Geant4SimSvc")
-    kwargs.setdefault("Simulator", acc.getService("ISFG4SimSvc"))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("PrevSimSvc", acc.getService("ISFG4SimSvc"))
+        kwargs.setdefault("Simulator", acc.getService("ISFG4SimSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.Geant4)
     acc.setPrivateTools(CompFactory.ISF.HistorySimSelector(name, **kwargs))
     return acc
@@ -527,7 +650,8 @@ def GlobalStickyGeant4SimSelectorCfg(flags, name="ISF_GlobalStickyGeant4SimSelec
     acc = Geant4SimCfg(flags)
     kwargs.setdefault("PrevSimSvc", acc.getService("ISFG4SimSvc"))
     kwargs.setdefault("RequiresUnchangedGeoID", False)
-    kwargs.setdefault("Simulator", acc.getService("ISFG4SimSvc"))
+    if flags.Concurrency.NumThreads == 0:
+        kwargs.setdefault("Simulator", acc.getService("ISFG4SimSvc"))
     kwargs.setdefault("SimulationFlavor", SimulationFlavor.Geant4)
     acc.setPrivateTools(CompFactory.ISF.HistorySimSelector(name, **kwargs))
     return acc