diff --git a/Event/EventOverlay/EventOverlayJobTransforms/share/BeamOverlay_jobOptions.py b/Event/EventOverlay/EventOverlayJobTransforms/share/BeamOverlay_jobOptions.py
index e861c3e655cffe6b9be88aea430ea79fe27fa118..8dfc573dad6cfc4ace70cdf30af4874f5801f50b 100644
--- a/Event/EventOverlay/EventOverlayJobTransforms/share/BeamOverlay_jobOptions.py
+++ b/Event/EventOverlay/EventOverlayJobTransforms/share/BeamOverlay_jobOptions.py
@@ -9,3 +9,6 @@ if DetFlags.overlay.BCM_on():
 
     from AthenaCommon import CfgGetter
     job += CfgGetter.getAlgorithm("BCM_OverlayDigitization")
+    job += CfgGetter.getAlgorithm("BCMOverlay")
+    if DetFlags.overlay.Truth_on():
+        job += CfgGetter.getAlgorithm("BCMSDOOverlay")
\ No newline at end of file
diff --git a/InnerDetector/InDetDigitization/BCM_Digitization/python/BCM_DigitizationConfig.py b/InnerDetector/InDetDigitization/BCM_Digitization/python/BCM_DigitizationConfig.py
index 63a12479a085841d9d30fa92f8d6da04988aff68..2faa67f815b17c4787c7d08c7c176e1761986545 100644
--- a/InnerDetector/InDetDigitization/BCM_Digitization/python/BCM_DigitizationConfig.py
+++ b/InnerDetector/InDetDigitization/BCM_Digitization/python/BCM_DigitizationConfig.py
@@ -31,15 +31,26 @@ def BCM_DigitizationTool(name="BCM_DigitizationTool",**kwargs):
  
     if digitizationFlags.doXingByXingPileUp():
         kwargs.setdefault("FirstXing", BCM_FirstXing() )
-        kwargs.setdefault("LastXing",  BCM_LastXing()  ) 
+        kwargs.setdefault("LastXing",  BCM_LastXing()  )
 
-    if digitizationFlags.PileUpPremixing and 'OverlayMT' in digitizationFlags.experimentalDigi():
+    from AthenaCommon.GlobalFlags import globalflags
+    if globalflags.isOverlay():
         from OverlayCommonAlgs.OverlayFlags import overlayFlags
-        kwargs.setdefault("OutputRDOKey", overlayFlags.bkgPrefix() + "BCM_RDOs")
-        kwargs.setdefault("OutputSDOKey", overlayFlags.bkgPrefix() + "BCM_SDO_Map")
+        if overlayFlags.isOverlayMT():
+            kwargs.setdefault("OnlyUseContainerName", False)
+            kwargs.setdefault("OutputRDOKey", overlayFlags.sigPrefix() + "BCM_RDOs")
+            kwargs.setdefault("OutputSDOKey", overlayFlags.sigPrefix() + "BCM_SDO_Map")
+        else:
+            kwargs.setdefault("OutputRDOKey", overlayFlags.evtStore() + "+BCM_RDOs")
+            kwargs.setdefault("OutputSDOKey", overlayFlags.evtStore() + "+BCM_SDO_Map")
     else:
-        kwargs.setdefault("OutputRDOKey", "BCM_RDOs")
-        kwargs.setdefault("OutputSDOKey", "BCM_SDO_Map")
+        if digitizationFlags.PileUpPremixing and 'OverlayMT' in digitizationFlags.experimentalDigi():
+            from OverlayCommonAlgs.OverlayFlags import overlayFlags
+            kwargs.setdefault("OutputRDOKey", overlayFlags.bkgPrefix() + "BCM_RDOs")
+            kwargs.setdefault("OutputSDOKey", overlayFlags.bkgPrefix() + "BCM_SDO_Map")
+        else:
+            kwargs.setdefault("OutputRDOKey", "BCM_RDOs")
+            kwargs.setdefault("OutputSDOKey", "BCM_SDO_Map")
 
     from AthenaCommon import CfgMgr
     return CfgMgr.BCM_DigitizationTool(name,**kwargs)
