diff --git a/Tracking/Acts/ActsConfig/share/ActsCheckObjectCounts.ref b/Tracking/Acts/ActsConfig/share/ActsCheckObjectCounts.ref
index 6b5656695797cb1738b7936c5f7ff343afb73cd4..ffd407d7abbf689aff897a6646d7f327d958ccd1 100644
--- a/Tracking/Acts/ActsConfig/share/ActsCheckObjectCounts.ref
+++ b/Tracking/Acts/ActsConfig/share/ActsCheckObjectCounts.ref
@@ -47,6 +47,7 @@ ActsTrackFindingAlg                                               INFO statistic
 | Tracks failing second CKF         |         11 |        186 |        197 |
 | Stopped tracks below pT cut       |       2414 |        494 |       2908 |
 | Stopped tracks above max eta      |          0 |          0 |          0 |
+| Total shared hits                 |      55958 |      12629 |      68587 |
 |-----------------------------------|------------|------------|------------|
 ActsTrackFindingAlg                                               INFO Ratios
 |------------------------------------------|------------|------------|------------|
@@ -59,6 +60,7 @@ ActsTrackFindingAlg                                               INFO Ratios
 | selected tracks / used seeds             |   0.171359 |  0.0516492 |   0.151384 |
 | branched tracks / used seeds             |          0 |          0 |          0 |
 | no 2nd CKF / CKF tracks                  | 0.000742942 |  0.0492976 |  0.0106034 |
+| shared hits / CKF tracks                 |    3.77941 |     3.3472 |    3.69164 |
 |------------------------------------------|------------|------------|------------|
 | selected / CKF tracks           0.0- 0.5 |   0.890205 |    0.11658 |   0.709443 |
 |                                 0.5- 1.0 |   0.913255 |   0.252874 |   0.737646 |
@@ -119,6 +121,7 @@ ActsLargeRadiusTrackFindingAlg                                    INFO statistic
 | Tracks failing second CKF         |         30 |         30 |
 | Stopped tracks below pT cut       |       1886 |       1886 |
 | Stopped tracks above max eta      |          0 |          0 |
+| Total shared hits                 |        582 |        582 |
 |-----------------------------------|------------|------------|
 ActsLargeRadiusTrackFindingAlg                                    INFO Ratios
 |------------------------------------------|------------|------------|
@@ -131,6 +134,7 @@ ActsLargeRadiusTrackFindingAlg                                    INFO Ratios
 | selected tracks / used seeds             |  0.0129692 |  0.0129692 |
 | branched tracks / used seeds             |          0 |          0 |
 | no 2nd CKF / CKF tracks                  |  0.0320513 |  0.0320513 |
+| shared hits / CKF tracks                 |   0.621795 |   0.621795 |
 |------------------------------------------|------------|------------|
 | selected / CKF tracks           0.0- 0.5 |   0.169014 |   0.169014 |
 |                                 0.5- 1.0 |   0.214286 |   0.214286 |
@@ -186,6 +190,7 @@ ActsConversionTrackFindingAlg                                     INFO statistic
 | Tracks failing second CKF         |          0 |          0 |
 | Stopped tracks below pT cut       |          8 |          8 |
 | Stopped tracks above max eta      |          0 |          0 |
+| Total shared hits                 |          0 |          0 |
 |-----------------------------------|------------|------------|
 ActsConversionTrackFindingAlg                                     INFO Ratios
 |------------------------------------------|------------|------------|
@@ -198,6 +203,7 @@ ActsConversionTrackFindingAlg                                     INFO Ratios
 | selected tracks / used seeds             |          0 |          0 |
 | branched tracks / used seeds             |          0 |          0 |
 | no 2nd CKF / CKF tracks                  |          0 |          0 |
+| shared hits / CKF tracks                 |          0 |          0 |
 |------------------------------------------|------------|------------|
 | selected / CKF tracks           0.0- 0.5 |          0 |          0 |
 |                                 0.5- 1.0 |          0 |          0 |
@@ -268,6 +274,7 @@ ActsLowPtTrackFindingAlg                                          INFO statistic
 | Tracks failing second CKF         |          0 |         71 |         71 |
 | Stopped tracks below pT cut       |        442 |         42 |        484 |
 | Stopped tracks above max eta      |          0 |          0 |          0 |
+| Total shared hits                 |       2538 |        257 |       2795 |
 |-----------------------------------|------------|------------|------------|
 ActsLowPtTrackFindingAlg                                          INFO Ratios
 |------------------------------------------|------------|------------|------------|
@@ -280,6 +287,7 @@ ActsLowPtTrackFindingAlg                                          INFO Ratios
 | selected tracks / used seeds             |  0.0134633 | 0.00498076 |   0.012098 |
 | branched tracks / used seeds             |          0 |          0 |          0 |
 | no 2nd CKF / CKF tracks                  |          0 |  0.0413753 |  0.0249123 |
+| shared hits / CKF tracks                 |     2.2381 |   0.149767 |   0.980702 |
 |------------------------------------------|------------|------------|------------|
 | selected / CKF tracks           0.0- 0.5 |   0.833333 |          0 |       0.36 |
 |                                 0.5- 1.0 |   0.965909 |  0.0215827 |   0.387665 |
diff --git a/Tracking/Acts/ActsConfig/share/ActsCheckObjectCountsCached.ref b/Tracking/Acts/ActsConfig/share/ActsCheckObjectCountsCached.ref
index 52c475733549ad123a1dc8004163f7520e72ba3d..f91569185751e029a84b585e2027a1e54d3dbd9f 100644
--- a/Tracking/Acts/ActsConfig/share/ActsCheckObjectCountsCached.ref
+++ b/Tracking/Acts/ActsConfig/share/ActsCheckObjectCountsCached.ref
@@ -72,6 +72,7 @@ ActsTrackFindingAlg                                               INFO statistic
 | Tracks failing second CKF         |         11 |        186 |        197 |
 | Stopped tracks below pT cut       |       2414 |        494 |       2908 |
 | Stopped tracks above max eta      |          0 |          0 |          0 |
+| Total shared hits                 |      55958 |      12649 |      68607 |
 |-----------------------------------|------------|------------|------------|
 ActsTrackFindingAlg                                               INFO Ratios
 |------------------------------------------|------------|------------|------------|
@@ -84,6 +85,7 @@ ActsTrackFindingAlg                                               INFO Ratios
 | selected tracks / used seeds             |   0.171359 |  0.0517098 |   0.151393 |
 | branched tracks / used seeds             |          0 |          0 |          0 |
 | no 2nd CKF / CKF tracks                  | 0.000742942 |  0.0492846 |  0.0106028 |
+| shared hits / CKF tracks                 |    3.77941 |    3.35162 |    3.69252 |
 |------------------------------------------|------------|------------|------------|
 | selected / CKF tracks           0.0- 0.5 |   0.890205 |    0.11658 |   0.709443 |
 |                                 0.5- 1.0 |   0.913255 |   0.252874 |   0.737646 |
@@ -160,6 +162,7 @@ ActsLargeRadiusTrackFindingAlg                                    INFO statistic
 | Tracks failing second CKF         |         30 |         30 |
 | Stopped tracks below pT cut       |       1886 |       1886 |
 | Stopped tracks above max eta      |          0 |          0 |
+| Total shared hits                 |        582 |        582 |
 |-----------------------------------|------------|------------|
 ActsLargeRadiusTrackFindingAlg                                    INFO Ratios
 |------------------------------------------|------------|------------|
