diff --git a/Trigger/TrigHypothesis/TrigEgammaHypo/python/TrigL2CaloHypoTool.py b/Trigger/TrigHypothesis/TrigEgammaHypo/python/TrigL2CaloHypoTool.py
index 4097991ba8ec323b15024d50298a516489cdb9dc..63a045f0fb1f32f8d338ee7473ae9855d060c929 100644
--- a/Trigger/TrigHypothesis/TrigEgammaHypo/python/TrigL2CaloHypoTool.py
+++ b/Trigger/TrigHypothesis/TrigEgammaHypo/python/TrigL2CaloHypoTool.py
@@ -1,34 +1,27 @@
 # Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 import re
-__pattern = "e(?P<threshold>\d+)"
-__cpattern = re.compile( __pattern )
+_pattern = "(?P<mult>\d*)(e(?P<threshold1>\d+))(e(?P<threshold2>\d+))*"
+_cpattern = re.compile( _pattern )
 
 from AthenaCommon.SystemOfUnits import GeV
 
-from TrigEgammaHypo.TrigEgammaHypoConf import TrigL2CaloHypoTool
-def TrigL2CaloHypoToolFromName( name ):
-    """ decode the name ( chain ) and figure out the threshold and selection from it """
 
-    assert name.startswith( "HLT_e" ), "Not a single electron chain"+name+" can't handle it yet"
-    bname = name.split('_')
-    m = __cpattern.match( bname[1] )
-    assert m, "The chain name part 1 "+name+" does not match pattern "+__pattern
 
-    # print m.groups()
-    threshold = int( m.group( "threshold" ) )
-    sel = bname[2]
-    
- #   print "configuring threshold " , threshold , " slection " , sel
+
+def _IncTool(name, threshold, sel):
+
+    from TrigEgammaHypo.TrigEgammaHypoConf import TrigL2CaloHypoToolInc    
+    #print "configuring threshold " , threshold , " slection " , sel
 
     from TrigL2CaloHypoCutDefs import L2CaloCutMaps    
     possibleSel = L2CaloCutMaps( threshold ).MapsHADETthr.keys()
     
 
-    tool = TrigL2CaloHypoTool( name ) 
+    tool = TrigL2CaloHypoToolInc( name ) 
     tool.AcceptAll = False
     tool.MonTool = ""
     from TriggerJobOpts.TriggerFlags import TriggerFlags
-    print "monitoring", TriggerFlags.enableMonitoring()
+    #print "monitoring", TriggerFlags.enableMonitoring()
 
 
     if 'Validation' in TriggerFlags.enableMonitoring() or 'Online' in  TriggerFlags.enableMonitoring():
@@ -115,28 +108,84 @@ def TrigL2CaloHypoToolFromName( name ):
     for prop in "ETthr HADETthr CARCOREthr CARCOREthr F1thr F3thr WSTOTthr WETA2thr HADETthr HADETthr ET2thr".split():
         propLen = len( getattr( tool, prop ) ) 
         assert propLen == etaBinsLen , "In " + name + " " + prop + " has length " + str( propLen ) + " which is different from EtaBins which has length " + str( etaBinsLen )
-        
 
-            
-            #    assert  __l( EtaBins, tool.ETthr, tool.HADETthr, tool.CARCOREthr, tool.CARCOREthr ) , "All list properties should have equal length ( as EtaBins )"
+        #    assert  _l( EtaBins, tool.ETthr, tool.HADETthr, tool.CARCOREthr, tool.CARCOREthr ) , "All list properties should have equal length ( as EtaBins )"
     #print tool
     return tool
 
+
+def _MultTool(name):
+    from TrigEgammaHypo.TrigEgammaHypoConf import TrigL2CaloHypoToolMult
+    return TrigL2CaloHypoToolMult( name )
+
+
+def decodeThreshold( threshold ):
+    """ decodes the thresholds of the form e10, 2e10, e10e15, ... """
+    print "decoding ", threshold
+    if threshold[0].isdigit(): # is if the from NeX, return as list [X,X,X...N times...]
+        assert threshold[1] == 'e', "Two digit multiplicity not supported"
+        return [ threshold[2:] ] * int( threshold[0] )
+
+    if threshold.count('e') > 1: # is of the form eXeYeZ, return as [X, Y, Z]
+        return threshold.strip('e').split('e')
+
+    # inclusive, return as 1 element list
+    return [ threshold[1:] ] 
+
+def TrigL2CaloHypoToolFromName( name ):
+    from AthenaCommon.Constants import DEBUG
+    """ decode the name ( chain ) and figure out the threshold and selection from it """
+    #print "Configuring ", name
+    bname = name.split('_')
+    threshold = bname[1]
+    sel = bname[2]
+
+    dt = decodeThreshold( threshold )
+    assert len(dt) >= 1, "Threshold "+ threshold +" not decoded properly"
+
+    if len( dt ) > 1:
+        tool = _MultTool(name) 
+        for cutNumber, th in enumerate( dt ):
+            print "cut and threshold ", cutNumber, th
+            tool.SubTools += [ _IncTool( name+"_"+str(cutNumber), th, sel ) ]
+        for t in tool.SubTools:
+            t.OutputLevel=DEBUG
+    else:
+        tool = _IncTool( name, dt[0], sel )
+    return tool
+
 if __name__ == "__main__":    
     from TriggerJobOpts.TriggerFlags import TriggerFlags
     TriggerFlags.enableMonitoring=['Validation']
     t = TrigL2CaloHypoToolFromName( "HLT_e10_nocut" )
     assert t, "cant configure NoCut"    
-    print t
+    #print t
+
     t = TrigL2CaloHypoToolFromName( "HLT_e10_etcut" )
     assert t, "cant configure EtCut"
-    print t
+    #print t
+
     t  = TrigL2CaloHypoToolFromName( "HLT_e10_tight" )
     assert t, "cant configure rel selection - tight"
-    print t    
+    #print t    
 
-    t  = TrigL2CaloHypoToolFromName( "HLT_e0_perf" )
+    t  = TrigL2CaloHypoToolFromName( "HLT_e10_perf" )
     assert t, "cant configure rel selection - perf"
-    print t    
+    #print t    
+
+    t = TrigL2CaloHypoToolFromName( "HLT_2e5_etcut" )
+    assert t, "cant configure symmetric selection"
+    assert len(t.SubTools) == 2, "Sub-tools not configured"
+    #print t    
+
+    t = TrigL2CaloHypoToolFromName( "HLT_3e5_etcut" )
+    assert t, "cant configure symmetric selection"
+    assert len(t.SubTools) == 3, "Sub-tools not configured"
+
+
+    t = TrigL2CaloHypoToolFromName( "HLT_e5e3_etcut" )
+    assert t, "cant configure asymmetric selection"
+    assert len(t.SubTools) == 2, "Sub-tools not configured"
+    #print t    
 
     print ( "\n\nALL OK\n\n" )
diff --git a/Trigger/TrigHypothesis/TrigEgammaHypo/python/TrigL2ElectronHypoTool.py b/Trigger/TrigHypothesis/TrigEgammaHypo/python/TrigL2ElectronHypoTool.py
index 9e88963e784879401d86ed0c7fbc489a2872bc7d..e46683c556ee61e59f02b0313228a8125ced226e 100644
--- a/Trigger/TrigHypothesis/TrigEgammaHypo/python/TrigL2ElectronHypoTool.py
+++ b/Trigger/TrigHypothesis/TrigEgammaHypo/python/TrigL2ElectronHypoTool.py
@@ -1,17 +1,15 @@
 
-
-
 def TrigL2ElectronHypoToolFromName( name ):
     """ provides configuration of the hypo tool giben the chain name
     The argument will be replaced by "parsed" chain dict. For now it only serves simplest chain HLT_eXYZ.
     """
-    assert name.startswith("HLT_e"), "The chain name does not start from HLT_e"
-
     bname = name.split('_')
-    threshold = int(bname[1][1:])
-    assert str(threshold) == bname[1][1:], "Threshold definition is not a simple int"
-    from TrigEgammaHypo.TrigEgammaHypoConf import TrigL2ElectronHypoTool
 
+    threshold = bname[1]
+    from TrigEgammaHypo.TrigL2CaloHypoTool import decodeThreshold
+    thresholds = decodeThreshold( threshold )
+
+    from TrigEgammaHypo.TrigEgammaHypoConf import TrigL2ElectronHypoTool
     tool = TrigL2ElectronHypoTool(name)
     tool.MonTool = ""
     from TriggerJobOpts.TriggerFlags import TriggerFlags
@@ -34,26 +32,38 @@ def TrigL2ElectronHypoToolFromName( name ):
         tool += monTool
 
     from AthenaCommon.SystemOfUnits import GeV    
-    tool.TrackPt = [ 1.0 * GeV ] 
-    tool.CaloTrackdETA = [ 0.2 ]
-    tool.CaloTrackdPHI = [ 999. ]
-    tool.CaloTrackdEoverPLow = [ 0.0 ]
-    tool.CaloTrackdEoverPHigh = [ 999.0 ]
-    tool.TRTRatio = [ -999. ]
-
-    if float(threshold) < 15:
-        tool.TrackPt = [ 1.0 * GeV ]
-    elif float(threshold) >= 15 and float(threshold) < 20:
-        tool.TrackPt = [ 2.0 * GeV ]
-    elif float(threshold) >= 20 and float(threshold) < 50:
-        tool.TrackPt = [ 3.0 * GeV ]
-    elif float(threshold) >= 50:
-        tool.TrackPt = [ 5.0 * GeV ]
-        tool.CaloTrackdETA = [ 999. ]
-        tool.CaloTrackdPHI = [ 999. ]
-    else:
-        raise RuntimeError('No threshold: Default cut configured')
+    nt = len( thresholds )
+    tool.TrackPt = [0.0] * nt
+    tool.CaloTrackdETA = [ 0.2 ] *nt
+    tool.CaloTrackdPHI = [ 990. ] *nt
+    tool.CaloTrackdEoverPLow = [ 0.0 ] * nt
+    tool.CaloTrackdEoverPHigh = [ 999.0 ] * nt
+    tool.TRTRatio = [ -999. ] * nt
+
+
+    for th, thvalue in enumerate(thresholds):
+        print th, thvalue
+        if float(thvalue) < 15:
+            tool.TrackPt[ th ] = 1.0 * GeV 
+        elif float(thvalue) >= 15 and float(thvalue) < 20:
+            tool.TrackPt[ th ] = 2.0 * GeV 
+        elif float(thvalue) >= 20 and float(thvalue) < 50:
+            tool.TrackPt[ th ] =  3.0 * GeV 
+        elif float(thvalue) >= 50:
+            tool.TrackPt[ th ] =  5.0 * GeV 
+            tool.CaloTrackdETA[ th ] =  999. 
+            tool.CaloTrackdPHI[ th ] =  999.
+        else:
+            raise RuntimeError('No threshold: Default cut configured')
     return tool
 
