diff --git a/Simulation/Barcode/BarcodeInterfaces/BarcodeInterfaces/IBarcodeSvc.h b/Simulation/Barcode/BarcodeInterfaces/BarcodeInterfaces/IBarcodeSvc.h
index d6e28fbbfc7a2bceb5c25732c83d57def8e1f0b2..f90638831cdd0b0df0d4b158dc42d8fc5d5414e8 100644
--- a/Simulation/Barcode/BarcodeInterfaces/BarcodeInterfaces/IBarcodeSvc.h
+++ b/Simulation/Barcode/BarcodeInterfaces/BarcodeInterfaces/IBarcodeSvc.h
@@ -33,6 +33,11 @@ namespace Barcode {
     ///////////////////////////////////////////////////////////////////
   public:
 
+    //TODO not fully implemented in Generic, Global, and Validation BarcodeSvcs
+    //only fully implemented in LegacyBarcodeSvc (only barcode service used in production)
+    virtual StatusCode initializeBarcodes() { return StatusCode::SUCCESS; };
+    virtual StatusCode resetBarcodes() { return StatusCode::SUCCESS; };
+
     /// Creates the InterfaceID and interfaceID() method
     DeclareInterfaceID(IBarcodeSvc, 1 , 0);
 
diff --git a/Simulation/Barcode/BarcodeServices/BarcodeServices/LegacyBarcodeSvc.h b/Simulation/Barcode/BarcodeServices/BarcodeServices/LegacyBarcodeSvc.h
index 51c4eb5bc3b557eb90f41e491281ae7ea1b72029..341b1dea4da00a22e78c6cc1100481d9938cc3d5 100644
--- a/Simulation/Barcode/BarcodeServices/BarcodeServices/LegacyBarcodeSvc.h
+++ b/Simulation/Barcode/BarcodeServices/BarcodeServices/LegacyBarcodeSvc.h
@@ -13,7 +13,6 @@
 #include <string>
 
 // FrameWork includes
-#include "GaudiKernel/IIncidentListener.h"
 #include "GaudiKernel/ServiceHandle.h"
 #include "AthenaBaseComps/AthService.h"
 
@@ -23,7 +22,8 @@
 
 #include "BarcodeServices/BitCalculator.h"
 
-class IIncidentSvc;
+#include "tbb/concurrent_unordered_map.h"
+
 
 
 namespace Barcode {
@@ -36,7 +36,7 @@ namespace Barcode {
       @author Andreas.Salzburger -at- cern.ch , Elmar.Ritsch -at- cern.ch
   */
 
-  class LegacyBarcodeSvc : public extends<AthService, IBarcodeSvc, IIncidentListener> {
+  class LegacyBarcodeSvc : public extends<AthService, IBarcodeSvc> {
   public:
 
     /** Constructor with parameters */
@@ -49,8 +49,11 @@ namespace Barcode {
     StatusCode  initialize();
     StatusCode  finalize();
 
-    /** Incident to reset the barcodes at the beginning of the event */
-    void handle(const Incident& inc);
+    /** Construct and insert a new set of barcode members. To be called for every new thread. */
+    virtual StatusCode initializeBarcodes() override;
+
+    /** Reset barcodes. To be called at the beginning of each event. */
+    virtual StatusCode resetBarcodes() override;
 
     /** Generate a new unique vertex barcode, based on the parent particle barcode and
         the physics process code causing the truth vertex*/
@@ -90,7 +93,6 @@ namespace Barcode {
     virtual inline bool hasBitCalculator() const { return (m_bitcalculator!=0); }
 
   private:
-    ServiceHandle<IIncidentSvc>                   m_incidentSvc;   //!< IncidentSvc to catch begin of event and end of envent
 
     /** bitwise utility calculator for barcodes */
     Barcode::BitCalculator*                       m_bitcalculator;
@@ -110,6 +112,20 @@ namespace Barcode {
 
     /** throw error messages if a possible overflow is detected */
     bool                                          m_doUnderOverflowChecks;
+
+    struct BarcodeInfo {
+        BarcodeInfo() = delete;
+        BarcodeInfo(VertexBarcode cv, ParticleBarcode cs) : currentVertex(cv), currentSecondary(cs) {};
+        VertexBarcode currentVertex;
+        ParticleBarcode currentSecondary;
+    };
+
+    using LegacyBarcodeSvcThreadMap_t = tbb::concurrent_unordered_map
+        < std::thread::id, BarcodeInfo, std::hash<std::thread::id> >;
+    LegacyBarcodeSvcThreadMap_t m_bcThreadMap;
+
+    BarcodeInfo& getBarcodeInfo() const;
+
   };
 
 
diff --git a/Simulation/Barcode/BarcodeServices/src/LegacyBarcodeSvc.cxx b/Simulation/Barcode/BarcodeServices/src/LegacyBarcodeSvc.cxx
index c9b816962b0ca764b71ee8ed21adfb58c1375ff2..633e382e0509406d02fe738649352720c98910f2 100644
--- a/Simulation/Barcode/BarcodeServices/src/LegacyBarcodeSvc.cxx
+++ b/Simulation/Barcode/BarcodeServices/src/LegacyBarcodeSvc.cxx
@@ -8,13 +8,11 @@
 
 #include "BarcodeServices/LegacyBarcodeSvc.h"
 // framework include
-#include "GaudiKernel/IIncidentSvc.h"
 
 
 /** Constructor **/
 Barcode::LegacyBarcodeSvc::LegacyBarcodeSvc(const std::string& name,ISvcLocator* svc) :
   base_class(name,svc),
-  m_incidentSvc("IncidentSvc", name),
   m_bitcalculator(new Barcode::BitCalculator()),
   m_firstVertex(-200001),
   m_vertexIncrement(-1),
@@ -45,33 +43,69 @@ Barcode::LegacyBarcodeSvc::~LegacyBarcodeSvc()
 StatusCode Barcode::LegacyBarcodeSvc::initialize()
 {
   ATH_MSG_VERBOSE ("initialize() ...");
+  ATH_MSG_DEBUG( "LegacyBarcodeSvc start of initialize in thread ID: " << std::this_thread::get_id() );
 
-  CHECK( m_incidentSvc.retrieve() );
-
-  // register to the incident service: BeginEvent needed for refresh of counter
-  m_incidentSvc->addListener( this, IncidentType::BeginEvent);
+  ATH_CHECK( this->initializeBarcodes() );
 
   ATH_MSG_VERBOSE ("initialize() successful");
   return StatusCode::SUCCESS;
 }
 
+StatusCode Barcode::LegacyBarcodeSvc::initializeBarcodes() {
+    static std::mutex barcodeMutex;
+    std::lock_guard<std::mutex> barcodeLock(barcodeMutex);
+    ATH_MSG_DEBUG( name() << "::initializeBarcodes()" );
+
+  // look for pair containing barcode info using the thread ID
+  // if it doesn't exist, construct one and insert it.
+  const auto tid = std::this_thread::get_id();
+  auto bcPair = m_bcThreadMap.find(tid);
+  if ( bcPair == m_bcThreadMap.end() ) {
+      auto result = m_bcThreadMap.insert( std::make_pair( tid, BarcodeInfo(m_currentVertex, m_currentSecondary)) );
+      if (result.second) {
+          ATH_MSG_DEBUG( "initializeBarcodes: initialized new barcodes for thread ID " << tid );
+          ATH_CHECK( this->resetBarcodes() );
+          ATH_MSG_DEBUG( "initializeBarcodes: reset new barcodes for thread ID " << tid );
+      } else {
+          ATH_MSG_ERROR( "initializeBarcodes: failed to initialize new barcode for thread ID " << tid );
+      }
+  } else {
+      ATH_MSG_DEBUG( "initializeBarcodes: barcodes for this thread ID found, did not construct new" );
+      ATH_CHECK( this->resetBarcodes() );
+      ATH_MSG_DEBUG( "initializeBarcodes: reset existing barcodes for thread ID " << tid );
+  }
+  return StatusCode::SUCCESS;
+}
+
+//FIXME this should return an optional type, since returning the value of the end iterator is undefined behaviour (I think it causes a segfault).
+Barcode::LegacyBarcodeSvc::BarcodeInfo& Barcode::LegacyBarcodeSvc::getBarcodeInfo() const {
+    const auto tid = std::this_thread::get_id();
+    auto bcPair = m_bcThreadMap.find(tid);
+    if ( bcPair == m_bcThreadMap.end() ) {
+        ATH_MSG_ERROR( "getBarcodeInfo: failed to get BarcodeInfo for thread ID " << tid );
+        return bcPair->second;
+    } else {
+        return bcPair->second;
+    }
+}
 
 /** Generate a new unique vertex barcode, based on the parent particle barcode and
     the physics process code causing the truth vertex*/
 Barcode::VertexBarcode Barcode::LegacyBarcodeSvc::newVertex( Barcode::ParticleBarcode /* parent */,
                                                              Barcode::PhysicsProcessCode /* process */)
 {
-  m_currentVertex += m_vertexIncrement;
+  BarcodeInfo& bc = getBarcodeInfo();
+  bc.currentVertex += m_vertexIncrement;
   // a naive underflog checking based on the fact that vertex
   // barcodes should never be positive
-  if ( m_doUnderOverflowChecks && (m_currentVertex > 0))
+  if ( m_doUnderOverflowChecks && (bc.currentVertex > 0))
     {
       ATH_MSG_ERROR("LegacyBarcodeSvc::newVertex(...)"
                     << " will return a vertex barcode greater than 0: "
-                    << m_currentVertex << ". Possibly Integer Underflow?");
+                    << bc.currentVertex << ". Possibly Integer Underflow?");
     }
 
-  return m_currentVertex;
+  return bc.currentVertex;
 }
 
 
@@ -81,19 +115,20 @@ Barcode::VertexBarcode Barcode::LegacyBarcodeSvc::newVertex( Barcode::ParticleBa
 Barcode::ParticleBarcode Barcode::LegacyBarcodeSvc::newSecondary( Barcode::ParticleBarcode /* parentBC */,
                                                                   Barcode::PhysicsProcessCode /* process */)
 {
-  m_currentSecondary += m_secondaryIncrement;
+  BarcodeInfo& bc = getBarcodeInfo();
+  bc.currentSecondary += m_secondaryIncrement;
   // a naive overflow checking based on the fact that particle
   // barcodes should never be negative
-  if ( m_doUnderOverflowChecks && (m_currentSecondary < 0))
+  if ( m_doUnderOverflowChecks && (bc.currentSecondary < 0))
     {
       ATH_MSG_DEBUG("LegacyBarcodeSvc::newSecondary(...)"
                     << " will return a particle barcode of less than 0: "
-                    << m_currentSecondary << ". Reset to zero.");
+                    << bc.currentSecondary << ". Reset to zero.");
 
-      m_currentSecondary = Barcode::fUndefinedBarcode;
+      bc.currentSecondary = Barcode::fUndefinedBarcode;
     }
 
-  return m_currentSecondary;
+  return bc.currentSecondary;
 }
 
 
@@ -152,16 +187,13 @@ Barcode::ParticleBarcode Barcode::LegacyBarcodeSvc::particleGenerationIncrement(
   return m_particleGenerationIncrement;
 }
 
-
-/** Handle incident */
-void Barcode::LegacyBarcodeSvc::handle(const Incident& inc)
+StatusCode Barcode::LegacyBarcodeSvc::resetBarcodes()
 {
-  if ( inc.type() == IncidentType::BeginEvent )
-    {
-      ATH_MSG_VERBOSE("'BeginEvent' incident caught. Resetting Vertex and Particle barcode counters.");
-      m_currentVertex    = m_firstVertex    - m_vertexIncrement;
-      m_currentSecondary = m_firstSecondary - m_secondaryIncrement;
-    }
+    ATH_MSG_DEBUG( "resetBarcodes: resetting barcodes" );
+    BarcodeInfo& bc = getBarcodeInfo();
+    bc.currentVertex    = m_firstVertex    - m_vertexIncrement;
+    bc.currentSecondary = m_firstSecondary - m_secondaryIncrement;
+    return StatusCode::SUCCESS;
 }
 
 
diff --git a/Simulation/G4Atlas/G4AtlasAlg/CMakeLists.txt b/Simulation/G4Atlas/G4AtlasAlg/CMakeLists.txt
index fcd25f3b0d79a3985f6e5964735e21dbca503b45..73f0687c14d315c6e844c9ca89c67f787c143c68 100644
--- a/Simulation/G4Atlas/G4AtlasAlg/CMakeLists.txt
+++ b/Simulation/G4Atlas/G4AtlasAlg/CMakeLists.txt
@@ -21,7 +21,8 @@ atlas_depends_on_subdirs( PUBLIC
                           Simulation/G4Atlas/G4AtlasTools
                           Simulation/G4Sim/MCTruth
                           Simulation/G4Sim/MCTruthBase
-                          Simulation/ISF/ISF_Core/ISF_Interfaces)
+                          Simulation/ISF/ISF_Core/ISF_Interfaces
+                          Simulation/Barcode/BarcodeInterfaces)
 
 # External dependencies:
 find_package( CLHEP )
diff --git a/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasAlg.cxx b/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasAlg.cxx
index e963695b27014340fe86dcff492831c901e99b8a..51497be66d0da8f120aa7c3652214e15e519a38e 100644
--- a/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasAlg.cxx
+++ b/Simulation/G4Atlas/G4AtlasAlg/src/G4AtlasAlg.cxx
@@ -273,7 +273,7 @@ StatusCode G4AtlasAlg::execute()
   }
 
   // tell TruthService we're starting a new event
-  ATH_CHECK( m_truthRecordSvc->initializeTruthCollection() ); //FIXME POINTLESS - THIS METHOD IS EMPTY IN MASTER
+  ATH_CHECK( m_truthRecordSvc->initializeTruthCollection() );
 
   // Release GeoModel Geometry if necessary
   if (m_releaseGeoModel) {
diff --git a/Simulation/ISF/ISF_Core/ISF_Services/src/TruthSvc.cxx b/Simulation/ISF/ISF_Core/ISF_Services/src/TruthSvc.cxx
index 3ff3e891ecb595fc45683867478e103268d866dc..13c532fcd0f60614a4fa7d1f015c9345a85ccadf 100644
--- a/Simulation/ISF/ISF_Core/ISF_Services/src/TruthSvc.cxx
+++ b/Simulation/ISF/ISF_Core/ISF_Services/src/TruthSvc.cxx
@@ -127,6 +127,7 @@ StatusCode ISF::TruthSvc::finalize()
 /** Initialize the TruthSvc and the truthSvc */
 StatusCode ISF::TruthSvc::initializeTruthCollection()
 {
+  ATH_CHECK( m_barcodeSvc->initializeBarcodes() );
   return StatusCode::SUCCESS;
 }
 
diff --git a/Simulation/ISF/ISF_Core/ISF_Services/test/TruthSvc_test.cxx b/Simulation/ISF/ISF_Core/ISF_Services/test/TruthSvc_test.cxx
index 707f2b87aacb67627315aeb4ff50840c736a4724..b1d78f4c4bf0989ffab2f0001fc8fc889cdbd390 100644
--- a/Simulation/ISF/ISF_Core/ISF_Services/test/TruthSvc_test.cxx
+++ b/Simulation/ISF/ISF_Core/ISF_Services/test/TruthSvc_test.cxx
@@ -306,7 +306,7 @@ namespace ISFTesting {
 
     ASSERT_EQ( vtxPosition, generated->position() );
     ASSERT_EQ( 1021, generated->id() );
-    ASSERT_EQ( -2, generated->barcode() );
+    ASSERT_EQ( -200001, generated->barcode() );
     ASSERT_EQ( 1, generated->particles_in_size());
     ASSERT_EQ( 0, generated->particles_out_size());
     ASSERT_EQ( inParticle3, *(generated->particles_in_const_begin()));
@@ -358,10 +358,10 @@ namespace ISFTesting {
       .WillOnce(::testing::Return(nullptr));
 
     recordIncidentToMCTruth(ti);
-    HepMC::GenVertex* generated = anEvent->barcode_to_vertex(-2); //Find a nicer way to get this.
+    HepMC::GenVertex* generated = anEvent->barcode_to_vertex(-200001); //Find a nicer way to get this.
     ASSERT_EQ( vtxPosition, generated->position() );
     ASSERT_EQ( 1021, generated->id() );
-    ASSERT_EQ( -2, generated->barcode() ); // by construction at the moment
+    ASSERT_EQ( -200001, generated->barcode() ); // by construction at the moment
     ASSERT_EQ( 1, generated->particles_in_size());
     ASSERT_EQ( 0, generated->particles_out_size());
     ASSERT_EQ( inParticle3, *(generated->particles_in_const_begin()));
@@ -404,7 +404,7 @@ namespace ISFTesting {
       .WillOnce(::testing::Return(inParticle3->barcode()));
 
     registerTruthIncident(ti);
-    HepMC::GenVertex* generated = anEvent->barcode_to_vertex(-2); //Find a nicer way to get this.
+    HepMC::GenVertex* generated = anEvent->barcode_to_vertex(-200001); //Find a nicer way to get this.
     HepMC::GenVertex* expectedVtx(nullptr);
     ASSERT_EQ( expectedVtx, generated);
   }
@@ -454,10 +454,10 @@ namespace ISFTesting {
       .WillOnce(::testing::Return(inParticle3));
 
     registerTruthIncident(ti);
-    HepMC::GenVertex* generated = anEvent->barcode_to_vertex(-2); //Find a nicer way to get this.
+    HepMC::GenVertex* generated = anEvent->barcode_to_vertex(-200001); //Find a nicer way to get this.
     ASSERT_EQ( vtxPosition, generated->position() );
     ASSERT_EQ( 1021, generated->id() );
-    ASSERT_EQ( -2, generated->barcode() ); // by construction at the moment
+    ASSERT_EQ( -200001, generated->barcode() ); // by construction at the moment
     ASSERT_EQ( 1, generated->particles_in_size());
     ASSERT_EQ( 0, generated->particles_out_size());
     ASSERT_EQ( inParticle3, *(generated->particles_in_const_begin()));
@@ -524,10 +524,10 @@ namespace ISFTesting {
       .WillOnce(::testing::Return(false));
 
     registerTruthIncident(ti);
-    HepMC::GenVertex* generated = anEvent->barcode_to_vertex(-2); //Find a nicer way to get this.
+    HepMC::GenVertex* generated = anEvent->barcode_to_vertex(-200001); //Find a nicer way to get this.
     ASSERT_EQ( vtxPosition, generated->position() );
     ASSERT_EQ( 1021, generated->id() );
-    ASSERT_EQ( -2, generated->barcode() ); // by construction at the moment
+    ASSERT_EQ( -200001, generated->barcode() ); // by construction at the moment
     ASSERT_EQ( 1, generated->particles_in_size());
     ASSERT_EQ( 0, generated->particles_out_size());
     ASSERT_EQ( inParticle3, *(generated->particles_in_const_begin()));
@@ -597,10 +597,10 @@ namespace ISFTesting {
       .WillOnce(::testing::Return(true));
 
     registerTruthIncident(ti);
-    HepMC::GenVertex* generated = anEvent->barcode_to_vertex(-2); //Find a nicer way to get this.
+    HepMC::GenVertex* generated = anEvent->barcode_to_vertex(-200001); //Find a nicer way to get this.
     ASSERT_EQ( vtxPosition, generated->position() );
     ASSERT_EQ( 1021, generated->id() );
-    ASSERT_EQ( -2, generated->barcode() ); // by construction at the moment
+    ASSERT_EQ( -200001, generated->barcode() ); // by construction at the moment
     ASSERT_EQ( 1, generated->particles_in_size());
     ASSERT_EQ( inParticle3, *(generated->particles_in_const_begin()));
     ASSERT_EQ( 1, generated->particles_out_size());