@@ -172,6 +175,7 @@ ActsLargeRadiusTrackFindingAlg                                    INFO Ratios
 | selected tracks / used seeds             |  0.0129692 |  0.0129692 |
 | branched tracks / used seeds             |          0 |          0 |
 | no 2nd CKF / CKF tracks                  |  0.0320513 |  0.0320513 |
+| shared hits / CKF tracks                 |   0.621795 |   0.621795 |
 |------------------------------------------|------------|------------|
 | selected / CKF tracks           0.0- 0.5 |   0.169014 |   0.169014 |
 |                                 0.5- 1.0 |   0.214286 |   0.214286 |
@@ -243,6 +247,7 @@ ActsConversionTrackFindingAlg                                     INFO statistic
 | Tracks failing second CKF         |          0 |          0 |
 | Stopped tracks below pT cut       |          8 |          8 |
 | Stopped tracks above max eta      |          0 |          0 |
+| Total shared hits                 |          0 |          0 |
 |-----------------------------------|------------|------------|
 ActsConversionTrackFindingAlg                                     INFO Ratios
 |------------------------------------------|------------|------------|
@@ -255,6 +260,7 @@ ActsConversionTrackFindingAlg                                     INFO Ratios
 | selected tracks / used seeds             |          0 |          0 |
 | branched tracks / used seeds             |          0 |          0 |
 | no 2nd CKF / CKF tracks                  |          0 |          0 |
+| shared hits / CKF tracks                 |          0 |          0 |
 |------------------------------------------|------------|------------|
 | selected / CKF tracks           0.0- 0.5 |          0 |          0 |
 |                                 0.5- 1.0 |          0 |          0 |
@@ -346,6 +352,7 @@ ActsLowPtTrackFindingAlg                                          INFO statistic
 | Tracks failing second CKF         |          0 |         71 |         71 |
 | Stopped tracks below pT cut       |        442 |         42 |        484 |
 | Stopped tracks above max eta      |          0 |          0 |          0 |
+| Total shared hits                 |       2538 |        257 |       2795 |
 |-----------------------------------|------------|------------|------------|
 ActsLowPtTrackFindingAlg                                          INFO Ratios
 |------------------------------------------|------------|------------|------------|
@@ -358,6 +365,7 @@ ActsLowPtTrackFindingAlg                                          INFO Ratios
 | selected tracks / used seeds             |  0.0134633 | 0.00498076 |   0.012098 |
 | branched tracks / used seeds             |          0 |          0 |          0 |
 | no 2nd CKF / CKF tracks                  |          0 |  0.0413753 |  0.0249123 |
+| shared hits / CKF tracks                 |     2.2381 |   0.149767 |   0.980702 |
 |------------------------------------------|------------|------------|------------|
 | selected / CKF tracks           0.0- 0.5 |   0.833333 |          0 |       0.36 |
 |                                 0.5- 1.0 |   0.965909 |  0.0215827 |   0.387665 |
diff --git a/Tracking/Acts/ActsConfig/share/ActsCheckObjectCountsHgtd.ref b/Tracking/Acts/ActsConfig/share/ActsCheckObjectCountsHgtd.ref
index e27d95f67f10a6f6a00facda6fe0c34b53c95c87..1de5e210ef24de569c32a22b19fcd7432d93428d 100644
--- a/Tracking/Acts/ActsConfig/share/ActsCheckObjectCountsHgtd.ref
+++ b/Tracking/Acts/ActsConfig/share/ActsCheckObjectCountsHgtd.ref
@@ -52,6 +52,7 @@ ActsTrackFindingAlg                                               INFO statistic
 | Tracks failing second CKF         |         11 |        186 |        197 |
 | Stopped tracks below pT cut       |       2414 |        495 |       2909 |
 | Stopped tracks above max eta      |          0 |          0 |          0 |
+| Total shared hits                 |      55972 |      12625 |      68597 |
 |-----------------------------------|------------|------------|------------|
 ActsTrackFindingAlg                                               INFO Ratios
 |------------------------------------------|------------|------------|------------|
@@ -64,6 +65,7 @@ ActsTrackFindingAlg                                               INFO Ratios
 | selected tracks / used seeds             |   0.171455 |  0.0516492 |   0.151462 |
 | branched tracks / used seeds             |          0 |          0 |          0 |
 | no 2nd CKF / CKF tracks                  | 0.00074194 |  0.0491803 |  0.0105868 |
+| shared hits / CKF tracks                 |    3.77526 |    3.33818 |    3.68643 |
 |------------------------------------------|------------|------------|------------|
 | selected / CKF tracks           0.0- 0.5 |   0.890205 |    0.11658 |   0.709443 |
 |                                 0.5- 1.0 |   0.913255 |   0.252874 |   0.737646 |
@@ -129,6 +131,7 @@ ActsLargeRadiusTrackFindingAlg                                    INFO statistic
 | Tracks failing second CKF         |         30 |         30 |
 | Stopped tracks below pT cut       |       1885 |       1885 |
 | Stopped tracks above max eta      |          0 |          0 |
+| Total shared hits                 |        582 |        582 |
 |-----------------------------------|------------|------------|
 ActsLargeRadiusTrackFindingAlg                                    INFO Ratios
 |------------------------------------------|------------|------------|
@@ -141,6 +144,7 @@ ActsLargeRadiusTrackFindingAlg                                    INFO Ratios
 | selected tracks / used seeds             |  0.0129706 |  0.0129706 |
 | branched tracks / used seeds             |          0 |          0 |
 | no 2nd CKF / CKF tracks                  |  0.0317797 |  0.0317797 |
+| shared hits / CKF tracks                 |   0.616525 |   0.616525 |
 |------------------------------------------|------------|------------|
 | selected / CKF tracks           0.0- 0.5 |   0.169014 |   0.169014 |
 |                                 0.5- 1.0 |   0.214286 |   0.214286 |
@@ -201,6 +205,7 @@ ActsConversionTrackFindingAlg                                     INFO statistic
 | Tracks failing second CKF         |          0 |          0 |
 | Stopped tracks below pT cut       |          8 |          8 |
 | Stopped tracks above max eta      |          0 |          0 |
+| Total shared hits                 |          0 |          0 |
 |-----------------------------------|------------|------------|
 ActsConversionTrackFindingAlg                                     INFO Ratios
 |------------------------------------------|------------|------------|
@@ -213,6 +218,7 @@ ActsConversionTrackFindingAlg                                     INFO Ratios
 | selected tracks / used seeds             |          0 |          0 |
 | branched tracks / used seeds             |          0 |          0 |
 | no 2nd CKF / CKF tracks                  |          0 |          0 |
+| shared hits / CKF tracks                 |          0 |          0 |
 |------------------------------------------|------------|------------|
 | selected / CKF tracks           0.0- 0.5 |          0 |          0 |
 |                                 0.5- 1.0 |          0 |          0 |
@@ -288,6 +294,7 @@ ActsLowPtTrackFindingAlg                                          INFO statistic
 | Tracks failing second CKF         |          0 |         71 |         71 |
 | Stopped tracks below pT cut       |        441 |         43 |        484 |
 | Stopped tracks above max eta      |          0 |          0 |          0 |
+| Total shared hits                 |       2538 |        257 |       2795 |
 |-----------------------------------|------------|------------|------------|
 ActsLowPtTrackFindingAlg                                          INFO Ratios
 |------------------------------------------|------------|------------|------------|
