diff --git a/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/SiSPSeededTrackFinderData/SiDetElementRoadMakerData_xk.h b/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/SiSPSeededTrackFinderData/SiDetElementRoadMakerData_xk.h
new file mode 100644
index 0000000000000000000000000000000000000000..260bbdc0dd4ae3cce7e408ba86f957c7baea578f
--- /dev/null
+++ b/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/SiSPSeededTrackFinderData/SiDetElementRoadMakerData_xk.h
@@ -0,0 +1,64 @@
+// -*- C++ -*-
+
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+/////////////////////////////////////////////////////////////////////////////////
+// Header file for class SiDetElementRoadMakerData_xk
+/////////////////////////////////////////////////////////////////////////////////
+
+#ifndef SiDetElementRoadMakerData_xk_H
+#define SiDetElementRoadMakerData_xk_H
+
+
+#include <vector>
+#include <array>
+
+namespace InDet {
+
+ /**
+    @class SiDetElementRoadMakerData_xk
+  
+    InDet::SiDetElementRoadMakerData_xk holds event dependent data
+    used by SiDetElementRoadMaker_xk. 
+    @author goblirsc@cern.ch
+  */
+
+  class SiDetElementRoadMakerData_xk {
+
+  public:
+
+    /// trivial constructor - the members of this event 
+    /// data struct need client tool information for 
+    /// initialisation, hence this is done at client-level. 
+    SiDetElementRoadMakerData_xk(){}
+
+    /// Default destructor
+    ~SiDetElementRoadMakerData_xk() = default;
+    
+    /// method to reset the flags stored in the elementUsageTracker
+    /// (below) when building a new search road. Does not perform any
+    /// allocations, but resets the existing slots. 
+    void resetUsageTracker();
+
+    /// Following the pattern established for example in the 
+    /// seed-maker event data, we use public members directly
+    /// rather than exposing private members with full read-write-access. 
+    /// This has the advantage that the members can be intialized by the 
+    /// client tools, which provide the tools needed to do so. 
+
+    /// This is a data structure used to track which of our detector elements 
+    /// are already on a search road. Nested in the hierarchy of 
+    /// detector region - layer - module within layer. 
+    /// Dynamic to avoid hard-coding a certain geometry. 
+    typedef std::array<std::vector<std::vector<bool> >,3> ElementUsageTracker;
+    ElementUsageTracker elementUsageTracker;
+
+    /// Flag to check if the event data was already initialized by the client tool. 
+    bool isInitialized{false}; 
+  };
+
+} // end of name space
+
+#endif // SiDetElementRoadMakerData_xk_H
diff --git a/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/SiSPSeededTrackFinderData/SiTrackMakerEventData_xk.h b/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/SiSPSeededTrackFinderData/SiTrackMakerEventData_xk.h
index 581edcba438fe0580ecfe04e0a9a3877b75b3f58..f937ac6afcd40f3a186b278e3358d350d8963e6e 100644
--- a/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/SiSPSeededTrackFinderData/SiTrackMakerEventData_xk.h
+++ b/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/SiSPSeededTrackFinderData/SiTrackMakerEventData_xk.h
@@ -12,6 +12,7 @@
 #define SiTrackMakerEventData_xk_H
 
 #include "SiSPSeededTrackFinderData/SeedToTrackConversionData.h"
+#include "SiSPSeededTrackFinderData/SiDetElementRoadMakerData_xk.h"
 #include "SiSPSeededTrackFinderData/SiCombinatorialTrackFinderData_xk.h"
 
 #include <array>
