diff --git a/Simulation/ISF/ISF_Core/ISF_Event/ISF_Event/ISFTruthIncident.h b/Simulation/ISF/ISF_Core/ISF_Event/ISF_Event/ISFTruthIncident.h
index 95c9c3996fbf51c98cf3197f00bfbb6d78b1a545..998c185d04107d2392058ba7d65427cc8fb35378 100644
--- a/Simulation/ISF/ISF_Core/ISF_Event/ISF_Event/ISFTruthIncident.h
+++ b/Simulation/ISF/ISF_Core/ISF_Event/ISF_Event/ISFTruthIncident.h
@@ -96,6 +96,11 @@ namespace ISF {
         simulation) - TODO only a dummy implementation currently */
     virtual HepMC::GenParticlePtr     updateChildParticle(unsigned short index,
                                                           HepMC::GenParticlePtr existingChild) const override final;
+    /** Update the id and particleLink properties of the parentAfterIncident (to be called after registerTruthIncident) */
+    void updateParentAfterIncidentProperties();
+    /** Update the id and particleLink properties of the child particles (to be called after registerTruthIncident) */
+    void updateChildParticleProperties();
+
   private:
     ISFTruthIncident();
 
diff --git a/Simulation/ISF/ISF_Core/ISF_Event/src/ISFTruthIncident.cxx b/Simulation/ISF/ISF_Core/ISF_Event/src/ISFTruthIncident.cxx
index b7b31cf2686c9039b58a85336c05b092971f55d1..5fb1e9f75431fb1c088f7954e7d8c52e3c92de24 100644
--- a/Simulation/ISF/ISF_Core/ISF_Event/src/ISFTruthIncident.cxx
+++ b/Simulation/ISF/ISF_Core/ISF_Event/src/ISFTruthIncident.cxx
@@ -22,8 +22,9 @@ static HepMC::GenParticlePtr ParticleHelper_convert( const ISF::ISFParticle &par
   HepMC::FourVector fourMomentum( mom.x(), mom.y(), mom.z(), energy);
 
   auto hepParticle = HepMC::newGenParticlePtr( fourMomentum, particle.pdgCode(), particle.status() );
+#ifndef HEPMC3
   HepMC::suggest_barcode(hepParticle, particle.barcode() );
-
+#endif
   // return a newly created GenParticle
   return hepParticle;
 }
@@ -119,6 +120,9 @@ HepMC::GenParticlePtr ISF::ISFTruthIncident::parentParticleAfterIncident(int new
   // set a new status
   m_parent.setStatus( parentStatus() + HepMC::SIM_STATUS_INCREMENT );
 
+  // FIXME At this point the m_parent ISFParticle's id, truthBinding
+  // and particleLink all still need to be updated
+
   // and update truth info (including the ISFParticle's HMPL)
   return updateHepMCTruthParticle(m_parent, &m_parent);
 }
@@ -154,6 +158,12 @@ HepMC::GenParticlePtr ISF::ISFTruthIncident::childParticle(unsigned short index,
     sec->setBarcode( bc);
   }
 
+  // Enforce that the status is set correctly
+  sec->setStatus(1 + HepMC::SIM_STATUS_THRESHOLD);
+
+  // FIXME At this point the sec ISFParticle's id, truthBinding
+  // and particleLink all still need to be updated
+
   // and update truth info (including the ISFParticle's HMPL)
   return updateHepMCTruthParticle( *sec, &m_parent );
 }