+
 if __name__ == "__main__":
-    tool = TrigL2ElectronHypoToolFromName("HLT_e4")    
+    tool = TrigL2ElectronHypoToolFromName("HLT_e3_etcut")    
+    assert tool, "Not configured simple tool"
+
+    tool = TrigL2ElectronHypoToolFromName("HLT_2e3_etcut")    
+    assert tool, "Not configured simple tool"
+    assert len(tool.TrackPt) == 2, "Multiplicity missonfigured, set "+ str( len( tool.TrackPt ) )
+
+    print ( "\n\nALL OK\n\n" )    
diff --git a/Trigger/TrigHypothesis/TrigEgammaHypo/src/ITrigL2CaloHypoTool.h b/Trigger/TrigHypothesis/TrigEgammaHypo/src/ITrigL2CaloHypoTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..967f6dd142d7fa5f2b1e71d7d3f1829caa4e8570
--- /dev/null
+++ b/Trigger/TrigHypothesis/TrigEgammaHypo/src/ITrigL2CaloHypoTool.h
@@ -0,0 +1,63 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+#ifndef TRIGEGAMMAHYPO_ITRIGL2CALOHYPOTOOL_H
+#define TRIGEGAMMAHYPO_ITRIGL2CALOHYPOTOOL_H 1
+
+#include "GaudiKernel/IAlgTool.h"
+
+
+
+
+
+/**
+ * @class Base for tools dooing L2 Calo Hypo selection
+ * @brief 
+ **/
+
+class ITrigL2CaloHypoTool
+  : virtual public ::IAlgTool
+{ 
+
+ public: 
+  DeclareInterfaceID(ITrigL2CaloHypoTool, 1, 0);
+  virtual ~ITrigL2CaloHypoTool(){}
+
+  struct ClusterInfo {
+  ClusterInfo( TrigCompositeUtils::Decision* d, const TrigRoiDescriptor* r, const xAOD::TrigEMCluster* c,
+	       const TrigCompositeUtils::Decision* previousDecision )
+  : decision( d ), 
+      roi( r ), 
+      cluster(c), 
+      previousDecisionIDs( TrigCompositeUtils::decisionIDs( previousDecision ).begin(), 
+			   TrigCompositeUtils::decisionIDs( previousDecision ).end() )
+    {}
+    
+    TrigCompositeUtils::Decision* decision;
+    const TrigRoiDescriptor* roi;
+    const xAOD::TrigEMCluster* cluster;
+    const TrigCompositeUtils::DecisionIDContainer previousDecisionIDs;
+  };
+  
+  
+  /**
+   * @brief decides upon all clusters
+   * Note it is for a reason a non-virtual method, it is an interface in gaudi sense and implementation.
+   * There will be many tools called often to perform this quick operation and we do not want to pay for polymorphism which we do not need to use.
+   * Will actually see when N obj hypos will enter the scene
+   **/
+  virtual StatusCode decide( std::vector<ClusterInfo>& input )  const = 0;
+
+  /**
+   * @brief Makes a decision for a single object
+   * The decision needs to be returned
+   **/ 
+  virtual bool decide( const ClusterInfo& i ) const = 0;
+
+ protected:
+
+
+}; 
+
+
+#endif //> !TRIGEGAMMAHYPO_ITRIGL2CALOHYPOTOOL_H
diff --git a/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2CaloHypoAlg.cxx b/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2CaloHypoAlg.cxx
index b382273c70ff11ceda5f4afbcc56c0a6ba9860c1..06b286ec50a8095d85e268d6a35f869eccd9bde1 100644
--- a/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2CaloHypoAlg.cxx
+++ b/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2CaloHypoAlg.cxx
@@ -11,11 +11,9 @@ TrigL2CaloHypoAlg::TrigL2CaloHypoAlg( const std::string& name,
 				      ISvcLocator* pSvcLocator ) : 
   ::AthReentrantAlgorithm( name, pSvcLocator ) {}
 
-TrigL2CaloHypoAlg::~TrigL2CaloHypoAlg()
-{}
+TrigL2CaloHypoAlg::~TrigL2CaloHypoAlg() {}
 