@@ -300,6 +307,7 @@ ActsLowPtTrackFindingAlg                                          INFO Ratios
 | selected tracks / used seeds             |  0.0134677 | 0.00498132 |  0.0121016 |
 | branched tracks / used seeds             |          0 |          0 |          0 |
 | no 2nd CKF / CKF tracks                  |          0 |  0.0411833 |  0.0247214 |
+| shared hits / CKF tracks                 |     2.2108 |   0.149072 |   0.973189 |
 |------------------------------------------|------------|------------|------------|
 | selected / CKF tracks           0.0- 0.5 |   0.833333 |          0 |       0.36 |
 |                                 0.5- 1.0 |   0.965909 |  0.0215827 |   0.387665 |
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackExtensionAlg.cxx b/Tracking/Acts/ActsTrackReconstruction/src/TrackExtensionAlg.cxx
index 41b6595d709dafc4abb6d7f436aec5c94c4ee231..79f6273b2c04a13c9a6c93d3ab0d4f9b827768fe 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackExtensionAlg.cxx
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackExtensionAlg.cxx
@@ -37,6 +37,8 @@
 #include "ActsInterop/TableUtils.h"
 #include "src/detail/AtlasMeasurementSelector.h"
 #include "src/detail/OnTrackCalibrator.h"
+#include "src/detail/TrackFindingMeasurements.h"
+#include "src/detail/SharedHitCounter.h"
 #include "ActsGeometry/SurfaceOfMeasurementUtil.h"
 
 // STL
@@ -135,7 +137,8 @@ namespace ActsTrk{
        acts_tracking_geometry = m_trackingGeometryTool->trackingGeometry().get();
     ATH_CHECK( acts_tracking_geometry != nullptr);
 
-    detail::TrackFindingMeasurements measurements = collectMeasurements(context, **detectorElementToGeometryIdMap);
+    const auto ms = collectMeasurements(context, **detectorElementToGeometryIdMap);
+    const auto& [measurements, sharedHits] = ms;
 
     ActsTrk::detail::UncalibSourceLinkAccessor slAccessor(measurements.measurementRanges());
     Acts::SourceLinkAccessorDelegate<ActsTrk::detail::UncalibSourceLinkAccessor::Iterator> slAccessorDelegate;
@@ -208,7 +211,7 @@ namespace ActsTrk{
         ATH_MSG_DEBUG("Reco MTJ size " << trackStateBackend.size() );
         for ( size_t stateIndex=0; stateIndex < trackStateBackend.size(); ++stateIndex) {
           auto state = trackStateBackend.getTrackState(stateIndex);
-          if (m_trackStatePrinter.isSet()) m_trackStatePrinter->printTrackState(tgContext, state, measurements.measurementContainerOffsets(), false);
+          if (m_trackStatePrinter.isSet()) m_trackStatePrinter->printTrackState(tgContext, state, sharedHits, false);
         }
         ATH_MSG_DEBUG("Track has: " << tempTrackProxy.nMeasurements() << " measurements ");
         ATH_MSG_DEBUG("track: eta: " <<  -1 * log(tan( tempTrackProxy.theta() * 0.5)) << " phi: " << tempTrackProxy.phi() << " pt:" << abs(1./tempTrackProxy.qOverP() * sin(protoTrack.parameters->theta())));
@@ -229,15 +232,18 @@ namespace ActsTrk{
   }
 
 
-  detail::TrackFindingMeasurements TrackExtensionAlg::collectMeasurements(
+  std::pair<detail::TrackFindingMeasurements, detail::SharedHitCounter> TrackExtensionAlg::collectMeasurements(
        const EventContext& context,
        const ActsTrk::DetectorElementToActsGeometryIdMap &detectorElementToGeometryIdMap) const {
     SG::ReadHandle<xAOD::PixelClusterContainer> pixelClustersHandle(m_pixelClusters, context);
 
-    detail::TrackFindingMeasurements measurements(1u /* only one measurement collection: pixel clusters*/);
+    // setup to return both objects with RVO. Note that SharedHitCounter is only used to get hit offsets needed by TrackStatePrinter.
+    std::pair<detail::TrackFindingMeasurements, detail::SharedHitCounter> res{{}, {1u /* only one measurement collection: pixel clusters*/}};
+    auto& [measurements, sharedHits] = res;
     ATH_MSG_DEBUG("Measurements (pixels only) size: " << pixelClustersHandle->size());
     // potential TODO: filtering only certain layers
     measurements.addMeasurements(0, *pixelClustersHandle, detectorElementToGeometryIdMap);
-    return measurements;
+    sharedHits.addMeasurements(0, *pixelClustersHandle);
+    return res;
   }
 } // EOF namespace
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackExtensionAlg.h b/Tracking/Acts/ActsTrackReconstruction/src/TrackExtensionAlg.h
index 5c308cb60a3c86ba32b851b0d81790c86d65f108..cdb82284f9c0ba5db3ea54dc60dc720c241036f5 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackExtensionAlg.h
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackExtensionAlg.h
@@ -97,7 +97,7 @@ class TrackExtensionAlg : public AthReentrantAlgorithm {
   std::unique_ptr<detail::CKF_config> m_ckfConfig;
   std::unique_ptr<const Acts::Logger> m_logger;
 
-  detail::TrackFindingMeasurements collectMeasurements(
+  std::pair<detail::TrackFindingMeasurements, detail::SharedHitCounter> collectMeasurements(
       const EventContext& context,
       const ActsTrk::DetectorElementToActsGeometryIdMap&
           detectorElementToGeometryIdMap) const;
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx
index 680b57ea08579bc44512968cd6b17e382065b775..69890a52f21abea776dd44599dfa6c57e1e9a12f 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.cxx
@@ -38,6 +38,8 @@
 #include "ActsInterop/TableUtils.h"
 #include "src/detail/AtlasMeasurementSelector.h"
 #include "src/detail/OnTrackCalibrator.h"
+#include "src/detail/TrackFindingMeasurements.h"
+#include "src/detail/SharedHitCounter.h"
 
 // STL
 #include <sstream>
@@ -306,7 +308,8 @@ namespace ActsTrk
       duplicateSeedDetector.addSeeds(icontainer, *seedContainers[icontainer]);
     }
 
-    detail::TrackFindingMeasurements measurements(uncalibratedMeasurementContainers.size() /* number of measurement containers*/);
+    detail::TrackFindingMeasurements measurements;
+    detail::SharedHitCounter sharedHits(uncalibratedMeasurementContainers.size() /* number of measurement containers*/);
     const Acts::TrackingGeometry *
        acts_tracking_geometry = m_trackingGeometryTool->trackingGeometry().get();
     ATH_CHECK(acts_tracking_geometry != nullptr);
@@ -316,10 +319,12 @@ namespace ActsTrk
       measurements.addMeasurements(icontainer,
                                    *uncalibratedMeasurementContainers[icontainer],
                                    **detectorElementToGeometryIdMap);
+      sharedHits.addMeasurements(icontainer,
+                                 *uncalibratedMeasurementContainers[icontainer]);
     }
 
-    if (!m_trackStatePrinter.empty()) {
-      m_trackStatePrinter->printMeasurements(ctx, uncalibratedMeasurementContainers, **detectorElementToGeometryIdMap, measurements.measurementOffsets());
+    if (m_trackStatePrinter.isSet()) {
+      m_trackStatePrinter->printMeasurements(ctx, uncalibratedMeasurementContainers, **detectorElementToGeometryIdMap, sharedHits.measurementOffsets());
     }
 
     // ================================================== //
@@ -350,6 +355,7 @@ namespace ActsTrk
                            *acts_tracking_geometry,
                            **detectorElementToGeometryIdMap,
                            measurements,
+                           sharedHits,
                            duplicateSeedDetector,
                            *seedContainers.at(icontainer),
                            *detElementsCollections.at(icontainer),
@@ -390,11 +396,12 @@ namespace ActsTrk
                               const Acts::TrackingGeometry &trackingGeometry,
                               const ActsTrk::DetectorElementToActsGeometryIdMap &detectorElementToGeoId,
                               const detail::TrackFindingMeasurements &measurements,
+                              detail::SharedHitCounter &sharedHits,
                               detail::DuplicateSeedDetector &duplicateSeedDetector,
                               const ActsTrk::SeedContainer &seeds,
                               const InDetDD::SiDetectorElementCollection& detElements,
                               ActsTrk::MutableTrackContainer &tracksContainer,
-                              size_t typeIndex,
+                              std::size_t typeIndex,
                               const char *seedType,
                               EventStats &event_stat) const
   {
@@ -481,7 +488,6 @@ namespace ActsTrk
     };
 
     std::size_t category_i = 0;
-    const auto measurementContainerOffsets = measurements.measurementContainerOffsets();
 
     using BranchStopperResult = Acts::CombinatorialKalmanFilterBranchStopperResult;
     auto stopBranch = [&](const detail::RecoTrackContainer::TrackProxy &track,
@@ -492,8 +498,8 @@ namespace ActsTrk
         checkPixelStripCounts(track);
       }
 
-      if (!m_trackStatePrinter.empty()) {
-        m_trackStatePrinter->printTrackState(tgContext, trackState, measurementContainerOffsets, true);
+      if (m_trackStatePrinter.isSet()) {
+        m_trackStatePrinter->printTrackState(tgContext, trackState, sharedHits, true);
       }
 
       if (!m_doBranchStopper)
@@ -581,13 +587,13 @@ namespace ActsTrk
     std::size_t nPrinted = 0;
     auto printSeed = [&](std::size_t iseed, const Acts::BoundTrackParameters &seedParameters, bool isKF = false)
     {
-      if (m_trackStatePrinter.empty())
+      if (!m_trackStatePrinter.isSet())
         return;
       if (!nPrinted++)
       {
         ATH_MSG_INFO("CKF results for " << seeds.size() << ' ' << seedType << " seeds:");
       }
-      m_trackStatePrinter->printSeed(tgContext, *seeds[iseed], seedParameters, measurementContainerOffsets, iseed, isKF);
+      m_trackStatePrinter->printSeed(tgContext, *seeds[iseed], seedParameters, sharedHits, iseed, isKF);
     };
 
     // Loop over the track finding results for all initial parameters
@@ -613,7 +619,7 @@ namespace ActsTrk
         category_i = getSeedCategory(typeIndex, *seeds[iseed]);
         ++event_stat[category_i][kNTotalSeeds];
         ++event_stat[category_i][kNDuplicateSeeds];
-        if (m_trackStatePrinter.empty()) continue;  // delay continue to estimate track parms for TrackStatePrinter?
+        if (!m_trackStatePrinter.isSet()) continue;  // delay continue to estimate track parms for TrackStatePrinter?
       }
 
       plainOptions.direction = reverseSearch ? Acts::Direction::Backward : Acts::Direction::Forward;
@@ -742,8 +748,8 @@ namespace ActsTrk
           checkPixelStripCounts(track);
         }
 
-        if (!m_trackStatePrinter.empty()) {
-          m_trackStatePrinter->printTrack(tgContext, tracksContainerTemp, track, measurementContainerOffsets);
+        if (m_trackStatePrinter.isSet()) {
+          m_trackStatePrinter->printTrack(tgContext, tracksContainerTemp, track, sharedHits);
         }
 
         ++ntracks;
@@ -758,6 +764,15 @@ namespace ActsTrk
         };
         if (trackFinder().trackSelector.isValidTrack(track) &&
             selectPixelStripCountsFinal(track)) {
+
+          auto [nShared, nBadTrackMeasurements] = sharedHits.computeSharedHits(track, tracksContainer);
+          if (nBadTrackMeasurements > 0)
+            ATH_MSG_WARNING("computeSharedHits: " << nBadTrackMeasurements << " track measurements not found in input for " << seedType << " seed " << iseed);
+          ATH_MSG_DEBUG("found " << nShared << " shared hits among"
+                                 << tracksContainer.size()
+                                 << " tracks (measurementIndexSize = " << sharedHits.measurementIndexSize() << ")");
+          event_stat[category_i][kNTotalSharedHits] += nShared;
+
           auto destProxy = tracksContainer.getTrack(tracksContainer.addTrack());
           destProxy.copyFrom(track, true);  // make sure we copy track states!
           ++event_stat[category_i][kNSelectedTracks];
@@ -860,7 +875,7 @@ namespace ActsTrk
       } else if (ntracks >= 2) {
         ++event_stat[category_i][kMultipleBranches];
       }
-      if (!m_trackStatePrinter.empty())
+      if (m_trackStatePrinter.isSet())
         std::cout << std::flush;
     }
 
