diff --git a/DDDigi/include/DDDigi/DigiContainerProcessor.h b/DDDigi/include/DDDigi/DigiContainerProcessor.h
index 0dcfee5e137bc89b421df12f094b02bb3ef15bfe..9be4485e7f907546178cffaeecbd3039479f87bb 100644
--- a/DDDigi/include/DDDigi/DigiContainerProcessor.h
+++ b/DDDigi/include/DDDigi/DigiContainerProcessor.h
@@ -66,18 +66,21 @@ namespace dd4hep {
 
       /// Hit processing predicate
       struct predicate_t  {
-	Callback callback                   { };
-	uint32_t id                         { 0 };
+	using deposit_t = std::pair<const CellID, EnergyDeposit>;
+	using callback_t = std::function<bool(const deposit_t&)>;
+	callback_t            callback      { };
+	uint32_t              id            { 0 };
 	const segmentation_t* segmentation  { nullptr };
 	predicate_t() = default;
+	predicate_t(std::function<bool(const deposit_t&)> func, uint32_t i, const segmentation_t* s)
+	: callback(func), id(i), segmentation(s) {}
 	predicate_t(predicate_t&& copy) = default;
 	predicate_t(const predicate_t& copy) = default;
-	predicate_t(const Callback& c, uint32_t i, const segmentation_t* s)
-	  : callback(c), id(i), segmentation(s) {}
 	predicate_t& operator = (predicate_t&& copy) = default;
 	predicate_t& operator = (const predicate_t& copy) = default;
 	/// Check if a deposit should be processed
-	bool operator()(const std::pair<const CellID, EnergyDeposit>& deposit)   const;
+	bool operator()(const deposit_t& deposit)   const;
+	static bool always_true(const deposit_t&)   { return true; }
       };
 
       /// Work definition
@@ -122,11 +125,36 @@ namespace dd4hep {
     };
 
     /// Check if a deposit should be processed
-    inline bool DigiContainerProcessor::predicate_t::operator()(const std::pair<const CellID, EnergyDeposit>& deposit)   const   {
-      const void* args[] = { &deposit };
-      return this->callback.execute(args);
+    inline bool DigiContainerProcessor::predicate_t::operator()(const deposit_t& deposit)   const   {
+      return this->callback(deposit);
     }
 
+    /// Worker class act on ONLY act on energy deposit containers in an event
+    /**
+     *  Worker class act on ONLY act on energy deposit containers in an event.
+     *  The deposit containers are identified by input masks and container name.
+     *
+     *  \author  M.Frank
+     *  \version 1.0
+     *  \ingroup DD4HEP_DIGITIZATION
+     */
+    class DigiDepositsProcessor : public DigiContainerProcessor  {
+    protected:
+      std::function<void(context_t& context, DepositVector& cont,  work_t& work, const predicate_t& predicate)>	m_handleVector;
+      std::function<void(context_t& context, DepositMapping& cont, work_t& work, const predicate_t& predicate)>	m_handleMapping;
+
+    public:
+      /// Standard constructor
+      using DigiContainerProcessor::DigiContainerProcessor;
+
+      /// Main functional callback adapter
+      virtual void execute(context_t& context, work_t& work, const predicate_t& predicate)  const;
+    };
+
+#define DEPOSIT_PROCESSOR_BIND_HANDLERS(X)   {     using namespace std::placeholders; \
+	this->m_handleVector  = std::bind( &X<DepositVector>,  this, _1, _2, _3, _4); \
+	this->m_handleMapping = std::bind( &X<DepositMapping>, this, _1, _2, _3, _4); }
+
     /// Worker class act on containers in an event identified by input masks and container name
     /**
      *  The sequencer calls all registered processors for the contaiers registered.
diff --git a/DDDigi/include/DDDigi/DigiData.h b/DDDigi/include/DDDigi/DigiData.h
index 2ae18985ade8eb8a6960f978a22d24c12d318b58..4937b1753ed351c9c395eba6e084a93b19280a04 100644
--- a/DDDigi/include/DDDigi/DigiData.h
+++ b/DDDigi/include/DDDigi/DigiData.h
@@ -471,7 +471,8 @@ namespace dd4hep {
 	ENERGY_SMEARED     = 1 << 1,
 	POSITION_SMEARED   = 1 << 2,
 	TIME_SMEARED       = 1 << 3,
-        RECALIBRATED       = 1 << 4
+	ZERO_SUPPRESSED    = 1 << 4,
+        RECALIBRATED       = 1 << 5
       };
 
       /// Hit position
diff --git a/DDDigi/include/DDDigi/DigiKernel.h b/DDDigi/include/DDDigi/DigiKernel.h
index 041cf245490e80b4b1a3aa9ebe4003bc0a1064c5..85b374db36d6c713603aab255ec56796319ff96c 100644
--- a/DDDigi/include/DDDigi/DigiKernel.h
+++ b/DDDigi/include/DDDigi/DigiKernel.h
@@ -14,7 +14,6 @@
 #define DDDIGI_DIGIKERNEL_H
 
 // Framework include files
-#include <DD4hep/Callback.h>
 #include <DDDigi/DigiEventAction.h>
 #include <DDDigi/DigiParallelWorker.h>
 
@@ -132,15 +131,15 @@ namespace dd4hep {
       std::size_t events_processing()  const;
 
       /// Register configure callback. Signature:   (function)()
-      void register_configure(const Callback& callback)   const;
+      void register_configure(const std::function<void()>& callback)   const;
       /// Register initialize callback. Signature:  (function)()
-      void register_initialize(const Callback& callback)   const;
+      void register_initialize(const std::function<void()>& callback)   const;
       /// Register terminate callback. Signature:   (function)()
-      void register_terminate(const Callback& callback)   const;
+      void register_terminate(const std::function<void()>& callback)   const;
       /// Register start event callback. Signature: (function)(DigiContext*)
-      void register_start_event(const Callback& callback)   const;
+      void register_start_event(const std::function<void(DigiContext&)>& callback)   const;
       /// Register end event callback. Signature:   (function)(DigiContext*)
-      void register_end_event(const Callback& callback)   const;
+      void register_end_event(const std::function<void(DigiContext&)>& callback)   const;
 
       /// Construct detector geometry using description plugin
       virtual void loadGeometry(const std::string& compact_file);
diff --git a/DDDigi/include/DDDigi/DigiSegmentSplitter.h b/DDDigi/include/DDDigi/DigiSegmentSplitter.h
index 85a046b55b99a79d8956ac044e95d05a4e238ab7..0c59ba13e5fa8ba95eef4d8129e0c868fa7e8fb8 100644
--- a/DDDigi/include/DDDigi/DigiSegmentSplitter.h
+++ b/DDDigi/include/DDDigi/DigiSegmentSplitter.h
@@ -69,8 +69,8 @@ namespace dd4hep {
       }
 
       /// Check if a deposit should be processed
-      bool use_depo(const std::pair<const CellID, EnergyDeposit>* deposit)   const   {
-	return this->matches(deposit->first);
+      bool use_depo(const std::pair<const CellID, EnergyDeposit>& deposit)   const   {
+	return this->matches(deposit.first);
       }
       void enable(uint32_t split_id);
     };
@@ -84,12 +84,11 @@ namespace dd4hep {
      */
     struct accept_segment_t : public DigiContainerProcessor::predicate_t  {
       accept_segment_t(const DigiSegmentContext* s, uint32_t i)
-	: predicate_t( {}, i, s)      {
-	callback = Callback(this).make(&accept_segment_t::use_depo);
+	: predicate_t(std::bind(&accept_segment_t::use_depo, this, std::placeholders::_1), i, s) {
       }
       /// Check if a deposit should be processed
-      bool use_depo(const std::pair<const CellID, EnergyDeposit>* deposit)   const   {
-	return this->segmentation->split_id(deposit->first) == this->id;
+      bool use_depo(const deposit_t& deposit)   const   {
+	return this->segmentation->split_id(deposit.first) == this->id;
       }
     };
 
@@ -108,8 +107,7 @@ namespace dd4hep {
       /**  Local use definitions                      */
       using self_t      = DigiSegmentSplitter;
       using tool_t      = DigiSegmentationTool;
-      using split_t     = std::pair<DetElement, VolumeID>;
-      using splits_t    = std::map<VolumeID, split_t>;
+      using splits_t    = std::set<uint32_t>;
       using segment_t   = DigiSegmentProcessContext;
       using processor_t = DigiContainerProcessor;
 
diff --git a/DDDigi/include/DDDigi/DigiSegmentationTool.h b/DDDigi/include/DDDigi/DigiSegmentationTool.h
index 713a4afa9568ccdbb6ecaa04d7fd4ff576105e03..9d6a802f71fb5b7d2c8591de8499c2847ba1a607 100644
--- a/DDDigi/include/DDDigi/DigiSegmentationTool.h
+++ b/DDDigi/include/DDDigi/DigiSegmentationTool.h
@@ -123,8 +123,7 @@ namespace dd4hep {
       DigiSegmentContext split_context(const std::string& split_by)  const;
 
       /// Create full set of detector segments which can be split according to the context
-      std::map<VolumeID, std::pair<DetElement, VolumeID> > 
-	split_segmentation(const std::string& split_by)  const;
+      std::set<uint32_t> split_segmentation(const std::string& split_by)  const;
     };
   }    // End namespace digi
 }      // End namespace dd4hep
diff --git a/DDDigi/plugins/DigiDepositSmearTime.cpp b/DDDigi/plugins/DigiDepositSmearTime.cpp
index 7925d1f82dfb8f31de661b9e77e0137dd370e730..e3e208de30a412dcfa3ee0c56efac508fbc8af14 100644
--- a/DDDigi/plugins/DigiDepositSmearTime.cpp
+++ b/DDDigi/plugins/DigiDepositSmearTime.cpp
@@ -13,7 +13,6 @@
 
 // Framework include files
 #include <DDDigi/DigiContainerProcessor.h>
-#include <DD4hep/InstanceCount.h>
 #include <DD4hep/DD4hepUnits.h>
 
 /// C/C++ include files
@@ -33,80 +32,45 @@ namespace dd4hep {
      *  \version 1.0
      *  \ingroup DD4HEP_DIGITIZATION
      */
-    class DigiDepositSmearTime : public DigiContainerProcessor   {
+    class DigiDepositSmearTime : public DigiDepositsProcessor  {
     protected:
       using limit_t = std::numeric_limits<double>;
       /// Property: Intrinsic energy resolution constant (gaussian ~ std::sqrt(energy))
       double m_resolution_time                { 0e0 };
       /// Property: Time window within the smeared deposits shall be accepted
       std::pair<double, double> m_window_time { limit_t::min(), limit_t::max() };
-      /// Property: Flag to update existing container in-place or create a new container
-      bool   m_update_in_place                { true };
 
     public:
-      /// Standard constructor
-      DigiDepositSmearTime(const DigiKernel& krnl, const std::string& nam)
-	: DigiContainerProcessor(krnl, nam)
-      {
-	declareProperty("resolution_time", m_resolution_time);
-	declareProperty("window_time",     m_window_time);
-	InstanceCount::increment(this);
-      }
-
-      /// Default destructor
-      virtual ~DigiDepositSmearTime() {
-	InstanceCount::decrement(this);
-      }
-
       /// Create deposit mapping with updates on same cellIDs
       template <typename T> void
-      smear(DigiContext& context, T& cont, work_t& work, const predicate_t& predicate)  const  {
+      smear(DigiContext& context, T& cont, work_t& /* work */, const predicate_t& predicate)  const  {
 	auto& random = context.randomGenerator();
-	T output_cont(cont.name, work.output.mask);
 	std::size_t killed  = 0UL;
 	std::size_t updated = 0UL;
-	std::size_t created = 0UL;
-
-	info("%s+++ TIME smearing deposit container: %s %6ld entries",
-	     context.event->id(), cont.name.c_str(), cont.size());
-	for( auto& dep : cont )    {
-	  if ( predicate(dep) )   {
+	for( auto& dep : cont )  {
+	  if ( predicate(dep) )  {
 	    int flag = EnergyDeposit::TIME_SMEARED;
 	    double delta_T = m_resolution_time * random.gaussian();
 	    if ( delta_T < m_window_time.first || delta_T > m_window_time.second )   {
 	      flag |= EnergyDeposit::KILLED;
 	      ++killed;
 	    }
-	    if ( m_update_in_place )   {
-	      EnergyDeposit& d = dep.second;
-	      d.time += delta_T;
-	      d.flag |= flag;
-	      ++updated;
-	    }
-	    else if ( !(flag&EnergyDeposit::KILLED) )  {
-	      EnergyDeposit d(dep.second);
-	      d.time += delta_T;
-	      d.flag |= flag;
-	      output_cont.emplace(dep.first, std::move(d));
-	      ++created;
-	    }
+	    dep.second.time += delta_T;
+	    dep.second.flag |= flag;
+	    ++updated;
 	  }
 	}
-	if ( !m_update_in_place )   {
-	  work.output.data.put(output_cont.key, std::move(output_cont));
-	}
-	info("%s+++ %-32s Smearing: created %6ld updated %6ld killed %6ld entries from mask: %04X",
-	     context.event->id(), cont.name.c_str(), created, updated, killed, cont.key.mask());
+	info("%s+++ %-32s Smeared time resolution: %6ld entries, updated %6ld killed %6ld entries from mask: %04X",
+	     context.event->id(), cont.name.c_str(), cont.size(), updated, killed, cont.key.mask());
       }
 
-      /// Main functional callback
-      virtual void execute(DigiContext& context, work_t& work, const predicate_t& predicate)  const override final  {
-	if ( auto* v = work.get_input<DepositVector>() )
-	  smear(context, *v, work, predicate);
-	else if ( auto* m = work.get_input<DepositMapping>() )
-	  smear(context, *m, work, predicate);
-	else
-	  except("Request to handle unknown data type: %s", work.input_type_name().c_str());
+      /// Standard constructor
+      DigiDepositSmearTime(const DigiKernel& krnl, const std::string& nam)
+	: DigiDepositsProcessor(krnl, nam)
+      {
+	declareProperty("resolution_time", m_resolution_time);
+	declareProperty("window_time",     m_window_time);
+	DEPOSIT_PROCESSOR_BIND_HANDLERS(DigiDepositSmearTime::smear)
       }
     };
   }    // End namespace digi
diff --git a/DDDigi/plugins/DigiDepositWeightedPosition.cpp b/DDDigi/plugins/DigiDepositWeightedPosition.cpp
index 4bde23c5af4449c5ca588e6398b4f18018db8bba..36e1f1ed04da3fd7110532b8cf93dac6f6843ff0 100644
--- a/DDDigi/plugins/DigiDepositWeightedPosition.cpp
+++ b/DDDigi/plugins/DigiDepositWeightedPosition.cpp
@@ -20,6 +20,7 @@
 
 /// Namespace for the AIDA detector description toolkit
 namespace dd4hep {
+
   /// Namespace for the Digitization part of the AIDA detector description toolkit
   namespace digi {
 
@@ -34,28 +35,15 @@ namespace dd4hep {
      *  \version 1.0
      *  \ingroup DD4HEP_DIGITIZATION
      */
-    class DigiDepositWeightedPosition : public DigiContainerProcessor   {
+    class DigiDepositWeightedPosition : public DigiDepositsProcessor   {
     protected:
       /// Property: Energy cutoff. No hits will be merged with a deposit smaller
       double m_cutoff { -std::numeric_limits<double>::epsilon() };
 
     public:
-      /// Standard constructor
-      DigiDepositWeightedPosition(const DigiKernel& krnl, const std::string& nam)
-	: DigiContainerProcessor(krnl, nam)
-      {
-	declareProperty("deposit_cutoff", m_cutoff);
-	InstanceCount::increment(this);
-      }
-
-      /// Default destructor
-      virtual ~DigiDepositWeightedPosition() {
-	InstanceCount::decrement(this);
-      }
-
       /// Create deposit mapping with updates on same cellIDs
       template <typename T> void
-      create_deposits(const char* tag, const T& cont, work_t& work, const predicate_t& predicate)  const  {
+      create_deposits(context_t& context, const T& cont, work_t& work, const predicate_t& predicate)  const  {
 	Key key(cont.name, work.output.mask);
 	DepositMapping m(cont.name, work.output.mask);
 	std::size_t dropped = 0UL, updated = 0UL, added = 0UL;
@@ -75,19 +63,22 @@ namespace dd4hep {
 	  }
 	}
 	info("%s+++ %-32s added %6ld updated %6ld dropped %6ld entries (now: %6ld) from mask: %04X to mask: %04X",
-	     tag, cont.name.c_str(), added, updated, dropped, m.size(), cont.key.mask(), m.key.mask());
+	     context.event->id(), cont.name.c_str(), added, updated, dropped, m.size(), cont.key.mask(), m.key.mask());
 	work.output.data.put(m.key, std::move(m));
       }
 
-      /// Main functional callback
-      virtual void execute(DigiContext& context, work_t& work, const predicate_t& predicate)  const override final  {
-	if ( const auto* v = work.get_input<DepositVector>() )
-	  create_deposits(context.event->id(), *v, work, predicate);
-	else if ( const auto* m = work.get_input<DepositMapping>() )
-	  create_deposits(context.event->id(), *m, work, predicate);
-	else
-	  except("%s+++ Request to handle unknown data type: %s", 
-		 context.event->id(), work.input_type_name().c_str());
+      /// Standard constructor
+      DigiDepositWeightedPosition(const DigiKernel& krnl, const std::string& nam)
+	: DigiDepositsProcessor(krnl, nam)
+      {
+	InstanceCount::increment(this);
+	declareProperty("deposit_cutoff", m_cutoff);
+	DEPOSIT_PROCESSOR_BIND_HANDLERS(DigiDepositWeightedPosition::create_deposits)
+      }
+
+      /// Default destructor
+      virtual ~DigiDepositWeightedPosition() {
+	InstanceCount::decrement(this);
       }
     };
   }    // End namespace digi
diff --git a/DDDigi/plugins/DigiDepositZeroSuppress.cpp b/DDDigi/plugins/DigiDepositZeroSuppress.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4f245f43a60017a12fa277e007e7f35caa98c13d
--- /dev/null
+++ b/DDDigi/plugins/DigiDepositZeroSuppress.cpp
@@ -0,0 +1,72 @@
+//==========================================================================
+//  AIDA Detector description implementation 
+//--------------------------------------------------------------------------
+// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+// All rights reserved.
+//
+// For the licensing terms see $DD4hepINSTALL/LICENSE.
+// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
+//
+// Author     : M.Frank
+//
+//==========================================================================
+
+// Framework include files
+#include <DDDigi/DigiContainerProcessor.h>
+#include <DD4hep/DD4hepUnits.h>
+
+/// C/C++ include files
+#include <limits>
+
+/// Namespace for the AIDA detector description toolkit
+namespace dd4hep {
+
+  /// Namespace for the Digitization part of the AIDA detector description toolkit
+  namespace digi {
+
+    /// Actor to zero-suppress a container of energy deposits
+    /**
+     *
+     *
+     *  \author  M.Frank
+     *  \version 1.0
+     *  \ingroup DD4HEP_DIGITIZATION
+     */
+    class DigiDepositZeroSuppress : public DigiDepositsProcessor   {
+    protected:
+      /// Property: Intrinsic energy resolution constant (gaussian ~ std::sqrt(energy))
+      double m_energy_threshold                { 0e0 };
+
+    public:
+      /// Create deposit mapping with updates on same cellIDs
+      template <typename T> void
+      handle_deposits(DigiContext& context, T& cont, work_t& /* work */, const predicate_t& predicate)  const  {
+	std::size_t killed  = 0UL;
+	std::size_t handled = 0UL;
+	for( auto& dep : cont )    {
+	  if ( predicate(dep) )   {
+	    int flag = EnergyDeposit::ZERO_SUPPRESSED;
+	    if ( dep.second.deposit * dd4hep::GeV < m_energy_threshold )   {
+	      flag |= EnergyDeposit::KILLED;
+	      ++killed;
+	    }
+	    dep.second.flag |= flag;
+	    ++handled;
+	  }
+	}
+	info("%s+++ %-32s Zero suppression: entries: %6ld handled: %6ld killed %6ld entries from mask: %04X",
+	     context.event->id(), cont.name.c_str(), cont.size(), handled, killed, cont.key.mask());
+      }
+      /// Standard constructor
+      DigiDepositZeroSuppress(const DigiKernel& krnl, const std::string& nam)
+	: DigiDepositsProcessor(krnl, nam)
+      {
+	declareProperty("threshold", m_energy_threshold);
+	DEPOSIT_PROCESSOR_BIND_HANDLERS(DigiDepositZeroSuppress::handle_deposits)
+      }
+    };
+  }    // End namespace digi
+}      // End namespace dd4hep
+
+#include <DDDigi/DigiFactories.h>
+DECLARE_DIGIACTION_NS(dd4hep::digi,DigiDepositZeroSuppress)
diff --git a/DDDigi/plugins/DigiResegment.cpp b/DDDigi/plugins/DigiResegment.cpp
index c34298d75cb7a77755aef287710a4db3eb4c53f2..70faf83aa7711dee7cc1362cdfe4f76d9ddfef17 100644
--- a/DDDigi/plugins/DigiResegment.cpp
+++ b/DDDigi/plugins/DigiResegment.cpp
@@ -63,7 +63,7 @@ namespace dd4hep {
 	declareProperty("detector",   m_detector_name);
 	declareProperty("readout",    m_readout_name);
 	declareProperty("descriptor", m_readout_descriptor);
-	m_kernel.register_initialize(Callback(this).make(&DigiResegment::initialize));
+	m_kernel.register_initialize(std::bind(&DigiResegment::initialize, this));
       }
 
       void initialize()   {
diff --git a/DDDigi/python/dddigi.py b/DDDigi/python/dddigi.py
index eb9028727dbd1731f14f3614a833effd9b8e428c..2f53ab5ad35577face9a1db7846a38fd429cbc8c 100644
--- a/DDDigi/python/dddigi.py
+++ b/DDDigi/python/dddigi.py
@@ -314,7 +314,7 @@ def _props(obj, **extensions):
       # print('Overloading: ' + str(cls) + ' ' + call + ' to __' + call)
       setattr(cls, '__' + call, getattr(cls, call))
     else:
-      print('FAILED: Overloading: ' + str(cls) + ' '+call + ' to __' + call + ' ' + str(hasattr(cls, call)))
+      print('FAILED: Overloading: ' + str(cls) + ' ' + call + ' to __' + call + ' ' + str(hasattr(cls, call)))
     setattr(cls, call, extension[1])
   cls.__getattr__ = _get
   cls.__setattr__ = _set
diff --git a/DDDigi/src/DigiContainerCombine.cpp b/DDDigi/src/DigiContainerCombine.cpp
index e6dc17af81469f4f5bf573b701db90d3dcce5649..22939f5a5cdef5e8d43a75aae9fa1a382c0c2127 100644
--- a/DDDigi/src/DigiContainerCombine.cpp
+++ b/DDDigi/src/DigiContainerCombine.cpp
@@ -231,7 +231,7 @@ DigiContainerCombine::DigiContainerCombine(const DigiKernel& krnl, const std::st
   declareProperty("output_mask",      m_deposit_mask);
   declareProperty("output_name_flag", m_output_name_flag);
   declareProperty("erase_combined",   m_erase_combined);
-  m_kernel.register_initialize(Callback(this).make(&DigiContainerCombine::initialize));
+  m_kernel.register_initialize(std::bind(&DigiContainerCombine::initialize,this));
   InstanceCount::increment(this);
 }
 
diff --git a/DDDigi/src/DigiContainerDrop.cpp b/DDDigi/src/DigiContainerDrop.cpp
index 550288c007ba318acacfec17ff7eab7505cd9751..efdcd5f3a6d56a72dde8e1378ff1daf8410ddd75 100644
--- a/DDDigi/src/DigiContainerDrop.cpp
+++ b/DDDigi/src/DigiContainerDrop.cpp
@@ -99,7 +99,7 @@ DigiContainerDrop::DigiContainerDrop(const DigiKernel& krnl, const std::string&
   declareProperty("containers",       m_containers);
   declareProperty("input_masks",      m_input_masks);
   declareProperty("input_segment",    m_input_segment = "inputs");
-  m_kernel.register_initialize(Callback(this).make(&DigiContainerDrop::initialize));
+  m_kernel.register_initialize(std::bind(&DigiContainerDrop::initialize,this));
   InstanceCount::increment(this);
 }
 
diff --git a/DDDigi/src/DigiContainerProcessor.cpp b/DDDigi/src/DigiContainerProcessor.cpp
index c93dba1926c6c88eb0b683bddc08ba73f4842fff..0fe42335f6bbb21e6aba1a75a943e55f5c94deca 100644
--- a/DDDigi/src/DigiContainerProcessor.cpp
+++ b/DDDigi/src/DigiContainerProcessor.cpp
@@ -81,12 +81,7 @@ std::string DigiContainerProcessor::work_t::input_type_name()  const   {
 
 /// Access to default callback 
 const DigiContainerProcessor::predicate_t& DigiContainerProcessor::accept_all()  {
-  struct true_t  {
-    bool use(const std::pair<const CellID, EnergyDeposit>&)  const {
-      return true;
-    }
-  } s_true;
-  static predicate_t s_pred { Callback(&s_true).make(&true_t::use), 0, nullptr };
+  static predicate_t s_pred { std::bind(predicate_t::always_true, std::placeholders::_1), 0, nullptr };
   return s_pred;
 }
 
@@ -108,6 +103,16 @@ void DigiContainerProcessor::execute(context_t&       /* context   */,
 				     const predicate_t& /* predicate */)  const   {
 }
 
+/// Main functional callback adapter
+void DigiDepositsProcessor::execute(context_t& context, work_t& work, const predicate_t& predicate)  const   {
+  if ( auto* v = work.get_input<DepositVector>() )
+    m_handleVector(context,  *v, work, predicate);
+  else if ( auto* m = work.get_input<DepositMapping>() )
+    m_handleMapping(context, *m, work, predicate);
+  else
+    except("Request to handle unknown data type: %s", work.input_type_name().c_str());
+}
+
 /// Standard constructor
 DigiContainerSequence::DigiContainerSequence(const kernel_t& krnl, const std::string& nam)
   : DigiContainerProcessor(krnl, nam)
@@ -152,7 +157,7 @@ DigiContainerSequenceAction::DigiContainerSequenceAction(const kernel_t& krnl, c
   declareProperty("input_segment",  m_input_segment);
   declareProperty("output_mask",    m_output_mask);
   declareProperty("output_segment", m_output_segment);
-  m_kernel.register_initialize(Callback(this).make(&DigiContainerSequenceAction::initialize));
+  m_kernel.register_initialize(std::bind(&DigiContainerSequenceAction::initialize,this));
   InstanceCount::increment(this);
 }
 
@@ -261,7 +266,7 @@ DigiMultiContainerProcessor::DigiMultiContainerProcessor(const kernel_t& krnl, c
   declareProperty("input_segment",  m_input_segment);
   declareProperty("output_mask",    m_output_mask);
   declareProperty("output_segment", m_output_segment);
-  m_kernel.register_initialize(Callback(this).make(&DigiMultiContainerProcessor::initialize));
+  m_kernel.register_initialize(std::bind(&DigiMultiContainerProcessor::initialize,this));
   InstanceCount::increment(this);
 }
 
diff --git a/DDDigi/src/DigiKernel.cpp b/DDDigi/src/DigiKernel.cpp
index 920dbd630f5015d2527ed85b41c1aa9b04b7cfe8..cbf1a625624b580b97628b741334629c986f7bad 100644
--- a/DDDigi/src/DigiKernel.cpp
+++ b/DDDigi/src/DigiKernel.cpp
@@ -76,16 +76,18 @@ public:
   /// Lock for global output logging
   std::mutex            global_output_lock  { };
 
+  using callbacks_t = std::vector<std::function<void()> >;
+  using ev_callbacks_t = std::vector<std::function<void(DigiContext&)> >;
   /// Configure callbacks
-  CallbackSequence      configurators       { };
+  callbacks_t           configurators       { };
   /// Initialize callbacks
-  CallbackSequence      initializers        { };
+  callbacks_t           initializers        { };
   //// Termination callback
-  CallbackSequence      terminators         { };
+  callbacks_t           terminators         { };
       /// Register start event callback
-  CallbackSequence      start_event         { };
+  ev_callbacks_t        start_event         { };
   /// Register end event callback
-  CallbackSequence      end_event           { };
+  ev_callbacks_t        end_event           { };
 
   /// The main data input action sequence
   DigiActionSequence*   input_action         { nullptr };
@@ -311,42 +313,42 @@ void DigiKernel::loadXML(const char* fname) {
 
 /// Configure the digitization: call all registered configurators
 int DigiKernel::configure()   {
-  internals->configurators();
+  for(auto& call : internals->configurators) call();
   return 1;
 }
 
 /// Initialize the digitization: call all registered initializers
 int DigiKernel::initialize()   {
-  internals->initializers();
+  for(auto& call : internals->initializers) call();
   return 1;
 }
 
 /// Register configure callback
-void DigiKernel::register_configure(const Callback& callback)   const  {
+void DigiKernel::register_configure(const std::function<void()>& callback)   const  {
   std::lock_guard<std::mutex> lock(initializer_lock());
-  internals->configurators.add(callback);
+  internals->configurators.push_back(callback);
 }
 
 /// Register initialize callback
-void DigiKernel::register_initialize(const Callback& callback)   const  {
+void DigiKernel::register_initialize(const std::function<void()>& callback)   const  {
   std::lock_guard<std::mutex> lock(initializer_lock());
-  internals->initializers.add(callback);
+  internals->initializers.push_back(callback);
 }
 
 /// Register terminate callback
-void DigiKernel::register_terminate(const Callback& callback)   const  {
+void DigiKernel::register_terminate(const std::function<void()>& callback)   const  {
   std::lock_guard<std::mutex> lock(initializer_lock());
-  internals->terminators.add(callback);
+  internals->terminators.push_back(callback);
 }
 
 /// Register start event callback
-void DigiKernel::register_start_event(const Callback& callback)   const  {
-  internals->start_event.add(callback);
+void DigiKernel::register_start_event(const std::function<void(DigiContext&)>& callback)   const  {
+  internals->start_event.push_back(callback);
 }
 
 /// Register end event callback
-void DigiKernel::register_end_event(const Callback& callback)   const  {
-  internals->end_event.add(callback);
+void DigiKernel::register_end_event(const std::function<void(DigiContext&)>& callback)   const  {
+  internals->end_event.push_back(callback);
 }
 
 /// Access to the main input action sequence from the kernel object
@@ -396,11 +398,11 @@ void DigiKernel::wait(DigiContext& context)   const  {
 void DigiKernel::executeEvent(std::unique_ptr<DigiContext>&& context)    {
   DigiContext& refContext = *context;
   try {
-    internals->start_event(&refContext);
+    for(auto& call : internals->start_event) call(refContext);
     inputAction().execute(refContext);
     eventAction().execute(refContext);
     outputAction().execute(refContext);
-    internals->end_event(&refContext);
+    for(auto& call : internals->end_event) call(refContext);
     notify(std::move(context));
   }
   catch(const std::exception& e)   {
@@ -474,7 +476,7 @@ int DigiKernel::run()   {
 /// Terminate the digitization: call all registered terminators and release the allocated resources
 int DigiKernel::terminate() {
   printout(INFO, "DigiKernel", "++ Terminate Digi and delete associated actions.");
-  internals->terminators();
+  for(auto& call : internals->terminators) call();
   m_detDesc->destroyInstance();
   m_detDesc = 0;
   return 1;
diff --git a/DDDigi/src/DigiSegmentSplitter.cpp b/DDDigi/src/DigiSegmentSplitter.cpp
index 1f016a5aae7b83289b39c0beec2f80094913b698..0b25a61e3fc4b533c6638c0bbe3717e92c14b918 100644
--- a/DDDigi/src/DigiSegmentSplitter.cpp
+++ b/DDDigi/src/DigiSegmentSplitter.cpp
@@ -42,7 +42,7 @@ DigiSegmentProcessContext::operator=(const DigiSegmentContext& copy)   {
 void DigiSegmentProcessContext::enable(uint32_t split_id)  {
   this->predicate.id = split_id;
   this->predicate.segmentation = this;
-  this->predicate.callback = Callback(this).make(&DigiSegmentProcessContext::use_depo);
+  this->predicate.callback = std::bind(&DigiSegmentProcessContext::use_depo, this, std::placeholders::_1);
 }
 
 /// Worker adaptor for caller DigiContainerSequence
@@ -63,7 +63,7 @@ DigiSegmentSplitter::DigiSegmentSplitter(const kernel_t& kernel, const std::stri
   declareProperty("split_by",        m_split_by);
   declareProperty("processor_type",  m_processor_type);
   declareProperty("share_processor", m_share_processor = false);
-  m_kernel.register_initialize(Callback(this).make(&DigiSegmentSplitter::initialize));
+  m_kernel.register_initialize(std::bind(&DigiSegmentSplitter::initialize,this));
   InstanceCount::increment(this);
 }
 
@@ -100,9 +100,8 @@ void DigiSegmentSplitter::initialize()   {
     auto group = m_workers.get_group();
     const auto& workers = group.actors();
     /// Create the processors:
-    for( auto& p : m_splits )   {
+    for( auto split_id : m_splits )   {
       bool ok = false;
-      auto split_id = p.second.second;
       for( auto* w : workers )   {
 	if ( w->options.predicate.id == split_id )  {
 	  w->options = m_split_context;
@@ -125,15 +124,14 @@ void DigiSegmentSplitter::initialize()   {
   }
   /// IF NOT:
   /// 2) Create the processors using the 'processor_type' option
-  for( auto& p : m_splits )   {
-    uint32_t id = m_split_context.split_id(p.first);
+  for( auto id : m_splits )   {
     ::snprintf(text, sizeof(text), "_%05X", id);
     std::string nam = this->name() + text;
     auto* proc = createAction<DigiContainerProcessor>(m_processor_type, m_kernel, nam);
     if ( !proc )   {
       except("+++ Failed to create split worker: %s/%s", m_processor_type.c_str(), nam.c_str());
     }
-    info("+++ Created worker: %s layer: %d %d", nam.c_str(), p.first, id);
+    info("+++ Created worker: %s layer: %d", nam.c_str(), id);
     auto* w = new worker_t(proc, m_split_context);
     w->options.enable(id);
     m_workers.insert(w);
@@ -165,8 +163,8 @@ void DigiSegmentSplitter::execute(context_t& context, work_t& work, const predic
   unmasked_key.set_item(key.item());
   if ( std::find(m_keys.begin(), m_keys.end(), unmasked_key) != m_keys.end() )   {
     if ( work.has_input() )   {
-      info("+++ Got hit collection %04X %08X. Prepare processors for %sparallel execution.",
-	   key.mask(), key.item(), m_parallel ? "" : "NON-");
+      info("%s+++ Got hit collection %04X %08X. Prepare processors for %sparallel execution.",
+	   context.event->id(), key.mask(), key.item(), m_parallel ? "" : "NON-");
       m_kernel.submit(context, m_workers.get_group(), m_workers.size(), &work, m_parallel);
     }
   }
diff --git a/DDDigi/src/DigiSegmentationTool.cpp b/DDDigi/src/DigiSegmentationTool.cpp
index c8f94fde03f0f7b56ff69344f06bcc2ef3db574c..b25be527bbc0849258a9755f546e38f82ddd6683 100644
--- a/DDDigi/src/DigiSegmentationTool.cpp
+++ b/DDDigi/src/DigiSegmentationTool.cpp
@@ -183,9 +183,7 @@ DigiSegmentationTool::split_context(const string& split_by)  const {
 }
 
 /// Create full set of detector segments which can be split according to the context
-map<dd4hep::VolumeID, pair<dd4hep::DetElement, dd4hep::VolumeID> >
-DigiSegmentationTool::split_segmentation(const string& split_by)  const
-{
+set<uint32_t> DigiSegmentationTool::split_segmentation(const string& split_by)  const  {
   map<VolumeID, pair<DetElement, VolumeID> > segmentation_splits;
   const auto& ids = this->detector.placement().volIDs();
   VolumeID    vid = this->iddescriptor.encode(ids);
@@ -198,17 +196,19 @@ DigiSegmentationTool::split_segmentation(const string& split_by)  const
 	   split_by.c_str(), this->iddescriptor.name());
   }
   ::scan_detector(*this, split_by, segmentation_splits, this->detector, vid, msk);
-  printout(INFO,"DigiSegmentationTool",
-	   "%-24s has %ld parallel entries when splitting by \"%s\"",
-	   det, segmentation_splits.size(), split_by.c_str());
-  stringstream str1, str2;
+  stringstream str;
+  set<uint32_t> splits;
   for( const auto& id : segmentation_splits )  {
-    str1 << setw(16) << hex << setfill('0') << id.first << " ";
-    str2 << setw(16) << hex << setfill(' ') << ((id.first&fld->mask())>>fld->offset()) << " ";
+    auto val = ((id.first&fld->mask())>>fld->offset());
+    splits.insert(val);
   }
-  printout(INFO,"DigiSegmentationTool","%-24s --> Parallel Entries: %s",
-	   det, str1.str().c_str());
+  for( const auto& id : splits )  {
+    str << setw(16) << hex << setfill(' ') << id << " ";
+  }
+  printout(INFO,"DigiSegmentationTool",
+	   "%-24s has %ld entries and %ld parallel entries when splitting by \"%s\"",
+	   det, segmentation_splits.size(), splits.size(), split_by.c_str());
   printout(INFO,"DigiSegmentationTool","%-24s --> %-12s ids: %s",
-	   "", split_by.c_str(), str2.str().c_str());
-  return segmentation_splits;
+	   "", split_by.c_str(), str.str().c_str());
+  return splits;
 }
diff --git a/DDDigi/src/DigiStoreDump.cpp b/DDDigi/src/DigiStoreDump.cpp
index a07881ee06573f955cb1195ad83a0ed0bb0117e0..c0e1d07efa5c26e7767771f331934b445d0db1a8 100644
--- a/DDDigi/src/DigiStoreDump.cpp
+++ b/DDDigi/src/DigiStoreDump.cpp
@@ -34,7 +34,7 @@ DigiStoreDump::DigiStoreDump(const DigiKernel& krnl, const std::string& nam)
   m_segments.push_back("output");
   declareProperty("containers", m_containers);
   declareProperty("masks",      m_masks);
-  m_kernel.register_initialize(Callback(this).make(&DigiStoreDump::initialize));
+  m_kernel.register_initialize(std::bind(&DigiStoreDump::initialize,this));
   InstanceCount::increment(this);
 }
 
diff --git a/examples/DDDigi/scripts/TestDepositSmearTime.py b/examples/DDDigi/scripts/TestDepositSmearTime.py
new file mode 100644
index 0000000000000000000000000000000000000000..48b68cc5c8347acb1b98d461406839755dc05b0e
--- /dev/null
+++ b/examples/DDDigi/scripts/TestDepositSmearTime.py
@@ -0,0 +1,37 @@
+# ==========================================================================
+#  AIDA Detector description implementation
+# --------------------------------------------------------------------------
+# Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+# All rights reserved.
+#
+# For the licensing terms see $DD4hepINSTALL/LICENSE.
+# For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
+#
+# ==========================================================================
+from __future__ import absolute_import
+
+
+def run():
+  import DigiTest
+  from dd4hep import units
+  digi = DigiTest.Test(geometry=None)
+  digi.load_geo(volume_manager=True)
+
+  event = DigiTest.test_setup_1(digi)
+  # ========================================================================================================
+  proc = event.adopt_action('DigiContainerSequenceAction/Smearing',
+                            parallel=False,
+                            input_mask=0xEEE5,
+                            input_segment='deposits')
+  smear = digi.create_action('DigiDepositSmearTime/Smear',
+                             resolution_time=1e-6 * units.second)
+  proc.adopt_container_processor(smear, ['SiVertexEndcapHits', 'SiVertexBarrelHits'])
+
+  event.adopt_action('DigiStoreDump/HeaderDump')
+  # ========================================================================================================
+  digi.info('Starting digitization core')
+  digi.run_checked(num_events=3, num_threads=10, parallel=5)
+
+
+if __name__ == '__main__':
+  run()
diff --git a/examples/DDDigi/scripts/TestSegmentationSplit2.py b/examples/DDDigi/scripts/TestSegmentationSplit2.py
index f0611c0dc648dfcf13c94f6e4127936260649a39..63fba35f90c3f1627e455adeeb8f8f5446ef35c2 100644
--- a/examples/DDDigi/scripts/TestSegmentationSplit2.py
+++ b/examples/DDDigi/scripts/TestSegmentationSplit2.py
@@ -31,13 +31,13 @@ def run():
   splitter = digi.create_action('DigiSegmentSplitter/Splitter',
                                 parallel=True,
                                 split_by='layer',
-                                detector='SiTrackerBarrel')
+                                detector='SiTrackerEndcap')
   printer = digi.create_action('DigiSegmentDepositPrint/P1')
   splitter.get().adopt_segment_processor(printer, 1)
   printer = digi.create_action('DigiSegmentDepositPrint/P2')
-  splitter.adopt_segment_processor(printer, [2, 3, 4])
+  splitter.adopt_segment_processor(printer, [2, 3])
   printer = digi.create_action('DigiSegmentDepositPrint/P3')
-  splitter.adopt_segment_processor(printer, [5])
+  splitter.adopt_segment_processor(printer, [4])
   split_action.adopt_container_processor(splitter, splitter.collection_names())
 
   event.adopt_action('DigiStoreDump/StoreDump')