-StatusCode TrigL2CaloHypoAlg::initialize()
-{
+StatusCode TrigL2CaloHypoAlg::initialize() {
   ATH_MSG_INFO ( "Initializing " << name() << "..." );
   CHECK( m_hypoTools.retrieve() );
 
@@ -27,19 +25,14 @@ StatusCode TrigL2CaloHypoAlg::initialize()
   renounce( m_roisKey );
   CHECK( m_roisKey.initialize() );
 
+  CHECK( m_previousDecisionsKey.initialize() );
+
   CHECK( m_decisionsKey.initialize() );
   return StatusCode::SUCCESS;
 }
 
-StatusCode TrigL2CaloHypoAlg::finalize()
-{
-  ATH_MSG_INFO ( "Finalizing " << name() << "..." );
 
-  return StatusCode::SUCCESS;
-}
-
-StatusCode TrigL2CaloHypoAlg::execute_r( const EventContext& context ) const
-{  
+StatusCode TrigL2CaloHypoAlg::execute_r( const EventContext& context ) const {  
   ATH_MSG_DEBUG ( "Executing " << name() << "..." );
   auto viewsHandle = SG::makeHandle( m_viewsKey, context );
   
@@ -48,7 +41,18 @@ StatusCode TrigL2CaloHypoAlg::execute_r( const EventContext& context ) const
   decisions->setStore( aux.get() );
 
 
-  std::vector<TrigL2CaloHypoTool::Input> toolInput;
+  std::map<const TrigRoiDescriptor*, const TrigCompositeUtils::Decision* > roiToDecision;
+  auto previousDecisionsHandle = SG::makeHandle( m_previousDecisionsKey, context );
+  for ( auto previousDecision: *previousDecisionsHandle ) {
+    auto roiEL = previousDecision->objectLink<TrigRoiDescriptorCollection>( "initialRoI" );
+    CHECK( roiEL.isValid() );
+    const TrigRoiDescriptor* roi = *roiEL;
+    roiToDecision.insert( std::make_pair( roi, previousDecision ) );
+  }
+  ATH_MSG_DEBUG( "RoI to decisions map size: " << roiToDecision.size() );
+
+
+  std::vector<ITrigL2CaloHypoTool::ClusterInfo> toolInput;
   // exploit knowledge that there is one cluster in the view
   size_t counter = 0;
   for ( auto view: *viewsHandle ) {
@@ -56,12 +60,12 @@ StatusCode TrigL2CaloHypoAlg::execute_r( const EventContext& context ) const
     
     auto roiHandle =  SG::makeHandle( m_roisKey, context );
     CHECK( roiHandle.setProxyDict( view ) );
+    const TrigRoiDescriptor* roi = roiHandle.cptr()->at(0);
 
     auto clusterHandle =  SG::makeHandle( m_clustersKey, context );
     CHECK( clusterHandle.setProxyDict( view ) );
-    
-    toolInput.emplace_back( d, roiHandle.cptr()->at(0), clusterHandle.cptr()->at(0) );
-
+       
+    toolInput.emplace_back( d, roi, clusterHandle.cptr()->at(0), roiToDecision[roi] );
 
     {
       auto el = ElementLink<xAOD::TrigEMClusterContainer>( view->name()+"_"+clusterHandle.key(), 0 ); // 0 because there is only one obj in per-view collection
@@ -83,7 +87,6 @@ StatusCode TrigL2CaloHypoAlg::execute_r( const EventContext& context ) const
   for ( auto& tool: m_hypoTools ) {
     CHECK( tool->decide( toolInput ) );
   }
-
  
   {
     auto handle =  SG::makeHandle( m_decisionsKey, context );
diff --git a/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2CaloHypoAlg.h b/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2CaloHypoAlg.h
index 92b6069138059dfaf03bb0628b5a180162e394ad..ca2db5bba32d63b85b54d70707d56dcee7703140 100644
--- a/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2CaloHypoAlg.h
+++ b/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2CaloHypoAlg.h
@@ -12,36 +12,35 @@
 #include "xAODTrigCalo/TrigEMClusterContainer.h"
 #include "DecisionHandling/TrigCompositeUtils.h"
 
-#include "TrigL2CaloHypoTool.h"
+#include "ITrigL2CaloHypoTool.h"
 
 /**
  * @class Implements egamma calo selection for the new HLT framework
  * @brief 
  **/
 
-class TrigL2CaloHypoAlg
-  : public ::AthReentrantAlgorithm
-{ 
+class TrigL2CaloHypoAlg : public ::AthReentrantAlgorithm { 
  public: 
 
   TrigL2CaloHypoAlg( const std::string& name, ISvcLocator* pSvcLocator );
 
   virtual ~TrigL2CaloHypoAlg(); 
 
-  StatusCode  initialize() override;
-  StatusCode  execute_r( const EventContext& context ) const override;
-  StatusCode  finalize() override;
+  virtual StatusCode  initialize() override;
+  virtual StatusCode  execute_r( const EventContext& context ) const override;
+
  
  private: 
   TrigL2CaloHypoAlg();
-  ToolHandleArray< TrigL2CaloHypoTool > m_hypoTools { this, "HypoTools", {}, "Hypo tools" };
+  ToolHandleArray< ITrigL2CaloHypoTool > m_hypoTools { this, "HypoTools", {}, "Hypo tools" };
   
   SG::ReadHandleKey< std::vector< SG::View* > > m_viewsKey { this, "Views", "Unspecified", "Input Views" };
   SG::ReadHandleKey< xAOD::TrigEMClusterContainer > m_clustersKey { this, "CaloClusters", "CaloClusters", "CaloClusters in view" };
   SG::ReadHandleKey< TrigRoiDescriptorCollection > m_roisKey { this, "RoIs", "RoIs", "RoIs key in the view" };
+  SG::ReadHandleKey< TrigCompositeUtils::DecisionContainer > m_previousDecisionsKey { this, "L1Decisions", "Undefined", "Key for L1 decisions per RoI" };
   SG::WriteHandleKey< TrigCompositeUtils::DecisionContainer > m_decisionsKey { this, "Decisions", "Unspecified", "Decisions" };
  
 }; 
 
-
+DECLARE_ALGORITHM_FACTORY( TrigL2CaloHypoAlg )
 #endif //> !TRIGEGAMMAHYPO_TRIGL2CALOHYPOALG_H
diff --git a/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2CaloHypoTool.cxx b/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2CaloHypoToolInc.cxx
similarity index 70%
rename from Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2CaloHypoTool.cxx
rename to Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2CaloHypoToolInc.cxx
index 3cab44a27d6af299611c39923eac92dea228d381..8bd1a9849d39a755cfd3ac02c321ac4cabe8232f 100644
--- a/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2CaloHypoTool.cxx
+++ b/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2CaloHypoToolInc.cxx
@@ -2,20 +2,22 @@
   Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 */
 
-
+#include <algorithm>
 #include "DecisionHandling/HLTIdentifier.h"
+#include "DecisionHandling/Combinators.h"
 
-#include "TrigL2CaloHypoTool.h"
+#include "TrigL2CaloHypoToolInc.h"
 
 
+using namespace TrigCompositeUtils;
 
-TrigL2CaloHypoTool::TrigL2CaloHypoTool( const std::string& type, 
+TrigL2CaloHypoToolInc::TrigL2CaloHypoToolInc( const std::string& type, 
 		    const std::string& name, 
-		    const IInterface* parent ) :
-  AthAlgTool( type, name, parent ),
-  m_decisionId( HLT::Identifier::fromToolName( name ) ) {}
+		    const IInterface* parent ) 
+  : base_class( type, name, parent ),
+    m_decisionId( HLT::Identifier::fromToolName( name ) ) {}
 
-StatusCode TrigL2CaloHypoTool::initialize()  {
+StatusCode TrigL2CaloHypoToolInc::initialize()  {
   ATH_MSG_DEBUG( "Initialization completed successfully"   );   
   ATH_MSG_DEBUG( "AcceptAll           = " << ( m_acceptAll==true ? "True" : "False" ) ); 
   ATH_MSG_DEBUG( "EtaBins        = " << m_etabin      );
@@ -34,10 +36,9 @@ StatusCode TrigL2CaloHypoTool::initialize()  {
     return StatusCode::FAILURE;
   }
 
-  unsigned int nEtaBin=m_etabin.size();
-#define CHECK_SIZE( __n) if ( m_##__n.size() != nEtaBin - 1 )		\
-    { ATH_MSG_DEBUG(" __n size is " << m_##__n.size() << " but needs to be " << nEtaBin - 1 ); \
-      return StatusCode::FAILURE; }
+  unsigned int nEtaBin = m_etabin.size();
+#define CHECK_SIZE( __n) if ( m_##__n.size() !=  (nEtaBin - 1) )		\
+    { ATH_MSG_DEBUG(" __n size is " << m_##__n.size() << " but needs to be " << (nEtaBin - 1) ); return StatusCode::FAILURE; }
 
   CHECK_SIZE( eTthr );
   CHECK_SIZE( eT2thr );
@@ -48,8 +49,11 @@ StatusCode TrigL2CaloHypoTool::initialize()  {
   CHECK_SIZE( WETA2thr );
   CHECK_SIZE( WSTOTthr ); 
   CHECK_SIZE( F3thr );
+#undef CHECK_SIZE
+
 
-  ATH_MSG_DEBUG( "Tool configured for chain/id: " << m_decisionId  );
+
+  ATH_MSG_DEBUG( "Tool configured for chain/id: " << m_decisionId );
 
   if ( not m_monTool.name().empty() ) 
     CHECK( m_monTool.retrieve() );
@@ -57,15 +61,12 @@ StatusCode TrigL2CaloHypoTool::initialize()  {
   return StatusCode::SUCCESS;
 }
 
-StatusCode TrigL2CaloHypoTool::finalize()  {
-  return StatusCode::SUCCESS;
-}
 
-TrigL2CaloHypoTool::~TrigL2CaloHypoTool()
-{}
+
+TrigL2CaloHypoToolInc::~TrigL2CaloHypoToolInc(){}
 
 
-bool TrigL2CaloHypoTool::singleObjectDecision( const Input& input, int selectionIndex ) const {
+bool TrigL2CaloHypoToolInc::decide( const ITrigL2CaloHypoTool::ClusterInfo& input ) const {
 
   bool pass = false;
 
@@ -105,8 +106,8 @@ bool TrigL2CaloHypoTool::singleObjectDecision( const Input& input, int selection
 
 
   if ( fabs( roiDescriptor->eta() ) > 2.6 ) {
-      ATH_MSG_DEBUG( "The cluster had eta coordinates beyond the EM fiducial volume : " << roiDescriptor->eta() << "; stop the chain now" );
-      pass=false; // special case 
+      ATH_MSG_DEBUG( "REJECT The cluster had eta coordinates beyond the EM fiducial volume : " << roiDescriptor->eta() << "; stop the chain now" );
+      pass=false; // special case       
       return pass;
   } 
 
@@ -124,13 +125,12 @@ bool TrigL2CaloHypoTool::singleObjectDecision( const Input& input, int selection
   auto pClus = input.cluster;
   
   float absEta = fabs( pClus->eta() );
-  etaBin = -1;
-  monEta = pClus->eta();
-  monPhi = pClus->phi();
-  for ( std::size_t iBin = 0; iBin < m_etabin.size()-1; iBin++ )
-    if ( absEta > m_etabin[iBin] && absEta < m_etabin[iBin+1] ) etaBin = iBin; 
+  // etaBin = -1;
+  // monEta = pClus->eta();
+  // monPhi = pClus->phi();
  
-  const size_t etaIndex = etaBin + ( m_etabin.size()/m_multiplicity ) * selectionIndex;
+  const int cutIndex = findCutIndex( absEta );
+  
   // find if electron is in calorimeter crack
   bool inCrack = ( absEta > 2.37 || ( absEta > 1.37 && absEta < 1.52 ) );
 
@@ -176,7 +176,10 @@ bool TrigL2CaloHypoTool::singleObjectDecision( const Input& input, int selection
   		 << " roi eta=" << etaRef << " DeltaEta=" << dEta
   		 << " cut: <"   << m_detacluster          );
   
-  if ( fabs( pClus->eta() - etaRef ) > m_detacluster ) return pass;
+  if ( fabs( pClus->eta() - etaRef ) > m_detacluster ) {
+    ATH_MSG_DEBUG("REJECT Cluster dEta cut failed");
+    return pass;
+  }
   PassedCuts = PassedCuts + 1; //Deta
   
   // DeltaPhi( clus-ROI )
@@ -184,55 +187,70 @@ bool TrigL2CaloHypoTool::singleObjectDecision( const Input& input, int selection
   		 << " roi phi="<< phiRef    << " DeltaPhi="<< dPhi
   		 << " cut: <"  << m_dphicluster );
   
-  if( dPhi > m_dphicluster ) return pass;
+  if( dPhi > m_dphicluster ) {
+    ATH_MSG_DEBUG("REJECT Clsuter dPhi cut failed");
+    return pass;
+  }
   PassedCuts = PassedCuts + 1; //DPhi
 
   // eta range
-  if ( etaBin==-1 ) {  // VD
+  if ( cutIndex == -1 ) {  // VD
     ATH_MSG_DEBUG( "Cluster eta: " << absEta << " outside eta range " << m_etabin[m_etabin.size()-1] );
     return pass;
   } else { 
-    ATH_MSG_DEBUG( "eta bin used for cuts " << etaIndex );
+    ATH_MSG_DEBUG( "eta bin used for cuts " << cutIndex );
   }
   PassedCuts = PassedCuts + 1; // passed eta cut
   
   // Rcore
   ATH_MSG_DEBUG ( "TrigEMCluster: Rcore=" << rCore 
-		  << " cut: >"  << m_carcorethr[etaIndex] );
-  if ( rCore < m_carcorethr[etaIndex] )  return pass;
+  		  << " cut: >"  << m_carcorethr[cutIndex] );
+  if ( rCore < m_carcorethr[cutIndex] ) {
+    ATH_MSG_DEBUG("REJECT rCore cut failed");
+    return pass;
+  }
   PassedCuts = PassedCuts + 1; //Rcore
 
   // Eratio
-  ATH_MSG_DEBUG( " cut: >"  << m_caeratiothr[etaIndex] );   
+  ATH_MSG_DEBUG( " cut: >"  << m_caeratiothr[cutIndex] );   
   if ( inCrack || F1 < m_F1thr[0] ) {
     ATH_MSG_DEBUG ( "TrigEMCluster: InCrack= " << inCrack << " F1=" << F1 );
   } else {
-    if ( energyRatio < m_caeratiothr[etaIndex] ) return pass;
+    if ( energyRatio < m_caeratiothr[cutIndex] ) {
+      ATH_MSG_DEBUG("REJECT e ratio cut failed");
+      return pass;
+    }
   }
   PassedCuts = PassedCuts + 1; //Eratio
   if( inCrack ) energyRatio = -1; //Set default value in crack for monitoring.
   
   // ET_em
-  ATH_MSG_DEBUG( "TrigEMCluster: ET_em=" << eT_T2Calo << " cut: >"  << m_eTthr[etaIndex] );
-  if ( eT_T2Calo < m_eTthr[etaIndex] ) return pass;
+  ATH_MSG_DEBUG( "TrigEMCluster: ET_em=" << eT_T2Calo << " cut: >"  << m_eTthr[cutIndex] );
+  if ( eT_T2Calo < m_eTthr[cutIndex] ) {
+    ATH_MSG_DEBUG("REJECT et cut failed");
+    return pass;
+  }
   PassedCuts = PassedCuts + 1; // ET_em
  
   float hadET_cut = 0.0;  
   // find which ET_had to apply	: this depends on the ET_em and the eta bin
-  if ( eT_T2Calo >  m_eT2thr[etaIndex] ) {
-    hadET_cut = m_hadeT2thr[etaIndex] ;
+  if ( eT_T2Calo >  m_eT2thr[cutIndex] ) {
+    hadET_cut = m_hadeT2thr[cutIndex] ;
 
-    ATH_MSG_DEBUG ( "ET_em>"     << m_eT2thr[etaIndex] << ": use high ET_had cut: <" << hadET_cut );
+    ATH_MSG_DEBUG ( "ET_em>"     << m_eT2thr[cutIndex] << ": use high ET_had cut: <" << hadET_cut );
   } else {
-    hadET_cut = m_hadeTthr[etaIndex];
+    hadET_cut = m_hadeTthr[cutIndex];
 
-    ATH_MSG_DEBUG ( "ET_em<"    << m_eT2thr[etaIndex] << ": use low ET_had cut: <" << hadET_cut );
+    ATH_MSG_DEBUG ( "ET_em<"    << m_eT2thr[cutIndex] << ": use low ET_had cut: <" << hadET_cut );
   }
   
   // ET_had
   ATH_MSG_DEBUG ( "TrigEMCluster: ET_had=" << hadET_T2Calo << " cut: <" << hadET_cut );
 
-  if ( hadET_T2Calo > hadET_cut ) return pass;
+  if ( hadET_T2Calo > hadET_cut ) {
+    ATH_MSG_DEBUG("REJECT et had cut failed");
+    return pass;
+  }
   PassedCuts = PassedCuts + 1; //ET_had
   
   // F1
@@ -240,21 +258,28 @@ bool TrigL2CaloHypoTool::singleObjectDecision( const Input& input, int selection
   // if ( m_F1 < m_F1thr[0] ) return pass;  //( VD ) not cutting on this variable, only used to select whether to cut or not on eRatio
   PassedCuts = PassedCuts + 1; //F1
 
-
   //Weta2
-  ATH_MSG_DEBUG ( "TrigEMCluster: Weta2=" << Weta2 << " cut: <"  << m_WETA2thr[etaIndex] ); 
-  if ( Weta2 > m_WETA2thr[etaIndex] ) return pass;
+  ATH_MSG_DEBUG ( "TrigEMCluster: Weta2=" << Weta2 << " cut: <"  << m_WETA2thr[cutIndex] ); 
+  if ( Weta2 > m_WETA2thr[cutIndex] ) {
+    ATH_MSG_DEBUG("REJECT weta 2 cut failed");
+    return pass;
+  }
   PassedCuts = PassedCuts + 1; //Weta2
 
-
   //Wstot
-  ATH_MSG_DEBUG ( "TrigEMCluster: Wstot=" <<Wstot << " cut: <"  << m_WSTOTthr[etaIndex] ); 
-  if ( Wstot >= m_WSTOTthr[etaIndex] ) return pass;
+  ATH_MSG_DEBUG ( "TrigEMCluster: Wstot=" <<Wstot << " cut: <"  << m_WSTOTthr[cutIndex] ); 
+  if ( Wstot >= m_WSTOTthr[cutIndex] ) {
+    ATH_MSG_DEBUG("REJECT wstot cut failed");
+    return pass;
+  }
   PassedCuts = PassedCuts + 1; //Wstot
 
   //F3
-  ATH_MSG_DEBUG( "TrigEMCluster: F3=" << F3 << " cut: <"  << m_F3thr[etaIndex] ); 
-  if ( F3 > m_F3thr[etaIndex] ) return pass;
+  ATH_MSG_DEBUG( "TrigEMCluster: F3=" << F3 << " cut: <"  << m_F3thr[cutIndex] ); 
+  if ( F3 > m_F3thr[cutIndex] ) {
+    ATH_MSG_DEBUG("REJECT F3 cut failed");
+    return pass;
+  }
   PassedCuts = PassedCuts + 1; //F3
 
   // got this far => passed!
@@ -266,13 +291,22 @@ bool TrigL2CaloHypoTool::singleObjectDecision( const Input& input, int selection
   return pass;
 }
 
+int TrigL2CaloHypoToolInc::findCutIndex( float eta ) const {
+  const float absEta = std::abs(eta);
+  
+  auto binIterator = std::adjacent_find( m_etabin.begin(), m_etabin.end(), [=](float left, float right){ return left < absEta and absEta < right; }  );
+  if ( binIterator == m_etabin.end() ) {
+    return -1;
+  }
+  return  binIterator - m_etabin.begin();
+}
 
-StatusCode TrigL2CaloHypoTool::decide( std::vector<Input>& input )  const {
 
-  if ( m_multiplicity == 1 ) {
-    for ( auto& i: input ) {
-      if ( singleObjectDecision( i ) ) {
-	TrigCompositeUtils::addDecisionID( m_decisionId, i.decision );
+StatusCode TrigL2CaloHypoToolInc::decide( std::vector<ClusterInfo>& input )  const {
+  for ( auto& i: input ) {
+    if ( passed ( m_decisionId.numeric(), i.previousDecisionIDs ) ) {
+      if ( decide( i ) ) {
+	addDecisionID( m_decisionId, i.decision );
       }
     }
   }
diff --git a/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2CaloHypoTool.h b/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2CaloHypoToolInc.h
similarity index 54%
rename from Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2CaloHypoTool.h
rename to Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2CaloHypoToolInc.h
index 50a84c9dc45ca9ca537e34d11a474d4af0e06986..fb5e6ca38151e6d461bf83351a12098b3b1cdb10 100644
--- a/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2CaloHypoTool.h
+++ b/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2CaloHypoToolInc.h
@@ -1,8 +1,8 @@
 /*
   Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 */
-#ifndef TRIGEGAMMAHYPO_TRIGL2CALOHYPOTOOL_H
-#define TRIGEGAMMAHYPO_TRIGL2CALOHYPOTOOL_H 1
+#ifndef TRIGEGAMMAHYPO_TRIGL2CALOHYPOTOOLINC_H
+#define TRIGEGAMMAHYPO_TRIGL2CALOHYPOTOOLINC_H 1
 
 //#include "GaudiKernel/IAlgTool.h"
 #include "CLHEP/Units/SystemOfUnits.h"
@@ -12,56 +12,29 @@
 #include "AthenaMonitoring/GenericMonitoringTool.h"
 #include "DecisionHandling/HLTIdentifier.h"
 #include "DecisionHandling/TrigCompositeUtils.h"
-
-
-static const InterfaceID IID_TrigL2CaloHypoTool("TrigL2CaloHypoTool", 1, 0);
+#include "ITrigL2CaloHypoTool.h"
 
 /**
  * @class Implementation of the Egamma selection for CaloClusters
  * @brief 
  **/
 
-
-
-class TrigL2CaloHypoTool
-  : virtual public ::AthAlgTool
-{ 
+class TrigL2CaloHypoToolInc : public extends<AthAlgTool, ITrigL2CaloHypoTool> { 
  public: 
+  TrigL2CaloHypoToolInc( const std::string& type, 
+			 const std::string& name, 
+			 const IInterface* parent );
 
+  virtual ~TrigL2CaloHypoToolInc();
+  virtual StatusCode initialize() override;
 
-  TrigL2CaloHypoTool( const std::string& type, 
-		      const std::string& name, 
-		      const IInterface* parent );
+  virtual StatusCode decide( std::vector<ITrigL2CaloHypoTool::ClusterInfo>& input )  const override;
 
-  virtual ~TrigL2CaloHypoTool();
-  StatusCode initialize() override;
-  StatusCode finalize() override;
+  virtual bool decide( const ITrigL2CaloHypoTool::ClusterInfo& i ) const override;
 
-  static const InterfaceID& interfaceID();
-
-  struct Input {
-    Input(TrigCompositeUtils::Decision* d, const TrigRoiDescriptor* r, const xAOD::TrigEMCluster* c)
-    : decision(d), roi(r), cluster(c) {}
-    TrigCompositeUtils::Decision* decision;
-    const TrigRoiDescriptor* roi;
-    const xAOD::TrigEMCluster* cluster;
-  };
-
-  /**
-   * @brief decides upon all clusters
-   * Note it is for a reason a non-virtual method, it is an interface in gaudi sense and implementation.
-   * There will be many tools called often to perform this quick operation and we do not want to pay for polymorphism which we do not need to use.
-   * Will actually see when N obj hypos will enter the scene
-   **/
-  StatusCode decide( std::vector<Input>& input )  const;
-  
  private:
   HLT::Identifier m_decisionId;
-
   
-  bool singleObjectDecision( const Input& i, int selectionIndex = 0 ) const;
-
-
   //Calorimeter electron ID  cuts
   Gaudi::Property< std::vector<float> > m_etabin { this, "EtaBins", {} , "Bins of eta" }; //!<  selection variable for L2 calo selection:eta bins
   Gaudi::Property< std::vector<float> > m_eTthr { this, "ETthr", {}, "ET Threshold" };
@@ -77,15 +50,10 @@ class TrigL2CaloHypoTool
   Gaudi::Property< float > m_detacluster { this, "dETACLUSTERthr", 0. , "" };
   Gaudi::Property< float > m_dphicluster { this, "dPHICLUSTERthr", 0. , "" };  
   Gaudi::Property< bool > m_acceptAll { this, "AcceptAll", false , "Ignore selection" };
-  Gaudi::Property< int > m_multiplicity { this, "Multiplicity", 1, "Multiplicity, when >1 all the cuts need to be duplicated" };
-
-  ToolHandle<GenericMonitoringTool> m_monTool { this, "MonTool", "GenericMonitoringTool/MonTool", "Monitoring tool" };
+  
+  ToolHandle< GenericMonitoringTool > m_monTool { this, "MonTool", "", "Monitoring tool" };
+  
+  int findCutIndex( float eta ) const;
 }; 
-
-inline const InterfaceID& TrigL2CaloHypoTool::interfaceID() 
-{ 
-   return IID_TrigL2CaloHypoTool; 
-}
-
-
+DECLARE_TOOL_FACTORY( TrigL2CaloHypoToolInc )
 #endif //> !TRIGEGAMMAHYPO_TRIGL2CALOHYPOTOOL_H
diff --git a/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2CaloHypoToolMult.cxx b/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2CaloHypoToolMult.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..30080dd49fd5c03131fbe841ce66e6b44708a6f0
--- /dev/null
+++ b/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2CaloHypoToolMult.cxx
@@ -0,0 +1,51 @@
+#include "DecisionHandling/Combinators.h"
+#include "DecisionHandling/TrigCompositeUtils.h"
+#include "TrigL2CaloHypoToolMult.h"
+
+using namespace TrigCompositeUtils;
+TrigL2CaloHypoToolMult::TrigL2CaloHypoToolMult( const std::string& type, 
+						const std::string& name, 
+						const IInterface* parent )
+  : base_class( type, name, parent ),
+    m_decisionId( HLT::Identifier::fromToolName( name ) ) {}
+
+TrigL2CaloHypoToolMult::~TrigL2CaloHypoToolMult() {}
+
+StatusCode TrigL2CaloHypoToolMult::initialize() {
+  if(  m_subTools.size() <= 1 ) {
+    ATH_MSG_ERROR( "Number of sub tools " << m_subTools.size() << ", while it has to be > 1, otherwise this is not a multiplicity selection" );
+    return StatusCode::FAILURE;
+  }
+  CHECK( m_subTools.retrieve() );
+  return StatusCode::SUCCESS;
+}
+
+StatusCode TrigL2CaloHypoToolMult::decide( std::vector<ITrigL2CaloHypoTool::ClusterInfo>& input )  const {
+  HLT::Index2DVec passingSelection( m_subTools.size() );
+  ATH_MSG_DEBUG( "Applying selection of multiplicity " << m_subTools.size() );
+
+  size_t cutIndex{ 0 };
+  for ( auto& tool: m_subTools ) {
+    size_t clusterIndex{ 0 };
+    for ( auto iIter =  input.begin(); iIter != input.end(); ++iIter, ++clusterIndex ) {
+      if ( passed( m_decisionId.numeric(), iIter->previousDecisionIDs ) ) {
+	if ( tool->decide( *iIter ) ) 
+	  passingSelection[ cutIndex ].push_back( clusterIndex );
+      }
+    }
+    
+    if ( passingSelection[cutIndex].empty() ) {
+      ATH_MSG_DEBUG( "No object passed selection " << cutIndex << " rejecting" );
+      return StatusCode::SUCCESS;
+    }
+    cutIndex++;
+  }
+  std::set<size_t> passingIndices;
+  HLT::elementsInUniqueCombinations( passingSelection, passingIndices );
+  
+  for ( auto idx: passingIndices ) 
+    addDecisionID( m_decisionId.numeric(), input[idx].decision );
+
+  
+  return StatusCode::SUCCESS;
+}
diff --git a/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2CaloHypoToolMult.h b/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2CaloHypoToolMult.h
new file mode 100644
index 0000000000000000000000000000000000000000..1b69ae5018c6ad77a1be4d931211b3dc0c8cbed7
--- /dev/null
+++ b/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2CaloHypoToolMult.h
@@ -0,0 +1,47 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+#ifndef TRIGEGAMMAHYPO_TRIGL2CALOHYPOTOOLMULT_H
+#define TRIGEGAMMAHYPO_TRIGL2CALOHYPOTOOLMULT_H 1
+
+//#include "GaudiKernel/IAlgTool.h"
+#include "CLHEP/Units/SystemOfUnits.h"
+#include "xAODTrigCalo/TrigEMCluster.h"
+#include "TrigSteeringEvent/TrigRoiDescriptor.h"
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "AthenaMonitoring/GenericMonitoringTool.h"
+#include "DecisionHandling/HLTIdentifier.h"
+#include "DecisionHandling/TrigCompositeUtils.h"
+#include "ITrigL2CaloHypoTool.h"
+
+
+
+/**
+ * @class Implementation of the Egamma selection for CaloClusters with multiplicity
+ * @brief 
+ **/
+
+class TrigL2CaloHypoToolMult : public extends<AthAlgTool, ITrigL2CaloHypoTool> { 
+ public: 
+  TrigL2CaloHypoToolMult( const std::string& type, 
+			  const std::string& name, 
+			  const IInterface* parent );
+
+  virtual ~TrigL2CaloHypoToolMult();
+  virtual StatusCode initialize() override;
+
+  virtual StatusCode decide( std::vector<ITrigL2CaloHypoTool::ClusterInfo>& input )  const override;
+
+  virtual bool decide( const ITrigL2CaloHypoTool::ClusterInfo& ) const { 
+    CHECK( StatusCode::FAILURE );  // this method should never be called
+    return StatusCode::FAILURE;
+  }
+
+ private:
+  HLT::Identifier m_decisionId;
+
+  ToolHandleArray<ITrigL2CaloHypoTool> m_subTools { this, "SubTools", {}, "Sub tools performing cuts" };
+  
+}; 
+DECLARE_TOOL_FACTORY( TrigL2CaloHypoToolMult )
+#endif //> !TRIGEGAMMAHYPO_TRIGL2CALOHYPOTOOLMULT_H
diff --git a/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2ElectronFexMT.h b/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2ElectronFexMT.h
index 9e85e478dc097c1048f893510de2b51144e83b71..a3d780ae44be49278756317fa3be388d48d0e9f6 100755
--- a/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2ElectronFexMT.h
+++ b/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2ElectronFexMT.h
@@ -130,4 +130,5 @@ class TrigL2ElectronFexMT : public AthAlgorithm  {
   ToolHandle<GenericMonitoringTool> m_monTool;
   
 };  
+DECLARE_ALGORITHM_FACTORY( TrigL2ElectronFexMT )
 #endif
diff --git a/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2ElectronHypoAlg.cxx b/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2ElectronHypoAlg.cxx
index 5fbad96b1a5cae23b63355c6f291b60c93e2cc0a..0fefd37a7be50bc2a174de80e814afe5cae10b84 100644
--- a/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2ElectronHypoAlg.cxx
+++ b/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2ElectronHypoAlg.cxx
@@ -15,17 +15,11 @@ using TrigCompositeUtils::linkToPrevious;
 
 TrigL2ElectronHypoAlg::TrigL2ElectronHypoAlg( const std::string& name, 
 			  ISvcLocator* pSvcLocator ) : 
-  ::AthReentrantAlgorithm( name, pSvcLocator )
-{
-  //declareProperty( "Property", m_nProperty );
+  ::AthReentrantAlgorithm( name, pSvcLocator ) {}
 
-}
-
-TrigL2ElectronHypoAlg::~TrigL2ElectronHypoAlg()
-{}
+TrigL2ElectronHypoAlg::~TrigL2ElectronHypoAlg() {}
 
-StatusCode TrigL2ElectronHypoAlg::initialize()
-{
+StatusCode TrigL2ElectronHypoAlg::initialize() {
   ATH_MSG_INFO ( "Initializing " << name() << "..." );
   ATH_CHECK( m_hypoTools.retrieve() );
   
@@ -37,23 +31,12 @@ StatusCode TrigL2ElectronHypoAlg::initialize()
   ATH_CHECK( m_electronsKey.initialize() );
 
 
-
   return StatusCode::SUCCESS;
 }
 
-StatusCode TrigL2ElectronHypoAlg::finalize()
-{
-  ATH_MSG_INFO ( "Finalizing " << name() << "..." );
-
-  return StatusCode::SUCCESS;
-}
 
-StatusCode TrigL2ElectronHypoAlg::execute_r( const EventContext& context ) const
-{  
+StatusCode TrigL2ElectronHypoAlg::execute_r( const EventContext& context ) const {  
   ATH_MSG_DEBUG ( "Executing " << name() << "..." );
-  // obtain electrons
-
-
   
   // prepare decisions container and link back to the clusters, and decision on clusters
   auto decisions = std::make_unique<DecisionContainer>();
@@ -77,7 +60,7 @@ StatusCode TrigL2ElectronHypoAlg::execute_r( const EventContext& context ) const
   ATH_MSG_DEBUG( "Cluster ptr to decision map has size " << clusterToIndexMap.size() );
 
   // prepare imput for tools
-  std::vector<TrigL2ElectronHypoTool::Input> hypoToolInput;
+  std::vector<TrigL2ElectronHypoTool::ElectronInfo> hypoToolInput;
   
   auto viewsHandle = SG::makeHandle( m_views, context );
   for ( auto view: *viewsHandle ) {
@@ -106,24 +89,20 @@ StatusCode TrigL2ElectronHypoAlg::execute_r( const EventContext& context ) const
       DecisionIDContainer clusterDecisionIDs;
       decisionIDs( clusterDecisions->at( origCluster->second ), clusterDecisionIDs );
       
-      hypoToolInput.emplace_back( TrigL2ElectronHypoTool::Input{ d, *electronIter,  origCluster->first, clusterDecisionIDs } );
+      hypoToolInput.emplace_back( TrigL2ElectronHypoTool::ElectronInfo{ d, *electronIter,  origCluster->first, clusterDecisionIDs } );
     }
   }
-  
 
   for ( auto & tool: m_hypoTools ) {
     ATH_CHECK( tool->decide( hypoToolInput ) );
     
   } 
 
-  
-
   {
     auto handle =  SG::makeHandle( m_decisionsKey, context );
     CHECK( handle.record( std::move( decisions ), std::move( aux ) ) );
   }
 
-
   return StatusCode::SUCCESS;
 }
 
diff --git a/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2ElectronHypoAlg.h b/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2ElectronHypoAlg.h
index 305c584e462b9b2b2f50eef869675249ce97dca4..98bf7f5e23da1b740c25bb1f32d438f1f1163d80 100644
--- a/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2ElectronHypoAlg.h
+++ b/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2ElectronHypoAlg.h
@@ -27,12 +27,9 @@ class TrigL2ElectronHypoAlg
 
   virtual ~TrigL2ElectronHypoAlg(); 
 
+  virtual StatusCode  initialize() override;
+  virtual StatusCode  execute_r(const EventContext& context) const override;
 
-  //TrigL2ElectronHypoAlg &operator=(const TrigL2ElectronHypoAlg &alg); 
-
-  StatusCode  initialize() override;
-  StatusCode  execute_r(const EventContext& context) const override;
-  StatusCode  finalize() override;
  
  private: 
   TrigL2ElectronHypoAlg();
@@ -46,9 +43,7 @@ class TrigL2ElectronHypoAlg
   // internally used to getch from views
   SG::ReadHandleKey< xAOD::TrigElectronContainer > m_electronsKey {this, "Electrons", "L2ElectronContainer", "Input"};
 
-
-
 }; 
-
+DECLARE_ALGORITHM_FACTORY( TrigL2ElectronHypoAlg )
 
 #endif //> !TRIGEGAMMAHYPO_TRIGL2ELECTRONHYPOALG_H
diff --git a/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2ElectronHypoTool.cxx b/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2ElectronHypoTool.cxx
index 858b24c8ec4e8b717ff450478a42c93ec1089704..482dbb8aa35aee1fc84bcd5408c98c5ab8dd28e3 100644
--- a/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2ElectronHypoTool.cxx
+++ b/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2ElectronHypoTool.cxx
@@ -11,11 +11,10 @@
 using namespace TrigCompositeUtils;
 
 TrigL2ElectronHypoTool::TrigL2ElectronHypoTool( const std::string& type, 
-		    const std::string& name, 
-		    const IInterface* parent ) :
-  AthAlgTool( type, name, parent ),
-  m_decisionId( HLT::Identifier::fromToolName( name ) )
-{}
+						const std::string& name, 
+						const IInterface* parent ) 
+  : AthAlgTool( type, name, parent ),
+    m_decisionId( HLT::Identifier::fromToolName( name ) ) {}
 
 StatusCode TrigL2ElectronHypoTool::initialize()  {
   
@@ -34,7 +33,6 @@ StatusCode TrigL2ElectronHypoTool::initialize()  {
   std::vector<size_t> sizes( {m_trackPt.size(), m_caloTrackDEta.size(), m_caloTrackDPhi.size(), m_caloTrackdEoverPLow.size(), m_caloTrackdEoverPHigh.size(), m_trtRatio.size() } );
 
 
-
   if ( *std::min_element( sizes.begin(), sizes.end() ) != *std::max_element( sizes.begin(), sizes.end() )  ) {
     ATH_MSG_ERROR( "Missconfiguration, cut properties listed above ( when DEBUG ) have different dimensions shortest: " <<  *std::min_element( sizes.begin(), sizes.end() ) << " longest " << *std::max_element( sizes.begin(), sizes.end() ) );
     return StatusCode::FAILURE;
@@ -46,12 +44,8 @@ StatusCode TrigL2ElectronHypoTool::initialize()  {
   return StatusCode::SUCCESS;
 }
 
-StatusCode TrigL2ElectronHypoTool::finalize()  {
-  return StatusCode::SUCCESS;
-}
 
-TrigL2ElectronHypoTool::~TrigL2ElectronHypoTool()
-{}
+TrigL2ElectronHypoTool::~TrigL2ElectronHypoTool() {}
 
 bool TrigL2ElectronHypoTool::decideOnSingleObject( const xAOD::TrigElectron* electron, 
 						   size_t cutIndex ) const {
@@ -90,7 +84,7 @@ bool TrigL2ElectronHypoTool::decideOnSingleObject( const xAOD::TrigElectron* ele
   float NStrawHits  = ( float )( electron->nTRTHiThresholdHits() );
   float TRTHitRatio = NStrawHits == 0 ? 1e10 : NTRHits/NStrawHits;
 
-  ATH_MSG_VERBOSE("Cut index " << cutIndex );
+  ATH_MSG_VERBOSE( "Cut index " << cutIndex );
   if ( ptCalo < m_trackPt[cutIndex] ){ 
     ATH_MSG_VERBOSE( "Fails pt cut" << ptCalo << " < " << m_trackPt[cutIndex] );
     return  false;
@@ -123,12 +117,12 @@ bool TrigL2ElectronHypoTool::decideOnSingleObject( const xAOD::TrigElectron* ele
     return  false;
   }
   cutCounter++;
-  ATH_MSG_DEBUG("Passed selection");
+  ATH_MSG_DEBUG( "Passed selection" );
   return  true;
 
 }
 
-StatusCode TrigL2ElectronHypoTool::inclusiveSelection( std::vector<Input>& input ) const {
+StatusCode TrigL2ElectronHypoTool::inclusiveSelection( std::vector<ElectronInfo>& input ) const {
     for ( auto i: input ) {
       if ( m_respectPreviousDecision 
 	   and ( i.previousDecisionIDs.count( m_decisionId.numeric() ) == 0 ) ) continue; // the decision was negative or not even made in previous stage
@@ -142,7 +136,7 @@ StatusCode TrigL2ElectronHypoTool::inclusiveSelection( std::vector<Input>& input
 }
 
 
-StatusCode TrigL2ElectronHypoTool::markPassing( std::vector<Input>& input, const std::set<size_t>& passing ) const {
+StatusCode TrigL2ElectronHypoTool::markPassing( std::vector<ElectronInfo>& input, const std::set<size_t>& passing ) const {
 
   for ( auto idx: passing ) 
     addDecisionID( m_decisionId.numeric(), input[idx].decision );
@@ -150,19 +144,19 @@ StatusCode TrigL2ElectronHypoTool::markPassing( std::vector<Input>& input, const
 }
 
 
-StatusCode TrigL2ElectronHypoTool::multiplicitySelection( std::vector<Input>& input ) const {
+StatusCode TrigL2ElectronHypoTool::multiplicitySelection( std::vector<ElectronInfo>& input ) const {
   HLT::Index2DVec passingSelection( m_multiplicity );
   
   for ( size_t cutIndex = 0; cutIndex < m_multiplicity; ++ cutIndex ) {
-    size_t elIndex = 0;
+    size_t elIndex{ 0 };
     for ( auto elIter =  input.begin(); elIter != input.end(); ++elIter, ++elIndex ) {
-      if ( m_respectPreviousDecision 
-	   and ( elIter->previousDecisionIDs.count( m_decisionId.numeric() ) == 0 ) ) continue;
-
-      if ( decideOnSingleObject( elIter->electron, cutIndex ) ) 
-	passingSelection[cutIndex].push_back( elIndex );
+      if ( passed( m_decisionId.numeric(), elIter->previousDecisionIDs ) ) {	
+	if ( decideOnSingleObject( elIter->electron, cutIndex ) ) {
+	  passingSelection[cutIndex].push_back( elIndex );
+	}
+      }
     }
-    // checking if by chance noe of the objects passed the single obj selection, if so there will be no valid combination and we can skip
+    // checking if by chance none of the objects passed the single obj selection, if so there will be no valid combination and we can skip
     if ( passingSelection[cutIndex].empty() ) {
       ATH_MSG_DEBUG( "No object passed selection " << cutIndex << " rejecting" );
       return StatusCode::SUCCESS;
@@ -193,7 +187,7 @@ StatusCode TrigL2ElectronHypoTool::multiplicitySelection( std::vector<Input>& in
   return markPassing( input, passingIndices );
 }
 
-StatusCode TrigL2ElectronHypoTool::decide(  std::vector<Input>& input )  const{
+StatusCode TrigL2ElectronHypoTool::decide(  std::vector<ElectronInfo>& input )  const {
   // handle the simplest and most common case ( multiplicity == 1 ) in easiest possible manner
   if ( m_trackPt.size() == 1 ) {
     return inclusiveSelection( input );
diff --git a/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2ElectronHypoTool.h b/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2ElectronHypoTool.h
index c5effd8f20e23376f19a4d07215887f53595d065..5169c3a379917e62dba65bea9639eb05455e3f52 100644
--- a/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2ElectronHypoTool.h
+++ b/Trigger/TrigHypothesis/TrigEgammaHypo/src/TrigL2ElectronHypoTool.h
@@ -14,16 +14,12 @@
 #include "DecisionHandling/TrigCompositeUtils.h"
 
 
-static const InterfaceID IID_TrigL2ElectronHypoTool("TrigL2ElectronHypoTool", 1, 0);
-
 /**
  * @class Implementation of the Egamma selection for CaloClusters
  * @brief 
  **/
 
-
-class TrigL2ElectronHypoTool
-  : virtual public ::AthAlgTool
+class TrigL2ElectronHypoTool : virtual public ::AthAlgTool
 { 
  public: 
   TrigL2ElectronHypoTool( const std::string& type, 
@@ -31,13 +27,11 @@ class TrigL2ElectronHypoTool
 			  const IInterface* parent );
 
   virtual ~TrigL2ElectronHypoTool();
-  StatusCode initialize() override;
-  StatusCode finalize() override;
+  virtual StatusCode initialize() override;
 
-  static const InterfaceID& interfaceID();
 
 
-  struct Input {
+  struct ElectronInfo {
     TrigCompositeUtils::Decision* decision;
     const xAOD::TrigElectron* electron;
     const xAOD::TrigEMCluster* cluster;
@@ -47,7 +41,7 @@ class TrigL2ElectronHypoTool
   /**
    * @brief decides upon a collection of electrons
    **/
-  StatusCode decide( std::vector<Input>& decisions )  const;
+  StatusCode decide( std::vector<ElectronInfo>& decisions )  const;
 
   /**
    * @brief Auxiluary method, single electron selection
@@ -55,20 +49,20 @@ class TrigL2ElectronHypoTool
   bool decideOnSingleObject( const xAOD::TrigElectron* electron, size_t cutIndex ) const;
 
   /**
-   * @brief actual implementation of decide, in case of inclusive selection (one object cut)
+   * @brief actual implementation of decide, in case of inclusive selection ( one object cut )
    **/
-  StatusCode inclusiveSelection( std::vector<Input>& input ) const;
+  StatusCode inclusiveSelection( std::vector<ElectronInfo>& input ) const;
 
   /**
-   * @brief actual implementation of decide, in case of multiple objects selection (independentone)
+   * @brief actual implementation of decide, in case of multiple objects selection ( independentone )
    **/
-  StatusCode multiplicitySelection( std::vector<Input>& input ) const;
+  StatusCode multiplicitySelection( std::vector<ElectronInfo>& input ) const;
 
   /**
    * @brief stores decisions for all object passing multiple cuts
    * The passsingSelection inner vectors have to have size == input size
    **/
-  StatusCode markPassing( std::vector<Input>& input, const std::set<size_t>& passing ) const;
+  StatusCode markPassing( std::vector<ElectronInfo>& input, const std::set<size_t>& passing ) const;
 
 
 
@@ -76,11 +70,11 @@ class TrigL2ElectronHypoTool
   
  private:
   HLT::Identifier m_decisionId;
-  Gaudi::Property<bool>  m_decisionPerCluster{ this, "DecisionPerCluster", true, "Is multiplicity requirement refering to electrons (false) or RoIs/clusters with electrons (false), relevant only in when multiplicity > 1" };
+  Gaudi::Property<bool>  m_decisionPerCluster{ this, "DecisionPerCluster", true, "Is multiplicity requirement refering to electrons ( false ) or RoIs/clusters with electrons ( false ), relevant only in when multiplicity > 1" };
 
-  Gaudi::Property<bool>  m_respectPreviousDecision{ this, "RespectPreviousDecision", false, "If false, (do not even check), the decision made for the cluster" };
+  Gaudi::Property<bool>  m_respectPreviousDecision{ this, "RespectPreviousDecision", false, "If false, ( do not even check ), the decision made for the cluster" };
   Gaudi::Property<bool>  m_acceptAll{ this, "AcceptAll", false, "Ignore selection" };
-  Gaudi::Property< std::vector<float> > m_trackPt{ this, "TrackPt",  { float(5.0*CLHEP::GeV) }, "Track pT requirement (separate threshold for each electron)" };
+  Gaudi::Property< std::vector<float> > m_trackPt{ this, "TrackPt",  { float( 5.0*CLHEP::GeV ) }, "Track pT requirement ( separate threshold for each electron )" };
   Gaudi::Property< std::vector<float> > m_caloTrackDEta{ this,  "CaloTrackdETA", {0}, "Delta Eta between the track and cluster"      }; //loose cut
   Gaudi::Property< std::vector<float> > m_caloTrackDPhi{ this,  "CaloTrackdPHI", {0}, "Delta Phi between track and cluster"     }; //loose cut
   Gaudi::Property< std::vector<float> > m_caloTrackdEoverPLow{ this,  "CaloTrackdEoverPLow", {0}, "Min E over Pt cut "};
@@ -93,10 +87,5 @@ class TrigL2ElectronHypoTool
   ToolHandle<GenericMonitoringTool> m_monTool{ this, "MonTool", "", "Monitoring tool" };
 }; 
 
-inline const InterfaceID& TrigL2ElectronHypoTool::interfaceID() 
-{ 
-   return IID_TrigL2ElectronHypoTool; 
-}
-
-
+DECLARE_TOOL_FACTORY( TrigL2ElectronHypoTool )
 #endif //> !TRIGEGAMMAHYPO_TRIGL2CALOHYPOTOOL_H
diff --git a/Trigger/TrigHypothesis/TrigEgammaHypo/src/components/TrigEgammaHypo_entries.cxx b/Trigger/TrigHypothesis/TrigEgammaHypo/src/components/TrigEgammaHypo_entries.cxx
index edabee8140ceacd1551f8e459864888201a6e443..195a11411260fa611d40a2aa6fecc9db4610bdb3 100755
--- a/Trigger/TrigHypothesis/TrigEgammaHypo/src/components/TrigEgammaHypo_entries.cxx
+++ b/Trigger/TrigHypothesis/TrigEgammaHypo/src/components/TrigEgammaHypo_entries.cxx
@@ -14,18 +14,12 @@
 #include "TrigEgammaHypo/TrigL2PhotonFex.h"
 #include "TrigEgammaHypo/TrigL2CaloLayersHypo.h"
 
-#include "../TrigL2CaloHypoAlg.h"
-#include "../TrigL2CaloHypoTool.h"
-#include "../TrigL2ElectronFexMT.h"
-#include "../TrigL2ElectronHypoAlg.h"
-#include "../TrigL2ElectronHypoTool.h"
 
 #include "GaudiKernel/DeclareFactoryEntries.h"
 
 
 DECLARE_ALGORITHM_FACTORY( TrigL2CaloHypo )
 DECLARE_ALGORITHM_FACTORY( TrigL2ElectronFex )
-DECLARE_ALGORITHM_FACTORY( TrigL2ElectronFexMT )
 DECLARE_ALGORITHM_FACTORY( TrigL2ElectronHypo )
 DECLARE_ALGORITHM_FACTORY( TrigL2PhotonFex )
 DECLARE_ALGORITHM_FACTORY( TrigL2PhotonHypo )
@@ -38,31 +32,10 @@ DECLARE_ALGORITHM_FACTORY( TrigEFElectronHypo )
 DECLARE_ALGORITHM_FACTORY( TrigEFPhotonHypo )
 DECLARE_ALGORITHM_FACTORY( TrigEFTrackHypo )
 DECLARE_ALGORITHM_FACTORY( TrigL2CaloLayersHypo )
-DECLARE_ALGORITHM_FACTORY( TrigL2CaloHypoAlg )
-DECLARE_TOOL_FACTORY( TrigL2CaloHypoTool )
-DECLARE_ALGORITHM_FACTORY( TrigL2ElectronHypoAlg )
-DECLARE_TOOL_FACTORY( TrigL2ElectronHypoTool )
 
-DECLARE_FACTORY_ENTRIES( TrigEgammaHypo ) {
-    DECLARE_ALGORITHM( TrigL2CaloHypo )
-    DECLARE_ALGORITHM( TrigL2ElectronFex )
-    DECLARE_ALGORITHM( TrigL2ElectronFexMT )
-    DECLARE_ALGORITHM( TrigL2ElectronHypo )
-    DECLARE_ALGORITHM( TrigL2PhotonFex )
-    DECLARE_ALGORITHM( TrigL2PhotonHypo )
-    DECLARE_ALGORITHM( TrigEFDielectronMassHypo )
-    DECLARE_ALGORITHM( TrigEFDielectronMassFex )
-    DECLARE_ALGORITHM( TrigEFMtAllTE )
-    DECLARE_ALGORITHM( TrigEFCaloCalibFex )
-    DECLARE_ALGORITHM( TrigEFCaloHypo )
-    DECLARE_ALGORITHM( TrigEFElectronHypo )
-    DECLARE_ALGORITHM( TrigEFPhotonHypo )
-    DECLARE_ALGORITHM( TrigEFTrackHypo )
-    DECLARE_ALGORITHM( TrigL2CaloLayersHypo )
-    DECLARE_ALGORITHM( TrigL2CaloHypoAlg )
-    DECLARE_TOOL( TrigL2CaloHypoTool )
-    DECLARE_ALGORITHM( TrigL2ElectronHypoAlg )
-    DECLARE_TOOL( TrigL2ElectronHypoTool )
 
-}
+
+
+
+
 
diff --git a/Trigger/TrigSteer/DecisionHandling/DecisionHandling/TrigCompositeUtils.h b/Trigger/TrigSteer/DecisionHandling/DecisionHandling/TrigCompositeUtils.h
index 7f41320f4980748fb2331a00e43a7e0e6f6dd2df..d3b4dab9b8c1b88e2311bc2d14aade0160d768c5 100644
--- a/Trigger/TrigSteer/DecisionHandling/DecisionHandling/TrigCompositeUtils.h
+++ b/Trigger/TrigSteer/DecisionHandling/DecisionHandling/TrigCompositeUtils.h
@@ -62,6 +62,13 @@ namespace TrigCompositeUtils {
    **/
   void decisionIDs( const Decision* d, DecisionIDContainer& id );
 
+  /**
+   * @brief Another variant of the above method
+   **/
+  const std::vector<int>& decisionIDs( const Decision* d ); 
+  std::vector<int>& decisionIDs( Decision* d );
+
+
   /**
    * @brief return true if thre is no positive decision stored
    **/
@@ -72,7 +79,11 @@ namespace TrigCompositeUtils {
    **/
   bool passingIDs( const Decision* d,  const DecisionIDContainer& required);
 
-
+  /**
+   * @brief checks if required ID is in the set of the decisions
+   **/
+  bool passed( DecisionID id, const DecisionIDContainer& );
+  
   /**
    * @brief Links to the previous object
    **/
diff --git a/Trigger/TrigSteer/DecisionHandling/src/DumpDecisions.cxx b/Trigger/TrigSteer/DecisionHandling/src/DumpDecisions.cxx
index 9898df207fe95f08fd7a7b0d8c6b1f28865014d3..f05fdb890ec8edee689c0411cf31e05a2766fb08 100644
--- a/Trigger/TrigSteer/DecisionHandling/src/DumpDecisions.cxx
+++ b/Trigger/TrigSteer/DecisionHandling/src/DumpDecisions.cxx
@@ -62,26 +62,3 @@ StatusCode DumpDecisions:: execute_r( const EventContext& ctx ) const {
   }
   return StatusCode::SUCCESS;
 }
-  
-
-/////////////////////////////////////////////////////////////////// 
-// Const methods: 
-///////////////////////////////////////////////////////////////////
-
-/////////////////////////////////////////////////////////////////// 
-// Non-const methods: 
-/////////////////////////////////////////////////////////////////// 
-
-/////////////////////////////////////////////////////////////////// 
-// Protected methods: 
-/////////////////////////////////////////////////////////////////// 
-
-/////////////////////////////////////////////////////////////////// 
-// Const methods: 
-///////////////////////////////////////////////////////////////////
-
-/////////////////////////////////////////////////////////////////// 
-// Non-const methods: 
-/////////////////////////////////////////////////////////////////// 
-
-
diff --git a/Trigger/TrigSteer/DecisionHandling/src/DumpDecisions.h b/Trigger/TrigSteer/DecisionHandling/src/DumpDecisions.h
index e335311a8b3a811aa47649c720ee268a0857b4cc..71ec3ce57ac56ece71b872d08a6fbd93d72b6524 100644
--- a/Trigger/TrigSteer/DecisionHandling/src/DumpDecisions.h
+++ b/Trigger/TrigSteer/DecisionHandling/src/DumpDecisions.h
@@ -36,7 +36,7 @@ class DumpDecisions
  private: 
 
   SG::ReadHandleKey<TrigCompositeUtils::DecisionContainer> m_decisionKey{ this, "Decisions", "Unspecified", "Input Decisions to dump" };
-  Gaudi::Property<size_t> m_verbosityLevel{ "VerbosityLevel", 3, "3 - tries to print as much possible, 2 - only list of objects and their decisions, 1 - only list of active objets" };
+  Gaudi::Property<size_t> m_verbosityLevel{ "VerbosityLevel", 3, "3 - tries to print as much possible, 2 - only list of objects and their decisions, 1 - only list of active objects" };
 
   /// Default constructor: 
   DumpDecisions();
diff --git a/Trigger/TrigSteer/DecisionHandling/src/TrigCompositeUtils.cxx b/Trigger/TrigSteer/DecisionHandling/src/TrigCompositeUtils.cxx
index 4d2c911655ca7e4c74acef9d25df65077d1da67d..9f7eb47855b75c21d062cba9fa544a3a72c0cb5a 100644
--- a/Trigger/TrigSteer/DecisionHandling/src/TrigCompositeUtils.cxx
+++ b/Trigger/TrigSteer/DecisionHandling/src/TrigCompositeUtils.cxx
@@ -42,6 +42,14 @@ namespace TrigCompositeUtils {
     destination.insert( decisions.begin(), decisions.end() );
   }
 
+  const std::vector<int>& decisionIDs( const Decision* d ) {    
+    return readOnlyAccessor( *d );    
+  }
+
+  std::vector<int>& decisionIDs( Decision* d ) {
+    return readWriteAccessor( *d );
+  }
+
   bool allFailed( const Decision* d ) {
     const std::vector<int>& decisions = readOnlyAccessor( *d );    
     return decisions.empty();
@@ -55,6 +63,9 @@ namespace TrigCompositeUtils {
     return false;
   }    
 
+  bool passed( DecisionID id, const DecisionIDContainer& idSet ) {
+    return idSet.count( id ) != 0;
+  }
 
   bool passingIDs( const Decision* d,  const DecisionIDContainer& required );
 
diff --git a/Trigger/TrigValidation/TrigUpgradeTest/python/TestUtils.py b/Trigger/TrigValidation/TrigUpgradeTest/python/TestUtils.py
index 3e50f3ef926f05fdce0560da9e23860b759852f9..c1f960bcdb2dce1d16eeaa477de7061b62d1270e 100644
--- a/Trigger/TrigValidation/TrigUpgradeTest/python/TestUtils.py
+++ b/Trigger/TrigValidation/TrigUpgradeTest/python/TestUtils.py
@@ -13,15 +13,21 @@ def writeEmulationFiles(data):
 # Testing menu used in the L1 decoders
 class MenuTest:
     CTPToChainMapping = ["0:HLT_e3_etcut",
+                         "0:HLT_e5_etcut"
                          "0:HLT_g5_etcut",
                          "1:HLT_e7_etcut",
                          "23:HLT_2e3_etcut",
+                         "23:HLT_e3e5_etcut",
                          "15:HLT_mu6",
                          "33:HLT_2mu6",
                          "15:HLT_mu6idperf",
                          "42:HLT_e15mu4"]
 
     EMThresholdToChainMapping = ["EM3 : HLT_e3_etcut",
+                                 "EM3 : HLT_e5_etcut",
+                                 "EM3 : HLT_2e3_etcut",
+                                 "EM3 : HLT_e3e5_etcut",
+                                 "EM5 : HLT_e3e5_etcut",
                                  "EM3 : HLT_g5_etcut",
                                  "EM7 : HLT_e7_etcut",
                                  "EM15 : HLT_e15mu4_etcut"]
diff --git a/Trigger/TrigValidation/TrigUpgradeTest/share/egamma.withViews.py b/Trigger/TrigValidation/TrigUpgradeTest/share/egamma.withViews.py
index 124d0c7f26e26f6e2aa81c1f90739804ff41671a..f6267a7945fd61386422664d4679d98bfaa01bfe 100644
--- a/Trigger/TrigValidation/TrigUpgradeTest/share/egamma.withViews.py
+++ b/Trigger/TrigValidation/TrigUpgradeTest/share/egamma.withViews.py
@@ -35,14 +35,11 @@ if viewTest:
 
 from InDetRecExample.InDetKeys import InDetKeys
 
-
 # provide a minimal menu information
-#topSequence.L1DecoderTest.ctpUnpacker.CTPToChainMapping = ['0:HLT_e3', '0:HLT_e5', '1:HLT_e7', '1:HLT_e10']
-topSequence.L1DecoderTest.ctpUnpacker.OutputLevel=DEBUG
 
-#topSequence.L1DecoderTest.roiUnpackers[0].ThresholdToChainMapping = ['EM3 : HLT_e3', 'EM3 : HLT_e5', 'EM7 : HLT_e7', 'EM7 : HLT_e10']
+topSequence.L1DecoderTest.ctpUnpacker.OutputLevel=DEBUG
 topSequence.L1DecoderTest.roiUnpackers[0].OutputLevel=DEBUG
-#topSequence.L1DecoderTest.roi[].ThresholdToChainMapping = ['EM3 : HLT_e3', 'EM3 : HLT_e5', 'EM7 : HLT_e7', 'EM7 : HLT_e10']
+testChains = ["HLT_e3_etcut", "HLT_e5_etcut", "HLT_e7_etcut", "HLT_2e3_etcut", "HLT_e3e5_etcut"]
 
 
 from TrigT2CaloEgamma.TrigT2CaloEgammaConfig import T2CaloEgamma_FastAlgo
@@ -53,15 +50,14 @@ svcMgr.ToolSvc.TrigDataAccess.ApplyOffsetCorrection=False
 
 from AthenaCommon.CFElements import parOR, seqAND, stepSeq
 
-from DecisionHandling.DecisionHandlingConf import RoRSeqFilter
-
+from DecisionHandling.DecisionHandlingConf import RoRSeqFilter, DumpDecisions
 
 from ViewAlgs.ViewAlgsConf import EventViewCreatorAlgorithm
 if viewTest:
   filterL1RoIsAlg = RoRSeqFilter("filterL1RoIsAlg")
   filterL1RoIsAlg.Input = ["EMRoIDecisions"]
   filterL1RoIsAlg.Output = ["FilteredEMRoIDecisions"]
-  filterL1RoIsAlg.Chains = ["HLT_e5_etcut", "HLT_e7_etcut"]
+  filterL1RoIsAlg.Chains = testChains
   filterL1RoIsAlg.OutputLevel = DEBUG
   
   allViewAlgorithms += theFastCaloAlgo
@@ -80,17 +76,22 @@ if viewTest:
   from TrigEgammaHypo.TrigL2CaloHypoTool import TrigL2CaloHypoToolFromName
   theFastCaloHypo = TrigL2CaloHypoAlg("L2CaloHypo")
   theFastCaloHypo.OutputLevel = DEBUG
+  theFastCaloHypo.L1Decisions = "EMRoIDecisions"
   theFastCaloHypo.Views = l2CaloViewsMaker.Views
   theFastCaloHypo.CaloClusters = theFastCaloAlgo.ClustersName
   theFastCaloHypo.RoIs = l2CaloViewsMaker.InViewRoIs
   theFastCaloHypo.Decisions = "EgammaCaloDecisions"
-  theFastCaloHypo.HypoTools =  [ TrigL2CaloHypoToolFromName("HLT_e5_etcut"),   TrigL2CaloHypoToolFromName("HLT_e7_etcut") ]
+  theFastCaloHypo.HypoTools =  [ TrigL2CaloHypoToolFromName( c ) for c in testChains ]
+#[ TrigL2CaloHypoToolFromName("HLT_e5_etcut"),   TrigL2CaloHypoToolFromName("HLT_e7_etcut") , TrigL2CaloHypoToolFromName("HLT_2e3_etcut"), TrigL2CaloHypoToolFromName("HLT_e3e5_etcut") ]
+
   for t in theFastCaloHypo.HypoTools:
     t.OutputLevel = DEBUG
 
   # topSequence += theFastCaloHypo
 
-  egammaCaloStep = stepSeq("egammaCaloStep", filterL1RoIsAlg, [ l2CaloViewsMaker, theFastCaloHypo ])
+  caloDecisionsDumper = DumpDecisions("caloDecisionsDumper", OutputLevel=DEBUG, Decisions = theFastCaloHypo.Decisions )  
+
+  egammaCaloStep = stepSeq("egammaCaloStep", filterL1RoIsAlg, [ l2CaloViewsMaker, theFastCaloHypo, caloDecisionsDumper ])
 
 else:
   topSequence += theFastCaloAlgo
@@ -275,7 +276,7 @@ if viewTest:
   filterCaloRoIsAlg = RoRSeqFilter("filterCaloRoIsAlg")
   filterCaloRoIsAlg.Input = [theFastCaloHypo.Decisions]
   filterCaloRoIsAlg.Output = ["Filtered"+theFastCaloHypo.Decisions]
-  filterCaloRoIsAlg.Chains = ["HLT_e5_etcut", "HLT_e7_etcut"]
+  filterCaloRoIsAlg.Chains = testChains
   filterCaloRoIsAlg.OutputLevel = DEBUG
 
 
@@ -311,12 +312,13 @@ if viewTest:
   theElectronHypo.ClusterDecisions = theFastCaloHypo.Decisions 
   theElectronHypo.ElectronDecisions = "ElectronL2Decisions"
   theElectronHypo.OutputLevel = VERBOSE
-  theElectronHypo.HypoTools = [ TrigL2ElectronHypoToolFromName("HLT_e5_etcut"), TrigL2ElectronHypoToolFromName("HLT_e7_etcut") ]
+  theElectronHypo.HypoTools = [ TrigL2ElectronHypoToolFromName( c ) for c in testChains ]
+
   for t in theElectronHypo.HypoTools:
     t.OutputLevel = VERBOSE
   # topSequence += theElectronHypo
-  
-  egammaIDStep = stepSeq("egammaIDStep", filterCaloRoIsAlg, [ l2ElectronViewsMaker, theElectronHypo ] )
+  electronDecisionsDumper = DumpDecisions("electronDecisionsDumper", OutputLevel=DEBUG, Decisions = theElectronHypo.ElectronDecisions )    
+  egammaIDStep = stepSeq("egammaIDStep", filterCaloRoIsAlg, [ l2ElectronViewsMaker, theElectronHypo, electronDecisionsDumper ] )
 
 else:
   # ID algs can't run w/o views yet