@@ -171,7 +181,7 @@ HepMC::GenParticlePtr ISF::ISFTruthIncident::getHepMCTruthParticle( ISF::ISFPart
   HepMC::GenParticlePtr hepTruthParticle = truthBinding ? truthBinding->getTruthParticle() : nullptr;
  
   // We have what we want
-  if(hepTruthParticle){
+  if (hepTruthParticle) {
     return hepTruthParticle;
   }
   //Otherwise we need to create it
@@ -193,17 +203,81 @@ HepMC::GenParticlePtr ISF::ISFTruthIncident::updateHepMCTruthParticle( ISF::ISFP
     truthBinding = new TruthBinding( hepTruthParticle, hepPrimaryParticle, hepGenZeroParticle );
     particle.setTruthBinding(truthBinding);
   }
+  // At this point the values returned by particle.getParticleLink()
+  // and particle.id() are not consistent with what is stored in the
+  // TruthBinding.
 
-  //register the new GenParticle as HepMcParticleLink, copying over some old properties if present
-  const HepMcParticleLink* oldHMPL = particle.getParticleLink();
-  HepMcParticleLink* newHMPL = nullptr;
-  if (oldHMPL) {
-    newHMPL = new HepMcParticleLink(hepTruthParticle, oldHMPL->eventIndex(), HepMcParticleLink::IS_EVENTNUM);
-    delete oldHMPL;
-  } else {
-    newHMPL = new HepMcParticleLink(hepTruthParticle, 0, HepMcParticleLink::IS_EVENTNUM); // FIXME should be HepMcParticleLink::IS_POSITION
+  // FIXME Consider deleting the HepMcParticleLink and setting the id to HepMC::UNDEFINED_ID at this point?
+  return hepTruthParticle;
+}
+
+/** Update the id and particleLink properties of the parentAfterIncident (to be called after registerTruthIncident) */
+void ISF::ISFTruthIncident::updateParentAfterIncidentProperties() {
+  // FIXME Check that we correctly deal with the case that the parent
+  // particle survives the interaction, but is rejected by
+  // registerTruthIncident
+  const ISF::TruthBinding *parentAfterIncidentTruthBinding = m_parent.getTruthBinding();
+  auto parentAfterIncidentGenParticle = (parentAfterIncidentTruthBinding)  ? parentAfterIncidentTruthBinding->getTruthParticle() : nullptr;
+  const int parentAfterIncidentID = (parentAfterIncidentGenParticle) ? HepMC::uniqueID(parentAfterIncidentGenParticle) : HepMC::UNDEFINED_ID;
+  HepMcParticleLink* parentAfterIncidentHMPL{};
+  const HepMcParticleLink* parentBeforeIncidentHMPL = m_parent.getParticleLink();
+  int eventIndex{0};
+  if (parentAfterIncidentGenParticle) { eventIndex = parentAfterIncidentGenParticle->parent_event()->event_number(); }
+  else if (parentBeforeIncidentHMPL) { eventIndex = parentBeforeIncidentHMPL->eventIndex(); }
+  const HepMcParticleLink::PositionFlag idxFlag =
+    (eventIndex==0) ? HepMcParticleLink::IS_POSITION: HepMcParticleLink::IS_EVENTNUM;
+  if (parentBeforeIncidentHMPL) {
+    delete parentBeforeIncidentHMPL;
+  }
+  if (!parentAfterIncidentGenParticle) {
+    parentAfterIncidentHMPL = new HepMcParticleLink(parentAfterIncidentID, eventIndex, idxFlag, HepMcParticleLink::IS_ID);
+  }
+  else {
+    parentAfterIncidentHMPL = new HepMcParticleLink(parentAfterIncidentGenParticle, eventIndex, idxFlag);
   }
-  particle.setParticleLink(newHMPL);
+  m_parent.setId(parentAfterIncidentID);
+  m_parent.setParticleLink(parentAfterIncidentHMPL);
+}
 
-  return hepTruthParticle;
+/** Update the id and particleLink properties of the child particles (to be called after registerTruthIncident) */
+void ISF::ISFTruthIncident::updateChildParticleProperties() {
+  unsigned short numSec = numberOfChildren();
+  for (unsigned short i=0; i<numSec; i++) {
+    // the current particle
+    ISF::ISFParticle *child = m_children[i];
+    ISF::TruthBinding *childTruthBinding = child->getTruthBinding();
+    if (!childTruthBinding) {
+      // Child particles which were rejected during
+      // registerTruthIncident need a TruthBinding
+      auto parentTruthBinding = m_parent.getTruthBinding();
+      if  (parentTruthBinding) {
+        childTruthBinding = parentTruthBinding->childTruthBinding(nullptr);
+      }
+      else  {
+        // FIXME We really shouldn't end up here, possibly abort if we hit this?
+        childTruthBinding = new TruthBinding( nullptr, nullptr, nullptr );
+      }
+      child->setTruthBinding(childTruthBinding);
+    }
+    auto childGenParticle = childTruthBinding->getTruthParticle();
+    const int childID = (childGenParticle) ? HepMC::uniqueID(childGenParticle) : HepMC::UNDEFINED_ID;
+    HepMcParticleLink* childHMPL{};
+    const HepMcParticleLink* oldChildHMPL = child->getParticleLink();
+    int eventIndex{0};
+    if (childGenParticle) { eventIndex = childGenParticle->parent_event()->event_number(); }
+    else if (oldChildHMPL) { eventIndex = oldChildHMPL->eventIndex(); }
+    const HepMcParticleLink::PositionFlag idxFlag =
+      (eventIndex==0) ? HepMcParticleLink::IS_POSITION: HepMcParticleLink::IS_EVENTNUM;
+    if (oldChildHMPL) {
+      delete oldChildHMPL;
+    }
+    if (!childGenParticle) {
+      childHMPL = new HepMcParticleLink(childID, eventIndex, idxFlag, HepMcParticleLink::IS_ID);
+    }
+    else {
+      childHMPL = new HepMcParticleLink(childGenParticle, eventIndex, idxFlag);
+    }
+    child->setId(childID);
+    child->setParticleLink(childHMPL);
+  }
 }
diff --git a/Simulation/ISF/ISF_Core/ISF_Services/src/TruthSvc.cxx b/Simulation/ISF/ISF_Core/ISF_Services/src/TruthSvc.cxx
index 2c63fcb7fd22737db4dfd697360d7516dd393892..d5d340ffe3719e056baa2b612d8cc83be783eb28 100644
--- a/Simulation/ISF/ISF_Core/ISF_Services/src/TruthSvc.cxx
+++ b/Simulation/ISF/ISF_Core/ISF_Services/src/TruthSvc.cxx
@@ -250,6 +250,9 @@ void ISF::TruthSvc::recordIncidentToMCTruth( ISF::ITruthIncident& ti, bool passW
 #ifdef HEPMC3
     HepMC::suggest_barcode( parentAfterIncident, newPrimaryBC ); // TODO check this works correctly
 #endif
+    // NB For ISFTruthIncident the m_parent ISFParticle still needs
+    // its id and particleLink properties to be properly updated at
+    // this point.
     ATH_MSG_VERBOSE ( "Parent After Incident: " << parentAfterIncident << ", barcode: " << HepMC::barcode(parentAfterIncident));
   }
 
@@ -278,6 +281,9 @@ void ISF::TruthSvc::recordIncidentToMCTruth( ISF::ITruthIncident& ti, bool passW
 #ifdef HEPMC3
         int secondaryParticleBCFromTI = ti.childBarcode(i);
         HepMC::suggest_barcode( p, secondaryParticleBCFromTI ? secondaryParticleBCFromTI : secondaryParticleBC );
+        // NB For ISFTruthIncident the current child ISFParticle still needs
+        // its id and particleLink properties to be properly updated at
+        // this point.
 #endif
       }
       ATH_MSG_VERBOSE ( "Writing out " << i << "th child particle: " << p << ", barcode: " << HepMC::barcode(p));
diff --git a/Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimServices/src/FastCaloSimV2Tool.cxx b/Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimServices/src/FastCaloSimV2Tool.cxx
index ebe953d79fa7f91ac3c40479dbf1f3da5409c08b..36ae8f140d5cfdbff27d30dbf010d755b765024b 100644
--- a/Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimServices/src/FastCaloSimV2Tool.cxx
+++ b/Simulation/ISF/ISF_FastCaloSim/ISF_FastCaloSimServices/src/FastCaloSimV2Tool.cxx
@@ -226,6 +226,9 @@ StatusCode ISF::FastCaloSimV2Tool::simulate(ISF::ISFParticle& isfp, ISFParticleC
                                      ISF::fKillsPrimary);
 
         m_truthRecordSvc->registerTruthIncident( truth, true );
+        // At this point we need to update the properties of the
+        // ISFParticles produced in the interaction
+        truth.updateChildParticleProperties();
 
         for (auto *secondary : *someSecondaries) {
           if (secondary->getTruthBinding()) {
diff --git a/Simulation/ISF/ISF_Fatras/ISF_FatrasTools/src/HadIntProcessorParametric.cxx b/Simulation/ISF/ISF_Fatras/ISF_FatrasTools/src/HadIntProcessorParametric.cxx
index 1f93510737a2a68a61b16d9896d0a89381f1a9b2..5129f732bc3f420c2ac9da151118a2dca4406694 100644
--- a/Simulation/ISF/ISF_Fatras/ISF_FatrasTools/src/HadIntProcessorParametric.cxx
+++ b/Simulation/ISF/ISF_Fatras/ISF_FatrasTools/src/HadIntProcessorParametric.cxx
@@ -227,7 +227,7 @@ bool iFatras::HadIntProcessorParametric::hadronicInteraction(const Amg::Vector3D
   if (CLHEP::RandFlat::shoot(m_randomEngine) < (1. - prob) * m_hadIntProbScale ) return recordHadState(0.,p,
 												       position,
 												       momentum.unit(),
-												       particle);
+												       particle); // Registers TruthIncident internally
 
   // no hadronic interactions were computed
   return false;
@@ -645,6 +645,9 @@ ISF::ISFParticleVector iFatras::HadIntProcessorParametric::getHadState(const ISF
 			       parent->nextGeoID(),
 			       ISF::fKillsPrimary );
   m_truthRecordSvc->registerTruthIncident( truth);
+  // At this point we need to update the properties of the
+  // ISFParticles produced in the interaction
+  truth.updateChildParticleProperties();
 
   // save info for validation
   if (m_validationMode && m_validationTool) {
@@ -665,28 +668,29 @@ ISF::ISFParticleVector iFatras::HadIntProcessorParametric::getHadState(const ISF
 }
 
 bool iFatras::HadIntProcessorParametric::doHadronicInteraction(double time, const Amg::Vector3D& position, const Amg::Vector3D& momentum,
-							       const Trk::Material* /*ematprop*/,
-							       Trk::ParticleHypothesis particle, bool processSecondaries) const {
+                                                               const Trk::Material* /*ematprop*/,
+                                                               Trk::ParticleHypothesis particle, bool processSecondaries) const {
+  // Called by McMaterialEffectsUpdator::interact
   // get parent particle
   const ISF::ISFParticle *parent = ISF::ParticleClipboard::getInstance().getParticle();
   // something is seriously wrong if there is no parent particle
   assert(parent);
 
-  ISF::ISFParticleVector ispVec=getHadState(parent, time, momentum.mag(), position, momentum.unit(), particle);
+  ISF::ISFParticleVector ispVec=getHadState(parent, time, momentum.mag(), position, momentum.unit(), particle); // Registers TruthIncident internally
+
 
   // having no secondaries does not necessarily mean the interaction did not take place  : TODO : add flag into ::getHadState
   //  if (!ispVec.size()) return false;
 
   // push onto ParticleStack
-
   if (processSecondaries && !ispVec.empty() ) {
-     // FIXME Check this doesn't cause problems in the TruthSvc
-       for (unsigned int ic=0; ic<ispVec.size(); ic++) {
- 	        if (!ispVec[ic]->getTruthBinding()) {
- 	                ispVec[ic]->setTruthBinding(new ISF::TruthBinding(*parent->getTruthBinding()));
- 	        }
- 	        m_particleBroker->push(ispVec[ic], parent);
-       }
+    for (auto *childParticle : ispVec) {
+      //Check that the new ISFParticles have a valid TruthBinding
+      if (!childParticle->getTruthBinding()) {
+        ATH_MSG_ERROR("Could not retrieve TruthBinding from child ISFParticle "<< *childParticle);
+      }
+      m_particleBroker->push(childParticle, parent);
+    }
   }
 
   return true;
@@ -697,8 +701,9 @@ ISF::ISFParticleVector iFatras::HadIntProcessorParametric::doHadIntOnLayer(const
 									   const Amg::Vector3D& position, const Amg::Vector3D& momentum,
 									   const Trk::Material* /*emat*/,
 									   Trk::ParticleHypothesis particle) const {
-
-  return getHadState(parent, time, momentum.mag(), position, momentum.unit(), particle);
+  // called from McMaterialEffectsUpdator::interact and
+  // McMaterialEffectsUpdator::interactLay methods
+  return getHadState(parent, time, momentum.mag(), position, momentum.unit(), particle); // Registers TruthIncident internally
 
 }
 
@@ -712,21 +717,21 @@ bool iFatras::HadIntProcessorParametric::recordHadState(double time, double p,
   // something is seriously wrong if there is no parent particle
   assert(parent);
 
-  ISF::ISFParticleVector ispVec=getHadState(parent, time, p, vertex, particleDir, particle);
+  ISF::ISFParticleVector ispVec=getHadState(parent, time, p, vertex, particleDir, particle); // Registers TruthIncident internally
 
   // having no secondaries does not necessarily mean the interaction did not take place : TODO : add flag into ::getHadState
   //  if (!ispVec.size()) return false;
 
   // push onto ParticleStack
   if (!ispVec.empty() ) {
-    // FIXME Check this doesn't cause problems in the TruthSvc
-	for (unsigned int ic=0; ic<ispVec.size(); ic++) {
-	        if (!ispVec[ic]->getTruthBinding()) {
-	                ispVec[ic]->setTruthBinding(new ISF::TruthBinding(*parent->getTruthBinding()));
-	        }
-	        m_particleBroker->push(ispVec[ic], parent);
-        }
-}
+    for (auto *childParticle : ispVec) {
+      //Check that the new ISFParticles have a valid TruthBinding
+      if (!childParticle->getTruthBinding()) {
+        ATH_MSG_ERROR("Could not retrieve TruthBinding from child ISFParticle "<< *childParticle);
+      }
+      m_particleBroker->push(childParticle, parent);
+    }
+  }
 
   return true;
 }
diff --git a/Simulation/ISF/ISF_Fatras/ISF_FatrasTools/src/McMaterialEffectsUpdator.cxx b/Simulation/ISF/ISF_Fatras/ISF_FatrasTools/src/McMaterialEffectsUpdator.cxx
index ddd73064ce86507f3f9f3a99332d9ae6e4fdb926..81fe6bad991e6015c01516b5ccc264aafe05260a 100644
--- a/Simulation/ISF/ISF_Fatras/ISF_FatrasTools/src/McMaterialEffectsUpdator.cxx
+++ b/Simulation/ISF/ISF_Fatras/ISF_FatrasTools/src/McMaterialEffectsUpdator.cxx
@@ -492,6 +492,22 @@ iFatras::McMaterialEffectsUpdator::updateInLay(
     pathLim.updateMat(dX0, m_matProp->averageZ(), dInL0);
     // register particle if not in the stack already
     if (isp != m_isp) {
+      ISF::TruthBinding *regTruthBinding{};
+      if (isp->getTruthBinding()) {
+        regTruthBinding = new ISF::TruthBinding(*(isp->getTruthBinding()));
+      }
+      else {
+        ATH_MSG_WARNING("Incomming ISParticle had no TruthBinding " << *isp);
+        regTruthBinding = new ISF::TruthBinding(nullptr, nullptr, nullptr);
+      }
+      HepMcParticleLink *regHMPL{};
+      if (isp->getParticleLink()) {
+        regHMPL = new HepMcParticleLink(*(isp->getParticleLink()));
+      }
+      else {
+        ATH_MSG_WARNING("Incomming ISParticle had no ParticleLink: " << *isp);
+        regHMPL = new HepMcParticleLink(isp->id(), 0, HepMcParticleLink::IS_POSITION, HepMcParticleLink::IS_ID);
+      }
       ISF::ISFParticle* regisp = new ISF::ISFParticle(isp->position(),
                                                       currPar->momentum(),
                                                       isp->mass(),
@@ -501,7 +517,9 @@ iFatras::McMaterialEffectsUpdator::updateInLay(
                                                       isp->timeStamp(),
                                                       *m_isp,
                                                       isp->id(),
-                                                      isp->barcode() // FIXME barcode-based
+                                                      isp->barcode(), // FIXME barcode-based
+                                                      regTruthBinding,
+                                                      regHMPL
                                                       );
       // add presampled process info
       if (isp->getUserInformation() && isp->getUserInformation()->materialLimit()) {
@@ -530,10 +548,10 @@ iFatras::McMaterialEffectsUpdator::updateInLay(
         }
         regisp->setUserInformation(validInfo);
       }
-      // Making sure we get some correct truth info from parent if needed
+      // Check that the returned ISFParticle has a valid TruthBinding
       // before pushing into the particle broker
       if (!regisp->getTruthBinding()) {
-        regisp->setTruthBinding(new ISF::TruthBinding(*isp->getTruthBinding()));
+        ATH_MSG_ERROR("Could not retrieve TruthBinding from non-interacting ISFParticle "<< *regisp);
       }
       m_particleBroker->push(regisp, m_isp);
     }
@@ -629,7 +647,7 @@ iFatras::McMaterialEffectsUpdator::updateInLay(
     ISF::ISFParticleVector childs;
 
     if (iStatus == 1) {
-      childs = interactLay(isp, timeLim.time, *currPar, particle, pathLim.process);
+      childs = interactLay(isp, timeLim.time, *currPar, particle, pathLim.process); // Registers TruthIncident internally
     } else {
       if (extMatProp) {
         childs = m_hadIntProcessor->doHadIntOnLayer(
@@ -683,6 +701,22 @@ iFatras::McMaterialEffectsUpdator::updateInLay(
 
   // register particle if not in the stack already
   if (isp != m_isp) {
+    ISF::TruthBinding *regTruthBinding{};
+    if (isp->getTruthBinding()) {
+      regTruthBinding = new ISF::TruthBinding(*(isp->getTruthBinding()));
+    }
+    else {
+      ATH_MSG_WARNING("Incomming ISParticle had no TruthBinding " << *isp);
+      regTruthBinding = new ISF::TruthBinding(nullptr, nullptr, nullptr);
+    }
+    HepMcParticleLink *regHMPL{};
+    if (isp->getParticleLink()) {
+      regHMPL = new HepMcParticleLink(*(isp->getParticleLink()));
+    }
+    else {
+      ATH_MSG_WARNING("Incomming ISParticle had no ParticleLink: " << *isp);
+      regHMPL = new HepMcParticleLink(isp->id(), 0, HepMcParticleLink::IS_POSITION, HepMcParticleLink::IS_ID);
+    }
     ISF::ISFParticle* regisp = new ISF::ISFParticle(isp->position(),
                                                     currPar->momentum(),
                                                     isp->mass(),
@@ -692,7 +726,9 @@ iFatras::McMaterialEffectsUpdator::updateInLay(
                                                     isp->timeStamp(),
                                                     *m_isp,
                                                     isp->id(),
-                                                    isp->barcode() // FIXME barcode-based
+                                                    isp->barcode(), // FIXME barcode-based
+                                                    regTruthBinding,
+                                                    regHMPL
                                                     );
     // add presampled process info
     if (isp->getUserInformation() && isp->getUserInformation()->materialLimit()) {
@@ -718,9 +754,10 @@ iFatras::McMaterialEffectsUpdator::updateInLay(
       else
         validInfo->setGeneration(-1); // signal problem in the validation chain
     }
-    // Making sure we get some correct truth info from parent if needed before pushing into the particle broker
+    // Check that the returned ISFParticle has a valid TruthBinding
+    // before pushing into the particle broker
     if (!regisp->getTruthBinding()) {
-      regisp->setTruthBinding(new ISF::TruthBinding(*isp->getTruthBinding()));
+      ATH_MSG_ERROR("Could not retrieve TruthBinding from non-interacting ISFParticle "<< *regisp);
     }
     m_particleBroker->push(regisp, m_isp);
   }
@@ -1316,12 +1353,21 @@ void iFatras::McMaterialEffectsUpdator::recordBremPhoton(double time,
                                  parent->nextGeoID(),
                                  ISF::fPrimarySurvives );
     m_truthRecordSvc->registerTruthIncident( truth);
-    //Making sure we get some correct truth info from parent if needed before pushing into the particle broker
-    if (!bremPhoton->getTruthBinding()) {
-	bremPhoton->setTruthBinding(new ISF::TruthBinding(*parent->getTruthBinding()));
+    // At this point we need to update the properties of the
+    // ISFParticles produced in the interaction
+    truth.updateParentAfterIncidentProperties();
+    truth.updateChildParticleProperties();
+
+    // Check that the new/updated ISFParticles have a valid TruthBinding before pushing into the particle broker
+    if (!parent->getTruthBinding()) {
+      ATH_MSG_ERROR("Could not retrieve TruthBinding from parent ISFParticle "<< *parent);
+    }
+    for (auto *childParticle : children) {
+      if (!childParticle->getTruthBinding()) {
+        ATH_MSG_ERROR("Could not retrieve TruthBinding from child ISFParticle "<< *childParticle);
+      }
+      m_particleBroker->push(childParticle, parent);
     }
-    m_particleBroker->push( bremPhoton, parent);
-
 
     // save info for validation
     if (m_validationMode && m_validationTool) {
@@ -1449,10 +1495,19 @@ void iFatras::McMaterialEffectsUpdator::recordBremPhotonLay(const ISF::ISFPartic
                                  parent->nextGeoID(),
                                  ISF::fPrimarySurvives );
     m_truthRecordSvc->registerTruthIncident( truth);
-
-    //Making sure we get some correct truth info from parent if needed before pushing into the particle broker
-    if (!bremPhoton->getTruthBinding()) {
-	bremPhoton->setTruthBinding(new ISF::TruthBinding(*parent->getTruthBinding()));
+    // At this point we need to update the properties of the
+    // ISFParticles produced in the interaction
+    truth.updateParentAfterIncidentProperties();
+    truth.updateChildParticleProperties();
+
+    // Check that the new/updated ISFParticles have a valid TruthBinding
+    if (!parent->getTruthBinding()) {
+      ATH_MSG_ERROR("Could not retrieve TruthBinding from parent ISFParticle "<< *parent);
+    }
+    for (auto *childParticle : children) {
+      if (!childParticle->getTruthBinding()) {
+        ATH_MSG_ERROR("Could not retrieve TruthBinding from child ISFParticle "<< *childParticle);
+      }
     }
 
     // save info for validation
@@ -1537,6 +1592,7 @@ iFatras::McMaterialEffectsUpdator::interact(double time,
                                             int process,
                                             const Trk::Material* extMatProp) const
 {
+  // Responsible for registering TruthIncidents
   if (process == 0)
     return nullptr;
 
@@ -1554,13 +1610,24 @@ iFatras::McMaterialEffectsUpdator::interact(double time,
     // update parent before decay
     ISF::ISFParticleVector childVector = m_particleDecayer->decayParticle(*parent,position,momentum,time);
 
-    for (unsigned int i=0; i<childVector.size(); i++) {
+     // register TruthIncident
+    ISF::ISFTruthIncident truth( const_cast<ISF::ISFParticle&>(*parent),
+                                 childVector,
+                                 process,
+                                 parent->nextGeoID(),  // inherits from the parent
+                                 ISF::fKillsPrimary );
+    m_truthRecordSvc->registerTruthIncident( truth);
+    // At this point we need to update the properties of the
+    // ISFParticles produced in the interaction
+    truth.updateChildParticleProperties();
+
+   for (unsigned int i=0; i<childVector.size(); i++) {
       // in the validation mode, add process info
       if (m_validationMode) {
-	ISF::ParticleUserInformation* validInfo = new ISF::ParticleUserInformation();
-	validInfo->setProcess(process);
-	if (parent->getUserInformation()) validInfo->setGeneration(parent->getUserInformation()->generation()+1);
-	else validInfo->setGeneration(1);     // assume parent is a primary track
+        ISF::ParticleUserInformation* validInfo = new ISF::ParticleUserInformation();
+        validInfo->setProcess(process);
+        if (parent->getUserInformation()) validInfo->setGeneration(parent->getUserInformation()->generation()+1);
+        else validInfo->setGeneration(1);     // assume parent is a primary track
         childVector[i]->setUserInformation(validInfo);
       }
       // register next geo (is current), next flavor can be defined by filter
@@ -1569,14 +1636,6 @@ iFatras::McMaterialEffectsUpdator::interact(double time,
       m_particleBroker->push(childVector[i], parent);
     }
 
-    // register TruthIncident
-    ISF::ISFTruthIncident truth( const_cast<ISF::ISFParticle&>(*parent),
-                                 childVector,
-                                 process,
-                                 parent->nextGeoID(),  // inherits from the parent
-                                 ISF::fKillsPrimary );
-    m_truthRecordSvc->registerTruthIncident( truth);
-
     // save info for validation
     if (m_validationMode && m_validationTool) {
       Amg::Vector3D* nMom = nullptr;
@@ -1623,6 +1682,28 @@ iFatras::McMaterialEffectsUpdator::interact(double time,
                                         id
                                         );
 
+    // register TruthIncident
+    ISF::ISFTruthIncident truth( const_cast<ISF::ISFParticle&>(*parent),
+                                 children,
+                                 process,
+                                 parent->nextGeoID(),  // inherits from the parent
+                                 ISF::fPrimarySurvives );
+    m_truthRecordSvc->registerTruthIncident( truth);
+    // At this point we need to update the properties of the
+    // ISFParticles produced in the interaction
+    truth.updateParentAfterIncidentProperties();
+    truth.updateChildParticleProperties();
+
+    // Check that the new/updated ISFParticles have a valid TruthBinding
+    if (!parent->getTruthBinding()) {
+      ATH_MSG_ERROR("Could not retrieve TruthBinding from parent ISFParticle "<< *parent);
+    }
+    for (auto *childParticle : children) {
+      if (!childParticle->getTruthBinding()) {
+        ATH_MSG_ERROR("Could not retrieve TruthBinding from child ISFParticle "<< *childParticle);
+      }
+    }
+
     // in the validation mode, add process info
     if (m_validationMode) {
       ISF::ParticleUserInformation* validInfo1 = new ISF::ParticleUserInformation();
@@ -1637,14 +1718,6 @@ iFatras::McMaterialEffectsUpdator::interact(double time,
       children[1]->setUserInformation(validInfo2);
     }
 
-    // register TruthIncident
-    ISF::ISFTruthIncident truth( const_cast<ISF::ISFParticle&>(*parent),
-                                 children,
-                                 process,
-                                 parent->nextGeoID(),  // inherits from the parent
-                                 ISF::fPrimarySurvives );
-    m_truthRecordSvc->registerTruthIncident( truth);
-
     // push child particles onto stack
     m_particleBroker->push( children[0], parent);
     m_particleBroker->push( children[1], parent);
@@ -1664,12 +1737,12 @@ iFatras::McMaterialEffectsUpdator::interact(double time,
 
     auto parm = std::make_unique<Trk::NeutralCurvilinearParameters>(position,momentum,parent->charge());
 
-    bool cStat = m_conversionTool->doConversion(time, *parm);
+    bool cStat = m_conversionTool->doConversion(time, *parm); // Registers TruthIncident internally
 
     if (!cStat) ATH_MSG_WARNING( "Conversion failed, killing photon anyway ");
 
     // kill the mother particle
-     return nullptr;
+    return nullptr;
   }
 
   if (process==121) {    // hadronic interaction
@@ -1678,7 +1751,7 @@ iFatras::McMaterialEffectsUpdator::interact(double time,
 
     auto parm = std::make_unique<Trk::CurvilinearParameters>(position,momentum,parent->charge());
 
-    bool recHad = m_hadIntProcessor->doHadronicInteraction(time, position, momentum, extMatProp, particle, true);
+    bool recHad = m_hadIntProcessor->doHadronicInteraction(time, position, momentum, extMatProp, particle, true); // Registers TruthIncident internally
     // eventually : bool recHad =  m_hadIntProcessor->recordHadState( time, p, position, pDir, particle);
 
     // kill the track if interaction recorded --------------------------
@@ -1693,11 +1766,11 @@ iFatras::McMaterialEffectsUpdator::interact(double time,
 }
 
 ISF::ISFParticleVector  iFatras::McMaterialEffectsUpdator::interactLay(const ISF::ISFParticle* parent,
-								       double time,
-								       const Trk::TrackParameters& parm,
-								       Trk::ParticleHypothesis particle,
-								       int process,
-								       const Trk::MaterialProperties* extMatProp) const {
+                                                                       double time,
+                                                                       const Trk::TrackParameters& parm,
+                                                                       Trk::ParticleHypothesis particle,
+                                                                       int process,
+                                                                       const Trk::MaterialProperties* extMatProp) const {
   ISF::ISFParticleVector childVector(0);
 
   if ( process==0 ) return childVector;
@@ -1765,6 +1838,10 @@ ISF::ISFParticleVector  iFatras::McMaterialEffectsUpdator::interactLay(const ISF
                                  parent->nextGeoID(),  // inherits from the parent
                                  ISF::fPrimarySurvives );
     m_truthRecordSvc->registerTruthIncident( truth);
+    // At this point we need to update the properties of the
+    // ISFParticles produced in the interaction
+    truth.updateParentAfterIncidentProperties();
+    truth.updateChildParticleProperties();
 
     // save info for validation
     if (m_validationMode && m_validationTool) {
@@ -1773,12 +1850,14 @@ ISF::ISFParticleVector  iFatras::McMaterialEffectsUpdator::interactLay(const ISF
       delete nMom;
     }
 
-    //Making sure we get some correct truth info from parent if needed before pushing into the particle broker
-    if (!children[0]->getTruthBinding()) {
-	children[0]->setTruthBinding(new ISF::TruthBinding(*parent->getTruthBinding()));
+    // Check that the new/updated ISFParticles have a valid TruthBinding
+    if (!parent->getTruthBinding()) {
+      ATH_MSG_ERROR("Could not retrieve TruthBinding from parent ISFParticle "<< *parent);
     }
-    if (!children[1]->getTruthBinding()) {
-	children[1]->setTruthBinding(new ISF::TruthBinding(*parent->getTruthBinding()));
+    for (auto *childParticle : children) {
+      if (!childParticle->getTruthBinding()) {
+        ATH_MSG_ERROR("Could not retrieve TruthBinding from child ISFParticle "<< *childParticle);
+      }
     }
 
     return children;
@@ -1787,32 +1866,32 @@ ISF::ISFParticleVector  iFatras::McMaterialEffectsUpdator::interactLay(const ISF
   if (process==14) {  // photon conversion
 
     Trk::NeutralCurvilinearParameters neu(position,momentum,parent->charge());
-    childVector=m_conversionTool->doConversionOnLayer(parent, time, neu);
+    childVector=m_conversionTool->doConversionOnLayer(parent, time, neu); // Registers TruthIncident internally
 
     // validation mode
     if (m_validationMode && m_validationTool) {
 
       // add process info for children
       for (unsigned int i=0; i<childVector.size(); i++) {
-	ISF::ParticleUserInformation* validInfo = new ISF::ParticleUserInformation();
-	validInfo->setProcess(process);
-	if (parent->getUserInformation()) validInfo->setGeneration(parent->getUserInformation()->generation()+1);
-	else validInfo->setGeneration(1);     // assume parent is a primary track
-	childVector[i]->setUserInformation(validInfo);
+        ISF::ParticleUserInformation* validInfo = new ISF::ParticleUserInformation();
+        validInfo->setProcess(process);
+        if (parent->getUserInformation()) validInfo->setGeneration(parent->getUserInformation()->generation()+1);
+        else validInfo->setGeneration(1);     // assume parent is a primary track
+        childVector[i]->setUserInformation(validInfo);
       }
       // save interaction info
       if ( m_validationTool ) {
-	Amg::Vector3D* nMom = nullptr;
-	m_validationTool->saveISFVertexInfo(process, position,*parent,momentum,nMom,childVector);
-	delete nMom;
+        Amg::Vector3D* nMom = nullptr;
+        m_validationTool->saveISFVertexInfo(process, position,*parent,momentum,nMom,childVector);
+        delete nMom;
       }
     }
 
-    //Making sure we get some correct truth info from parent if needed before pushing into the particle broker
-    for (unsigned int i=0; i<childVector.size(); i++) {
-	if (!childVector[i]->getTruthBinding()) {
-		childVector[i]->setTruthBinding(new ISF::TruthBinding(*parent->getTruthBinding()));
-	}
+    // Check that the new ISFParticles have a valid TruthBinding
+    for (auto *childParticle : childVector) {
+      if (!childParticle->getTruthBinding()) {
+        ATH_MSG_ERROR("Could not retrieve TruthBinding from child ISFParticle "<< *childParticle);
+      }
     }
 
     return childVector;
@@ -1821,7 +1900,7 @@ ISF::ISFParticleVector  iFatras::McMaterialEffectsUpdator::interactLay(const ISF
   if (process==121) {    // hadronic interaction
 
     return ( m_hadIntProcessor->doHadIntOnLayer(parent, time, position, momentum,
-						extMatProp? &extMatProp->material() : nullptr, particle) );
+                                                extMatProp? &extMatProp->material() : nullptr, particle) );
 
   }
 
@@ -1830,10 +1909,10 @@ ISF::ISFParticleVector  iFatras::McMaterialEffectsUpdator::interactLay(const ISF
     // in the validation mode, add process info
     if (m_validationMode) {
       for (unsigned int i=0; i<childVector.size(); i++) {
-	ISF::ParticleUserInformation* validInfo = new ISF::ParticleUserInformation();
-	validInfo->setProcess(process);
-	if (parent->getUserInformation()) validInfo->setGeneration(parent->getUserInformation()->generation()+1);
-	else validInfo->setGeneration(1);     // assume parent is a primary track
+        ISF::ParticleUserInformation* validInfo = new ISF::ParticleUserInformation();
+        validInfo->setProcess(process);
+        if (parent->getUserInformation()) validInfo->setGeneration(parent->getUserInformation()->generation()+1);
+        else validInfo->setGeneration(1);     // assume parent is a primary track
         childVector[i]->setUserInformation(validInfo);
       }
     }
@@ -1845,6 +1924,9 @@ ISF::ISFParticleVector  iFatras::McMaterialEffectsUpdator::interactLay(const ISF
                                  parent->nextGeoID(),  // inherits from the parent
                                  ISF::fKillsPrimary );
     m_truthRecordSvc->registerTruthIncident( truth);
+    // At this point we need to update the properties of the
+    // ISFParticles produced in the interaction
+    truth.updateChildParticleProperties();
 
     // save info for validation
     if (m_validationMode && m_validationTool) {
@@ -1854,11 +1936,11 @@ ISF::ISFParticleVector  iFatras::McMaterialEffectsUpdator::interactLay(const ISF
     }
   }
 
-  //Making sure we get some correct truth info from parent if needed before pushing into the particle broker
-  for (unsigned int i=0; i<childVector.size(); i++) {
-	if (!childVector[i]->getTruthBinding()) {
-		childVector[i]->setTruthBinding(new ISF::TruthBinding(*parent->getTruthBinding()));
-	}
+  // Check that the new ISFParticles have a valid TruthBinding
+  for (auto *childParticle : childVector) {
+    if (!childParticle->getTruthBinding()) {
+      ATH_MSG_ERROR("Could not retrieve TruthBinding from child ISFParticle "<< *childParticle);
+    }
   }
 
   return childVector;
diff --git a/Simulation/ISF/ISF_Fatras/ISF_FatrasTools/src/PhotonConversionTool.cxx b/Simulation/ISF/ISF_Fatras/ISF_FatrasTools/src/PhotonConversionTool.cxx
index 528ad9ca62150995491b2a6bb27072f1dc716773..be5a1c512444307a170388afe1aa08404bab01f8 100755
--- a/Simulation/ISF/ISF_Fatras/ISF_FatrasTools/src/PhotonConversionTool.cxx
+++ b/Simulation/ISF/ISF_Fatras/ISF_FatrasTools/src/PhotonConversionTool.cxx
@@ -264,11 +264,6 @@ void iFatras::PhotonConversionTool::recordChilds(double time,
         ch1->setUserInformation(validInfo);
       }
       children[ichild] = ch1;
-      // FIXME Check this doesn't cause problems in the TruthSvc
-      if (!ch1->getTruthBinding()) {
-	ch1->setTruthBinding(new ISF::TruthBinding(*parent->getTruthBinding()));
-      }
-      m_particleBroker->push( ch1, parent);
       ichild++;
     }
 
@@ -293,11 +288,6 @@ void iFatras::PhotonConversionTool::recordChilds(double time,
         ch2->setUserInformation(validInfo);
       }
       children[ichild] = ch2;
-      // FIXME Check this doesn't cause problems in the TruthSvc
-      if (!ch2->getTruthBinding()) {
-        ch2->setTruthBinding(new ISF::TruthBinding(*parent->getTruthBinding()));
-      }
-      m_particleBroker->push( ch2, parent);
     }
 
     // register TruthIncident
@@ -307,6 +297,20 @@ void iFatras::PhotonConversionTool::recordChilds(double time,
                                  parent->nextGeoID(),
                                  ISF::fKillsPrimary );
     m_truthRecordSvc->registerTruthIncident( truth);
+    // At this point we need to update the properties of the
+    // ISFParticles produced in the interaction
+    truth.updateChildParticleProperties();
+
+    // push onto ParticleStack
+    if (!children.empty() ) {
+      for (auto *childParticle : children) {
+        //Check that the new ISFParticles have a valid TruthBinding
+        if (!childParticle->getTruthBinding()) {
+          ATH_MSG_ERROR("Could not retrieve TruthBinding from child ISFParticle "<< *childParticle);
+        }
+        m_particleBroker->push(childParticle, parent);
+      }
+    }
 
     // save info for validation
     if (m_validationMode && m_validationTool) {
@@ -324,6 +328,7 @@ ISF::ISFParticleVector iFatras::PhotonConversionTool::getChilds(const ISF::ISFPa
 								       const Amg::Vector3D& childDirection,
 								       Trk::ParticleHypothesis childType) const
 {
+  // Called by PhotonConversionTool::doConversionOnLayer
     // calculate the child momentum
     double p1 = sqrt(childEnergy*childEnergy-Trk::ParticleMasses::mass[childType]*Trk::ParticleMasses::mass[childType]);    
 
@@ -388,14 +393,15 @@ ISF::ISFParticleVector iFatras::PhotonConversionTool::getChilds(const ISF::ISFPa
                                  parent->nextGeoID(),
                                  ISF::fKillsPrimary );
     m_truthRecordSvc->registerTruthIncident( truth);
-
-    //Make sure the conversion products get a chance to have correct truth info before pushing into the particle broker
-    // FIXME Check this doesn't cause problems later in the TruthSvc
-    if (!children[0]->getTruthBinding()) {
-        children[0]->setTruthBinding(new ISF::TruthBinding(*parent->getTruthBinding()));
-    }
-    if (!children[1]->getTruthBinding()) {
-        children[1]->setTruthBinding(new ISF::TruthBinding(*parent->getTruthBinding()));
+    // At this point we need to update the properties of the
+    // ISFParticles produced in the interaction
+    truth.updateChildParticleProperties();
+
+    // Check that the new ISFParticles have a valid TruthBinding
+    for (auto *childParticle : children) {
+      if (!childParticle->getTruthBinding()) {
+        ATH_MSG_ERROR("Could not retrieve TruthBinding from child ISFParticle "<< *childParticle);
+      }
     }
 
     return children;
@@ -613,6 +619,7 @@ Amg::Vector3D iFatras::PhotonConversionTool::childDirection(const Amg::Vector3D&
 bool iFatras::PhotonConversionTool::doConversion(double time, const Trk::NeutralParameters& parm,
 						const Trk::ExtendedMaterialProperties* /*extMatProp*/) const {
 
+  // Called by McMaterialEffectsUpdator::interact
   double p = parm.momentum().mag();
 
   // get the energy
@@ -632,7 +639,7 @@ bool iFatras::PhotonConversionTool::doConversion(double time, const Trk::Neutral
                parm.momentum().unit(),
 	       childEnergy, p,
 	       childDir,
-	       Trk::electron);
+	       Trk::electron); // Registers TruthIncident internally
   // fill the TTree ----------------------------
   if (m_validationTree)
     m_validationTree->Fill();
@@ -644,7 +651,7 @@ bool iFatras::PhotonConversionTool::doConversion(double time, const Trk::Neutral
 ISF::ISFParticleVector iFatras::PhotonConversionTool::doConversionOnLayer(const ISF::ISFParticle* parent, 
 									 double time, const Trk::NeutralParameters& parm,
 									 const Trk::ExtendedMaterialProperties* /*ematprop*/) const {
-  
+  // Called by McMaterialEffectsUpdator::interactLay
   double p = parm.momentum().mag();
 
   // get the energy
@@ -668,7 +675,7 @@ ISF::ISFParticleVector iFatras::PhotonConversionTool::doConversionOnLayer(const
 		   parm.momentum().unit(),
 		   childEnergy, p,
 		   childDir,
-		   Trk::electron);
+		   Trk::electron); // Registers TruthIncident internally
 
 }
 
diff --git a/Simulation/ISF/ISF_Fatras/ISF_FatrasTools/src/TransportTool.cxx b/Simulation/ISF/ISF_Fatras/ISF_FatrasTools/src/TransportTool.cxx
index 9a517fe89023c89c52d90a46c5ec588a4e5321b6..7b097a056460714416d37c20be1dd9423e7a515e 100755
--- a/Simulation/ISF/ISF_Fatras/ISF_FatrasTools/src/TransportTool.cxx
+++ b/Simulation/ISF/ISF_Fatras/ISF_FatrasTools/src/TransportTool.cxx
@@ -243,7 +243,7 @@ ISF::ISFParticle* iFatras::TransportTool::process( const ISF::ISFParticle& isp,
   if ( freepath>0. && freepath<0.01 ) {
     if (!m_particleDecayHelper.empty()) {
       ATH_MSG_VERBOSE( "[ fatras transport ] Decay is triggered for input particle.");
-      m_particleDecayHelper->decay(isp,isp.position(),isp.momentum(),isp.timeStamp());
+      m_particleDecayHelper->decay(isp,isp.position(),isp.momentum(),isp.timeStamp()); // Registers TruthIncident internally
     }
 
     // validation mode - for all particle registered into stack
@@ -381,7 +381,7 @@ ISF::ISFParticle* iFatras::TransportTool::process( const ISF::ISFParticle& isp,
   if (uisp && timeLim.tMax>0.  && timeLim.time >=timeLim.tMax ) {
     if (!m_particleDecayHelper.empty()) {
       ATH_MSG_VERBOSE( "[ fatras transport ] Decay is triggered for input particle.");
-      m_particleDecayHelper->decay(*uisp,uisp->position(),uisp->momentum(),uisp->timeStamp());
+      m_particleDecayHelper->decay(*uisp,uisp->position(),uisp->momentum(),uisp->timeStamp()); // Registers TruthIncident internally
     }
     delete uisp;
     return nullptr;
diff --git a/Simulation/ISF/ISF_Fatras/ISF_FatrasToolsG4/src/G4HadIntProcessor.cxx b/Simulation/ISF/ISF_Fatras/ISF_FatrasToolsG4/src/G4HadIntProcessor.cxx
index 2dc8db93d025d11137c2f03ce32cfa990f621928..6e8d1c20ecae56bce40c4d6661205634b1496025 100644
--- a/Simulation/ISF/ISF_Fatras/ISF_FatrasToolsG4/src/G4HadIntProcessor.cxx
+++ b/Simulation/ISF/ISF_Fatras/ISF_FatrasToolsG4/src/G4HadIntProcessor.cxx
@@ -495,16 +495,6 @@ ISF::ISFParticleVector iFatras::G4HadIntProcessor::getHadState(const ISF::ISFPar
       const G4ThreeVector &momG4 = dynPar->GetMomentum();
       Amg::Vector3D mom( momG4.x(), momG4.y(), momG4.z() );
 
-      //Let's make sure the new ISFParticles get a valid TruthBinding
-      // FIXME check that this does not cause problems in the TruthSvc
-      ISF::TruthBinding* truthBinding{};
-      if (parent->getTruthBinding()) {
-        ATH_MSG_VERBOSE("Could retrieve TruthBinding from original ISFParticle");
-        truthBinding = new ISF::TruthBinding(*parent->getTruthBinding());
-      }
-      else {
-        ATH_MSG_WARNING("Could not retrieve TruthBinding from original ISFParticle, might cause issues later on.");
-      }
       const int status = 1 + HepMC::SIM_STATUS_THRESHOLD;
       const int id = HepMC::UNDEFINED_ID;
       ISF::ISFParticle* cParticle = new ISF::ISFParticle( position,
@@ -515,9 +505,7 @@ ISF::ISFParticleVector iFatras::G4HadIntProcessor::getHadState(const ISF::ISFPar
                                                           status,
                                                           time,
                                                           *parent,
-                                                          id,
-                                                          HepMC::UNDEFINED_ID, // barcode
-                                                          truthBinding );
+                                                          id );
       cParticle->setNextGeoID( parent->nextGeoID() );
       cParticle->setNextSimID( parent->nextSimID() );
       // process sampling tool takes care of validation info
@@ -526,7 +514,25 @@ ISF::ISFParticleVector iFatras::G4HadIntProcessor::getHadState(const ISF::ISFPar
     }
 
     children.resize(numChildren);
-    // truth info handled by process sampling tool
+
+    // register TruthIncident
+    const int processForTI  = 121; // Hadronic interaction
+    ISF::ISFTruthIncident truth( const_cast<ISF::ISFParticle&>(*parent),
+                                 children,
+                                 processForTI,
+                                 parent->nextGeoID(),  // inherits from the parent
+                                 ISF::fKillsPrimary );
+    m_truthRecordSvc->registerTruthIncident( truth);
+    // At this point we need to update the properties of the
+    // ISFParticles produced in the interaction
+    truth.updateChildParticleProperties();
+
+    // Check that the new ISFParticles have a valid TruthBinding
+    for (auto *childParticle : children) {
+      if (!childParticle->getTruthBinding()) {
+        ATH_MSG_ERROR("Could not retrieve TruthBinding from child ISFParticle "<< *childParticle);
+      }
+    }
 
     // free up memory
     g4change->Clear();
@@ -546,25 +552,25 @@ bool iFatras::G4HadIntProcessor::doHadronicInteraction(double time, const Amg::V
 						       Trk::ParticleHypothesis /*particle*/,
 						       bool  processSecondaries) const
 {
+  // Called by G4HadIntProcessor::hadronicInteraction and McMaterialEffectsUpdator::interact
   // get parent particle
   // @TODO: replace by Fatras internal bookkeeping
   const ISF::ISFParticle *parent = ISF::ParticleClipboard::getInstance().getParticle();
   // something is seriously wrong if there is no parent particle
   assert(parent);
 
-  ISF::ISFParticleVector ispVec=getHadState(parent, time, position, momentum, ematprop);
+  ISF::ISFParticleVector ispVec=getHadState(parent, time, position, momentum, ematprop); // Registers TruthIncident interally
 
-  if (!ispVec.size()) return false;
+  if (ispVec.empty()) return false; // FIXME Inconsistent with HadIntProcessorParametric::doHadronicInteraction
 
   // push onto ParticleStack
-
   if (processSecondaries) {
-    for (unsigned int ic=0; ic<ispVec.size(); ic++) {
-	//First let's make sure that new ISFParticles have valid truth info
-	if (!ispVec[ic]->getTruthBinding()) {
-		ispVec[ic]->setTruthBinding(new ISF::TruthBinding(*parent->getTruthBinding()));
-	}
-	m_particleBroker->push(ispVec[ic], parent);
+    for (auto *childParticle : ispVec) {
+      //Check that the new ISFParticles have a valid TruthBinding
+      if (!childParticle->getTruthBinding()) {
+        ATH_MSG_ERROR("Could not retrieve TruthBinding from child ISFParticle "<< *childParticle);
+      }
+      m_particleBroker->push(childParticle, parent);
     }
   }
 
@@ -578,7 +584,7 @@ ISF::ISFParticleVector iFatras::G4HadIntProcessor::doHadIntOnLayer(const ISF::IS
 								   Trk::ParticleHypothesis /*particle=Trk::pion*/) const
 {
 
-  return getHadState(parent, time, position, momentum, emat);
+  return getHadState(parent, time, position, momentum, emat); // Registers TruthIncident interally
 
 }
 
diff --git a/Simulation/ISF/ISF_Fatras/ISF_FatrasToolsG4/src/G4ParticleDecayHelper.cxx b/Simulation/ISF/ISF_Fatras/ISF_FatrasToolsG4/src/G4ParticleDecayHelper.cxx
index ca606257cab89078c2faed019c988329ec6695c4..6e11f6076282be539c4c48d17cc9e9cc58dc62ac 100644
--- a/Simulation/ISF/ISF_Fatras/ISF_FatrasToolsG4/src/G4ParticleDecayHelper.cxx
+++ b/Simulation/ISF/ISF_Fatras/ISF_FatrasToolsG4/src/G4ParticleDecayHelper.cxx
@@ -206,62 +206,65 @@ void iFatras::G4ParticleDecayHelper::decay(const ISF::ISFParticle& particleToDec
   const ISF::ISFParticleVector decayProducts = decayParticle(particleToDecay,vertex,momentum,timeStamp);
 
   // fill them into broker & truth svc
-  handleDecayParticles(particleToDecay,decayProducts);
+  handleDecayParticles(particleToDecay,decayProducts); // Registers TruthIncident internally
 }
 
-                
+
 void iFatras::G4ParticleDecayHelper::handleDecayParticles(const ISF::ISFParticle& particle,
                                                           const ISF::ISFParticleVector& decayProducts) const {
    // process the decay products ---------------------------------------
   int                 process = 201;
-   // (i) none       
+
+  // (i) none
    if (!decayProducts.size()) {
         ATH_MSG_WARNING("[ decay ] Particle Decay Creator did not return any"
             << " decay products for particle with PDG code "
-            << particle.pdgCode() );       
+            << particle.pdgCode() );
    } else {
    // (ii) many
       std::ostringstream productSummaryString;
       productSummaryString << "[ decay ] products:";
-      //!< @TODO
-      // truth service !!!
-      // simulate the tracks of the daughter particles ------- run over decay products
-      
-      ISF::ISFParticleVector::const_iterator decayProductsItr = decayProducts.begin();
-      for (; decayProductsItr != decayProducts.end(); ++decayProductsItr)
-      {
-	productSummaryString << "     - "  << (**decayProductsItr) << '\n';
-	// in the validation mode, add process info
-	if (m_validationMode) {
-	  ISF::ParticleUserInformation* validInfo = new ISF::ParticleUserInformation();
-	  validInfo->setProcess(process);
-	  if (particle.getUserInformation()) validInfo->setGeneration(particle.getUserInformation()->generation()+1);
-	  else validInfo->setGeneration(1);     // assume parent is a primary track
-	  (*decayProductsItr)->setUserInformation(validInfo);
-	}
-	// register next geo (is current), next flavor can be defined by filter
-	(*decayProductsItr)->setNextGeoID( particle.nextGeoID() );
-	// feed it the particle broker with parent information
-	m_particleBroker->push(*decayProductsItr, &particle);
+
+      for (ISF::ISFParticle *decayProduct : decayProducts) {
+        productSummaryString << "     - "  << (*decayProduct) << '\n';
+        // in the validation mode, add process info
+        if (m_validationMode) {
+          ISF::ParticleUserInformation* validInfo = new ISF::ParticleUserInformation();
+          validInfo->setProcess(process);
+          if (particle.getUserInformation()) validInfo->setGeneration(particle.getUserInformation()->generation()+1);
+          else validInfo->setGeneration(1);     // assume parent is a primary track
+          decayProduct->setUserInformation(validInfo);
+        }
+        // register next geo (is current), next flavor can be defined by filter
+        decayProduct->setNextGeoID( particle.nextGeoID() );
       }//loop over all decay products
-      ATH_MSG_VERBOSE(  productSummaryString.str() );     
 
       // register TruthIncident
       ISF::ISFTruthIncident truth( const_cast<ISF::ISFParticle&>(particle),
-				   decayProducts,
-				   process,
-				   particle.nextGeoID(),  // inherits from the parent
-				   ISF::fKillsPrimary );
+                                   decayProducts,
+                                   process,
+                                   particle.nextGeoID(),  // inherits from the parent
+                                   ISF::fKillsPrimary );
       m_truthRecordSvc->registerTruthIncident( truth);
-      
+      // At this point we need to update the properties of the
+      // ISFParticles produced in the interaction
+      truth.updateChildParticleProperties();
+
+      // simulate the tracks of the daughter particles ------- run over decay products
+      for (ISF::ISFParticle *decayProduct : decayProducts) {
+        // feed it the particle broker with parent information
+        m_particleBroker->push(decayProduct, &particle);
+      }//loop over all decay products
+      ATH_MSG_VERBOSE(  productSummaryString.str() );
+
       // save info for validation
       if (m_validationMode && m_validationTool) {
-	Amg::Vector3D* nMom = 0;
-	m_validationTool->saveISFVertexInfo(process,particle.position(),particle,particle.momentum(),nMom,decayProducts);
-	delete nMom;
+        Amg::Vector3D* nMom = 0;
+        m_validationTool->saveISFVertexInfo(process,particle.position(),particle,particle.momentum(),nMom,decayProducts);
+        delete nMom;
       }
 
-    }    
+    }
 }
 
 std::vector<ISF::ISFParticle*>
@@ -270,6 +273,7 @@ iFatras::G4ParticleDecayHelper::decayParticle(const ISF::ISFParticle& parent,
                                                const Amg::Vector3D& momentum,
                                                double timeStamp) const
 {
+  // Called from McMaterialEffectsUpdator::interact, McMaterialEffectsUpdator::interactLay and G4ParticleDecayHelper::decay
   // return vector for children
   std::vector<ISF::ISFParticle*> children;
 
@@ -368,14 +372,6 @@ iFatras::G4ParticleDecayHelper::decayParticle(const ISF::ISFParticle& parent,
     const G4ThreeVector &mom= prod->GetMomentum();
     Amg::Vector3D amgMom( mom.x(), mom.y(), mom.z() );
 
-    //Let's make sure the new ISFParticles get a valid TruthBinding
-    // FIXME check that this does not cause problems in the TruthSvc
-    ISF::TruthBinding* truthBinding{};
-    if (parent.getTruthBinding()) {
-      ATH_MSG_VERBOSE("Could retrieve TruthBinding from original ISFParticle");
-      truthBinding = new ISF::TruthBinding(*parent.getTruthBinding());
-    }
-    else { ATH_MSG_WARNING("Could not retrieve original TruthBinding  from ISFParticle"); }
     const int status = 1 + HepMC::SIM_STATUS_THRESHOLD;
     const int id = HepMC::UNDEFINED_ID;
     ISF::ISFParticle* childParticle = new ISF::ISFParticle( vertex,
@@ -386,9 +382,7 @@ iFatras::G4ParticleDecayHelper::decayParticle(const ISF::ISFParticle& parent,
                                                             status,
                                                             timeStamp,
                                                             parent,
-                                                            id,
-							    HepMC::UNDEFINED_ID, // barcode
-							    truthBinding );
+                                                            id );
 
     children.push_back( childParticle);
   }