@@ -1065,7 +1080,8 @@ namespace ActsTrk
                                           std::make_pair(kMultipleBranches, "Seeds with more than one branch"),
                                           std::make_pair(kNoSecond, "Tracks failing second CKF"),
                                           std::make_pair(kNStoppedTracksMinPt, "Stopped tracks below pT cut"),
-                                          std::make_pair(kNStoppedTracksMaxEta, "Stopped tracks above max eta")
+                                          std::make_pair(kNStoppedTracksMaxEta, "Stopped tracks above max eta"),
+                                          std::make_pair(kNTotalSharedHits, "Total shared hits")
                                       });
       assert(stat_labels.size() == kNStat);
       std::vector<std::string> categories;
@@ -1158,7 +1174,8 @@ namespace ActsTrk
                                                       TableUtils::defineSimpleRatio("selected / CKF tracks", kNSelectedTracks, kNOutputTracks),
                                                       TableUtils::defineSimpleRatio("selected tracks / used seeds", kNSelectedTracks, kNUsedSeeds),
                                                       TableUtils::defineSimpleRatio("branched tracks / used seeds", kMultipleBranches, kNUsedSeeds),
-                                                      TableUtils::defineSimpleRatio("no 2nd CKF / CKF tracks", kNoSecond, kNOutputTracks)});
+                                                      TableUtils::defineSimpleRatio("no 2nd CKF / CKF tracks", kNoSecond, kNOutputTracks),
+                                                      TableUtils::defineSimpleRatio("shared hits / CKF tracks", kNTotalSharedHits, kNOutputTracks)});
 
       std::vector<float> ratio = TableUtils::computeRatios(ratio_def,
                                                            nSeedCollections() + 1,
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h
index 346e72cd727c9cfcc626fdf493cabbd21b493ca5..0b8a671d98eb15d1c81f13533104d77266b63fc5 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackFindingAlg.h
@@ -55,10 +55,13 @@
 #include "ActsEvent/TrackContainerHandlesHelper.h"
 #include "src/detail/Definitions.h"
 #include "src/detail/DuplicateSeedDetector.h"
-#include "src/detail/TrackFindingMeasurements.h"
 
 namespace ActsTrk
 {
+  namespace detail {
+    class TrackFindingMeasurements;
+    class SharedHitCounter;
+  }
 
   class TrackFindingAlg : public AthReentrantAlgorithm
   {
@@ -172,6 +175,7 @@ namespace ActsTrk
       kNoSecond,
       kNStoppedTracksMinPt,
       kNStoppedTracksMaxEta,
+      kNTotalSharedHits,
       kNStat
     };
     using EventStats = std::vector<std::array<unsigned int, kNStat>>;
@@ -183,28 +187,33 @@ namespace ActsTrk
      * @brief invoke track finding procedure
      *
      * @param ctx - event context
-     * @param measurements - measurements container
+     * @param trackingGeometry - Acts tracking geometry
+     * @param detectorElementToGeoId - map Trk detector element to Acts Geometry id
+     * @param measurements - measurements container used in MeasurementSelector
+     * @param sharedHits - measurements container used for shared hit counting
+     * @param duplicateSeedDetector - duplicate seed detector
      * @param seeds - spacepoint triplet seeds
+     * @param detElements - Trk detector elements
      * @param tracksContainer - output tracks
-     * @param tracksCollection - auxiliary output for downstream tools compatibility (to be removed in the future)
-     * @param seedCollectionIndex - index of seeds in measurements
-     * @param seedType name of type of seeds (strip or pixel) - only used for messages
+     * @param seedCollectionIndex - index of this collection of seeds
+     * @param seedType - name of type of seeds (strip or pixel) - only used for messages
+     * @param event_stat - stats, just for this event
      */
     StatusCode
     findTracks(const EventContext &ctx,
                const Acts::TrackingGeometry &trackingGeometry,
                const ActsTrk::DetectorElementToActsGeometryIdMap &detectorElementToGeoId,
                const detail::TrackFindingMeasurements &measurements,
+               detail::SharedHitCounter &sharedHits,
                detail::DuplicateSeedDetector &duplicateSeedDetector,
                const ActsTrk::SeedContainer &seeds,
                const InDetDD::SiDetectorElementCollection& detElements,
                ActsTrk::MutableTrackContainer &tracksContainer,
-               size_t seedCollectionIndex,
+               std::size_t seedCollectionIndex,
                const char *seedType,
                EventStats &event_stat) const;
 
     // Create tracks from one seed's CKF result, appending to tracksContainer
-
     void storeSeedInfo(const detail::RecoTrackContainer &tracksContainer,
                        const detail::RecoTrackContainerProxy &track,
                        detail::DuplicateSeedDetector &duplicateSeedDetector) const;
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.cxx b/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.cxx
index dd099da1aeb33b12dad720b0babea34a740b9ed1..04410ef19b0b14b96bba491d9d37cd4a05a9d688 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.cxx
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.cxx
@@ -450,7 +450,7 @@ namespace ActsTrk
   TrackStatePrinterTool::printSeed(const Acts::GeometryContext &tgContext,
 				   const ActsTrk::Seed &seed,
 				   const Acts::BoundTrackParameters &initialParameters,
-				   const std::vector<std::pair<const xAOD::UncalibratedMeasurementContainer *, size_t>> &offset,
+				   const detail::SharedHitCounter &sharedHits,
 				   size_t iseed,
 				   bool isKF) const
   {
@@ -470,7 +470,7 @@ namespace ActsTrk
           os << ',';
         ++nos;
         ++nom;
-        os << el->index() + containerOffset(el->container(), offset);
+        os << sharedHits.measurementIndex(*el);
       }
     }
 
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.h b/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.h
index 4f074883d91baba6fdd89903a6a1ebc72353abe2..4e91480fd98b6d3ec8272a4e55fdeb79a2ec9be5 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.h
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.h
@@ -21,13 +21,13 @@
 #include "Acts/EventData/TrackStateType.hpp"
 
 // PACKAGE
+#include "src/detail/SharedHitCounter.h"
 #include "ActsGeometry/ATLASSourceLink.h"
 #include "ActsEvent/Seed.h"
 #include "ActsEvent/TrackContainer.h"
 #include "ActsGeometryInterfaces/ActsGeometryContext.h"
 #include "ActsGeometryInterfaces/IActsTrackingGeometryTool.h"
 #include "xAODInDetMeasurement/SpacePointContainer.h"
-
 #include "ActsGeometry/DetectorElementToActsGeometryIdMap.h"
 
 // Other
@@ -64,7 +64,7 @@ namespace ActsTrk
     printSeed(const Acts::GeometryContext &tgContext,
               const ActsTrk::Seed &seed,
               const Acts::BoundTrackParameters &initialParameters,
-              const std::vector<std::pair<const xAOD::UncalibratedMeasurementContainer *, size_t>> &offset,
+              const detail::SharedHitCounter &sharedHits,
               size_t iseed,
               bool isKF) const;
 
@@ -73,13 +73,13 @@ namespace ActsTrk
     printTrack(const Acts::GeometryContext &tgContext,
                const track_container_t &tracks,
                const typename track_container_t::TrackProxy &track,
-               const std::vector<std::pair<const xAOD::UncalibratedMeasurementContainer *, size_t>> &offset) const;
+               const detail::SharedHitCounter &sharedHits) const;
 
     template <typename track_state_proxy_t>
     bool
     printTrackState(const Acts::GeometryContext &tgContext,
                     const track_state_proxy_t &state,
-                    const std::vector<std::pair<const xAOD::UncalibratedMeasurementContainer *, size_t>> &container_offset,
+                    const detail::SharedHitCounter &sharedHits,
                     bool useFiltered = false,
                     bool newLine = true) const;
 
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.icc b/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.icc
index 2d99609e4ec0ac1424740b6e6549c08c7bcaf5ce..848960ca70ceb91bea4cb1df25af1806aaea91e3 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.icc
+++ b/Tracking/Acts/ActsTrackReconstruction/src/TrackStatePrinterTool.icc
@@ -26,24 +26,12 @@ namespace ActsTrk
     return os.str();
   }
 