diff --git a/InnerDetector/InDetRawAlgs/InDetOverlay/CMakeLists.txt b/InnerDetector/InDetRawAlgs/InDetOverlay/CMakeLists.txt
index c6b38a0444e4352b988f64c1ac5262064c09b8ae..aab831a248a079e66846610dbe75e84862844c5a 100644
--- a/InnerDetector/InDetRawAlgs/InDetOverlay/CMakeLists.txt
+++ b/InnerDetector/InDetRawAlgs/InDetOverlay/CMakeLists.txt
@@ -15,6 +15,7 @@ atlas_depends_on_subdirs( PUBLIC
                           Control/StoreGate
                           DetectorDescription/IdDictParser
                           Generators/GeneratorObjects
+                          InnerDetector/InDetRawEvent/InDetBCM_RawData
                           InnerDetector/InDetDetDescr/InDetIdentifier
                           InnerDetector/InDetRawEvent/InDetSimData
                           InnerDetector/InDetRecTools/TRT_ElectronPidTools
@@ -48,7 +49,7 @@ atlas_add_component( InDetOverlay
                      src/*.cxx
                      src/components/*.cxx
                      INCLUDE_DIRS ${CLHEP_INCLUDE_DIRS}
-                     LINK_LIBRARIES ${CLHEP_LIBRARIES} AthenaBaseComps IDC_OverlayBase GaudiKernel InDetRawData StoreGateLib SGtests GeneratorObjects InDetIdentifier InDetSimData TrkTrack TRT_ConditionsServicesLib)
+                     LINK_LIBRARIES ${CLHEP_LIBRARIES} AthenaBaseComps IDC_OverlayBase GaudiKernel InDetRawData StoreGateLib SGtests GeneratorObjects InDetBCM_RawData InDetIdentifier InDetSimData TrkTrack TRT_ConditionsServicesLib)
 
 # Install files from the package:
 atlas_install_headers( InDetOverlay )
@@ -67,3 +68,8 @@ atlas_add_test( SCTOverlayConfig_test
 atlas_add_test( TRTOverlayConfig_test
                 SCRIPT test/TRTOverlayConfig_test.py
                 PROPERTIES TIMEOUT 300 )
+
+atlas_add_test( BCMOverlay_test
+                SOURCES test/BCMOverlay_test.cxx src/BCMOverlay.cxx
+                INCLUDE_DIRS ${CLHEP_INCLUDE_DIRS} ${GTEST_INCLUDE_DIRS}
+                LINK_LIBRARIES ${CLHEP_LIBRARIES} AthenaBaseComps GaudiKernel StoreGateLib SGtests GeneratorObjects InDetBCM_RawData InDetSimData ${GTEST_LIBRARIES} )
diff --git a/InnerDetector/InDetRawAlgs/InDetOverlay/InDetOverlay/BCMOverlay.h b/InnerDetector/InDetRawAlgs/InDetOverlay/InDetOverlay/BCMOverlay.h
new file mode 100644
index 0000000000000000000000000000000000000000..159c481cef602f1690daa9e0ce25462647900744
--- /dev/null
+++ b/InnerDetector/InDetRawAlgs/InDetOverlay/InDetOverlay/BCMOverlay.h
@@ -0,0 +1,54 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+/** @class BCMOverlay
+
+  BCM overlay algorithm
+      @author  Jakob Novak <jakob.novak@cern.ch>
+
+*/
+
+#ifndef INDETOVERLAY_BCMOVERLAY_H
+#define INDETOVERLAY_BCMOVERLAY_H
+
+#include "AthenaBaseComps/AthReentrantAlgorithm.h"
+#include "InDetBCM_RawData/BCM_RDO_Container.h"
+
+struct BCM_Pulse {
+  BCM_Pulse(unsigned int p_, unsigned int w_) {p = p_; w = w_;};
+  unsigned int p;
+  unsigned int w;
+};
+
+class BCMOverlay : public AthReentrantAlgorithm
+{
+public:
+
+  BCMOverlay(const std::string &name, ISvcLocator *pSvcLocator);
+
+  virtual StatusCode initialize() override final;
+  virtual StatusCode execute(const EventContext& ctx) const override final;
+
+  StatusCode overlayContainer(const BCM_RDO_Container *bkgContainer, 
+                              const BCM_RDO_Container *signalContainer, 
+                              BCM_RDO_Container *outputContainer) const;
+
+private:
+
+  BCM_RawData *mergeChannel(const BCM_RawData *bkgRDO, 
+                            const BCM_RawData *signalRDO) const;
+
+  void overlayPulses(std::vector<std::unique_ptr<BCM_Pulse>>& merged_pulses) const;
+
+  std::pair<BCM_Pulse*, BCM_Pulse*> timeOrder(BCM_Pulse* pulse1, BCM_Pulse* pulse2) const;
+
+  static bool compare(const std::unique_ptr<BCM_Pulse>& a, const std::unique_ptr<BCM_Pulse>& b);
+
+  SG::ReadHandleKey<BCM_RDO_Container> m_bkgInputKey{ this, "BkgInputKey", "Bkg_BCM_RDOs", "ReadHandleKey for Background Input BCM_RDO_Container" };
+  SG::ReadHandleKey<BCM_RDO_Container> m_signalInputKey{ this, "SignalInputKey", "Sig_BCM_RDOs", "ReadHandleKey for Signal Input BCM_RDO_Container" };
+  SG::WriteHandleKey<BCM_RDO_Container> m_outputKey{ this, "OutputKey", "BCM_RDOs", "WriteHandleKey for Output BCM_RDO_Container" };
+
+};
+
+#endif // INDETOVERLAY_BCMOVERLAY_H
diff --git a/InnerDetector/InDetRawAlgs/InDetOverlay/python/InDetOverlayConfig.py b/InnerDetector/InDetRawAlgs/InDetOverlay/python/InDetOverlayConfig.py
index 846616af04c6a156ed8785fa6d30c95700455306..db4353a3fb4de431e41dd9dc2451d64d9df87c2d 100644
--- a/InnerDetector/InDetRawAlgs/InDetOverlay/python/InDetOverlayConfig.py
+++ b/InnerDetector/InDetRawAlgs/InDetOverlay/python/InDetOverlayConfig.py
@@ -110,3 +110,35 @@ def getTRTSDOOverlay(name="TRTSDOOverlay", **kwargs):
         kwargs.setdefault("OutputKey", overlayFlags.outputStore() + "+TRT_SDO_Map");
 
     return CfgMgr.InDetSDOOverlay(name, **kwargs)
+
+
+def getBCMOverlay(name="BCMOverlay", **kwargs):
+    from OverlayCommonAlgs.OverlayFlags import overlayFlags
+
+    if overlayFlags.isOverlayMT():
+        kwargs.setdefault("BkgInputKey", overlayFlags.bkgPrefix() + "BCM_RDOs");
+        kwargs.setdefault("SignalInputKey", overlayFlags.sigPrefix() + "BCM_RDOs");
+        kwargs.setdefault("OutputKey", "BCM_RDOs");
+    else:
+        kwargs.setdefault("BkgInputKey", overlayFlags.dataStore() + "+BCM_RDOs");
+        kwargs.setdefault("SignalInputKey", overlayFlags.evtStore() + "+BCM_RDOs");
+        kwargs.setdefault("OutputKey", overlayFlags.outputStore() + "+BCM_RDOs");
+
+    return CfgMgr.BCMOverlay(name, **kwargs)
+
+
+def getBCMSDOOverlay(name="BCMSDOOverlay", **kwargs):
+    from OverlayCommonAlgs.OverlayFlags import overlayFlags
+
+    # We do not need background pixel SDOs
+    kwargs.setdefault("BkgInputKey", "");
+
+    if overlayFlags.isOverlayMT():
+        kwargs.setdefault("SignalInputKey", overlayFlags.sigPrefix() + "BCM_SDO_Map");
+        kwargs.setdefault("OutputKey", "BCM_SDO_Map");
+    else:
+        kwargs.setdefault("SignalInputKey", overlayFlags.evtStore() + "+BCM_SDO_Map");
+        kwargs.setdefault("OutputKey", overlayFlags.outputStore() + "+BCM_SDO_Map");
+
+    return CfgMgr.InDetSDOOverlay(name, **kwargs)
+
diff --git a/InnerDetector/InDetRawAlgs/InDetOverlay/python/InDetOverlayConfigDb.py b/InnerDetector/InDetRawAlgs/InDetOverlay/python/InDetOverlayConfigDb.py
index 142e4e353f322f94cdf71fe80f829649d963489b..61e773770e15502f80858791ea1a3ec3b98b1f85 100644
--- a/InnerDetector/InDetRawAlgs/InDetOverlay/python/InDetOverlayConfigDb.py
+++ b/InnerDetector/InDetRawAlgs/InDetOverlay/python/InDetOverlayConfigDb.py
@@ -5,6 +5,9 @@ from AthenaCommon.CfgGetter import addAlgorithm
 addAlgorithm("InDetOverlay.InDetOverlayConfig.getPixelOverlay", "PixelOverlay")
 addAlgorithm("InDetOverlay.InDetOverlayConfig.getPixelSDOOverlay", "PixelSDOOverlay")
 
+addAlgorithm("InDetOverlay.InDetOverlayConfig.getBCMOverlay", "BCMOverlay")
+addAlgorithm("InDetOverlay.InDetOverlayConfig.getBCMSDOOverlay", "BCMSDOOverlay")
+
 addAlgorithm("InDetOverlay.InDetOverlayConfig.getSCTOverlay", "SCTOverlay")
 addAlgorithm("InDetOverlay.InDetOverlayConfig.getSCTSDOOverlay", "SCTSDOOverlay")
 
diff --git a/InnerDetector/InDetRawAlgs/InDetOverlay/src/BCMOverlay.cxx b/InnerDetector/InDetRawAlgs/InDetOverlay/src/BCMOverlay.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..8969078a486627902303ac12f8f4b791c7c0887c
--- /dev/null
+++ b/InnerDetector/InDetRawAlgs/InDetOverlay/src/BCMOverlay.cxx
@@ -0,0 +1,267 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "InDetOverlay/BCMOverlay.h"
+
+#include "StoreGate/ReadHandle.h"
+#include "StoreGate/WriteHandle.h"
+
+
+BCMOverlay::BCMOverlay(const std::string &name, ISvcLocator *pSvcLocator)
+  : AthReentrantAlgorithm(name, pSvcLocator)
+{
+}
+
+StatusCode BCMOverlay::initialize()
+{
+  ATH_MSG_DEBUG("Initializing...");
+
+  // Check and initialize keys
+  ATH_CHECK( m_bkgInputKey.initialize(!m_bkgInputKey.empty()) );
+  ATH_MSG_VERBOSE("Initialized ReadHandleKey: " << m_bkgInputKey);
+  ATH_CHECK( m_signalInputKey.initialize() );
+  ATH_MSG_VERBOSE("Initialized ReadHandleKey: " << m_signalInputKey);
+  ATH_CHECK( m_outputKey.initialize() );
+  ATH_MSG_VERBOSE("Initialized WriteHandleKey: " << m_outputKey);
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode BCMOverlay::execute(const EventContext& ctx) const
+{
+  ATH_MSG_DEBUG("execute() begin");
+
+  // Reading the input RDOs
+  ATH_MSG_VERBOSE("Retrieving input RDO containers");
+
+  const BCM_RDO_Container *bkgContainerPtr = nullptr;
+  if (!m_bkgInputKey.empty()) {
+    SG::ReadHandle<BCM_RDO_Container> bkgContainer(m_bkgInputKey, ctx);
+    if (!bkgContainer.isValid()) {
+      ATH_MSG_ERROR("Could not get background BCM RDO container " << bkgContainer.name() << " from store " << bkgContainer.store());
+      return StatusCode::FAILURE;
+    }
+    bkgContainerPtr = bkgContainer.cptr();
+
+    ATH_MSG_DEBUG("Found background BCM RDO container " << bkgContainer.name() << " in store " << bkgContainer.store());
+  }
+
+  SG::ReadHandle<BCM_RDO_Container> signalContainer(m_signalInputKey, ctx);
+  if (!signalContainer.isValid()) {
+    ATH_MSG_ERROR("Could not get signal BCM RDO container " << signalContainer.name() << " from store " << signalContainer.store());
+    return StatusCode::FAILURE;
+  }
+  ATH_MSG_DEBUG("Found signal BCM RDO container " << signalContainer.name() << " in store " << signalContainer.store());
+
+  // Creating output RDO container
+  SG::WriteHandle<BCM_RDO_Container> outputContainer(m_outputKey, ctx);
+  ATH_CHECK(outputContainer.record(std::make_unique<BCM_RDO_Container>()));
+  if (!outputContainer.isValid()) {
+    ATH_MSG_ERROR("Could not record output BCM RDO container " << outputContainer.name() << " to store " << outputContainer.store());
+    return StatusCode::FAILURE;
+  }
+  ATH_MSG_DEBUG("Recorded output BCM RDO container " << outputContainer.name() << " in store " << outputContainer.store());
+
+  ATH_CHECK(overlayContainer(bkgContainerPtr, signalContainer.cptr(), outputContainer.ptr()));
+
+  ATH_MSG_DEBUG("execute() end");
+  return StatusCode::SUCCESS;
+}
+
+StatusCode BCMOverlay::overlayContainer(const BCM_RDO_Container *bkgContainer, 
+                                        const BCM_RDO_Container *signalContainer, 
+                                        BCM_RDO_Container *outputContainer) const
+{
+
+  if (!bkgContainer) {
+    for (const BCM_RDO_Collection *coll : *signalContainer) {
+
+      std::unique_ptr<BCM_RDO_Collection> outputColl = std::make_unique<BCM_RDO_Collection>();
+      
+      for (const BCM_RawData *rdo : *coll) {
+        outputColl->push_back(new BCM_RawData(rdo->getWord1(), rdo->getWord2()));
+      }
+      outputContainer->push_back(outputColl.release());
+    }
+
+    return StatusCode::SUCCESS;
+  }
+
+  size_t containerSize = signalContainer->size();
+
+  for (size_t i = 0; i < containerSize; i++) {
+
+    const BCM_RDO_Collection *sigColl = signalContainer->at(i);
+    const BCM_RDO_Collection *bkgColl = bkgContainer->at(i);
+
+    std::unique_ptr<BCM_RDO_Collection> outputColl = std::make_unique<BCM_RDO_Collection>();
+    size_t collectionSize = sigColl->size();
+    if (collectionSize != bkgColl->size()) {
+      ATH_MSG_ERROR ("BCM signal and background collection size mismatch");
+      return StatusCode::FAILURE;
+    }
+
+    if (bkgColl->getChannel() == sigColl->getChannel()) {
+      outputColl->setChannel(sigColl->getChannel());
+    } else {
+      ATH_MSG_ERROR ("BCM signal and background channel mismatch");
+      return StatusCode::FAILURE;
+    }
+
+    for (size_t j = 0; j < collectionSize; j++) {
+
+      if (bkgColl->at(j)->getChannel() == sigColl->at(j)->getChannel()) {
+        BCM_RawData *mergedRDO = mergeChannel(bkgColl->at(j),sigColl->at(j));
+        if (mergedRDO) outputColl->push_back(mergedRDO);
+        else {
+          ATH_MSG_ERROR ("BCM channel merging failed");
+          return StatusCode::FAILURE;
+        }
+      }
+      else {
+        ATH_MSG_ERROR ("BCM signal and background channel mismatch");
+        return StatusCode::FAILURE;
+      }
+
+    }
+    outputContainer->push_back(outputColl.release());
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+BCM_RawData *BCMOverlay::mergeChannel(const BCM_RawData *bkgRDO, 
+                                      const BCM_RawData *signalRDO) const
+{
+
+  if (bkgRDO->getPulse1Width()==0) {
+    return new BCM_RawData(signalRDO->getWord1(), signalRDO->getWord2());
+  } else if (signalRDO->getPulse1Width()==0) {
+    return new BCM_RawData(bkgRDO->getWord1(), bkgRDO->getWord2());
+  }
+
+  unsigned int bkg_p1 = bkgRDO->getPulse1Position();
+  unsigned int bkg_w1 = bkgRDO->getPulse1Width();
+  unsigned int bkg_p2 = bkgRDO->getPulse2Position();
+  unsigned int bkg_w2 = bkgRDO->getPulse2Width();
+  unsigned int sig_p1 = signalRDO->getPulse1Position();
+  unsigned int sig_w1 = signalRDO->getPulse1Width();
+  unsigned int sig_p2 = signalRDO->getPulse2Position();
+  unsigned int sig_w2 = signalRDO->getPulse2Width();
+
+  std::vector<std::unique_ptr<BCM_Pulse>> merged_pulses;
+
+  if (bkg_w1 > 0) merged_pulses.push_back(std::make_unique<BCM_Pulse>(bkg_p1,bkg_w1));
+  if (bkg_w2 > 0) merged_pulses.push_back(std::make_unique<BCM_Pulse>(bkg_p2,bkg_w2));
+  if (sig_w1 > 0) merged_pulses.push_back(std::make_unique<BCM_Pulse>(sig_p1,sig_w1));
+  if (sig_w2 > 0) merged_pulses.push_back(std::make_unique<BCM_Pulse>(sig_p2,sig_w2));
+
+  overlayPulses(merged_pulses);
+  std::sort(merged_pulses.begin(), merged_pulses.end(), compare);
+
+  // Check whether some of the pulses merged
+  for (size_t i = 0; i < merged_pulses.size()-1; i++) {
+
+    BCM_Pulse *early = merged_pulses.at(i).get();
+    BCM_Pulse *later = merged_pulses.at(i+1).get();
+
+    if ( (early->p + early->w - 1) >= later->p ) {
+      early->w = later->p - early->p + later->w;      // Enlarge early pulse
+      merged_pulses.erase(merged_pulses.begin()+i+1, 
+                          merged_pulses.begin()+i+2); // Omit later pulse
+      i--;
+    }
+  }
+
+  unsigned int merged_p1;
+  unsigned int merged_w1;
+  unsigned int merged_p2;
+  unsigned int merged_w2;
+
+  if (merged_pulses.size() > 0) {
+    merged_p1 = merged_pulses.at(0)->p;
+    merged_w1 = merged_pulses.at(0)->w;
+  } else {
+    merged_p1 = 0;
+    merged_w1 = 0;
+  }
+
+  if (merged_pulses.size() > 1) {
+    merged_p2 = merged_pulses.at(1)->p;
+    merged_w2 = merged_pulses.at(1)->w;
+  } else {
+    merged_p2 = 0;
+    merged_w2 = 0;
+  }
+
+  // Record two earliest pulses into the output RDO
+  return new BCM_RawData(signalRDO->getChannel(),
+                         merged_p1, merged_w1,
+                         merged_p2, merged_w2,
+                         signalRDO->getLVL1A(),
+                         signalRDO->getBCID(),
+                         signalRDO->getLVL1ID());
+}
+
+void BCMOverlay::overlayPulses(std::vector<std::unique_ptr<BCM_Pulse>>& merged_pulses) const
+{
+
+  constexpr double fullPulseWidth{15.};      // Analogue pulse width
+                                             // before application of
+                                             // time over threshold
+  constexpr double slopeUpFraction{1./3.};   // Pulse rise time,
+                                             // expressed in the fraction
+                                             // of full pulse width
+  constexpr double slopeDownFraction{2./3.}; // Pulse fall time,
+                                             // expressed in the fraction
+                                             // of full pulse width
+
+  for (size_t i = 0; i < merged_pulses.size(); i++) {
+    BCM_Pulse* pulse_1 = merged_pulses.at(i).get();
+
+    for (size_t j = 0; j < i; j++) {
+      BCM_Pulse* pulse_2 = merged_pulses.at(j).get();
+      auto[early,later] = timeOrder(pulse_1, pulse_2);
+
+      double slope_up = 1./slopeUpFraction/(fullPulseWidth - later->w);
+      double slope_down = 1./slopeDownFraction/(fullPulseWidth - early->w);
+      int bin_min = early->p + early->w;
+      int bin_max = later->p;
+
+      // Widen the pulses, if they lie close enough to each other
+      for (int bin_iter=bin_min; bin_iter < bin_max; bin_iter++) {
+        if (slope_up*(bin_iter - bin_max) - slope_down*(bin_iter - bin_min) > -1) {
+          early->w++;
+        }
+        else break;
+      }
+      for (int bin_iter=bin_max-1; bin_iter >= bin_min; bin_iter--) {
+        if (slope_up*(bin_iter - bin_max) - slope_down*(bin_iter - bin_min) > -1) {
+          later->p = bin_iter;
+          later->w++;
+        }
+        else break;
+      }
+
+    }
+  }
+
+}
+
+std::pair<BCM_Pulse*, BCM_Pulse*> BCMOverlay::timeOrder(BCM_Pulse* pulse1, 
+                                                        BCM_Pulse* pulse2) const
+{
+
+  if (pulse2->p > pulse1->p) return std::pair(pulse1,pulse2);
+  else return std::pair(pulse2,pulse1);
+
+}
+
+bool BCMOverlay::compare(const std::unique_ptr<BCM_Pulse>& a, 
+                         const std::unique_ptr<BCM_Pulse>& b)
+{
+
+  return a->p < b->p;
+  
+}
\ No newline at end of file
diff --git a/InnerDetector/InDetRawAlgs/InDetOverlay/src/components/InDetOverlay_entries.cxx b/InnerDetector/InDetRawAlgs/InDetOverlay/src/components/InDetOverlay_entries.cxx
index 581212fbb98709a4a5613ca18e9abec53cef663a..d559b49df9816f66a6d49703b32635c0a51cbcc0 100644
--- a/InnerDetector/InDetRawAlgs/InDetOverlay/src/components/InDetOverlay_entries.cxx
+++ b/InnerDetector/InDetRawAlgs/InDetOverlay/src/components/InDetOverlay_entries.cxx
@@ -1,3 +1,4 @@
+#include "InDetOverlay/BCMOverlay.h"
 #include "InDetOverlay/PixelOverlay.h"
 #include "InDetOverlay/SCTOverlay.h"
 #include "InDetOverlay/TRTOverlay.h"
@@ -6,6 +7,7 @@
 
 DECLARE_COMPONENT( InDetSDOOverlay )
   
+DECLARE_COMPONENT( BCMOverlay )
 DECLARE_COMPONENT( PixelOverlay )
 DECLARE_COMPONENT( SCTOverlay )
 DECLARE_COMPONENT( TRTOverlay )
diff --git a/InnerDetector/InDetRawAlgs/InDetOverlay/test/BCMOverlay_test.cxx b/InnerDetector/InDetRawAlgs/InDetOverlay/test/BCMOverlay_test.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..2d3cee07df4fcb6129ac377b6a56690a0bc0644a
--- /dev/null
+++ b/InnerDetector/InDetRawAlgs/InDetOverlay/test/BCMOverlay_test.cxx
@@ -0,0 +1,688 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+/** @class BCMOverlay_test
+
+  Tests for BCMOverlay
+      @author  Jakob Novak <jakob.novak@cern.ch>
+
+*/
+
+#undef NDEBUG
+
+// Framework
+#include "TestTools/initGaudi.h"
+
+// Google Test
+#include "gtest/gtest.h"
+
+// Tested AthAlgorithm
+#include "../InDetOverlay/BCMOverlay.h"
+
+namespace OverlayTesting {
+
+  // needed every time an AthAlgorithm, AthAlgTool or AthService is instantiated
+  ISvcLocator* g_svcLoc = nullptr;
+
+  // global test environment takes care of setting up Gaudi
+  class GaudiEnvironment : public ::testing::Environment {
+  protected:
+    virtual void SetUp() override {
+      Athena_test::initGaudi(OverlayTesting::g_svcLoc);
+    }
+  };
+
+  class BCMOverlay_test : public ::testing::Test {
+
+  protected:
+    virtual void SetUp() override {
+      m_alg = new BCMOverlay{"BCMOverlay", g_svcLoc};
+      ASSERT_TRUE( m_alg->setProperties().isSuccess() );
+      ASSERT_TRUE( g_svcLoc->service("StoreGateSvc", m_sg) );
+    }
+
+    virtual void TearDown() override {
+      ASSERT_TRUE( m_alg->finalize().isSuccess() );
+      delete m_alg;
+      ASSERT_TRUE( m_sg->clearStore().isSuccess() );
+    }
+
+    BCMOverlay* m_alg{};
+    StoreGateSvc* m_sg{};
+  };   // BCMOverlay_test fixture
+
+
+  TEST_F(BCMOverlay_test, set_properties) {
+    EventContext ctx(0,0);
+    ctx.setExtension( Atlas::ExtendedEventContext( m_sg, 0 ) );
+    // ordering A, C, B is on purpose to test for unintended alphabetic ordering
+    std::string  inputSigPropertyValue = "'StoreGateSvc+BCM_RDOs_SIG'";
+    std::string  inputBkgPropertyValue = "'StoreGateSvc+BCM_RDOs_BKG'";
+    std::string    outputPropertyValue = "'StoreGateSvc+BCM_RDOs'";
+    ASSERT_TRUE( m_alg->setProperty( "SignalInputKey",   inputSigPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->setProperty( "BkgInputKey",   inputBkgPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->initialize().isSuccess() );
+    ASSERT_TRUE( m_alg->execute(ctx).isFailure() ); //inputs don't exist
+  }
+
+  TEST_F(BCMOverlay_test, empty_containers_alg_execute) {
+    EventContext ctx(0,0);
+    ctx.setExtension( Atlas::ExtendedEventContext( m_sg, 0 ) );
+    SG::WriteHandle<BCM_RDO_Container> inputSigDataHandle{"StoreGateSvc+BCM_RDOs_SIG"};
+    inputSigDataHandle = std::make_unique<BCM_RDO_Container>();
+    SG::WriteHandle<BCM_RDO_Container> inputBkgDataHandle{"StoreGateSvc+BCM_RDOs_BKG"};
+    inputBkgDataHandle = std::make_unique<BCM_RDO_Container>();
+
+    // ordering A, C, B is on purpose to test for unintended alphabetic ordering
+    std::string  inputSigPropertyValue = "'StoreGateSvc+BCM_RDOs_SIG'";
+    std::string  inputBkgPropertyValue = "'StoreGateSvc+BCM_RDOs_BKG'";
+    std::string    outputPropertyValue = "'StoreGateSvc+BCM_RDOs'";
+    ASSERT_TRUE( m_alg->setProperty( "SignalInputKey",   inputSigPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->setProperty( "BkgInputKey",   inputBkgPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->initialize().isSuccess() );
+    ASSERT_TRUE( m_alg->execute(ctx).isSuccess() );
+  }
+
+  TEST_F(BCMOverlay_test, containers_with_empty_collections) {
+    EventContext ctx(0,0);
+    ctx.setExtension( Atlas::ExtendedEventContext( m_sg, 0 ) );
+    SG::WriteHandle<BCM_RDO_Container> inputSigDataHandle{"StoreGateSvc+BCM_RDOs_SIG1"};
+    const unsigned int sigChannel(0);
+    inputSigDataHandle = std::make_unique<BCM_RDO_Container>();
+    std::unique_ptr<BCM_RDO_Collection> sigCollection = std::make_unique<BCM_RDO_Collection>();
+    inputSigDataHandle->push_back(sigCollection.get());
+    sigCollection.release(); // Now owned by inputSigDataHandle
+    SG::WriteHandle<BCM_RDO_Container> inputBkgDataHandle{"StoreGateSvc+BCM_RDOs_BKG1"};
+    inputBkgDataHandle = std::make_unique<BCM_RDO_Container>();
+    std::unique_ptr<BCM_RDO_Collection> bkgCollection = std::make_unique<BCM_RDO_Collection>();
+    inputBkgDataHandle->push_back(bkgCollection.get());
+    bkgCollection.release(); // Now owned by inputBkgDataHandle
+
+    // ordering A, C, B is on purpose to test for unintended alphabetic ordering
+    std::string  inputSigPropertyValue = "'StoreGateSvc+BCM_RDOs_SIG1'";
+    std::string  inputBkgPropertyValue = "'StoreGateSvc+BCM_RDOs_BKG1'";
+    std::string    outputPropertyValue = "'StoreGateSvc+BCM_RDOs1'";
+    ASSERT_TRUE( m_alg->setProperty( "SignalInputKey",   inputSigPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->setProperty( "BkgInputKey",   inputBkgPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->initialize().isSuccess() );
+    ASSERT_TRUE( m_alg->execute(ctx).isSuccess() );
+    // check output makes sense
+    SG::ReadHandle<BCM_RDO_Container> outputDataHandle{"StoreGateSvc+BCM_RDOs1"};
+    ASSERT_TRUE( outputDataHandle.isValid() );
+    const BCM_RDO_Collection *outputCollection = outputDataHandle->at(sigChannel);
+    ASSERT_TRUE( outputCollection!=nullptr );
+    ASSERT_TRUE( outputCollection->empty() );
+  }
+
+  TEST_F(BCMOverlay_test, containers_with_empty_bkg_collection) {
+    EventContext ctx(0,0);
+    ctx.setExtension( Atlas::ExtendedEventContext( m_sg, 0 ) );
+    SG::WriteHandle<BCM_RDO_Container> inputSigDataHandle{"StoreGateSvc+BCM_RDOs_SIG2"};
+    const unsigned int sigChannel(0);
+    const unsigned int sigPulse1Position(5);
+    const unsigned int sigPulse1Width(8);
+    const unsigned int sigPulse2Position(0);
+    const unsigned int sigPulse2Width(0);
+    inputSigDataHandle = std::make_unique<BCM_RDO_Container>();
+    std::unique_ptr<BCM_RDO_Collection> sigCollection = std::make_unique<BCM_RDO_Collection>();
+    std::unique_ptr<BCM_RawData> sigDigit = std::make_unique<BCM_RawData>(sigChannel,sigPulse1Position,sigPulse1Width,sigPulse2Position,sigPulse2Width,0,0,0,0);
+    sigCollection->push_back(sigDigit.release());
+    inputSigDataHandle->push_back(sigCollection.get());
+    sigCollection.release(); // Now owned by inputSigDataHandle
+    SG::WriteHandle<BCM_RDO_Container> inputBkgDataHandle{"StoreGateSvc+BCM_RDOs_BKG2"};
+    inputBkgDataHandle = std::make_unique<BCM_RDO_Container>();
+    std::unique_ptr<BCM_RDO_Collection> bkgCollection = std::make_unique<BCM_RDO_Collection>();
+    inputBkgDataHandle->push_back(bkgCollection.get());
+    bkgCollection.release(); // Now owned by inputBkgDataHandle
+
+    // ordering A, C, B is on purpose to test for unintended alphabetic ordering
+    std::string  inputSigPropertyValue = "'StoreGateSvc+BCM_RDOs_SIG2'";
+    std::string  inputBkgPropertyValue = "'StoreGateSvc+BCM_RDOs_BKG2'";
+    std::string    outputPropertyValue = "'StoreGateSvc+BCM_RDOs2'";
+    ASSERT_TRUE( m_alg->setProperty( "SignalInputKey",   inputSigPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->setProperty( "BkgInputKey",   inputBkgPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->initialize().isSuccess() );
+    ASSERT_TRUE( m_alg->execute(ctx).isFailure() ); //signal and background collection size mismatch
+  }
+
+  TEST_F(BCMOverlay_test, containers_with_pulses_from_different_channels) {
+    EventContext ctx(0,0);
+    ctx.setExtension( Atlas::ExtendedEventContext( m_sg, 0 ) );
+    SG::WriteHandle<BCM_RDO_Container> inputSigDataHandle{"StoreGateSvc+BCM_RDOs_SIG3"};
+    const unsigned int sigChannel(0);
+    const unsigned int sigPulse1Position(0);
+    const unsigned int sigPulse1Width(0);
+    const unsigned int sigPulse2Position(0);
+    const unsigned int sigPulse2Width(0);
+    const unsigned int bkgChannel(1);
+    const unsigned int bkgPulse1Position(0);
+    const unsigned int bkgPulse1Width(0);
+    const unsigned int bkgPulse2Position(0);
+    const unsigned int bkgPulse2Width(0);
+    inputSigDataHandle = std::make_unique<BCM_RDO_Container>();
+    std::unique_ptr<BCM_RDO_Collection> sigCollection = std::make_unique<BCM_RDO_Collection>();
+    //Add a BCM_RawData object
+    std::unique_ptr<BCM_RawData> sigDigit = std::make_unique<BCM_RawData>(sigChannel,sigPulse1Position,sigPulse1Width,sigPulse2Position,sigPulse2Width,0,0,0,0);
+    sigCollection->push_back(sigDigit.release());
+    inputSigDataHandle->push_back(sigCollection.get());
+    sigCollection.release(); // Now owned by inputSigDataHandle
+    SG::WriteHandle<BCM_RDO_Container> inputBkgDataHandle{"StoreGateSvc+BCM_RDOs_BKG3"};
+    inputBkgDataHandle = std::make_unique<BCM_RDO_Container>();
+    std::unique_ptr<BCM_RDO_Collection> bkgCollection = std::make_unique<BCM_RDO_Collection>();
+    //Add a BCM_RawData object
+    std::unique_ptr<BCM_RawData> bkgDigit = std::make_unique<BCM_RawData>(bkgChannel,bkgPulse1Position,bkgPulse1Width,bkgPulse2Position,bkgPulse2Width,0,0,0,0);
+    bkgCollection->push_back(bkgDigit.release());
+    inputBkgDataHandle->push_back(bkgCollection.get());
+    bkgCollection.release(); // Now owned by inputBkgDataHandle
+
+    // ordering A, C, B is on purpose to test for unintended alphabetic ordering
+    std::string  inputSigPropertyValue = "'StoreGateSvc+BCM_RDOs_SIG3'";
+    std::string  inputBkgPropertyValue = "'StoreGateSvc+BCM_RDOs_BKG3'";
+    std::string    outputPropertyValue = "'StoreGateSvc+BCM_RDOs3'";
+    ASSERT_TRUE( m_alg->setProperty( "SignalInputKey",   inputSigPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->setProperty( "BkgInputKey",   inputBkgPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->initialize().isSuccess() );
+    ASSERT_TRUE( m_alg->execute(ctx).isFailure() ); //signal and background channel mismatch
+  }
+
+  TEST_F(BCMOverlay_test, containers_with_two_independent_pulses) {
+    EventContext ctx(0,0);
+    ctx.setExtension( Atlas::ExtendedEventContext( m_sg, 0 ) );
+    SG::WriteHandle<BCM_RDO_Container> inputSigDataHandle{"StoreGateSvc+BCM_RDOs_SIG4"};
+    const unsigned int sigChannel(0);
+    const unsigned int sigPulse1Position(5);
+    const unsigned int sigPulse1Width(8);
+    const unsigned int sigPulse2Position(0);
+    const unsigned int sigPulse2Width(0);
+    const unsigned int bkgChannel(0);
+    const unsigned int bkgPulse1Position(39);
+    const unsigned int bkgPulse1Width(10);
+    const unsigned int bkgPulse2Position(0);
+    const unsigned int bkgPulse2Width(0);
+    inputSigDataHandle = std::make_unique<BCM_RDO_Container>();
+    std::unique_ptr<BCM_RDO_Collection> sigCollection = std::make_unique<BCM_RDO_Collection>();
+    //Add a BCM_RawData object
+    std::unique_ptr<BCM_RawData> sigDigit = std::make_unique<BCM_RawData>(sigChannel,sigPulse1Position,sigPulse1Width,sigPulse2Position,sigPulse2Width,0,0,0,0);
+    sigCollection->push_back(sigDigit.release());
+    inputSigDataHandle->push_back(sigCollection.get());
+    sigCollection.release(); // Now owned by inputSigDataHandle
+    SG::WriteHandle<BCM_RDO_Container> inputBkgDataHandle{"StoreGateSvc+BCM_RDOs_BKG4"};
+    inputBkgDataHandle = std::make_unique<BCM_RDO_Container>();
+    std::unique_ptr<BCM_RDO_Collection> bkgCollection = std::make_unique<BCM_RDO_Collection>();
+    //Add a BCM_RawData object
+    std::unique_ptr<BCM_RawData> bkgDigit = std::make_unique<BCM_RawData>(bkgChannel,bkgPulse1Position,bkgPulse1Width,bkgPulse2Position,bkgPulse2Width,0,0,0,0);
+    bkgCollection->push_back(bkgDigit.release());
+    inputBkgDataHandle->push_back(bkgCollection.get());
+    bkgCollection.release(); // Now owned by inputBkgDataHandle
+
+    // ordering A, C, B is on purpose to test for unintended alphabetic ordering
+    std::string  inputSigPropertyValue = "'StoreGateSvc+BCM_RDOs_SIG4'";
+    std::string  inputBkgPropertyValue = "'StoreGateSvc+BCM_RDOs_BKG4'";
+    std::string    outputPropertyValue = "'StoreGateSvc+BCM_RDOs4'";
+    ASSERT_TRUE( m_alg->setProperty( "SignalInputKey",   inputSigPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->setProperty( "BkgInputKey",   inputBkgPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->initialize().isSuccess() );
+    ASSERT_TRUE( m_alg->execute(ctx).isSuccess() );
+    // check output makes sense
+    SG::ReadHandle<BCM_RDO_Container> outputDataHandle{"StoreGateSvc+BCM_RDOs4"};
+    ASSERT_TRUE( outputDataHandle.isValid() );
+    const BCM_RDO_Collection *outputCollection = outputDataHandle->at(sigChannel);
+    ASSERT_TRUE( outputCollection!=nullptr );
+    ASSERT_TRUE( outputCollection->size()==1 );
+    const BCM_RawData* outputDigit = outputCollection->at(0);
+    ASSERT_TRUE( outputDigit!=nullptr );
+    ASSERT_TRUE( outputDigit->getChannel()==sigChannel );
+    ASSERT_TRUE( outputDigit->getPulse1Position()==sigPulse1Position ); // First pulse is signal pulse
+    ASSERT_TRUE( outputDigit->getPulse1Width()==sigPulse1Width );
+    ASSERT_TRUE( outputDigit->getPulse2Position()==bkgPulse1Position ); // Second pulse is background pulse
+    ASSERT_TRUE( outputDigit->getPulse2Width()==bkgPulse1Width );
+  }
+
+  TEST_F(BCMOverlay_test, containers_with_two_pulses_affecting_each_other) {
+    EventContext ctx(0,0);
+    ctx.setExtension( Atlas::ExtendedEventContext( m_sg, 0 ) );
+    SG::WriteHandle<BCM_RDO_Container> inputSigDataHandle{"StoreGateSvc+BCM_RDOs_SIG5"};
+    const unsigned int sigChannel(0);
+    const unsigned int sigPulse1Position(12);
+    const unsigned int sigPulse1Width(9);
+    const unsigned int sigPulse2Position(0);
+    const unsigned int sigPulse2Width(0);
+    const unsigned int bkgChannel(0);
+    const unsigned int bkgPulse1Position(5);
+    const unsigned int bkgPulse1Width(3);
+    const unsigned int bkgPulse2Position(0);
+    const unsigned int bkgPulse2Width(0);
+    inputSigDataHandle = std::make_unique<BCM_RDO_Container>();
+    std::unique_ptr<BCM_RDO_Collection> sigCollection = std::make_unique<BCM_RDO_Collection>();
+    //Add a BCM_RawData object
+    std::unique_ptr<BCM_RawData> sigDigit = std::make_unique<BCM_RawData>(sigChannel,sigPulse1Position,sigPulse1Width,sigPulse2Position,sigPulse2Width,0,0,0,0);
+    sigCollection->push_back(sigDigit.release());
+    inputSigDataHandle->push_back(sigCollection.get());
+    sigCollection.release(); // Now owned by inputSigDataHandle
+    SG::WriteHandle<BCM_RDO_Container> inputBkgDataHandle{"StoreGateSvc+BCM_RDOs_BKG5"};
+    inputBkgDataHandle = std::make_unique<BCM_RDO_Container>();
+    std::unique_ptr<BCM_RDO_Collection> bkgCollection = std::make_unique<BCM_RDO_Collection>();
+    //Add a BCM_RawData object
+    std::unique_ptr<BCM_RawData> bkgDigit = std::make_unique<BCM_RawData>(bkgChannel,bkgPulse1Position,bkgPulse1Width,bkgPulse2Position,bkgPulse2Width,0,0,0,0);
+    bkgCollection->push_back(bkgDigit.release());
+    inputBkgDataHandle->push_back(bkgCollection.get());
+    bkgCollection.release(); // Now owned by inputBkgDataHandle
+
+    // ordering A, C, B is on purpose to test for unintended alphabetic ordering
+    std::string  inputSigPropertyValue = "'StoreGateSvc+BCM_RDOs_SIG5'";
+    std::string  inputBkgPropertyValue = "'StoreGateSvc+BCM_RDOs_BKG5'";
+    std::string    outputPropertyValue = "'StoreGateSvc+BCM_RDOs5'";
+    ASSERT_TRUE( m_alg->setProperty( "SignalInputKey",   inputSigPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->setProperty( "BkgInputKey",   inputBkgPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->initialize().isSuccess() );
+    ASSERT_TRUE( m_alg->execute(ctx).isSuccess() );
+    // check output makes sense
+    SG::ReadHandle<BCM_RDO_Container> outputDataHandle{"StoreGateSvc+BCM_RDOs5"};
+    ASSERT_TRUE( outputDataHandle.isValid() );
+    const BCM_RDO_Collection *outputCollection = outputDataHandle->at(sigChannel);
+    ASSERT_TRUE( outputCollection!=nullptr );
+    ASSERT_TRUE( outputCollection->size()==1 );
+    const BCM_RawData* outputDigit = outputCollection->at(0);
+    ASSERT_TRUE( outputDigit!=nullptr );
+    ASSERT_TRUE( outputDigit->getChannel()==sigChannel );
+    ASSERT_TRUE( outputDigit->getPulse1Position()==bkgPulse1Position ); // First pulse is background pulse
+    ASSERT_TRUE( outputDigit->getPulse1Width()==bkgPulse1Width );
+    ASSERT_TRUE( outputDigit->getPulse2Position()==11 ); // Second pulse is broader signal pulse
+    ASSERT_TRUE( outputDigit->getPulse2Width()==10 );
+  }
+
+  TEST_F(BCMOverlay_test, containers_with_two_merging_pulses) {
+    EventContext ctx(0,0);
+    ctx.setExtension( Atlas::ExtendedEventContext( m_sg, 0 ) );
+    SG::WriteHandle<BCM_RDO_Container> inputSigDataHandle{"StoreGateSvc+BCM_RDOs_SIG6"};
+    const unsigned int sigChannel(0);
+    const unsigned int sigPulse1Position(5);
+    const unsigned int sigPulse1Width(3);
+    const unsigned int sigPulse2Position(0);
+    const unsigned int sigPulse2Width(0);
+    const unsigned int bkgChannel(0);
+    const unsigned int bkgPulse1Position(11);
+    const unsigned int bkgPulse1Width(3);
+    const unsigned int bkgPulse2Position(0);
+    const unsigned int bkgPulse2Width(0);
+    inputSigDataHandle = std::make_unique<BCM_RDO_Container>();
+    std::unique_ptr<BCM_RDO_Collection> sigCollection = std::make_unique<BCM_RDO_Collection>();
+    //Add a BCM_RawData object
+    std::unique_ptr<BCM_RawData> sigDigit = std::make_unique<BCM_RawData>(sigChannel,sigPulse1Position,sigPulse1Width,sigPulse2Position,sigPulse2Width,0,0,0,0);
+    sigCollection->push_back(sigDigit.release());
+    inputSigDataHandle->push_back(sigCollection.get());
+    sigCollection.release(); // Now owned by inputSigDataHandle
+    SG::WriteHandle<BCM_RDO_Container> inputBkgDataHandle{"StoreGateSvc+BCM_RDOs_BKG6"};
+    inputBkgDataHandle = std::make_unique<BCM_RDO_Container>();
+    std::unique_ptr<BCM_RDO_Collection> bkgCollection = std::make_unique<BCM_RDO_Collection>();
+    //Add a BCM_RawData object
+    std::unique_ptr<BCM_RawData> bkgDigit = std::make_unique<BCM_RawData>(bkgChannel,bkgPulse1Position,bkgPulse1Width,bkgPulse2Position,bkgPulse2Width,0,0,0,0);
+    bkgCollection->push_back(bkgDigit.release());
+    inputBkgDataHandle->push_back(bkgCollection.get());
+    bkgCollection.release(); // Now owned by inputBkgDataHandle
+
+    // ordering A, C, B is on purpose to test for unintended alphabetic ordering
+    std::string  inputSigPropertyValue = "'StoreGateSvc+BCM_RDOs_SIG6'";
+    std::string  inputBkgPropertyValue = "'StoreGateSvc+BCM_RDOs_BKG6'";
+    std::string    outputPropertyValue = "'StoreGateSvc+BCM_RDOs6'";
+    ASSERT_TRUE( m_alg->setProperty( "SignalInputKey",   inputSigPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->setProperty( "BkgInputKey",   inputBkgPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->initialize().isSuccess() );
+    ASSERT_TRUE( m_alg->execute(ctx).isSuccess() );
+    // check output makes sense
+    SG::ReadHandle<BCM_RDO_Container> outputDataHandle{"StoreGateSvc+BCM_RDOs6"};
+    ASSERT_TRUE( outputDataHandle.isValid() );
+    const BCM_RDO_Collection *outputCollection = outputDataHandle->at(sigChannel);
+    ASSERT_TRUE( outputCollection!=nullptr );
+    ASSERT_TRUE( outputCollection->size()==1 );
+    const BCM_RawData* outputDigit = outputCollection->at(0);
+    ASSERT_TRUE( outputDigit!=nullptr );
+    ASSERT_TRUE( outputDigit->getChannel()==sigChannel );
+    ASSERT_TRUE( outputDigit->getPulse1Position()==sigPulse1Position ); // Merged pulse
+    ASSERT_TRUE( outputDigit->getPulse1Width()==9 );
+    ASSERT_TRUE( outputDigit->getPulse2Position()==0 ); // No second pulse
+    ASSERT_TRUE( outputDigit->getPulse2Width()==0 );
+  }
+
+  TEST_F(BCMOverlay_test, containers_with_one_signal_and_two_independent_background_pulses) {
+    EventContext ctx(0,0);
+    ctx.setExtension( Atlas::ExtendedEventContext( m_sg, 0 ) );
+    SG::WriteHandle<BCM_RDO_Container> inputSigDataHandle{"StoreGateSvc+BCM_RDOs_SIG7"};
+    const unsigned int sigChannel(0);
+    const unsigned int sigPulse1Position(25);
+    const unsigned int sigPulse1Width(9);
+    const unsigned int sigPulse2Position(0);
+    const unsigned int sigPulse2Width(0);
+    const unsigned int bkgChannel(0);
+    const unsigned int bkgPulse1Position(5);
+    const unsigned int bkgPulse1Width(9);
+    const unsigned int bkgPulse2Position(45);
+    const unsigned int bkgPulse2Width(9);
+    inputSigDataHandle = std::make_unique<BCM_RDO_Container>();
+    std::unique_ptr<BCM_RDO_Collection> sigCollection = std::make_unique<BCM_RDO_Collection>();
+    //Add a BCM_RawData object
+    std::unique_ptr<BCM_RawData> sigDigit = std::make_unique<BCM_RawData>(sigChannel,sigPulse1Position,sigPulse1Width,sigPulse2Position,sigPulse2Width,0,0,0,0);
+    sigCollection->push_back(sigDigit.release());
+    inputSigDataHandle->push_back(sigCollection.get());
+    sigCollection.release(); // Now owned by inputSigDataHandle
+    SG::WriteHandle<BCM_RDO_Container> inputBkgDataHandle{"StoreGateSvc+BCM_RDOs_BKG7"};
+    inputBkgDataHandle = std::make_unique<BCM_RDO_Container>();
+    std::unique_ptr<BCM_RDO_Collection> bkgCollection = std::make_unique<BCM_RDO_Collection>();
+    //Add a BCM_RawData object
+    std::unique_ptr<BCM_RawData> bkgDigit = std::make_unique<BCM_RawData>(bkgChannel,bkgPulse1Position,bkgPulse1Width,bkgPulse2Position,bkgPulse2Width,0,0,0,0);
+    bkgCollection->push_back(bkgDigit.release());
+    inputBkgDataHandle->push_back(bkgCollection.get());
+    bkgCollection.release(); // Now owned by inputBkgDataHandle
+
+    // ordering A, C, B is on purpose to test for unintended alphabetic ordering
+    std::string  inputSigPropertyValue = "'StoreGateSvc+BCM_RDOs_SIG7'";
+    std::string  inputBkgPropertyValue = "'StoreGateSvc+BCM_RDOs_BKG7'";
+    std::string    outputPropertyValue = "'StoreGateSvc+BCM_RDOs7'";
+    ASSERT_TRUE( m_alg->setProperty( "SignalInputKey",   inputSigPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->setProperty( "BkgInputKey",   inputBkgPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->initialize().isSuccess() );
+    ASSERT_TRUE( m_alg->execute(ctx).isSuccess() );
+    // check output makes sense
+    SG::ReadHandle<BCM_RDO_Container> outputDataHandle{"StoreGateSvc+BCM_RDOs7"};
+    ASSERT_TRUE( outputDataHandle.isValid() );
+    const BCM_RDO_Collection *outputCollection = outputDataHandle->at(sigChannel);
+    ASSERT_TRUE( outputCollection!=nullptr );
+    ASSERT_TRUE( outputCollection->size()==1 );
+    const BCM_RawData* outputDigit = outputCollection->at(0);
+    ASSERT_TRUE( outputDigit!=nullptr );
+    ASSERT_TRUE( outputDigit->getChannel()==sigChannel );
+    ASSERT_TRUE( outputDigit->getPulse1Position()==bkgPulse1Position ); // First pulse is first background pulse
+    ASSERT_TRUE( outputDigit->getPulse1Width()==bkgPulse1Width );
+    ASSERT_TRUE( outputDigit->getPulse2Position()==sigPulse1Position ); // Second pulse is signal pulse
+    ASSERT_TRUE( outputDigit->getPulse2Width()==sigPulse1Width );
+  }
+
+  TEST_F(BCMOverlay_test, containers_with_two_signal_and_one_independent_background_pulse) {
+    EventContext ctx(0,0);
+    ctx.setExtension( Atlas::ExtendedEventContext( m_sg, 0 ) );
+    SG::WriteHandle<BCM_RDO_Container> inputSigDataHandle{"StoreGateSvc+BCM_RDOs_SIG8"};
+    const unsigned int sigChannel(0);
+    const unsigned int sigPulse1Position(5);
+    const unsigned int sigPulse1Width(9);
+    const unsigned int sigPulse2Position(45);
+    const unsigned int sigPulse2Width(9);
+    const unsigned int bkgChannel(0);
+    const unsigned int bkgPulse1Position(25);
+    const unsigned int bkgPulse1Width(9);
+    const unsigned int bkgPulse2Position(0);
+    const unsigned int bkgPulse2Width(0);
+    inputSigDataHandle = std::make_unique<BCM_RDO_Container>();
+    std::unique_ptr<BCM_RDO_Collection> sigCollection = std::make_unique<BCM_RDO_Collection>();
+    //Add a BCM_RawData object
+    std::unique_ptr<BCM_RawData> sigDigit = std::make_unique<BCM_RawData>(sigChannel,sigPulse1Position,sigPulse1Width,sigPulse2Position,sigPulse2Width,0,0,0,0);
+    sigCollection->push_back(sigDigit.release());
+    inputSigDataHandle->push_back(sigCollection.get());
+    sigCollection.release(); // Now owned by inputSigDataHandle
+    SG::WriteHandle<BCM_RDO_Container> inputBkgDataHandle{"StoreGateSvc+BCM_RDOs_BKG8"};
+    inputBkgDataHandle = std::make_unique<BCM_RDO_Container>();
+    std::unique_ptr<BCM_RDO_Collection> bkgCollection = std::make_unique<BCM_RDO_Collection>();
+    //Add a BCM_RawData object
+    std::unique_ptr<BCM_RawData> bkgDigit = std::make_unique<BCM_RawData>(bkgChannel,bkgPulse1Position,bkgPulse1Width,bkgPulse2Position,bkgPulse2Width,0,0,0,0);
+    bkgCollection->push_back(bkgDigit.release());
+    inputBkgDataHandle->push_back(bkgCollection.get());
+    bkgCollection.release(); // Now owned by inputBkgDataHandle
+
+    // ordering A, C, B is on purpose to test for unintended alphabetic ordering
+    std::string  inputSigPropertyValue = "'StoreGateSvc+BCM_RDOs_SIG8'";
+    std::string  inputBkgPropertyValue = "'StoreGateSvc+BCM_RDOs_BKG8'";
+    std::string    outputPropertyValue = "'StoreGateSvc+BCM_RDOs8'";
+    ASSERT_TRUE( m_alg->setProperty( "SignalInputKey",   inputSigPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->setProperty( "BkgInputKey",   inputBkgPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->initialize().isSuccess() );
+    ASSERT_TRUE( m_alg->execute(ctx).isSuccess() );
+    // check output makes sense
+    SG::ReadHandle<BCM_RDO_Container> outputDataHandle{"StoreGateSvc+BCM_RDOs8"};
+    ASSERT_TRUE( outputDataHandle.isValid() );
+    const BCM_RDO_Collection *outputCollection = outputDataHandle->at(sigChannel);
+    ASSERT_TRUE( outputCollection!=nullptr );
+    ASSERT_TRUE( outputCollection->size()==1 );
+    const BCM_RawData* outputDigit = outputCollection->at(0);
+    ASSERT_TRUE( outputDigit!=nullptr );
+    ASSERT_TRUE( outputDigit->getChannel()==sigChannel );
+    ASSERT_TRUE( outputDigit->getPulse1Position()==sigPulse1Position ); // First pulse is first signal pulse
+    ASSERT_TRUE( outputDigit->getPulse1Width()==sigPulse1Width );
+    ASSERT_TRUE( outputDigit->getPulse2Position()==bkgPulse1Position ); // Second pulse is background pulse
+    ASSERT_TRUE( outputDigit->getPulse2Width()==bkgPulse1Width );
+  }
+
+  TEST_F(BCMOverlay_test, containers_with_three_pulses_two_merging) {
+    EventContext ctx(0,0);
+    ctx.setExtension( Atlas::ExtendedEventContext( m_sg, 0 ) );
+    SG::WriteHandle<BCM_RDO_Container> inputSigDataHandle{"StoreGateSvc+BCM_RDOs_SIG9"};
+    const unsigned int sigChannel(0);
+    const unsigned int sigPulse1Position(5);
+    const unsigned int sigPulse1Width(3);
+    const unsigned int sigPulse2Position(0);
+    const unsigned int sigPulse2Width(0);
+    const unsigned int bkgChannel(0);
+    const unsigned int bkgPulse1Position(11);
+    const unsigned int bkgPulse1Width(3);
+    const unsigned int bkgPulse2Position(45);
+    const unsigned int bkgPulse2Width(9);
+    inputSigDataHandle = std::make_unique<BCM_RDO_Container>();
+    std::unique_ptr<BCM_RDO_Collection> sigCollection = std::make_unique<BCM_RDO_Collection>();
+    //Add a BCM_RawData object
+    std::unique_ptr<BCM_RawData> sigDigit = std::make_unique<BCM_RawData>(sigChannel,sigPulse1Position,sigPulse1Width,sigPulse2Position,sigPulse2Width,0,0,0,0);
+    sigCollection->push_back(sigDigit.release());
+    inputSigDataHandle->push_back(sigCollection.get());
+    sigCollection.release(); // Now owned by inputSigDataHandle
+    SG::WriteHandle<BCM_RDO_Container> inputBkgDataHandle{"StoreGateSvc+BCM_RDOs_BKG9"};
+    inputBkgDataHandle = std::make_unique<BCM_RDO_Container>();
+    std::unique_ptr<BCM_RDO_Collection> bkgCollection = std::make_unique<BCM_RDO_Collection>();
+    //Add a BCM_RawData object
+    std::unique_ptr<BCM_RawData> bkgDigit = std::make_unique<BCM_RawData>(bkgChannel,bkgPulse1Position,bkgPulse1Width,bkgPulse2Position,bkgPulse2Width,0,0,0,0);
+    bkgCollection->push_back(bkgDigit.release());
+    inputBkgDataHandle->push_back(bkgCollection.get());
+    bkgCollection.release(); // Now owned by inputBkgDataHandle
+
+    // ordering A, C, B is on purpose to test for unintended alphabetic ordering
+    std::string  inputSigPropertyValue = "'StoreGateSvc+BCM_RDOs_SIG9'";
+    std::string  inputBkgPropertyValue = "'StoreGateSvc+BCM_RDOs_BKG9'";
+    std::string    outputPropertyValue = "'StoreGateSvc+BCM_RDOs9'";
+    ASSERT_TRUE( m_alg->setProperty( "SignalInputKey",   inputSigPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->setProperty( "BkgInputKey",   inputBkgPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->initialize().isSuccess() );
+    ASSERT_TRUE( m_alg->execute(ctx).isSuccess() );
+    // check output makes sense
+    SG::ReadHandle<BCM_RDO_Container> outputDataHandle{"StoreGateSvc+BCM_RDOs9"};
+    ASSERT_TRUE( outputDataHandle.isValid() );
+    const BCM_RDO_Collection *outputCollection = outputDataHandle->at(sigChannel);
+    ASSERT_TRUE( outputCollection!=nullptr );
+    ASSERT_TRUE( outputCollection->size()==1 );
+    const BCM_RawData* outputDigit = outputCollection->at(0);
+    ASSERT_TRUE( outputDigit!=nullptr );
+    ASSERT_TRUE( outputDigit->getChannel()==sigChannel );
+    ASSERT_TRUE( outputDigit->getPulse1Position()==sigPulse1Position ); // First pulse is merged
+    ASSERT_TRUE( outputDigit->getPulse1Width()==9 );
+    ASSERT_TRUE( outputDigit->getPulse2Position()==bkgPulse2Position ); // Second pulse is second background pulse
+    ASSERT_TRUE( outputDigit->getPulse2Width()==bkgPulse2Width );
+  }
+
+  TEST_F(BCMOverlay_test, containers_with_one_signal_two_bkg_merging_pulses) {
+    EventContext ctx(0,0);
+    ctx.setExtension( Atlas::ExtendedEventContext( m_sg, 0 ) );
+    SG::WriteHandle<BCM_RDO_Container> inputSigDataHandle{"StoreGateSvc+BCM_RDOs_SIG10"};
+    const unsigned int sigChannel(0);
+    const unsigned int sigPulse1Position(11);
+    const unsigned int sigPulse1Width(3);
+    const unsigned int sigPulse2Position(0);
+    const unsigned int sigPulse2Width(0);
+    const unsigned int bkgChannel(0);
+    const unsigned int bkgPulse1Position(5);
+    const unsigned int bkgPulse1Width(3);
+    const unsigned int bkgPulse2Position(17);
+    const unsigned int bkgPulse2Width(3);
+    inputSigDataHandle = std::make_unique<BCM_RDO_Container>();
+    std::unique_ptr<BCM_RDO_Collection> sigCollection = std::make_unique<BCM_RDO_Collection>();
+    //Add a BCM_RawData object
+    std::unique_ptr<BCM_RawData> sigDigit = std::make_unique<BCM_RawData>(sigChannel,sigPulse1Position,sigPulse1Width,sigPulse2Position,sigPulse2Width,0,0,0,0);
+    sigCollection->push_back(sigDigit.release());
+    inputSigDataHandle->push_back(sigCollection.get());
+    sigCollection.release(); // Now owned by inputSigDataHandle
+    SG::WriteHandle<BCM_RDO_Container> inputBkgDataHandle{"StoreGateSvc+BCM_RDOs_BKG10"};
+    inputBkgDataHandle = std::make_unique<BCM_RDO_Container>();
+    std::unique_ptr<BCM_RDO_Collection> bkgCollection = std::make_unique<BCM_RDO_Collection>();
+    //Add a BCM_RawData object
+    std::unique_ptr<BCM_RawData> bkgDigit = std::make_unique<BCM_RawData>(bkgChannel,bkgPulse1Position,bkgPulse1Width,bkgPulse2Position,bkgPulse2Width,0,0,0,0);
+    bkgCollection->push_back(bkgDigit.release());
+    inputBkgDataHandle->push_back(bkgCollection.get());
+    bkgCollection.release(); // Now owned by inputBkgDataHandle
+
+    // ordering A, C, B is on purpose to test for unintended alphabetic ordering
+    std::string  inputSigPropertyValue = "'StoreGateSvc+BCM_RDOs_SIG10'";
+    std::string  inputBkgPropertyValue = "'StoreGateSvc+BCM_RDOs_BKG10'";
+    std::string    outputPropertyValue = "'StoreGateSvc+BCM_RDOs10'";
+    ASSERT_TRUE( m_alg->setProperty( "SignalInputKey",   inputSigPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->setProperty( "BkgInputKey",   inputBkgPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->initialize().isSuccess() );
+    ASSERT_TRUE( m_alg->execute(ctx).isSuccess() );
+    // check output makes sense
+    SG::ReadHandle<BCM_RDO_Container> outputDataHandle{"StoreGateSvc+BCM_RDOs10"};
+    ASSERT_TRUE( outputDataHandle.isValid() );
+    const BCM_RDO_Collection *outputCollection = outputDataHandle->at(sigChannel);
+    ASSERT_TRUE( outputCollection!=nullptr );
+    ASSERT_TRUE( outputCollection->size()==1 );
+    const BCM_RawData* outputDigit = outputCollection->at(0);
+    ASSERT_TRUE( outputDigit!=nullptr );
+    ASSERT_TRUE( outputDigit->getChannel()==sigChannel );
+    ASSERT_TRUE( outputDigit->getPulse1Position()==bkgPulse1Position ); // Merged pulse
+    ASSERT_TRUE( outputDigit->getPulse1Width()==15 );
+    ASSERT_TRUE( outputDigit->getPulse2Position()==0 ); // No second pulse
+    ASSERT_TRUE( outputDigit->getPulse2Width()==0 );
+  }
+
+  TEST_F(BCMOverlay_test, containers_with_one_bkg_two_signal_merging_pulses) {
+    EventContext ctx(0,0);
+    ctx.setExtension( Atlas::ExtendedEventContext( m_sg, 0 ) );
+    SG::WriteHandle<BCM_RDO_Container> inputSigDataHandle{"StoreGateSvc+BCM_RDOs_SIG11"};
+    const unsigned int sigChannel(0);
+    const unsigned int sigPulse1Position(5);
+    const unsigned int sigPulse1Width(3);
+    const unsigned int sigPulse2Position(17);
+    const unsigned int sigPulse2Width(3);
+    const unsigned int bkgChannel(0);
+    const unsigned int bkgPulse1Position(11);
+    const unsigned int bkgPulse1Width(3);
+    const unsigned int bkgPulse2Position(0);
+    const unsigned int bkgPulse2Width(0);
+    inputSigDataHandle = std::make_unique<BCM_RDO_Container>();
+    std::unique_ptr<BCM_RDO_Collection> sigCollection = std::make_unique<BCM_RDO_Collection>();
+    //Add a BCM_RawData object
+    std::unique_ptr<BCM_RawData> sigDigit = std::make_unique<BCM_RawData>(sigChannel,sigPulse1Position,sigPulse1Width,sigPulse2Position,sigPulse2Width,0,0,0,0);
+    sigCollection->push_back(sigDigit.release());
+    inputSigDataHandle->push_back(sigCollection.get());
+    sigCollection.release(); // Now owned by inputSigDataHandle
+    SG::WriteHandle<BCM_RDO_Container> inputBkgDataHandle{"StoreGateSvc+BCM_RDOs_BKG11"};
+    inputBkgDataHandle = std::make_unique<BCM_RDO_Container>();
+    std::unique_ptr<BCM_RDO_Collection> bkgCollection = std::make_unique<BCM_RDO_Collection>();
+    //Add a BCM_RawData object
+    std::unique_ptr<BCM_RawData> bkgDigit = std::make_unique<BCM_RawData>(bkgChannel,bkgPulse1Position,bkgPulse1Width,bkgPulse2Position,bkgPulse2Width,0,0,0,0);
+    bkgCollection->push_back(bkgDigit.release());
+    inputBkgDataHandle->push_back(bkgCollection.get());
+    bkgCollection.release(); // Now owned by inputBkgDataHandle
+
+    // ordering A, C, B is on purpose to test for unintended alphabetic ordering
+    std::string  inputSigPropertyValue = "'StoreGateSvc+BCM_RDOs_SIG11'";
+    std::string  inputBkgPropertyValue = "'StoreGateSvc+BCM_RDOs_BKG11'";
+    std::string    outputPropertyValue = "'StoreGateSvc+BCM_RDOs11'";
+    ASSERT_TRUE( m_alg->setProperty( "SignalInputKey",   inputSigPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->setProperty( "BkgInputKey",   inputBkgPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->initialize().isSuccess() );
+    ASSERT_TRUE( m_alg->execute(ctx).isSuccess() );
+    // check output makes sense
+    SG::ReadHandle<BCM_RDO_Container> outputDataHandle{"StoreGateSvc+BCM_RDOs11"};
+    ASSERT_TRUE( outputDataHandle.isValid() );
+    const BCM_RDO_Collection *outputCollection = outputDataHandle->at(sigChannel);
+    ASSERT_TRUE( outputCollection!=nullptr );
+    ASSERT_TRUE( outputCollection->size()==1 );
+    const BCM_RawData* outputDigit = outputCollection->at(0);
+    ASSERT_TRUE( outputDigit!=nullptr );
+    ASSERT_TRUE( outputDigit->getChannel()==sigChannel );
+    ASSERT_TRUE( outputDigit->getPulse1Position()==sigPulse1Position ); // Merged pulse
+    ASSERT_TRUE( outputDigit->getPulse1Width()==15 );
+    ASSERT_TRUE( outputDigit->getPulse2Position()==0 ); // No second pulse
+    ASSERT_TRUE( outputDigit->getPulse2Width()==0 );
+  }
+
+  TEST_F(BCMOverlay_test, containers_with_four_pulses_two_merging) {
+    EventContext ctx(0,0);
+    ctx.setExtension( Atlas::ExtendedEventContext( m_sg, 0 ) );
+    SG::WriteHandle<BCM_RDO_Container> inputSigDataHandle{"StoreGateSvc+BCM_RDOs_SIG12"};
+    const unsigned int sigChannel(0);
+    const unsigned int sigPulse1Position(5);
+    const unsigned int sigPulse1Width(3);
+    const unsigned int sigPulse2Position(50);
+    const unsigned int sigPulse2Width(9);
+    const unsigned int bkgChannel(0);
+    const unsigned int bkgPulse1Position(11);
+    const unsigned int bkgPulse1Width(3);
+    const unsigned int bkgPulse2Position(30);
+    const unsigned int bkgPulse2Width(9);
+    inputSigDataHandle = std::make_unique<BCM_RDO_Container>();
+    std::unique_ptr<BCM_RDO_Collection> sigCollection = std::make_unique<BCM_RDO_Collection>();
+    //Add a BCM_RawData object
+    std::unique_ptr<BCM_RawData> sigDigit = std::make_unique<BCM_RawData>(sigChannel,sigPulse1Position,sigPulse1Width,sigPulse2Position,sigPulse2Width,0,0,0,0);
+    sigCollection->push_back(sigDigit.release());
+    inputSigDataHandle->push_back(sigCollection.get());
+    sigCollection.release(); // Now owned by inputSigDataHandle
+    SG::WriteHandle<BCM_RDO_Container> inputBkgDataHandle{"StoreGateSvc+BCM_RDOs_BKG12"};
+    inputBkgDataHandle = std::make_unique<BCM_RDO_Container>();
+    std::unique_ptr<BCM_RDO_Collection> bkgCollection = std::make_unique<BCM_RDO_Collection>();
+    //Add a BCM_RawData object
+    std::unique_ptr<BCM_RawData> bkgDigit = std::make_unique<BCM_RawData>(bkgChannel,bkgPulse1Position,bkgPulse1Width,bkgPulse2Position,bkgPulse2Width,0,0,0,0);
+    bkgCollection->push_back(bkgDigit.release());
+    inputBkgDataHandle->push_back(bkgCollection.get());
+    bkgCollection.release(); // Now owned by inputBkgDataHandle
+
+    // ordering A, C, B is on purpose to test for unintended alphabetic ordering
+    std::string  inputSigPropertyValue = "'StoreGateSvc+BCM_RDOs_SIG12'";
+    std::string  inputBkgPropertyValue = "'StoreGateSvc+BCM_RDOs_BKG12'";
+    std::string    outputPropertyValue = "'StoreGateSvc+BCM_RDOs12'";
+    ASSERT_TRUE( m_alg->setProperty( "SignalInputKey",   inputSigPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->setProperty( "BkgInputKey",   inputBkgPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->setProperty( "OutputKey", outputPropertyValue).isSuccess() );
+    ASSERT_TRUE( m_alg->initialize().isSuccess() );
+    ASSERT_TRUE( m_alg->execute(ctx).isSuccess() );
+    // check output makes sense
+    SG::ReadHandle<BCM_RDO_Container> outputDataHandle{"StoreGateSvc+BCM_RDOs12"};
+    ASSERT_TRUE( outputDataHandle.isValid() );
+    const BCM_RDO_Collection *outputCollection = outputDataHandle->at(sigChannel);
+    ASSERT_TRUE( outputCollection!=nullptr );
+    ASSERT_TRUE( outputCollection->size()==1 );
+    const BCM_RawData* outputDigit = outputCollection->at(0);
+    ASSERT_TRUE( outputDigit!=nullptr );
+    ASSERT_TRUE( outputDigit->getChannel()==sigChannel );
+    ASSERT_TRUE( outputDigit->getPulse1Position()==sigPulse1Position ); // Merged pulse
+    ASSERT_TRUE( outputDigit->getPulse1Width()==9 );
+    ASSERT_TRUE( outputDigit->getPulse2Position()==bkgPulse2Position ); // Second pulse is second background pulse
+    ASSERT_TRUE( outputDigit->getPulse2Width()==bkgPulse2Width );
+  }
+
+} // <-- namespace OverlayTesting
+
+
+int main(int argc, char *argv[])
+{
+  ::testing::InitGoogleTest( &argc, argv );
+  ::testing::AddGlobalTestEnvironment( new OverlayTesting::GaudiEnvironment );
+  return RUN_ALL_TESTS();
+}
diff --git a/Tools/PROCTools/python/RunTier0TestsTools.py b/Tools/PROCTools/python/RunTier0TestsTools.py
index 1344cc6849e35b591c0ca6bba8d0b20afcab4962..02fcca2f770ba40847c30e72fa1f7349f291891c 100644
--- a/Tools/PROCTools/python/RunTier0TestsTools.py
+++ b/Tools/PROCTools/python/RunTier0TestsTools.py
@@ -28,7 +28,7 @@ ciRefFileMap = {
                 's3505-22.0'           : 'v3',
                 # OverlayTier0Test_required-test
                 'overlay-d1498-21.0'   : 'v2',
-                'overlay-d1498-22.0'   : 'v30',
+                'overlay-d1498-22.0'   : 'v31',
                 'overlay-bkg-21.0'     : 'v1',
                 'overlay-bkg-22.0'     : 'v4',
                }