@@ -64,6 +65,7 @@ namespace InDet {
 
     SeedToTrackConversionData& conversionData();
     SiCombinatorialTrackFinderData_xk& combinatorialData();
+    SiDetElementRoadMakerData_xk& roadMakerData();
 
   protected:
     virtual void dummy() = 0; //!< make sure this cannot be instantiated (for testing)
@@ -114,6 +116,7 @@ namespace InDet {
 
     /// SeedToTrackConversionData to hold the event dependent data of SeedToTrackConversionTool.
     SeedToTrackConversionData m_conversionData;
+    SiDetElementRoadMakerData_xk m_roadMakerData;
 
     class ExtendedSiCombinatorialTrackFinderData_xk : public SiCombinatorialTrackFinderData_xk {
     public:
diff --git a/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/src/SiDetElementRoadMakerData_xk.cxx b/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/src/SiDetElementRoadMakerData_xk.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..71c439d4e0cd29c125b7b06de03e840cde37cdaf
--- /dev/null
+++ b/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/src/SiDetElementRoadMakerData_xk.cxx
@@ -0,0 +1,10 @@
+#include "SiSPSeededTrackFinderData/SiDetElementRoadMakerData_xk.h"
+#include <algorithm>
+
+void InDet::SiDetElementRoadMakerData_xk::resetUsageTracker(){
+    for (auto & outerVec : elementUsageTracker){    /// loop over detector regions 
+        for (auto & innerVec : outerVec){           /// loop over layers in region
+            std::fill(innerVec.begin(), innerVec.end(), false);   /// loop over elements on layer
+        }
+    }
+}
\ No newline at end of file
diff --git a/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/src/SiTrackMakerEventData_xk.cxx b/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/src/SiTrackMakerEventData_xk.cxx
index 50b8c9492fac47bb8558d4c60cf23993e6977ad2..a52ca8fab844fb024396ef18bf5f9947b4c4fd71 100644
--- a/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/src/SiTrackMakerEventData_xk.cxx
+++ b/InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData/src/SiTrackMakerEventData_xk.cxx
@@ -98,6 +98,10 @@ namespace InDet {
     return m_conversionData;
   }
 
+  SiDetElementRoadMakerData_xk& SiTrackMakerEventData_xk::roadMakerData() {
+    return m_roadMakerData;
+  }
+
   SiCombinatorialTrackFinderData_xk& SiTrackMakerEventData_xk::combinatorialData() {
     return m_combinatorialData;
   }
diff --git a/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ISiDetElementsRoadMaker.h b/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ISiDetElementsRoadMaker.h
index 2b5984c2feab4415be87f3b8db12ad3ba3631aa1..7a2b0e2f8a48c2939871aab05cea787316acb79e 100644
--- a/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ISiDetElementsRoadMaker.h
+++ b/InnerDetector/InDetRecTools/InDetRecToolInterfaces/InDetRecToolInterfaces/ISiDetElementsRoadMaker.h
@@ -29,6 +29,7 @@ namespace InDetDD {
 }
 
 namespace InDet {
+  class SiDetElementRoadMakerData_xk; 
 
   /**
    * @class ISiDetElementsRoadMaker
@@ -52,17 +53,39 @@ namespace InDet {
       ///////////////////////////////////////////////////////////////////
       /// @name Main methods for road builder
       ///////////////////////////////////////////////////////////////////
+      /// This signature assumes you already have a list of positions
+      /// along the trajectory. It will look for detector elements 
+      /// compatible with being crossed by the linearised 
+      /// trajectory provided and fill those into the 'Road' argument. 
+      /// If 'testDirection' is used, we only fill detector elements 
+      /// encountered while traversing in the positive direction. 
+      /// 
+      /// @param[in] globalPositions: set of points along the trajectory. Will linearise between them. 
+      /// @param[out] Road: List to be populated with the elements of the search road. Will be sorted along the trajectory. 
+      /// @param[in] testDirection: If set, avoid adding detector elements encountered only when travelling in the negative direction. Set true for inside-out tracking, false for cosmic tracking. 
+      /// @param[in,out] roadMakerData: event data object used to cache information during an event in a thread-safe way 
       //@{
       virtual void detElementsRoad
-	(std::list<Amg::Vector3D>&,
-	 std::list<const InDetDD::SiDetectorElement*>&,
-         bool test) const=0;
-
+      ( std::list<Amg::Vector3D>& globalPositions,
+	      std::list<const InDetDD::SiDetectorElement*>& Road,
+        bool testDirection, 
+        InDet::SiDetElementRoadMakerData_xk & roadMakerData) const=0;
+
+      /// This is the signature used in most ATLAS clients. 
+      /// @param[in] ctx: Event context
+      /// @param[in] fieldCache: Magnetic field cache
+      /// @param[in] Tp: Track parameter hypothesis used for road building. For example obtained from a seed. Will be used to populate a set of space points along the expected trajectory, and to search 
+      /// for detector elements along this linearised trajectory using the signature above
+      /// @param[in] direction: Direction of propagation - either along (inside out) or against (cosmic) momentum.
+      /// @param[out] Road: List to be populated with the elements of the search road. Will be sorted along the trajectory. 
+      /// @param[in,out] roadMakerData: event data object used to cache information during an event in a thread-safe way   
       virtual void detElementsRoad
       (const EventContext& ctx,
        MagField::AtlasFieldCache& fieldCache,
-       const Trk::TrackParameters&,Trk::PropDirection,
-       std::list<const InDetDD::SiDetectorElement*>&) const=0;
+       const Trk::TrackParameters& Tp,
+       Trk::PropDirection direction,
+       std::list<const InDetDD::SiDetectorElement*>& Road, 
+       InDet::SiDetElementRoadMakerData_xk & roadMakerData) const=0;
       //@} 
 
       ///////////////////////////////////////////////////////////////////
diff --git a/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/CMakeLists.txt b/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/CMakeLists.txt
index 5364d8c1ce0ef3c3392e125a9f7207c8f9b6619f..7fa20f0660163cc1cc376c433159c4bec7a94215 100644
--- a/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/CMakeLists.txt
+++ b/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/CMakeLists.txt
@@ -13,6 +13,7 @@ atlas_depends_on_subdirs( PUBLIC
                           InnerDetector/InDetDetDescr/InDetReadoutGeometry
 			  InnerDetector/InDetDetDescr/PixelReadoutGeometry
 			  InnerDetector/InDetDetDescr/SCT_ReadoutGeometry
+			  InnerDetector/InDetRecEvent/SiSPSeededTrackFinderData
                           InnerDetector/InDetRecTools/InDetRecToolInterfaces
                           MagneticField/MagFieldInterfaces
                           Tracking/TrkDetDescr/TrkGeometry
@@ -29,7 +30,7 @@ atlas_depends_on_subdirs( PUBLIC
 atlas_add_component( SiDetElementsRoadTool_xk
                      src/*.cxx
                      src/components/*.cxx
-                     LINK_LIBRARIES AthenaBaseComps AthenaKernel GaudiKernel InDetReadoutGeometry PixelReadoutGeometry SCT_ReadoutGeometry InDetRecToolInterfaces MagFieldInterfaces TrkGeometry TrkSurfaces AthenaPoolUtilities EventInfo TrkPrepRawData TrkExInterfaces MagFieldElements MagFieldConditions )
+                     LINK_LIBRARIES AthenaBaseComps AthenaKernel GaudiKernel InDetReadoutGeometry SiSPSeededTrackFinderData PixelReadoutGeometry SCT_ReadoutGeometry InDetRecToolInterfaces MagFieldInterfaces TrkGeometry TrkSurfaces AthenaPoolUtilities EventInfo TrkPrepRawData TrkExInterfaces MagFieldElements MagFieldConditions )
 
 # Install files from the package:
 atlas_install_headers( SiDetElementsRoadTool_xk )
diff --git a/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/SiDetElementsRoadTool_xk/SiDetElementLink_xk.h b/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/SiDetElementsRoadTool_xk/SiDetElementLink_xk.h
index 379a7d3b06f1d7e9d26208868162f4898cbf91d0..f930f2a13d7643d9316078ad6560bd3f9ebcac32 100644
--- a/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/SiDetElementsRoadTool_xk/SiDetElementLink_xk.h
+++ b/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/SiDetElementsRoadTool_xk/SiDetElementLink_xk.h
@@ -29,17 +29,6 @@ namespace InDet{
 
     public:
 
-       class UsedFlag {
-       public:
-          UsedFlag() : m_used(false) {}
-
-          bool used() const { return m_used; }
-
-          void setUsed() { m_used=true; }
-       private:
-          bool m_used;
-       };
-
        class ElementWay {
        public:
           ElementWay(const InDet::SiDetElementLink_xk*link, float way, float distance)
diff --git a/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/SiDetElementsRoadTool_xk/SiDetElementsLayer_xk.h b/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/SiDetElementsRoadTool_xk/SiDetElementsLayer_xk.h
index c6d5e839b0ccc47394a2e82df7e8ed04dd62cdfc..915e3f65f3a0528fcabfd9e5feaa93fd731fac7d 100644
--- a/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/SiDetElementsRoadTool_xk/SiDetElementsLayer_xk.h
+++ b/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/SiDetElementsRoadTool_xk/SiDetElementsLayer_xk.h
@@ -19,6 +19,7 @@
 #include <vector>
 #include <list>
 #include "SiDetElementsRoadTool_xk/SiDetElementLink_xk.h"
+#include "SiSPSeededTrackFinderData/SiDetElementRoadMakerData_xk.h"
 
 namespace InDet{
 
@@ -80,13 +81,13 @@ namespace InDet{
         (const std::array<float,6> & startingPoint,
          const std::array<float,3> & searchDirection,
          std::vector<InDet::SiDetElementLink_xk::ElementWay> &lDE,
-         std::vector<InDet::SiDetElementLink_xk::UsedFlag>   &used) const;
+         std::vector<bool>   &used) const;
 
       void getEndcapDetElements
 	      (const std::array<float,6> & startingPoint,
          const std::array<float,3> & searchDirection,
          std::vector<InDet::SiDetElementLink_xk::ElementWay> &lDE,
-         std::vector<InDet::SiDetElementLink_xk::UsedFlag>   &used) const;
+         std::vector<bool>   &used) const;
 
       void sortDetectorElements();
 
@@ -113,7 +114,7 @@ namespace InDet{
                           float phiCrossing,
                           float reducedRoadWidth,
                           std::vector<InDet::SiDetElementLink_xk::ElementWay> &lDE,
-                          std::vector<InDet::SiDetElementLink_xk::UsedFlag>   &used) const;
+                          std::vector<bool>   &used) const;
     };
   
   /////////////////////////////////////////////////////////////////////////////////
diff --git a/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/SiDetElementsRoadTool_xk/SiDetElementsRoadMaker_xk.h b/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/SiDetElementsRoadTool_xk/SiDetElementsRoadMaker_xk.h
index fff1588f5b08231d5c6567d30e4caf40c218bfdb..0136496eaff6d85a91c32262f3781be9ef2d6e6e 100644
--- a/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/SiDetElementsRoadTool_xk/SiDetElementsRoadMaker_xk.h
+++ b/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/SiDetElementsRoadTool_xk/SiDetElementsRoadMaker_xk.h
@@ -37,6 +37,7 @@
 #include <list>
 #include <mutex>
 #include <vector>
+#include <array>
 
 class MsgStream;
 
@@ -53,7 +54,7 @@ namespace InDet{
      /// of the detector.  
      @author Igor.Gavrilenko@cern.ch     
   */
-
+  class SiDetElementRoadMakerData_xk; 
 
   class SiDetElementsRoadMaker_xk : 
     public extends<AthAlgTool, ISiDetElementsRoadMaker>
@@ -78,18 +79,40 @@ namespace InDet{
     ///////////////////////////////////////////////////////////////////
     /// @name Main methods for road builder
     ///////////////////////////////////////////////////////////////////
-    //@{ 
+    /// 
+    /// This signature assumes you already have a list of positions
+    /// along the trajectory. It will look for detector elements 
+    /// compatible with being crossed by the linearised 
+    /// trajectory provided and fill those into the 'Road' argument. 
+    /// If 'testDirection' is used, we only fill detector elements 
+    /// encountered while traversing in the positive direction. 
+    /// 
+    /// @param[in] globalPositions: set of points along the trajectory. Will linearise between them. 
+    /// @param[out] Road: List to be populated with the elements of the search road. Will be sorted along the trajectory. 
+    /// @param[in] testDirection: If set, avoid adding detector elements encountered only when travelling in the negative direction. Set true for inside-out tracking, false for cosmic tracking. 
+    /// @param[in,out] roadMakerData: event data object used to cache information during an event in a thread-safe way 
     virtual void detElementsRoad
-      (std::list<Amg::Vector3D>&, 
-       std::list<const InDetDD::SiDetectorElement*>&,
-       bool test) const override;
-
+      (std::list<Amg::Vector3D>& globalPositions, 
+       std::list<const InDetDD::SiDetectorElement*>& Road,
+       bool testDirection,
+       SiDetElementRoadMakerData_xk & roadMakerData) const override;
+
+
+      /// This is the signature used in most ATLAS clients. 
+      /// @param[in] ctx: Event context
+      /// @param[in] fieldCache: Magnetic field cache
+      /// @param[in] Tp: Track parameter hypothesis used for road building. For example obtained from a seed. Will be used to populate a set of space points along the expected trajectory, and to search 
+      /// for detector elements along this linearised trajectory using the signature above
+      /// @param[in] direction: Direction of propagation - either along (inside out) or against (cosmic) momentum.
+      /// @param[out] Road: List to be populated with the elements of the search road. Will be sorted along the trajectory. 
+      /// @param[in,out] roadMakerData: event data object used to cache information during an event in a thread-safe way   
     virtual void detElementsRoad
       (const EventContext& ctx,
        MagField::AtlasFieldCache& fieldCache,
-       const Trk::TrackParameters&,
-       Trk::PropDirection,
-       std::list<const InDetDD::SiDetectorElement*>&) const override;
+       const Trk::TrackParameters& Tp,
+       Trk::PropDirection direction,
+       std::list<const InDetDD::SiDetectorElement*>& Road,
+       SiDetElementRoadMakerData_xk & roadMakerData) const override;
     //@}
 
     ///////////////////////////////////////////////////////////////////
@@ -160,6 +183,11 @@ namespace InDet{
        }
        return layerVec.cptr();
     }
+    /// this method is used to initialize the detector element usage tracker member 
+    /// of the event data struct in case it has not been previously set. 
+    /// modifies the 'data' argument, based on information in the 'layers' argument. 
+    void bookUsageTracker(InDet::SiDetElementRoadMakerData_xk & data, const SiDetElementsLayerVectors_xk &layers) const;
+
   };
 
   MsgStream&    operator << (MsgStream&   , const SiDetElementsRoadMaker_xk&);
diff --git a/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/src/SiDetElementsLayer_xk.cxx b/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/src/SiDetElementsLayer_xk.cxx
index e5e9b5505d243f9535bdbf277230abdfcb41a295..f79ab320f6ecf1bf313fa0b36c28cc613eb688f1 100644
--- a/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/src/SiDetElementsLayer_xk.cxx
+++ b/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/src/SiDetElementsLayer_xk.cxx
@@ -31,7 +31,7 @@ void InDet::SiDetElementsLayer_xk::getBarrelDetElements
 (const std::array<float,6> & startingPoint,
  const std::array<float,3> & searchDirection,
  std::vector<InDet::SiDetElementLink_xk::ElementWay> &lDE,
- std::vector<InDet::SiDetElementLink_xk::UsedFlag>   &used) const
+ std::vector<bool>   &used) const
 {
 
   /// In the following, identify where we cross the layer in r
@@ -99,7 +99,7 @@ void InDet::SiDetElementsLayer_xk::getEndcapDetElements
 (const std::array<float,6> & startingPoint,
  const std::array<float,3> & searchDirection,
  std::vector<InDet::SiDetElementLink_xk::ElementWay> &lDE,
- std::vector<InDet::SiDetElementLink_xk::UsedFlag>   &used) const
+ std::vector<bool>   &used) const
 {
   /// solve the linear equation 
   /// z_layer = z_startingPont + s * z_searchDirection
@@ -137,7 +137,7 @@ void InDet::SiDetElementsLayer_xk::getDetElements
  float phiCrossing,
  float reducedRoadWidth,
  std::vector<InDet::SiDetElementLink_xk::ElementWay> &lDE,
- std::vector<InDet::SiDetElementLink_xk::UsedFlag>   &used) const
+ std::vector<bool>   &used) const
 {
   constexpr float pi = M_PI;
   constexpr float pi2 = 2.*pi; 
@@ -166,7 +166,7 @@ void InDet::SiDetElementsLayer_xk::getDetElements
   while(1) {
     assert( static_cast<unsigned int>(i)<m_elements.size() );
     /// if detector element i on this layer is not already used for this road
-    if(!used[i].used()) {
+    if(!used[i]) {
       /// 
       float dPhi =std::abs(m_elements[i].phi()-phiCrossing); 
       if(dPhi>pi) dPhi=std::abs(dPhi-pi2);    /// project delta phi into -pi..pi
@@ -187,7 +187,7 @@ void InDet::SiDetElementsLayer_xk::getDetElements
           ) {
          /// we found a compatible detector element - add to our list  
          lDE.push_back(InDet::SiDetElementLink_xk::ElementWay(&m_elements[i],startingPoint[5]+intersectionOutcome[2],std::max(intersectionOutcome[0],intersectionOutcome[1]))); 
-         used[i].setUsed();
+         used[i]=true;
       }
     }
     ++i; 
@@ -204,7 +204,7 @@ void InDet::SiDetElementsLayer_xk::getDetElements
     /// stop at full circle
     if(i==i1) return;
     assert( static_cast<unsigned int>(i)<m_elements.size() );
-    if(!used[i].used()) {
+    if(!used[i]) {
       float dPhi =std::abs(m_elements[i].phi()-phiCrossing); 
       if(dPhi>pi) dPhi=std::abs(dPhi-pi2);
       if((dPhi-reducedRoadWidth)>m_dfe) return;
@@ -212,7 +212,7 @@ void InDet::SiDetElementsLayer_xk::getDetElements
 
       if((intersectionOutcome[0]-startingPoint[4])<=0 && (intersectionOutcome[1]-startingPoint[4])<=0.) {
          lDE.push_back(InDet::SiDetElementLink_xk::ElementWay(&m_elements[i],startingPoint[5]+intersectionOutcome[2],std::max(intersectionOutcome[0],intersectionOutcome[1]))); 
-         used[i].setUsed();
+         used[i]=true;
       }
     }
   }
diff --git a/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/src/SiDetElementsRoadMaker_xk.cxx b/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/src/SiDetElementsRoadMaker_xk.cxx
index 09ef2fd75b7f6e7e547495b568ec7b6f47da6a20..b82051bccb78679a2d4815491ffd6e432723ea7d 100644
--- a/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/src/SiDetElementsRoadMaker_xk.cxx
+++ b/InnerDetector/InDetRecTools/SiDetElementsRoadTool_xk/src/SiDetElementsRoadMaker_xk.cxx
@@ -12,6 +12,7 @@
 ///////////////////////////////////////////////////////////////////
 
 #include "SiDetElementsRoadTool_xk/SiDetElementsRoadMaker_xk.h"
+#include "SiSPSeededTrackFinderData/SiDetElementRoadMakerData_xk.h"
 
 #include "SiDetElementsRoadUtils_xk.h"
 
@@ -21,7 +22,7 @@
 #include "SiDetElementsRoadUtils_xk.h"
 #include "StoreGate/ReadCondHandle.h"
 #include "TrkPrepRawData/PrepRawData.h"
-
+#include "GaudiKernel/ContextSpecificPtr.h"
 #include <ostream>
 #include <iomanip>
 
@@ -42,8 +43,6 @@ InDet::SiDetElementsRoadMaker_xk::SiDetElementsRoadMaker_xk
 StatusCode InDet::SiDetElementsRoadMaker_xk::initialize()
 {
   //Class optimization checks
-  static_assert(std::is_trivially_copyable<SiDetElementLink_xk::UsedFlag>::value);
-  static_assert(std::is_trivially_destructible<SiDetElementLink_xk::UsedFlag>::value);
   static_assert(std::is_trivially_copyable<SiDetElementLink_xk::ElementWay>::value);
   static_assert(std::is_trivially_destructible<SiDetElementLink_xk::ElementWay>::value);
   static_assert(std::is_trivially_copyable<SiDetElementLink_xk>::value);
@@ -301,9 +300,10 @@ std::ostream& InDet::operator <<
 ///////////////////////////////////////////////////////////////////
 
 void InDet::SiDetElementsRoadMaker_xk::detElementsRoad
-(std::list<Amg::Vector3D>& GP,
+(std::list<Amg::Vector3D>& globalPositions,
  std::list<const InDetDD::SiDetectorElement*>& Road,
- bool testDirection) const
+ bool testDirection,
+ SiDetElementRoadMakerData_xk & roadMakerData) const
 {  
   if (!m_usePIX && !m_useSCT) return;
 
@@ -321,7 +321,7 @@ void InDet::SiDetElementsRoadMaker_xk::detElementsRoad
   const SiDetElementsLayerVectors_xk &layer = *getLayers();
 
   /// iterators over the positions to consider
-  std::list<Amg::Vector3D>::iterator currentPosition=GP.begin(), endPositions=GP.end();
+  std::list<Amg::Vector3D>::iterator currentPosition=globalPositions.begin(), endPositions=globalPositions.end();
 
   /// fill an array with the reference point (start with the first one), the road width and a placeholder
   /// for the step length
@@ -356,16 +356,17 @@ void InDet::SiDetElementsRoadMaker_xk::detElementsRoad
 
   
   std::vector<InDet::SiDetElementLink_xk::ElementWay> lDE;
-  /// book an impressively nested structure to keep track of which detector elements we use 
-  std::array<std::vector<std::vector<InDet::SiDetElementLink_xk::UsedFlag> >,3> used;
-
-  /// module_i: iterate over the detector side 
-  for ( unsigned int module_i=0; module_i<3; ++module_i) {
-     used[module_i].resize( layer[module_i].size() ); /// for each side, book the number of layers we expect to see
-     for (unsigned int layer_i=0; layer_i < layer[module_i].size(); ++layer_i) {
-        /// for each layer, book one slot for each detector element on the layer
-        used[module_i][layer_i].resize( layer[module_i][layer_i].nElements() );
-     }
+
+  /// reset the detector-element usage info. 
+  /// If we are the first client to see this event data object,
+  /// we allocate the storage for all modules 
+  if (!roadMakerData.isInitialized){
+    bookUsageTracker(roadMakerData,layer);
+  }
+  else{ 
+    /// if we are not the first client, we reset the event data without
+    /// re-allocation
+    roadMakerData.resetUsageTracker();
   }
 
   /// done with the first probed position. Now we can start to move along the trajectory
@@ -433,18 +434,19 @@ void InDet::SiDetElementsRoadMaker_xk::detElementsRoad
       for (; n1<static_cast<int>(layer[1].size()); ++n1) {
         /// stop if we moved past the targer point in R
 	      if (par_targetPoint[3] < layer[1][n1].r()) break;
-        assert( used[1].size() > static_cast<unsigned int>(n1) );
+        assert( roadMakerData.elementUsageTracker[1].size() > static_cast<unsigned int>(n1) );
         /// collect all compatible detector elements from the current layer
-	      layer[1][n1].getBarrelDetElements(par_startingPoint, searchDirection, lDE, used[1][n1]);
+	      layer[1][n1].getBarrelDetElements(par_startingPoint, searchDirection, lDE, roadMakerData.elementUsageTracker[1][n1]);
       }
       /// if we are moving inward in R, iterate the other way for the barrel
     } else {
       for (--n1; n1>=0; --n1) {
         /// stop if we moved past the test point in R
 	      if (par_targetPoint[3] > layer[1][n1].r()+dr) break;
-        assert( used[1].size() > static_cast<unsigned int>(n1) );
+        assert( roadMakerData.elementUsageTracker[1].size() > static_cast<unsigned int>(n1) );
         /// collect all compatible detector elements        
-	      layer[1][n1].getBarrelDetElements(par_startingPoint, searchDirection, lDE, used[1][n1]);
+	      layer[1][n1].getBarrelDetElements(par_startingPoint, searchDirection, lDE, roadMakerData.elementUsageTracker[1][n1]);
+
       }
       ++n1;
     }
@@ -454,16 +456,16 @@ void InDet::SiDetElementsRoadMaker_xk::detElementsRoad
     if (par_targetPoint[2]>par_startingPoint[2]) {
       for (; n2<static_cast<int>(layer[2].size()); ++n2) {
 	      if (par_targetPoint[2] < layer[2][n2].z()) break;
-        assert( used[2].size() > static_cast<unsigned int>(n2) );
+        assert( roadMakerData.elementUsageTracker[2].size() > static_cast<unsigned int>(n2) );
         /// collect all compatible detector elements        
-	      layer[2][n2].getEndcapDetElements(par_startingPoint, searchDirection, lDE,used[2][n2]);
+	      layer[2][n2].getEndcapDetElements(par_startingPoint, searchDirection, lDE,roadMakerData.elementUsageTracker[2][n2]);
       }
     } else {
       for (--n2; n2>=0; --n2) {
 	      if (par_targetPoint[2] > layer[2][n2].z()) break;
-        assert( used[2].size() > static_cast<unsigned int>(n2) );
+        assert( roadMakerData.elementUsageTracker[2].size() > static_cast<unsigned int>(n2) );
         /// collect all compatible detector elements        
-	      layer[2][n2].getEndcapDetElements(par_startingPoint, searchDirection, lDE, used[2][n2]);
+	      layer[2][n2].getEndcapDetElements(par_startingPoint, searchDirection, lDE, roadMakerData.elementUsageTracker[2][n2]);
       }
       ++n2;
     }
@@ -473,16 +475,16 @@ void InDet::SiDetElementsRoadMaker_xk::detElementsRoad
     if (par_targetPoint[2]<par_startingPoint[2]) {
       for (; n0<static_cast<int>(layer[0].size()); ++n0) {
 	      if (par_targetPoint[2] > layer[0][n0].z()) break;
-        assert( used[0].size() > static_cast<unsigned int>(n0) );
+        assert( roadMakerData.elementUsageTracker[0].size() > static_cast<unsigned int>(n0) );
         /// collect all compatible detector elements        
-	      layer[0][n0].getEndcapDetElements(par_startingPoint, searchDirection, lDE,used[0][n0]);
+	      layer[0][n0].getEndcapDetElements(par_startingPoint, searchDirection, lDE,roadMakerData.elementUsageTracker[0][n0]);
       }
     } else {
       for (--n0; n0>=0; --n0) {
 	      if (par_targetPoint[2] < layer[0][n0].z()) break;
-        assert( used[0].size() > static_cast<unsigned int>(n0) );
+        assert( roadMakerData.elementUsageTracker[0].size() > static_cast<unsigned int>(n0) );
         /// collect all compatible detector elements        
-	      layer[0][n0].getEndcapDetElements(par_startingPoint, searchDirection, lDE,used[0][n0]);
+	      layer[0][n0].getEndcapDetElements(par_startingPoint, searchDirection, lDE,roadMakerData.elementUsageTracker[0][n0]);
       }
       ++n0;
     }
@@ -503,6 +505,21 @@ void InDet::SiDetElementsRoadMaker_xk::detElementsRoad
   }
 }
 
+/// obtain an event usage tracker object 
+void InDet::SiDetElementsRoadMaker_xk::bookUsageTracker(InDet::SiDetElementRoadMakerData_xk & data, const SiDetElementsLayerVectors_xk &layers) const{
+
+    /// book sufficient space
+    /// module_i: iterate over the detector side 
+    for ( unsigned int side_i=0; side_i<3; ++side_i) {
+      data.elementUsageTracker[side_i].resize( layers[side_i].size() ); /// for each side, book the number of layers we expect to see
+      for (unsigned int layer_i=0; layer_i < layers[side_i].size(); ++layer_i) {
+          /// for each layer, book one slot for each detector element on the layer
+          data.elementUsageTracker[side_i][layer_i].resize( layers[side_i][layer_i].nElements() );
+      }
+    }
+    data.isInitialized=true;
+} 
+
 ///////////////////////////////////////////////////////////////////
 // Main methods for road builder using track parameters and direction
 ///////////////////////////////////////////////////////////////////
@@ -511,8 +528,9 @@ void InDet::SiDetElementsRoadMaker_xk::detElementsRoad
 (const EventContext& ctx,
  MagField::AtlasFieldCache& fieldCache,
  const Trk::TrackParameters& Tp,
- Trk::PropDirection D,
- std::list<const InDetDD::SiDetectorElement*>& R) const
+ Trk::PropDirection direction,
+ std::list<const InDetDD::SiDetectorElement*>& Road,
+ SiDetElementRoadMakerData_xk & roadMakerData) const
 {
   if (!m_usePIX && !m_useSCT) return;
   /// 500 MeV / pT 
@@ -525,7 +543,7 @@ void InDet::SiDetElementsRoadMaker_xk::detElementsRoad
   if (S  > 1000. ) S  = 1000. ;
 
   bool testDirection = true;
-  if (D<0) {
+  if (direction<0) {
     testDirection = false;
     S=-S;
   }
@@ -546,7 +564,7 @@ void InDet::SiDetElementsRoadMaker_xk::detElementsRoad
 
   /// if we are extrapolating along them momentum direction, 
   /// we pick out the part ascending in R 
-  if (D > 0) {
+  if (direction > 0) {
     std::list<Amg::Vector3D>::iterator currentPosition=G.begin(), nextPosition, endPositions=G.end();
     float r0 = (*currentPosition).x()*(*currentPosition).x()+(*currentPosition).y()*(*currentPosition).y();
 
@@ -565,7 +583,7 @@ void InDet::SiDetElementsRoadMaker_xk::detElementsRoad
     }
   }
   /// now perform the road building using our set of positions
-  detElementsRoad(G, R,testDirection);
+  detElementsRoad(G, Road,testDirection, roadMakerData);
 }
 
 
diff --git a/InnerDetector/InDetRecTools/SiTrackMakerTool_xk/src/SiTrackMaker_xk.cxx b/InnerDetector/InDetRecTools/SiTrackMakerTool_xk/src/SiTrackMaker_xk.cxx
index 790197d1979eda1eba674a37cdebdeff73ab4a04..1390b1de699708c07b7bde03872a714cf42a9cf9 100644
--- a/InnerDetector/InDetRecTools/SiTrackMakerTool_xk/src/SiTrackMaker_xk.cxx
+++ b/InnerDetector/InDetRecTools/SiTrackMakerTool_xk/src/SiTrackMaker_xk.cxx
@@ -675,8 +675,8 @@ std::list<Trk::Track*> InDet::SiTrackMaker_xk::getTracks
   // Get detector elements road
   //
   std::list<const InDetDD::SiDetectorElement*> DE;
-  if (!m_cosmicTrack) m_roadmaker->detElementsRoad(ctx, fieldCache, *Tp,Trk::alongMomentum,   DE);
-  else                m_roadmaker->detElementsRoad(ctx, fieldCache, *Tp,Trk::oppositeMomentum,DE);
+  if (!m_cosmicTrack) m_roadmaker->detElementsRoad(ctx, fieldCache, *Tp,Trk::alongMomentum,   DE, data.roadMakerData());
+  else                m_roadmaker->detElementsRoad(ctx, fieldCache, *Tp,Trk::oppositeMomentum,DE, data.roadMakerData());
 
   if (!data.pix() || !data.sct() || data.dbm()) detectorElementsSelection(data, DE);
 
@@ -768,8 +768,8 @@ std::list<Trk::Track*> InDet::SiTrackMaker_xk::getTracks
   // Get detector elements road
   //
   std::list<const InDetDD::SiDetectorElement*> DE;
-  if (!m_cosmicTrack) m_roadmaker->detElementsRoad(ctx, fieldCache, Tp,Trk::alongMomentum,   DE);
-  else                m_roadmaker->detElementsRoad(ctx, fieldCache, Tp,Trk::oppositeMomentum,DE);
+  if (!m_cosmicTrack) m_roadmaker->detElementsRoad(ctx, fieldCache, Tp,Trk::alongMomentum,   DE, data.roadMakerData());
+  else                m_roadmaker->detElementsRoad(ctx, fieldCache, Tp,Trk::oppositeMomentum,DE, data.roadMakerData());
 
   if (!data.pix() || !data.sct()) detectorElementsSelection(data, DE);
 
diff --git a/InnerDetector/InDetRecTools/TRT_SeededTrackFinderTool/TRT_SeededTrackFinderTool/TRT_SeededTrackFinder_ATL.h b/InnerDetector/InDetRecTools/TRT_SeededTrackFinderTool/TRT_SeededTrackFinderTool/TRT_SeededTrackFinder_ATL.h
index 81d1f91377588c25b8a26fdaf9f51b07a4da5b90..1c7b181db55af668a3b4e181bc66d5aaa480fbfe 100755
--- a/InnerDetector/InDetRecTools/TRT_SeededTrackFinderTool/TRT_SeededTrackFinderTool/TRT_SeededTrackFinder_ATL.h
+++ b/InnerDetector/InDetRecTools/TRT_SeededTrackFinderTool/TRT_SeededTrackFinderTool/TRT_SeededTrackFinder_ATL.h
@@ -43,6 +43,7 @@
 //Si Tools
 //
 #include "TRT_SeededTrackFinderTool/SiNoise_bt.h"
+#include "SiSPSeededTrackFinderData/SiDetElementRoadMakerData_xk.h"
 
 //Combinatorial Track Finder Tool
 //
@@ -142,6 +143,7 @@ namespace InDet{
           const std::vector<double>&                                caloE()  const { return m_caloE; }
           InDet::SiNoise_bt&                                        noise()        { return m_noise; }
           const InDet::SiNoise_bt&                                  noise()  const { return m_noise; }
+          InDet::SiDetElementRoadMakerData_xk& roadMakerData() {return m_roadMakerData; }
        protected:
           SiCombinatorialTrackFinderData_xk                              *m_combinaatorialData;
           std::unique_ptr<InDet::ITRT_SeededSpacePointFinder::IEventData> m_spacePointFinderEventData;
@@ -151,6 +153,7 @@ namespace InDet{
 
           /** Needed for adding material related noise   */
           InDet::SiNoise_bt                    m_noise        ;
+          InDet::SiDetElementRoadMakerData_xk  m_roadMakerData; 
        };
 
       ///////////////////////////////////////////////////////////////////
diff --git a/InnerDetector/InDetRecTools/TRT_SeededTrackFinderTool/src/TRT_SeededTrackFinder_ATL.cxx b/InnerDetector/InDetRecTools/TRT_SeededTrackFinderTool/src/TRT_SeededTrackFinder_ATL.cxx
index 9ca0d9bea57dca9642685b7797f881ef1f0c3b99..76d2640a6b530a9fe31920b6feebc1418c1efdce 100755
--- a/InnerDetector/InDetRecTools/TRT_SeededTrackFinderTool/src/TRT_SeededTrackFinder_ATL.cxx
+++ b/InnerDetector/InDetRecTools/TRT_SeededTrackFinderTool/src/TRT_SeededTrackFinder_ATL.cxx
@@ -664,7 +664,7 @@ std::list<Trk::Track*> InDet::TRT_SeededTrackFinder_ATL::findTrack
 
     //Get list of InDet Elements
     std::list<const InDetDD::SiDetectorElement*> DE;
-    m_roadmaker->detElementsRoad(ctx, fieldCache, *per,Trk::alongMomentum,DE);
+    m_roadmaker->detElementsRoad(ctx, fieldCache, *per,Trk::alongMomentum,DE,event_data.roadMakerData());
     delete per;
     if( int(DE.size()) < m_nclusmin){ //Not enough detector elements to satisfy the minimum number of clusters requirement. Stop
       if(msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << "Too few detector elements, not expected" << endmsg;