-  template <typename measurement_container_t>
-  static std::size_t
-  containerOffset(const measurement_container_t *container,
-                  const std::vector<std::pair<const xAOD::UncalibratedMeasurementContainer *, size_t>> &container_offsets)
-  {
-    for (const auto &[c, offset] : container_offsets)
-    {
-      if (c == container) return offset;
-    }
-    return 0;
-  }
-
   template <typename track_container_t>
   void
   TrackStatePrinterTool::printTrack(const Acts::GeometryContext &tgContext,
 				    const track_container_t &tracks,
 				    const typename track_container_t::TrackProxy &track,
-				    const std::vector<std::pair<const xAOD::UncalibratedMeasurementContainer *, size_t>> &container_offset) const
+				    const detail::SharedHitCounter &sharedHits) const
   {
     const auto lastMeasurementIndex = track.tipIndex();
     // to print track states from inside outward, we need to reverse the order of visitBackwards().
@@ -91,7 +79,7 @@ namespace ActsTrk
 
     for (auto i = states.size(); i > 0;)
     {
-      printTrackState(tgContext, states[--i], container_offset);
+      printTrackState(tgContext, states[--i], sharedHits);
     }
   }
 
@@ -99,7 +87,7 @@ namespace ActsTrk
   bool
   TrackStatePrinterTool::printTrackState(const Acts::GeometryContext &tgContext,
                                          const track_state_proxy_t &state,
-                                         const std::vector<std::pair<const xAOD::UncalibratedMeasurementContainer *, size_t>> &container_offsets,
+                                         const detail::SharedHitCounter &sharedHits,
                                          bool useFiltered,
                                          bool newLine) const
   {
@@ -112,7 +100,7 @@ namespace ActsTrk
     {
       ATLASUncalibSourceLink sl = state.getUncalibratedSourceLink().template get<ATLASUncalibSourceLink>();
       const xAOD::UncalibratedMeasurement &umeas = getUncalibratedMeasurement(sl);
-      index = umeas.index() + containerOffset(umeas.container(), container_offsets);
+      index = sharedHits.measurementIndex(umeas);
     }
 
     std::cout << std::setw(5) << state.index() << ' ';
@@ -159,4 +147,3 @@ namespace ActsTrk
   }
 
 }  // namespace ActsTrk
-
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.h b/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.h
new file mode 100644
index 0000000000000000000000000000000000000000..9ae813ba6144ebddc31a7f754a499e960b26154d
--- /dev/null
+++ b/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.h
@@ -0,0 +1,55 @@
+/*
+  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef ACTSTRACKRECONSTRUCTION_SHAREDHITCOUNTER_H
+#define ACTSTRACKRECONSTRUCTION_SHAREDHITCOUNTER_H
+
+#include "src/detail/AtlasUncalibSourceLinkAccessor.h"
+#include "src/detail/Definitions.h"
+
+#include <utility>
+#include <vector>
+
+namespace ActsTrk {
+ class MutableTrackContainer;
+}
+
+namespace ActsTrk::detail {
+
+  // Helper class to keep track of measurement indices, used for shared hits and debug printing
+  class SharedHitCounter {
+  public:
+    inline SharedHitCounter(std::size_t nMeasurementContainerMax);
+    SharedHitCounter(const SharedHitCounter &) = default;
+    SharedHitCounter &operator=(const SharedHitCounter &) = default;
+    SharedHitCounter(SharedHitCounter &&) noexcept = default;
+    SharedHitCounter &operator=(SharedHitCounter &&) noexcept = default;
+    ~SharedHitCounter() = default;
+
+    inline void addMeasurements(std::size_t typeIndex, const xAOD::UncalibratedMeasurementContainer &clusterContainer);
+    inline std::pair<std::size_t, std::size_t> computeSharedHits(RecoTrackContainerProxy &track, ActsTrk::MutableTrackContainer &tracks);
+
+    inline std::size_t measurementIndex(const xAOD::UncalibratedMeasurement &hit) const;
+    inline std::size_t measurementIndexSize() const;
+
+    inline const std::vector<std::size_t> &measurementOffsets() const;
+    inline std::size_t nMeasurements() const;
+
+  private:
+    struct TrackStateIndex {
+      std::size_t trackIndex;
+      std::size_t stateIndex;
+    };
+    std::vector<std::size_t> m_measurementOffsets;
+    std::vector<std::pair<const SG::AuxVectorData *, std::size_t>> m_measurementContainerOffsets;
+    std::size_t m_measurementIndexSize{0ul};
+    std::size_t m_measurementsTotal{0ul};
+    std::vector<TrackStateIndex> m_firstTrackStateOnTheHit;
+  };
+
+}  // namespace ActsTrk::detail
+
+#include "src/detail/SharedHitCounter.icc"
+
+#endif
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.icc b/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.icc
new file mode 100644
index 0000000000000000000000000000000000000000..65b5dc80d4936dfadffeea78fdf66f17d69723da
--- /dev/null
+++ b/Tracking/Acts/ActsTrackReconstruction/src/detail/SharedHitCounter.icc
@@ -0,0 +1,116 @@
+/*
+  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "ActsEvent/TrackContainer.h"
+
+#include <algorithm>
+
+namespace ActsTrk::detail {
+
+inline SharedHitCounter::SharedHitCounter(std::size_t nMeasurementContainerMax)
+    : m_measurementOffsets(nMeasurementContainerMax, 0ul) {
+  m_measurementContainerOffsets.reserve(nMeasurementContainerMax);
+}
+
+inline std::size_t SharedHitCounter::nMeasurements() const {
+  return m_measurementsTotal;
+}
+
+inline const std::vector<std::size_t>& SharedHitCounter::measurementOffsets() const {
+  return m_measurementOffsets;
+}
+
+inline std::size_t SharedHitCounter::measurementIndexSize() const {
+  return m_measurementIndexSize;
+}
+
+inline void SharedHitCounter::addMeasurements(std::size_t typeIndex, const xAOD::UncalibratedMeasurementContainer& clusterContainer) {
+  if (typeIndex < m_measurementOffsets.size())
+    m_measurementOffsets[typeIndex] = m_measurementsTotal;
+
+  for (const auto* measurement : clusterContainer) {
+    auto container = measurement->container();  // owning container, which might be different from clusterContainer
+    if (std::none_of(m_measurementContainerOffsets.begin(),
+                     m_measurementContainerOffsets.end(),
+                     [container](const auto& c) { return c.first == container; })) {
+      m_measurementContainerOffsets.emplace_back(container, m_measurementIndexSize);
+      m_measurementIndexSize += container->size_v();
+    }
+  }
+  m_measurementsTotal += clusterContainer.size();
+}
+
+inline std::size_t SharedHitCounter::measurementIndex(const xAOD::UncalibratedMeasurement& hit) const {
+  const auto* container = hit.container();
+  auto it =
+      std::find_if(m_measurementContainerOffsets.begin(),
+                   m_measurementContainerOffsets.end(),
+                   [container](const auto& c) {
+                     return c.first == container;
+                   });
+  if (it == m_measurementContainerOffsets.end())
+    return m_measurementIndexSize;
+  std::size_t offset = it->second;
+
+  // check our local index is less than the saved size of the container
+  ++it;
+  std::size_t nextOffset = (it != m_measurementContainerOffsets.end()) ? it->second : m_measurementIndexSize;
+  if (!(hit.index() < (nextOffset - offset)))
+    return m_measurementIndexSize;
+
+  return offset + hit.index();
+}
+
+inline std::pair<std::size_t, std::size_t> SharedHitCounter::computeSharedHits(RecoTrackContainerProxy& track,
+                                                                               MutableTrackContainer& tracks) {
+  // Based on ActsExamples::TrackFindingAlgorithm::computeSharedHits().
+  // Finds shared hits in the reconstructed track and updates SharedHitFlag in both tracks.
+  // Uses measurementIndex() to convert hit to hitIndex, and then m_firstTrackStateOnTheHit[] to convert hitIndex -> TrackStateIndex
+  // Returns stats: nShared and nBadTrackMeasurements
+
+  constexpr TrackStateIndex noTrackState{std::numeric_limits<std::size_t>::max(), std::numeric_limits<std::size_t>::max()};
+
+  if (m_firstTrackStateOnTheHit.size() < m_measurementIndexSize)
+    m_firstTrackStateOnTheHit.resize(m_measurementIndexSize, noTrackState);
+
+  std::size_t nShared = 0;
+  std::size_t nBadTrackMeasurements = 0;
+  for (auto state : track.trackStatesReversed()) {
+    if (!state.typeFlags().test(Acts::TrackStateFlag::MeasurementFlag))
+      continue;
+
+    if (!state.hasUncalibratedSourceLink())
+      continue;
+
+    auto sl = state.getUncalibratedSourceLink().template get<ATLASUncalibSourceLink>();
+    const xAOD::UncalibratedMeasurement& hit = getUncalibratedMeasurement(sl);
+    std::size_t hitIndex = measurementIndex(hit);
+    if (!(hitIndex < m_measurementIndexSize)) {
+      ++nBadTrackMeasurements;
+      continue;
+    }
+
+    // Check if hit not already used
+    if (m_firstTrackStateOnTheHit[hitIndex].trackIndex == noTrackState.trackIndex) {
+      m_firstTrackStateOnTheHit[hitIndex] = {track.index(), state.index()};
+      continue;
+    }
+
+    // if already used, control if first track state has been marked as shared
+    const TrackStateIndex& indexFirstTrackState = m_firstTrackStateOnTheHit[hitIndex];
+
+    auto firstState = tracks.getTrack(indexFirstTrackState.trackIndex).container().trackStateContainer().getTrackState(indexFirstTrackState.stateIndex);
+    if (!firstState.typeFlags().test(Acts::TrackStateFlag::SharedHitFlag)) {
+      firstState.typeFlags().set(Acts::TrackStateFlag::SharedHitFlag);
+      ++nShared;
+    }
+
+    // Decorate this track state
+    state.typeFlags().set(Acts::TrackStateFlag::SharedHitFlag);
+    ++nShared;
+  }
+  return {nShared, nBadTrackMeasurements};
+}
+
+}  // namespace ActsTrk::detail
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.cxx b/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.cxx
index eece7af053a3f39fad5b7e768626a29743da1227..cf5082b1be86741ed2fa1e22218ac44d5ff34200 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.cxx
+++ b/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.cxx
@@ -4,22 +4,15 @@
 
 #include "src/detail/TrackFindingMeasurements.h"
 
+#include "ActsGeometry/DetectorElementToActsGeometryIdMap.h"
+#include "ActsGeometry/SurfaceOfMeasurementUtil.h"
+
 namespace ActsTrk::detail {
 
-  TrackFindingMeasurements::TrackFindingMeasurements(std::size_t nMeasurementContainerMax)
-    : m_measurementOffsets(nMeasurementContainerMax, 0ul)
-  {}
-  
-  // NB. all addDetectorElements() must have been done before calling first addMeasurements().
   void TrackFindingMeasurements::addMeasurements(std::size_t typeIndex,
 						 const xAOD::UncalibratedMeasurementContainer &clusterContainer,
 						 const DetectorElementToActsGeometryIdMap &detectorElementToGeoid)
   {
-    if (typeIndex >= m_measurementOffsets.size()) {
-      throw std::runtime_error("Adding collection with too big a typeIndex");
-    }    
-    m_measurementOffsets[typeIndex] = m_measurementsTotal;
-    
     if (m_measurementRanges.empty()) {
       // try to reserve needed space,
       // this however will reserve more than necessary not just the space needed for the surfaces of
@@ -77,29 +70,5 @@ namespace ActsTrk::detail {
     
     m_measurementsTotal += clusterContainer.size();
   }
-  
-  std::vector<std::pair<const xAOD::UncalibratedMeasurementContainer *, std::size_t>>
-  TrackFindingMeasurements::measurementContainerOffsets() const
-  {
-    std::vector<std::pair<const xAOD::UncalibratedMeasurementContainer *, std::size_t>> offsets;
-    if (m_measurementRanges.numContainers() == 0) return offsets;
-    offsets.reserve(m_measurementRanges.numContainers() - 1); // first one usually 0
-    
-    for (std::size_t typeIndex = 0; typeIndex < m_measurementRanges.numContainers(); ++typeIndex)
-      {
-        const xAOD::UncalibratedMeasurementContainer *theContainer
-	  = std::visit( [] (const auto &a) -> const xAOD::UncalibratedMeasurementContainer *
-	  { return a.containerPtr(); },
-	    m_measurementRanges.container(typeIndex));
-	
-        if (measurementOffset(typeIndex) > 0 and theContainer != nullptr)
-	  {
-	    offsets.emplace_back(theContainer, measurementOffset(typeIndex));
-	  }
-      }
-    
-    return offsets;
-  }
-  
-} // namespace ActsTrk::detail
 
+} // namespace ActsTrk::detail
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.h b/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.h
index 01c23811155b269de356c5b4e42e2e40288d1ef5..13701fba287236011e36e2357c18ad80f7a837e5 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.h
+++ b/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.h
@@ -5,45 +5,38 @@
 #ifndef ACTSTRACKRECONSTRUCTION_TRACKFINDINGMEASUREMENTS_H
 #define ACTSTRACKRECONSTRUCTION_TRACKFINDINGMEASUREMENTS_H
 
-#include "ActsGeometry/SurfaceOfMeasurementUtil.h"
-#include "ActsGeometry/DetectorElementToActsGeometryIdMap.h"
-
 #include "src/detail/AtlasUncalibSourceLinkAccessor.h"
 
+namespace ActsTrk {
+  class DetectorElementToActsGeometryIdMap;
+}
+
 namespace ActsTrk::detail {
 
-  // === TrackFindingMeasurements ============================================
-  // Helper class to convert MeasurementContainer specializations to UncalibSourceLinkMultiset.
+  // Helper class to convert and store MeasurementContainer specializations to MeasurementRangeList
   class TrackFindingMeasurements {
   public:
-    TrackFindingMeasurements(std::size_t nMeasurementContainerMax);
+    TrackFindingMeasurements() = default;
     TrackFindingMeasurements(const TrackFindingMeasurements &) = default;
-    TrackFindingMeasurements& operator=(const TrackFindingMeasurements &) = default;
-    TrackFindingMeasurements(TrackFindingMeasurements&&) noexcept = default;
-    TrackFindingMeasurements& operator=(TrackFindingMeasurements&&) noexcept = default;
+    TrackFindingMeasurements &operator=(const TrackFindingMeasurements &) = default;
+    TrackFindingMeasurements(TrackFindingMeasurements &&) noexcept = default;
+    TrackFindingMeasurements &operator=(TrackFindingMeasurements &&) noexcept = default;
     ~TrackFindingMeasurements() = default;
-    
-    // NB. all addDetectorElements() must have been done before calling first addMeasurements().
+
     void addMeasurements(std::size_t typeIndex,
                          const xAOD::UncalibratedMeasurementContainer &clusterContainer,
                          const DetectorElementToActsGeometryIdMap &detectorElementToGeoid);
 
-    std::vector<std::pair<const xAOD::UncalibratedMeasurementContainer *, std::size_t>> measurementContainerOffsets() const;
-
-
-    inline std::size_t measurementOffset(std::size_t typeIndex) const;    
-    inline const std::vector<std::size_t>& measurementOffsets() const;
-    inline const ActsTrk::detail::MeasurementRangeList& measurementRanges() const;
+    inline const ActsTrk::detail::MeasurementRangeList &measurementRanges() const;
     inline std::size_t nMeasurements() const;
-    
+
   private:
-    std::vector<std::size_t> m_measurementOffsets{};
     // ActsTrk::detail::MeasurementRangeList is an std::unordered_map;
     ActsTrk::detail::MeasurementRangeList m_measurementRanges{};
     std::size_t m_measurementsTotal{0ul};
   };
 
-} // namespace ActsTrk::detail
+}  // namespace ActsTrk::detail
 
 #include "src/detail/TrackFindingMeasurements.icc"
 
diff --git a/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.icc b/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.icc
index fcc03bd10b945d498ccae4cf65f5570294d5d725..ea60fe67121a5384108ad718d149a7dc7339f77c 100644
--- a/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.icc
+++ b/Tracking/Acts/ActsTrackReconstruction/src/detail/TrackFindingMeasurements.icc
@@ -3,18 +3,13 @@
 */
 
 namespace ActsTrk::detail {
-  
-  inline std::size_t TrackFindingMeasurements::measurementOffset(std::size_t typeIndex) const
-  { return typeIndex < m_measurementOffsets.size() ? m_measurementOffsets[typeIndex] : 0ul; }
-  
-  inline const std::vector<std::size_t>& TrackFindingMeasurements::measurementOffsets() const
-  { return m_measurementOffsets; }
-  
-  inline const ActsTrk::detail::MeasurementRangeList& TrackFindingMeasurements::measurementRanges() const
-  { return m_measurementRanges; }
-  
-  inline std::size_t TrackFindingMeasurements::nMeasurements() const
-  { return m_measurementsTotal; }
-  
-} // namespace ActsTrk::detail
 
+  inline const ActsTrk::detail::MeasurementRangeList& TrackFindingMeasurements::measurementRanges() const {
+    return m_measurementRanges;
+  }
+
+  inline std::size_t TrackFindingMeasurements::nMeasurements() const {
+    return m_measurementsTotal;
+  }
+
+}  // namespace ActsTrk::detail
diff --git a/Tracking/Acts/ActsTrackReconstruction/test/TrackFindingMeasurementsTest.cxx b/Tracking/Acts/ActsTrackReconstruction/test/TrackFindingMeasurementsTest.cxx
index f3008ad60bd097be9b78bde76caf40f33fc24b8e..4586cc29cd5be46efbb17e6608548f5b25d897b7 100644
--- a/Tracking/Acts/ActsTrackReconstruction/test/TrackFindingMeasurementsTest.cxx
+++ b/Tracking/Acts/ActsTrackReconstruction/test/TrackFindingMeasurementsTest.cxx
@@ -16,6 +16,7 @@
 #include "ActsGeometry/DetectorElementToActsGeometryIdMap.h"
 
 #include "src/detail/TrackFindingMeasurements.h"
+#include "src/detail/SharedHitCounter.h"
 
 #include "Acts/Geometry/GeometryIdentifier.hpp"
 
@@ -23,19 +24,17 @@
 
 template <typename std::size_t N>
 void checkList(const ActsTrk::detail::TrackFindingMeasurements& measurements,
+               const ActsTrk::detail::SharedHitCounter& sharedHits,
 	       const std::array<std::size_t, N>& entries,
 	       bool isFilled) {
+  const std::vector<std::size_t>& offsets = sharedHits.measurementOffsets();
   std::size_t cumulativeOffset = 0ul;
   for (std::size_t i(0); i<N; ++i) {
-    std::cout << "Checking measurementOffset " << i << " : " << measurements.measurementOffset(i) << " with expected " << cumulativeOffset << std::endl;
-    assert( measurements.measurementOffset(i) == cumulativeOffset );
+    std::cout << "Checking measurementOffset " << i << " : " << offsets.at(i) << " with expected " << cumulativeOffset << std::endl;
+    assert( offsets.at(i) == cumulativeOffset );
     cumulativeOffset += entries.at(i);
   }
-  // always 0ul if index too high
-  std::cout << "Checking measurementOffset " << N << " : " << measurements.measurementOffset(N) << " with expected " << 0ul << " (too big)" << std::endl;
-  assert( measurements.measurementOffset(N) == 0ul );
   
-  const std::vector<std::size_t>& offsets = measurements.measurementOffsets();
   std::cout << "Checking offsets size: " << offsets.size() << " with expected " <<	N << std::endl;
   assert( offsets.size() == N );
 
@@ -106,12 +105,13 @@ int main() {
   // checks pre-fill
   std::cout << "----------------------------------------------" << std::endl;
   std::cout << "Checking tests pre-fill ..." << std::endl;
-  ActsTrk::detail::TrackFindingMeasurements measurements(N);
+  ActsTrk::detail::TrackFindingMeasurements measurements;
+  ActsTrk::detail::SharedHitCounter sharedHits(N);
   std::cout << "Checking nMeasurements: " << measurements.nMeasurements() << " with the expected " << 0ul << std::endl;
   assert( measurements.nMeasurements() == 0ul );
 
   std::array<std::size_t, N> entries {};
-  checkList<N>(measurements, entries, false);
+  checkList<N>(measurements, sharedHits, entries, false);
 
   // fill
   std::cout << "----------------------------------------------" << std::endl;
@@ -131,28 +131,28 @@ int main() {
   measurements.addMeasurements(0, pixelContainer, geometryIdMap);
   measurements.addMeasurements(1, stripContainer, geometryIdMap);
   measurements.addMeasurements(2, hgtdContainer, geometryIdMap);
-   
+
+  sharedHits.addMeasurements(0, pixelContainer);
+  sharedHits.addMeasurements(1, stripContainer);
+  sharedHits.addMeasurements(2, hgtdContainer);
+
   // check post-fill
   std::cout << "----------------------------------------------" << std::endl;
   std::cout << "Checking tests post-fill ..." << std::endl;
   std::cout << "Checking nMeasurements: " << measurements.nMeasurements() << " with the expected " << nPixelClusters + nStripClusters + nHgtdClusters << std::endl;
   entries = { nPixelClusters, nStripClusters, nHgtdClusters };
-  checkList<N>(measurements, entries, true);
+  checkList<N>(measurements, sharedHits, entries, true);
 
-  std::vector<std::pair<const xAOD::UncalibratedMeasurementContainer *, std::size_t>> containerOffsets = measurements.measurementContainerOffsets();
-  std::cout << "Checking measurementContainerOffsets size: " << containerOffsets.size() << " with expected " << N - 1 << std::endl;
-  assert( containerOffsets.size() == N - 1 );
   //  collections
-  auto [container, offset] = containerOffsets.at(0);
-  std::cout << "Checking container : " << container << " with expected " << &stripContainer << std::endl;
-  assert( container == &stripContainer );
-  std::cout << "Checking offset value : " << pixelContainer.size() << " with expected " << offset << std::endl;
-  assert( pixelContainer.size() == offset );
-
-  //
-  auto [container2, offset2] = containerOffsets.at(1);
-  std::cout << "Checking container : " << container2 << " with expected " << &hgtdContainer << std::endl;
-  assert( container2 == &hgtdContainer );
-  std::cout << "Checking offset value : " << pixelContainer.size() + stripContainer.size() << " with expected " << offset2 << std::endl;
-  assert( pixelContainer.size() + stripContainer.size() == offset2 );
+  std::size_t index = sharedHits.measurementIndex(*pixelContainer[0]);
+  std::cout << "Checking index value : " << index << " with expected " << 0ul << std::endl;
+  assert( index == 0ul );
+
+  std::size_t index2 = sharedHits.measurementIndex(*stripContainer[0]);
+  std::cout << "Checking index value : " << index2 << " with expected " << pixelContainer.size() << std::endl;
+  assert( index2 == pixelContainer.size() );
+
+  std::size_t index3 = sharedHits.measurementIndex(*hgtdContainer[0]);
+  std::cout << "Checking index value : " << index3 << " with expected " << pixelContainer.size() + stripContainer.size() << std::endl;
+  assert( index3 == pixelContainer.size() + stripContainer.size() );
 }