diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/AllJetsGrouper.h b/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/AllJetsGrouper.h
index f2d3190d77eb6e892d1f91ce9262b4ba3c696524..9bc4ae4008f925838d45a82f05162d0f03d551de 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/AllJetsGrouper.h
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/AllJetsGrouper.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRIGHLTJETHYPO_ALLJETSGROUPER_H
@@ -9,12 +9,21 @@
 
 class AllJetsGrouper: public IJetGrouper{
  public:
+  AllJetsGrouper();
+  AllJetsGrouper(const HypoJetIter& b, const HypoJetIter& e);
+  AllJetsGrouper(const HypoJetVector&);
+  
   std::vector<HypoJetGroupVector> group(HypoJetIter&,
 					HypoJetIter&) const override;
   
-  std::optional<HypoJetGroupVector> next(HypoJetIter&,
-					 HypoJetIter&) const override;
+  std::optional<HypoJetGroupVector> next();
+  
   std::string getName() const override; 
   std::string toString() const override;
+
+private:
+  HypoJetVector m_jets{};
+  bool m_done{false};
+
 };
 #endif
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/CombinationsGrouper.h b/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/CombinationsGrouper.h
index 72b1b60b62cf920812a9ea56241e84afc68bafb5..57f5f57d3a091299d112f793eaee4943df6a2a16 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/CombinationsGrouper.h
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/CombinationsGrouper.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRIGHLTJETHYPO_COMBINATIONSGROUPER_H
@@ -9,14 +9,26 @@
 
 class CombinationsGrouper: public IJetGrouper{
  public:
+  CombinationsGrouper();
+
   CombinationsGrouper(unsigned int);
+
+  CombinationsGrouper(unsigned int, const HypoJetVector&);
+
+  CombinationsGrouper(unsigned int,
+		      const HypoJetCIter& b,
+		      const HypoJetCIter& e
+		      );
+  
   std::vector<HypoJetGroupVector> group(HypoJetIter&,
 					HypoJetIter&) const override;
-  std::optional<HypoJetGroupVector> next(HypoJetIter&,
-					 HypoJetIter&) const override;
+  std::optional<HypoJetGroupVector> next() override;
+
   std::string getName() const override; 
   std::string toString() const override;
  private:
   unsigned int m_groupSize;
+  HypoJetVector m_jets;
+
 };
 #endif
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/IJetGrouper.h b/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/IJetGrouper.h
index ba22e5f47ac904357c71fa2fa9fbe0ca2b058ff0..5830516dece0a3cebb3cfb0e2a479cd43f06e47e 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/IJetGrouper.h
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/IJetGrouper.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRIGHLTJETHYPO_IJETGROUPER_H
@@ -25,8 +25,7 @@ class IJetGrouper{
    */
   virtual std::vector<HypoJetGroupVector> group(HypoJetIter&,
 						HypoJetIter&) const = 0;
-  virtual std::optional<HypoJetGroupVector> next(HypoJetIter&,
-						 HypoJetIter&) const = 0;
+  virtual std::optional<HypoJetGroupVector> next() = 0;
   virtual std::string toString() const = 0; 
   virtual std::string getName() const = 0; 
 };
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/IndexedJetsGrouper.h b/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/IndexedJetsGrouper.h
index 64bcbd240c5590793bdb816bef9bddd6f0f06022..e26d29639fe834fea8aefe375a13160799005102 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/IndexedJetsGrouper.h
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/IndexedJetsGrouper.h
@@ -22,18 +22,27 @@
 class IndexedJetsGrouper: public IJetGrouper{
   /* Select jets ordered all jets in descnding Et at goven index positions.*/
 public:
+  IndexedJetsGrouper(const std::vector<unsigned int>& indices,
+		     const HypoJetVector& jets);
+
+  IndexedJetsGrouper(const std::vector<unsigned int>& indices,
+		     const HypoJetCIter& b,
+		     const HypoJetCIter& e);
+
   IndexedJetsGrouper(const std::vector<unsigned int>& indices);
+
   virtual ~IndexedJetsGrouper(){}
 
   std::vector<HypoJetGroupVector>
-    group(HypoJetIter&, HypoJetIter&) const override;
-
-    std::optional<HypoJetGroupVector> next(HypoJetIter&,
-					 HypoJetIter&) const override;
-    
+  group(HypoJetIter&, HypoJetIter&) const override;
+  
+  std::optional<HypoJetGroupVector> next() override;
+      
   std::string getName() const override;
   std::string toString() const override;
 private:
-  std::vector<unsigned int> m_indices;
+  std::vector<unsigned int> m_indices{};
+  HypoJetVector m_jets{};
+  bool m_done{false};
 };
 #endif
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/PartitionsGrouper.h b/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/PartitionsGrouper.h
deleted file mode 100644
index ff5a2c0241b40670de51db183039bab7386bd3ad..0000000000000000000000000000000000000000
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/PartitionsGrouper.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
-*/
-
-#ifndef TRIGHLTJETHYPO_PARTITIONSGROUPER_H
-#define TRIGHLTJETHYPO_PARTITIONSGROUPER_H
-
-/*
- * Find all non-overlapping allocation of jet groups to conditions.
- * The number pf jets needed by a contition is input.
- *
- * std::vector<HypoJetGroupVector is a vector of ..
- *  ... a vector of a vector of jet indicies.
- * The permutations engine finds all the index  allocactions of jets to
- * condtions. Schematically, if the engine is told that c0 needs 2 jets
- * and c3 needs 3 jets,
- *
- * (i0, i1) (i3, i4, i5) assigns indices i0, i1 to c0 and  i3, i4, i5
- * to c1.
- * There will be many such assignments. The next one may be
- * (i0, i2) (i1, i3, i4)
- */
-
-
-#include "TrigHLTJetHypo/TrigHLTJetHypoUtils/IJetGrouper.h"
-#include <vector>
-#include <fstream>
-
-class PartitionsGrouper: public IJetGrouper{
- public:
-  PartitionsGrouper(const std::vector<std::size_t>& mults);
-  std::vector<HypoJetGroupVector> group(HypoJetIter&,
-					HypoJetIter&) const override;
-  
-  std::optional<HypoJetGroupVector> next(HypoJetIter&,
-					 HypoJetIter&) const override;
-  std::string getName() const override; 
-  std::string toString() const override;
- private:
-
-  // m_mults entry at position i gives the number of jets required by the
-  // ith condition.
-  std::vector<std::size_t> m_mults;
-};
-#endif
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/SingleJetGrouper.h b/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/SingleJetGrouper.h
index bdcb22d7b4fa14263ed96a310a72c7139e5ae48c..5d0b474276c72be54531855b3e134cd85978b2a1 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/SingleJetGrouper.h
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/SingleJetGrouper.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRIGHLTJETHYPO_SINGLEJETGROUPER_H
@@ -9,12 +9,20 @@
 
 class SingleJetGrouper: public IJetGrouper{
  public:
+  SingleJetGrouper();
+  SingleJetGrouper(const HypoJetVector&);
+  SingleJetGrouper(const HypoJetCIter& b, const HypoJetCIter& e);
+
   std::vector<HypoJetGroupVector> group(HypoJetIter&,
 					HypoJetIter&) const override;
 
-  std::optional<HypoJetGroupVector> next(HypoJetIter&,
-					 HypoJetIter&) const override;
+  std::optional<HypoJetGroupVector> next() override;
   std::string getName() const override; 
   std::string toString() const override;
+
+private:
+  HypoJetVector m_jets;
+  std::size_t m_size;
+  std::size_t m_index{0};
 };
 #endif
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/ConditionsToolSetterFastReduction.py b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/ConditionsToolSetterFastReduction.py
index 2162fa0f2f638fcef1d5f34454c1065c6cb53cce..6e545440dd3f09d68aff988528a65e79c955faa6 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/ConditionsToolSetterFastReduction.py
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/ConditionsToolSetterFastReduction.py
@@ -10,8 +10,6 @@ from AthenaConfiguration.ComponentFactory import CompFactory
 
 from collections import defaultdict
 
-import copy
-
 from AthenaCommon.Logging import logging
 log = logging.getLogger( 'ConditionsToolSetterFastReduction' )
 
@@ -33,9 +31,8 @@ class ConditionsToolSetterFastReduction(object):
         'hecfrac' : 'HECFrac',
     }
 
-    def __init__(self, name):
+    def __init__(self):
 
-        self.name = name
         # for simple, use TrigJetConditionConfig_etaet. Needs to be
         # completed because simple can conain any single jet condition
         self.tool_factories = {
@@ -73,51 +70,7 @@ class ConditionsToolSetterFastReduction(object):
             self._set_conditions(cn)
 
 
-    def _remove_combgen(self, node):                       
-        """Combination nodes represent parent children relationships.
-        The child may be a subtree. For now, the parent will be in the 
-        child list at position 0, and the child subtree in position 1."""
-
-        parent_children = {}
-        ipos  = 0
-
-        # identify the combgen nodes, and rotate them
-        for cn in node.children:
-            if cn.scenario == 'combgen':
-                assert (len(cn.children) == 2)
-                parent_children[ipos] = cn.children
-            ipos += 1
-
-        # rotate the first combgen child (parent) into the position of the
-        # combgen node, and set its child node.
-        for pos, p_c in parent_children.items():
-            node.children[pos] = p_c[0]
-            node.children[pos].children = [p_c[1]]
-
-        for cn in node.children:
-            self._remove_combgen(cn)
-
-    def _remove_scenario(self, node, scenario):                       
-        """Remove Partgen nodes by adding their children to their 
-        parent's children."""
-
-        def remove_scenario(node, scenario):
-            for cn in node.children:
-                if cn.scenario == scenario:
-                    node.children.remove(cn)
-                    node.children.extend(cn.children)
-                    return True
-
-            return False
-
-        more = True
-        while(more):
-            more = remove_scenario(node, scenario)
-
-        for cn in node.children:
-            self._remove_scenario(cn, scenario)
-
-  
+ 
     def _get_tool_instance(self, key, extra=''):
    
         klass = self.tool_factories[key][0]
@@ -138,7 +91,15 @@ class ConditionsToolSetterFastReduction(object):
 
         # loop  over elements of node.conf_attrs. The elements are (dict, int)
         # int is multiplicity, dict holds Condition parameters.
-        for c, mult in node.conf_attrs:
+
+        for i in range(len(node.conf_attrs)):
+            c, mult = node.conf_attrs[i]
+            cpi = ''
+            if node.chainpartinds:
+                cpi = node.chainpartinds[i][0]
+                assert mult == node.chainpartinds[i][1]
+                    
+                
             condition_tools = [] # elemental conditions for this compounnd ct.
             for k, v in c.items(): # loop over elemental conditions
                 condition_tool = self._get_tool_instance(k)
@@ -159,12 +120,17 @@ class ConditionsToolSetterFastReduction(object):
 
             # create capacitychecked condition from elemental condition
             condition_tool =self._get_tool_instance('capacitychecked')
+
+            if cpi:
+                condition_tool.chainLegLabel = cpi
+            else:
+                condition_tool.chainLegLabel = ''
+            
             condition_tool.conditionMakers = condition_tools
             condition_tool.multiplicity = mult
-
             # add capacitychecked condition to list
             outer_condition_tools.append(condition_tool)
-
+            
         return outer_condition_tools
 
     def _mod_leaf(self, node):
@@ -186,59 +152,6 @@ class ConditionsToolSetterFastReduction(object):
         node.compound_condition_tools = self._make_compound_condition_tools(
             node)
 
-    def _split_leaves(self, node):
-        """Recursively replace leaf nodes with >1 Condition tools by nodes with
-        one Condition tool."""
-
-        def split_leaves(node):   
-            for cn in node.children:
-                if is_leaf(cn):
-                    if len(cn.compound_condition_tools) > 1:
-                        new_children =  []
-                        new_node = copy.deepcopy(cn)
-                        # set scenarrio to other than leaf results in 
-                        # the assignement of  an acceptall condition
-                        new_node.scenario = 'inserted'
-                        new_node.compound_condition_tools = []
-                        for ct in cn.compound_condition_tools:
-                            new_children.append(copy.deepcopy(cn))
-                            new_children[-1].compound_condition_tools = [ct]
-                            new_children[-1].conf_attrs = []
-                        new_node.children.extend(new_children)
-                        node.children.remove(cn)
-                        node.children.append(new_node)
-                        return True # return after first modification
-
-            return False
-
-
-        more = True
-        while(more):
-            more = split_leaves(node)
-
-        for cn in node.children:
-            self._split_leaves(cn)
-
-
-    def _find_shared(self, node, shared):
-        """Determine which nodes are "shared" - shared nodes
-        are nodes that see the input jet collection. There
-        more than one set of shared nodes. These are generated
-        if an "And" not is present in the hypo tree"""
-
-        if node.scenario == 'simple':
-            shared.append(node.node_id)
-        else:
-            shared.append(-1)
-            
-        for cn in node.children:
-            self._find_shared(cn, shared)
-
-
-        return shared
-
-
-
     def report(self):
         wid = max(len(k) for k in self.tool_factories.keys())
         rep = '\n%s: ' % self.__class__.__name__
@@ -289,9 +202,8 @@ class ConditionsToolSetterFastReduction(object):
     def mod(self, tree):
         """Entry point for this module. 
         Modifies a  (usually compound) hypo tree node to 
-        reduce it to form from whuch the treevector, conditionsVector and
-        sharedNodes list can be extracted. These will be used to initialise
-        FastReductionMatcher.
+        reduce it to form from whuch the treevector, and conditionsVector
+        These will be used to initialise FastReductionMatcher.
 
         In particular: all leaf nodes will have a single ConmpoundCondition
         All other nodes will be assigned an AcceptAll condition.
@@ -304,41 +216,24 @@ class ConditionsToolSetterFastReduction(object):
         
         # add Condition builders to leaf nodes.
         self._set_conditions(tree)
-        
-#         # Alg step 2: remove combgen nodes
-#         self._remove_combgen(root)
-
-        # Alg step 3: split leaf nodes with multiple Conditions with a
-        # single Condition
-#         self._split_leaves(root)
-        
-        # Alg step 4: remove partgen nodes
-        # single Condition
-
-        # Alg step 5: identify the leaf nodes that are to shared
-        # ie that see the input jet collection. Then remove And nodes
-        shared = []
-        self.shared = self._find_shared(tree, shared)
-        if shared[-1] != -1: self.shared.append(-1)
+  
 
-        print ('shared ', self.shared)
         tree_map = {}
         self._fill_tree_map(tree, tree_map)
 
         for k, v in tree_map.items():
             log.debug("Tree map debug ", str(k), str(v))
             
-        self.treeVec = self._map_2_vec(tree_map)
+        treeVec = self._map_2_vec(tree_map)
 
         conditionsMap = {}
         self._fill_conditions_map(tree, conditionsMap)
-        self.conditionsVec = self._map_2_vec(conditionsMap)
+        conditionsVec = self._map_2_vec(conditionsMap)
                
         # make a config tool and provide it with condition makers
         config_tool = self._get_tool_instance('fastreduction')
-        config_tool.conditionMakers = self.conditionsVec
-        config_tool.treeVector = self.treeVec
-        config_tool.sharedVector = self.shared
+        config_tool.conditionMakers = conditionsVec
+        config_tool.treeVector = treeVec
 
         nodestr = 'n%dp%d' % (tree.node_id, tree.parent_id)
         helper_tool = self._get_tool_instance('helper', extra=nodestr)
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/ConditionsToolSetterHT.py b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/ConditionsToolSetterHT.py
index bc866daca9b8a002ccf706229377d0cc9007bafe..c2727f25f3f6eb1065cd5a5683d2d2e18e069edf 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/ConditionsToolSetterHT.py
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/ConditionsToolSetterHT.py
@@ -16,9 +16,8 @@ class ConditionsToolSetterHT(object):
 
     """Visitor to set instantiated AlgTools to a jet hypo tree"""
     
-    def __init__(self, name):
+    def __init__(self):
 
-        self.name = name
         # for simple, use TrigJetConditionConfig_etaet. Needs to be
         # completed because simple can conain any single jet condition
         self.tool_factories = {
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/NodeSplitterVisitor.py b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/NodeSplitterVisitor.py
index 8a6c8187a022bdce144f3f611a58134a89305e7c..21f3ebb23e71077cbbc4dcbfedee76f3353f4d97 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/NodeSplitterVisitor.py
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/NodeSplitterVisitor.py
@@ -17,7 +17,6 @@ def is_leaf(node):
 
 
 def is_inner(node):
-    # return node.scenario in ('root', 'and', 'combgen', 'partgen' , 'inserted')
     return node.scenario in ('root', 'all', 'inserted')
 
 
@@ -31,9 +30,12 @@ class NodeSplitterVisitor(object):
         new_children = []
         for c in node.children:
             if c.scenario == 'simple':
-                for c_a in c.conf_attrs:
+                assert ((len(c.chainpartinds) ==
+                        len(c.conf_attrs))) or not c.chainpartinds
+                for cpi, c_a in zip(c.chainpartinds, c.conf_attrs):
                     n_c = copy.deepcopy(c)
                     n_c.conf_attrs = [c_a]
+                    n_c.chainpartinds = [cpi]
                     new_children.append(n_c)
             else:
                 new_children.append(c)
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/TrigJetHypoToolConfig.py b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/TrigJetHypoToolConfig.py
index e5be52b755bf1dd20bce953e4d71c5f63d19bad0..b73f20f38c93557ed2cdee6323ca082561dc269b 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/TrigJetHypoToolConfig.py
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/TrigJetHypoToolConfig.py
@@ -20,9 +20,10 @@ from TrigHLTJetHypo.NodeSplitterVisitor import NodeSplitterVisitor
 from AthenaCommon.Logging import logging
 log = logging.getLogger( 'TrigJetHypoToolConfig' )
 
-def  trigJetHypoToolHelperFromDict_(chain_label,
-                                    chain_name,
-                                    toolSetter=None):
+def  trigJetHypoToolHelperFromDict_(
+        chain_label, # simple([(260et,320eta490, leg000)])
+        chain_name, # HLT_j260_320eta490_L1J75_31ETA49
+        toolSetter=None):
 
     parser = ChainLabelParser(chain_label, debug=False)
 
@@ -92,22 +93,22 @@ def  trigJetHypoToolHelperFromDict(chain_dict):
 
     toolSetter = None
     if 'agg' in chain_name:
-        toolSetter=ConditionsToolSetterHT(chain_name)
+        toolSetter=ConditionsToolSetterHT()
     else:
-        toolSetter=ConditionsToolSetterFastReduction(chain_name)
+        toolSetter=ConditionsToolSetterFastReduction()
 
     return trigJetHypoToolHelperFromDict_(chain_label,
                                           chain_name,
                                           toolSetter)
 
 
-def  trigJetHypoToolFromDict(chain_dict):
+def  trigJetHypoToolFromDict_(chain_dict, tool):
     """Produce  a jet trigger hypo tool from a chainDict"""
 
-    log.debug('trigJetHypoToolFromDict chainDict %s', str(chain_dict))
-
-    chain_name = chain_dict['chainName']
-    tool = CompFactory.TrigJetHypoToolMT(name=chain_name)
+    log.debug('trigJetHypoToolFromDict_ tool type ',
+              tool.__class__.__name__,
+              ' chainDict ',
+              str(chain_dict))
 
     # obtain  a Helper Tool (possibly a tree of tools) to
     # make the hypo decision.
@@ -120,25 +121,16 @@ def  trigJetHypoToolFromDict(chain_dict):
 
     return tool
 
-def  trigJetTLAHypoToolFromDict(chain_dict):
-    """Produce  a TLA jet trigger hypo tool from a chainDict"""
-
-    log.info('trigJetTLAHypoToolFromDict chainDict %s', str(chain_dict))
 
-    chain_name = chain_dict['chainName']
-    tool = CompFactory.TrigJetTLAHypoToolMT(name=chain_name)
+def  trigJetTLAHypoToolFromDict(chain_dict):
+    tool = CompFactory.TrigJetTLAHypoToolMT(name=chain_dict['chainName'])
+    return trigJetHypoToolFromDict_(chain_dict, tool)
 
-    # obtain  a Helper Tool (possibly a tree of tools) to
-    # make the hypo decision.
-    # CD: why do we do this? Question to TJ
-    tool.helper_tool = trigJetHypoToolHelperFromDict(chain_dict)
 
-    # controls whether debug visitor is sent to helper tool
-    debug = False  # SET TO False WHEN COMMITTING
-    tool.visit_debug = debug
-    log.debug('%s', tool)
+def  trigJetHypoToolFromDict(chain_dict):
+    tool = CompFactory.TrigJetHypoToolMT(name=chain_dict['chainName'])
+    return trigJetHypoToolFromDict_(chain_dict, tool)
 
-    return tool
 
 import unittest
 class TestStringMethods(unittest.TestCase):
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/chainDict2jetLabel.py b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/chainDict2jetLabel.py
index c1e28d3aaf21eab59af17ce70fe90327ab454a5c..d01c48a6395663499eab149a73489f913a6efa31 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/chainDict2jetLabel.py
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/chainDict2jetLabel.py
@@ -28,10 +28,12 @@ def _select_simple_chainparts(chain_parts):
     return True
 
 
-def _make_simple_label(chain_parts):
+def _make_simple_label(chain_parts, leg_label):
     """Marshal information deom the selected chainParts to create a
     'simple' label. NOTE: THIS IS A SPECIAL CASE - IT DOES NOT DEPEND
     SOLELY ON THE HYPO SCENARIO.
+    Argument leg_label is not used - rather the leg label is fouNd
+    from the chain parts.
     """
     
     if not _select_simple_chainparts(chain_parts):
@@ -39,7 +41,8 @@ def _make_simple_label(chain_parts):
               'chain fails substring selection: not "simple" '
 
         raise NotImplementedError(msg)
-    
+
+    chainpartind = 0
     label = 'simple(['
     for cp in chain_parts:
         smcstr =  str(cp['smc'])
@@ -65,9 +68,12 @@ def _make_simple_label(chain_parts):
                         condition_str += ',%s' % cut
                 else:
                     condition_str += ',%s' % momstr
+            condition_str += ', leg{:0>3}'.format(chainpartind)
             if not condition_str.endswith(')'):
                 condition_str += ')'
             label += condition_str
+        chainpartind += 1
+
     label += '])'
     return label
 
@@ -89,7 +95,7 @@ def _cuts_from_momCuts(momCuts):
     return ''
 
 
-def _make_vbenf_label(chain_parts):
+def _make_vbenf_label(chain_parts, leg_label):
     """Marshal information from the selected chainParts to create a
     vbenf label. Use a Reducer for elimination of unusable jets
     """
@@ -100,6 +106,7 @@ def _make_vbenf_label(chain_parts):
     # scenario requires a dijet of mass > 900, and opening angle in phi > 2.6
 
     assert len(chain_parts) == 1
+    
     scenario = chain_parts[0]['hypoScenario']
     assert scenario.startswith('vbenf')
     args = _args_from_scenario(scenario)
@@ -141,26 +148,27 @@ def _make_vbenf_label(chain_parts):
     assert len(args) == len(arg_res)
     assert len(args) == 0
 
+    argvals['leg_label'] = leg_label
     return """
     all
     (
       []
       simple
       (
-        [(%(etlo).0fet, 500neta)(%(etlo).0fet, peta500)]
+        [(%(etlo).0fet, 500neta, leg000)(%(etlo).0fet, peta500, %(leg_label)s)]
       )
       dijet
       (
         [(%(masslo).0fdjmass, 26djdphi)]
         simple
         (
-          [(10et, 0eta320)(20et, 0eta320)]
+          [(10et, 0eta320, leg000)(20et, 0eta320, %(leg_label)s)]
         )
       )
     )""" % argvals
 
 
-def _make_dijet_label(chain_parts):
+def _make_dijet_label(chain_parts, leg_label):
     """dijet label. supports dijet cuts, and cuts on particpating jets
     Currently supported cuts:
     - dijet mass
@@ -219,16 +227,16 @@ def _make_dijet_label(chain_parts):
     assert len(args) == len(arg_res)
     assert len(args) == 0
 
+    argvals['leg_label'] = leg_label
+    
     return """
-    all([]
-        dijet(
-              [(%(djmasslo).0fdjmass)])
-        simple([(%(j1etlo).0fet, %(j1etalo).0feta%(j1etahi).0f)
-                (%(j2etlo).0fet, %(j2etalo).0feta%(j2etahi).0f)])
-    )""" % argvals
+    dijet(
+    [(%(djmasslo).0fdjmass)]
+    simple([(%(j1etlo).0fet, %(j1etalo).0feta%(j1etahi).0f, %(leg_label)s)
+    (%(j2etlo).0fet, %(j2etalo).0feta%(j2etahi).0f, %(leg_label)s)]))""" % argvals
 
 
-def _make_agg_label(chain_parts):
+def _make_agg_label(chain_parts, leg_label):
     """agg label. cuts on aggregate quantities, and cuts on particpating jets
     Only partway migrated from pure ht to more general agg
     Currently supported cuts:
@@ -285,12 +293,11 @@ def _make_agg_label(chain_parts):
                     hi = float(defaults[key][1])
                 argvals[key+'hi'] =  hi
 
-    print (argvals)
     assert len(argvals) == 2*nargs, 'no of args: %d, expected %d' % (len(argvals), 2*nargs)
 
-    print ('sent 100')
+    argvals['leg_label'] = leg_label
     result =  """
-    ht([(%(htlo).0fht)
+    ht([(%(htlo).0fht, %(leg_label)s)
         (%(etlo).0fet)
         (%(etalo).0feta%(etahi).0f)
     ])"""  % argvals
@@ -322,7 +329,8 @@ def chainDict2jetLabel(chain_dict):
     cp_sorter = {}
     for k in router: cp_sorter[k] = []
 
-    for cp in chain_dict['chainParts']:
+    chain_parts = chain_dict['chainParts']
+    for cp in chain_parts:
         if cp['signature'] != 'Jet' and cp['signature'] != 'Bjet': 
             continue
         for k in cp_sorter:
@@ -332,8 +340,11 @@ def chainDict2jetLabel(chain_dict):
 
     # obtain labels by scenario.
     labels = []
+
+    leg_label = 'leg%03d' % (len(chain_parts) - 1)
     for k, chain_parts in cp_sorter.items():
-        if chain_parts: labels.append(router[k](chain_parts))
+        if chain_parts:
+            labels.append(router[k](chain_parts, leg_label))
 
     assert labels
     nlabels = len(labels)
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/node.py b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/node.py
index 0b21c68951108579703549316f8444ceb08bbb15..7b75c37525d04072399faa426506afecf2c9919d 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/node.py
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/node.py
@@ -33,6 +33,7 @@ class Node(object):
         # self.compound_condition_tools = []
         # self.tree_top kludge carensure top level tools get chain name
         # as Tool name
+        self.chainpartinds = []
         self.tree_top = False
         self.tool = None
         
@@ -85,6 +86,7 @@ class Node(object):
              indent + 'parent node id: %s' % self.parent_id,
              indent + 'is tree top? %s' % self.tree_top,
              indent + 'parameters: %s' % str(self.parameters),
+             indent + 'chainpartinds %s' % str(self.chainpartinds),
              indent + 'conf_attrs [%d]:' % len(self.conf_attrs)]
         for ca in self.conf_attrs:
             s.append(indent + str(ca))
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/treeVisitors.py b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/treeVisitors.py
index a226fec52b7ccdc72db13870755088eb32be2343..3133ab0191dbd3fb0f113c2a1f41fb9d3330eb66 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/treeVisitors.py
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/treeVisitors.py
@@ -124,7 +124,7 @@ class ConditionsDictMaker(object):
         r'^(?P<lo>\d*)(?P<attr>[%s]+)(?P<hi>\d*)' % lchars)
 
 
-    # key: substring from chain label. value: asttribute of python
+    # key: substring from chain label. value: attribute of python
     # component proxy
     
     def get_conditions(self, params):
@@ -155,6 +155,7 @@ class ConditionsDictMaker(object):
 
 
     def makeDict(self, params):
+
         # conditions example: ['10et,0eta320', '20et']
         conditions = self.get_conditions(params)
 
@@ -164,14 +165,21 @@ class ConditionsDictMaker(object):
         for c in conditions: mult_conditions[c] += 1
         
         result = []
+        chainpartinds = []
         msgs = []
 
 
         # process each parameter string once.
         for c, mult in mult_conditions.items(): # c is condition string
             cdict = defaultdict(dict)
+            
             toks = c.split(',')  # parameters in par string are separated by ','
             toks = [t.strip() for t in toks]
+            cpis = [t for t in toks if t.startswith('leg')]
+            assert len(cpis) < 2
+            if cpis:
+                chainpartinds.append((cpis[0], mult))
+                toks.remove(chainpartinds[-1][0])
 
             for t in toks:
                 m = self.window_re.match(t)
@@ -248,7 +256,7 @@ class ConditionsDictMaker(object):
 
         msgs = ['ConditionsDict OK']
         error = False
-        return result, error, msgs
+        return result, chainpartinds, error, msgs
 
 
 class TreeParameterExpander_simple(object):
@@ -267,10 +275,11 @@ class TreeParameterExpander_simple(object):
     def mod(self, node):
 
         cdm = ConditionsDictMaker()
-        d, error, msgs = cdm.makeDict(node.parameters)
+        d, chainpartinds, error, msgs = cdm.makeDict(node.parameters)
         self.msgs.extend(msgs)
         node.conf_attrs = d
-
+        node.chainpartinds = chainpartinds
+        
     def report(self):
         return '%s: ' % self.__class__.__name__ + '\n'.join(self.msgs) 
 
@@ -295,9 +304,10 @@ class TreeParameterExpander_dijet(object):
     def mod(self, node):
 
         cdm = ConditionsDictMaker()
-        d, error, msgs = cdm.makeDict(node.parameters)
+        d, chainpartinds, error, msgs = cdm.makeDict(node.parameters)
         self.msgs.extend(msgs)
         node.conf_attrs = d
+        node.chainpartinds = chainpartinds
 
     def report(self):
         return '%s: ' % self.__class__.__name__ + '\n'.join(self.msgs)
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/CapacityCheckedCondition.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/CapacityCheckedCondition.cxx
index bcf2cfe05335583b7c13ec757b2992e3f5acc40a..87146ac19127369e0906971c465917dc1756c850 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/CapacityCheckedCondition.cxx
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/CapacityCheckedCondition.cxx
@@ -8,8 +8,10 @@
 #include <string>
 
 
-CapacityCheckedCondition::CapacityCheckedCondition(std::unique_ptr<IConditionMT> cp,  std::size_t mult):
-  m_condition{std::move(cp)}, m_multiplicity{mult} {}
+CapacityCheckedCondition::CapacityCheckedCondition(std::unique_ptr<IConditionMT> cp,
+						   std::size_t mult,
+						   const std::string& label):
+  m_condition{std::move(cp)}, m_multiplicity{mult}, m_label{label}{}
 
 
 CapacityCheckedCondition::~CapacityCheckedCondition(){}
@@ -35,7 +37,20 @@ std::string CapacityCheckedCondition::toString() const {
   const void* address = static_cast<const void*>(this);
   
   ss << "CapacityCheckedCondition (" << address << ") Multiplicity: "
-     << m_multiplicity << '\n' << m_condition->toString();
+     << m_multiplicity << " label "
+     << m_label << '\n'
+     << m_condition->toString();
 
   return ss.str();
 }
+
+std::string CapacityCheckedCondition::label() const {
+  return m_label;
+}
+
+std::ostream& operator<<(std::ostream& out,
+			 const CapacityCheckedCondition& c){
+
+  out << c.toString();
+  return out;
+}
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/CapacityCheckedCondition.h b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/CapacityCheckedCondition.h
index e01bcc13918d18baafbeb8412aa7e269ea32ca94..90d6e03fbd2a003249cfb782f1148af6b14136ee 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/CapacityCheckedCondition.h
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/CapacityCheckedCondition.h
@@ -21,6 +21,7 @@
 
 #include <memory>
 #include <string>
+#include <ostream>
 
 
 class ITrigJetHypoInfoCollector;
@@ -28,7 +29,8 @@ class ITrigJetHypoInfoCollector;
 class CapacityCheckedCondition: public ICapacityCheckedCondition {
  public:
  CapacityCheckedCondition(std::unique_ptr<IConditionMT> cp,
-			  std::size_t mult);
+			  std::size_t mult,
+			  const std::string& label="");
   virtual ~CapacityCheckedCondition();
   
   virtual bool
@@ -42,10 +44,16 @@ class CapacityCheckedCondition: public ICapacityCheckedCondition {
   
   virtual std::string toString() const override;
 
+  virtual std::string label() const override;
+
 private:
 
   std::unique_ptr<IConditionMT> m_condition;
   std::size_t m_multiplicity;
+  std::string m_label;
 };
 
+std::ostream& operator<<(std::ostream&,
+			 const CapacityCheckedCondition&);
+
 #endif
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/FastReducer.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/FastReducer.cxx
index 3a56736c333e8929a90b83472101f3b33b87e15b..7e174e07d330c3df6b6781fd99feba301e4039f6 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/FastReducer.cxx
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/FastReducer.cxx
@@ -40,13 +40,9 @@ FastReducer::FastReducer(const HypoJetGroupCIter& groups_b,
                          const HypoJetGroupCIter& groups_e,
                          const ConditionPtrs& conditions,
                          const Tree& tree,
-                         const std::vector<std::vector<int>>& sharedConditions,
                          xAODJetCollector& jetCollector,
                          const Collector& collector):
-  m_conditions(conditions),
-  m_tree(tree),
-  m_sharedConditions(std::move(sharedConditions))
-{
+  m_conditions(conditions),  m_tree(tree) {
 
   // create an empty vector of indices of satisfying jet groups
   // for each Condition.
@@ -56,18 +52,15 @@ FastReducer::FastReducer(const HypoJetGroupCIter& groups_b,
   }
 
 
-  for(const auto& leaves: m_sharedConditions){
-    if(!findInitialJetGroups(leaves,
-			     groups_b,
-			     groups_e,
-			     collector)){
-      if(collector){
-	collector->collect("FastReducer early return",
-			   "from findInitialJetGroups");
-	dumpDataStructures(collector);
-      }
-      return;  // m_pass retains initial value ie false 
+  if(!findInitialJetGroups(groups_b,
+			   groups_e,
+			   collector)){
+    if(collector){
+      collector->collect("FastReducer early return",
+			 "from findInitialJetGroups");
+      dumpDataStructures(collector);
     }
+    return;  // m_pass retains initial value ie false 
   }
 
   
@@ -97,43 +90,79 @@ void FastReducer::collectLeafJets(xAODJetCollector& jetCollector,
 
   // basic passing jet reporting
 
-  // find the indices of the leaf nodes
-  std::set<int> leafCondInds;
-  for (const auto& leaves: m_sharedConditions){
-    leafCondInds.insert(leaves.begin(), leaves.end());
+  // find the indices of the jets that make up the jet groups that pass
+  // the root node.
+
+  //.. obtain the passing jet groups for the root node...
+
+  std::set<std::size_t> rootSatJetGroupInds(m_satisfiedBy.at(0).begin(),
+					    m_satisfiedBy.at(0).end());
+
+  // ...obtain the elemental jet group indicies...
+
+  std::set<std::size_t> rootElSatJetGroupInds;
+  for (const auto& ji : rootSatJetGroupInds) {
+    rootElSatJetGroupInds.insert(m_jg2elemjgs.at(ji).begin(),
+				 m_jg2elemjgs.at(ji).end());
   }
 
-  // obtain the jet group indices for the jet groups satisfying the leaf conds
-  std::set<std::size_t> satJetGroupInds;
-  for (const auto& ci : leafCondInds) {
+    
+
+  // now do the same for the leaf nodes
+  
 
+  auto leaves = m_tree.leaves();
+  // obtain the jet group indices for the jet groups satisfying the leaf conds
+  for (const auto& ci : leaves) {  // for each leaf node...
+    std::set<std::size_t> satJetGroupInds;
+    
+    // ... collect the (possibly compound) jet group indices...
     satJetGroupInds.insert(m_satisfiedBy.at(ci).cbegin(),
                            m_satisfiedBy.at(ci).cend());
-  }
-  
-  // obtain the corresponding elemental jet group indices
-  std::set<std::size_t> elSatJetGroupInds;
-  for (const auto& ji : satJetGroupInds) {
-    elSatJetGroupInds.insert(m_jg2elemjgs.at(ji).begin(),
-			     m_jg2elemjgs.at(ji).end());
-  }
+    
+    // ...obtain the corresponding elemental jet group indices...
+    std::set<std::size_t> elSatJetGroupInds;
+    for (const auto& ji : satJetGroupInds) {
+      elSatJetGroupInds.insert(m_jg2elemjgs.at(ji).begin(),
+			       m_jg2elemjgs.at(ji).end());
+    }
+    
+    // .. get the leg label for the condition (possibly "")
+    auto conditionLabel = (m_conditions.at(ci))->label();
+    
+    if (collector) {
+      std::stringstream ss;
+      ss <<  "elSatJettGroupInds.size() "
+	 << conditionLabel
+	 << ": "
+	 << elSatJetGroupInds.size();
+      collector->collect("FastReducer", ss.str());
+    }
 
-  if (collector) {
-    std::stringstream ss;
-    ss <<  "elSatJettGroupInds.size() " << elSatJetGroupInds.size();
-    collector->collect("FastReducer", ss.str());
+    // ... use the elemental jet group induces to recover the jets
+
+    // if the leaf not jet is one of the jets that contributes to
+    // passing root, store it in the collector, labelled by the leaf node
+    // chainLegLabel
+    
+    auto end = rootElSatJetGroupInds.end();
+    for(const auto& ji : elSatJetGroupInds) {
+      
+      if (rootElSatJetGroupInds.find(ji) != end){  /// jets by indices
+	jetCollector.addJets(m_indJetGroup.at(ji).begin(), //jets py ptrs
+			     m_indJetGroup.at(ji).end(),
+			     conditionLabel);
+      }
+    }
   }
-  
-  for(const auto& ji : elSatJetGroupInds) {
-    jetCollector.addJets(m_indJetGroup.at(ji).begin(),
-                         m_indJetGroup.at(ji).end());
+  if (collector) {
+    collector->collect("FastReducer",
+		       "collected " + std::to_string(jetCollector.size()));
   }
-
 }
 
 
-bool FastReducer::findInitialJetGroups(const std::vector<int>& leaves,
-				       const HypoJetGroupCIter& groups_b,
+bool FastReducer::findInitialJetGroups(const HypoJetGroupCIter& groups_b,
 				       const HypoJetGroupCIter& groups_e,
 				       const Collector& collector) {
   
@@ -141,8 +170,10 @@ bool FastReducer::findInitialJetGroups(const std::vector<int>& leaves,
   /*
     Will now test the incoming jet groups against the leaf conditions.
   */
-  
+
   std::size_t ijg{0};
+  auto leaves = m_tree.leaves();
+
   for(auto iter = groups_b; iter != groups_e; ++iter){
     auto jg = *iter;
     
@@ -160,17 +191,19 @@ bool FastReducer::findInitialJetGroups(const std::vector<int>& leaves,
       
       m_testedBy[leaf].insert(cur_jg);
       if (m_conditions[leaf]->isSatisfied(jg, collector)){
-	  jg_used= true;
-	  if(collector){recordJetGroup(cur_jg, jg, collector);}
-	  // do the following for each satisfied condition ...
-	  m_satisfiedBy[leaf].push_back(cur_jg);
+	jg_used= true;
+	if(collector){recordJetGroup(cur_jg, jg, collector);}
+	// do the following for each satisfied condition ...
+	m_satisfiedBy[leaf].push_back(cur_jg);
       }
     }
+    
     if(jg_used){
       m_jg2elemjgs[cur_jg] =  std::vector<std::size_t>{cur_jg};
       m_indJetGroup.emplace(cur_jg, jg);
       ++ijg;
     }
+    
   }
   
   if(collector){
@@ -186,7 +219,7 @@ bool FastReducer::findInitialJetGroups(const std::vector<int>& leaves,
       return false;
     }
   }
-
+  
   /*
     For the special but important case where all leaf nodes have
     the root node as a parent, check that there are enough jets
@@ -213,7 +246,7 @@ bool FastReducer::findInitialJetGroups(const std::vector<int>& leaves,
   if (std::all_of(m_tree.cbegin(),
 		  m_tree.cend(),
 		  [](std::size_t i){return i == 0;})) {
-
+    
     if (m_conditions[0]->capacity() > ijg) {
       
       if (collector){
@@ -406,14 +439,6 @@ std::string FastReducer::toString() const {
   std::stringstream ss;
   ss << "FastReducer:\n";
   ss << "  treeVector: " << m_tree << '\n';;
-  ss << "  shared node sets [" << m_sharedConditions.size() << "]:\n";
-  for(const auto& snodelist : m_sharedConditions){
-    for(const auto el : snodelist){
-      ss << el << " ";
-    }
-    ss << '\n';
-  }
-
   ss << "FastReducer Conditions ["
      << m_conditions.size() << "]: \n";
 
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/FastReducer.h b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/FastReducer.h
index 9cb957d1dfe4ae96e9742420164eab5c4499d5c9..7f3d1191fdd18e53c32bec702fa71b4bd4c992fb 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/FastReducer.h
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/FastReducer.h
@@ -10,6 +10,7 @@
 #include "./JetGroupProduct.h"
 #include "./JetGroupIndAllocator.h"
 #include "./xAODJetCollector.h"
+#include "./ITrigJetHypoInfoCollector.h"
 #include <string>
 
 using TreeVec = std::vector<std::size_t>;
@@ -22,7 +23,6 @@ typedef std::unique_ptr<ITrigJetHypoInfoCollector> Collector;
 
 using JetGroupInd2ElemInds = std::map<int, std::vector<std::size_t>>;
 
-class ITrigJetHypoInfoCollector;
 
 class FastReducer {
  public:
@@ -31,7 +31,6 @@ class FastReducer {
               const HypoJetGroupCIter& groups_e,
               const ConditionPtrs& conditionObjects,
               const Tree& conditionsTree,
-              const std::vector<std::vector<int>>& sharedConditions,
               xAODJetCollector& jetCollector,
               const Collector& collector);
 
@@ -55,12 +54,6 @@ class FastReducer {
   
   Tree m_tree;
 
-  /** A vector of shared Condition indices. All shared Conditions are leaf
-   Conditions  that see the jet icoming jets.
-  */
-  
-  std::vector<std::vector<int>> m_sharedConditions;
-
   // map Condition index onto a list of indices of satisfying job groups.
   CondInd2JetGroupsInds m_satisfiedBy;
 
@@ -89,8 +82,7 @@ class FastReducer {
    in preparration for testing against parent conditions.
   */
   
-  bool findInitialJetGroups(const std::vector<int>& leaves,
-			    const HypoJetGroupCIter& groups_b,
+  bool findInitialJetGroups(const HypoJetGroupCIter& groups_b,
 			    const HypoJetGroupCIter& groups_e,
 			    const Collector& collector);
   
@@ -108,7 +100,7 @@ class FastReducer {
   
   void recordJetGroup(std::size_t ind,
 		      const HypoJetVector& jg,
-		      const std::unique_ptr<ITrigJetHypoInfoCollector>& collector) const;
+		      const Collector& collector) const;
 
   void collectLeafJets(xAODJetCollector& jetCollector,
 		       const Collector& collector) const;
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/FastReductionMatcher.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/FastReductionMatcher.cxx
index 4dfffac4ca42c542b11b33516585717d0b95716a..350de12c4b287444bf9397ece869e0348a79b86c 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/FastReductionMatcher.cxx
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/FastReductionMatcher.cxx
@@ -10,16 +10,20 @@
 #include <algorithm>
 #include <sstream>
 
-
-
 FastReductionMatcher::FastReductionMatcher(ConditionPtrs conditions,
-					   const Tree& tree,
-					   const std::vector<std::vector<int>>& sharedNodes):
+					   const Tree& tree):
   m_conditions(std::move(conditions)),
-  m_tree(tree),
-  m_sharedNodes(sharedNodes){
-  }
+  m_tree(tree){
 
+  for (const auto& il : m_tree.leaves()){
+    auto label = m_conditions[il]->label();
+    if (label.rfind("leg", 0) != 0) { // startswith "leg"
+      throw std::runtime_error("Leaf condition " + std::to_string(il) +
+			       "has no leg label");
+    }
+  }
+}
+	 
 
 
 std::optional<bool>
@@ -46,7 +50,6 @@ FastReductionMatcher::match(const HypoJetGroupCIter& groups_b,
                       groups_e,
                       m_conditions,
                       m_tree,
-                      m_sharedNodes,
                       jetCollector,
                       collector);
 
@@ -56,17 +59,9 @@ FastReductionMatcher::match(const HypoJetGroupCIter& groups_b,
 
 std::string FastReductionMatcher::toString() const {
   std::stringstream ss;
-  ss << "FastReductionMatcher:\n";
-  ss << "  treeVector: " << m_tree << '\n';;
-  ss << "  shared node sets [" << m_sharedNodes.size() << "]:\n";
-  for(const auto& snodelist : m_sharedNodes){
-    for(const auto el : snodelist){
-      ss << el << " ";
-    }
-    ss << '\n';
-  }
-
-  ss << "FastReductionMatcher Conditions ["
+  ss << "FastReductionMatcher:\n"
+     << "  treeVector: " << m_tree << '\n'
+     << "FastReductionMatcher Conditions ["
      << m_conditions.size() << "]: \n";
 
   std::size_t count{0u};
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/FastReductionMatcher.h b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/FastReductionMatcher.h
index 62210f404a39f23639f2a4984ecba85e4ed2855b..9b1e68b8a6ff7639cc816a945e1b359d5f4863a1 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/FastReductionMatcher.h
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/FastReductionMatcher.h
@@ -17,8 +17,7 @@ class FastReductionMatcher: public IGroupsMatcherMT {
  public:
 
   FastReductionMatcher(ConditionPtrs,
-		       const Tree&,
-		       const std::vector<std::vector<int>>&);
+		       const Tree&);
 
 
   /** determine whether a set of jets satisfies all hypo conditions.
@@ -51,11 +50,5 @@ class FastReductionMatcher: public IGroupsMatcherMT {
   
   Tree m_tree;
 
-  /** a vector of shared nodes. All shared nodes are leaf node that
-  see the jet collection.
-  */
-  
-  std::vector<std::vector<int>> m_sharedNodes;
-
 };
 #endif
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/ICapacityCheckedCondition.h b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/ICapacityCheckedCondition.h
index c49ea11ab1f8fc7cba13df0122ff0a42f0f497c4..c38345684e6136d4fe57416e09dc525560e929f2 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/ICapacityCheckedCondition.h
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/ICapacityCheckedCondition.h
@@ -32,7 +32,10 @@ class ICapacityCheckedCondition: public IConditionMT {
 
   virtual bool multiplicitySatisfied(std::size_t jgMultiplicity,
 				     const Collector&) const = 0;
-  
+
+  virtual std::string label() const = 0;
+  virtual std::string toString() const = 0;
+
 };
 
 #endif
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/PartitionsGroupsMatcherMT.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/PartitionsGroupsMatcherMT.cxx
deleted file mode 100644
index 25f1a293e85dc775d4eb2b8b146b0e106f98de30..0000000000000000000000000000000000000000
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/PartitionsGroupsMatcherMT.cxx
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
-*/
-
-// ********************************************************************
-//
-// NAME:     PartitionsGroupsMatcherMT.cxx
-// PACKAGE:  Trigger/TrigHypothesis/TrigHLTJetHypo
-//
-// AUTHOR:   P Sherwood
-//
-// ********************************************************************
-//
-
-#include "./PartitionsGroupsMatcherMT.h"
-#include "./ITrigJetHypoInfoCollector.h"
-#include "./xAODJetCollector.h"
-
-// #include <cmath>
-// #include <sstream>
-#include <algorithm>
-// #include <map>
-
-PartitionsGroupsMatcherMT::PartitionsGroupsMatcherMT(ConditionsMT&& cs):
-  m_conditions(std::move(cs)), m_nConditions(m_conditions.size()){
-  std::size_t minNjets{0};
-  for(const auto& c : m_conditions){minNjets += c->capacity();}
-  m_minNjets = minNjets;
-}
-
-std::optional<bool>
-PartitionsGroupsMatcherMT::match(const HypoJetGroupCIter& groups_b,
-				 const HypoJetGroupCIter& groups_e,
-				 xAODJetCollector& jetCollector,
-				 const std::unique_ptr<ITrigJetHypoInfoCollector>& collector,
-				 bool) const {
-  
-
-
-  // minimal input correctness checks. More detailed checking
-  // responsibility of the caller.
-
-  auto iter_diff = groups_e - groups_b;
-  if (iter_diff < 0){return std::optional<bool>();}
-  auto n_jetvecs = static_cast<std::size_t>(iter_diff);
-  auto n_conditions = m_conditions.size();
-  
-  if(n_conditions != n_jetvecs){
-    if(collector){
-      std::string msg = "Number of HypoJetVectors " +
-	std::to_string(n_jetvecs) + " !=  number of children " +
-	std::to_string(n_conditions);
-      
-      collector->collect("PartitionsGroupsMatcherMT", msg);
-    }
-    return std::optional<bool>();
-  }
-
-  for(std::size_t i = 0;  i != n_conditions; ++i){
-    // Pass each job group to its corresposonding child, check if pass.
-    // Return false any child does not pass.
-    if (!m_conditions[i]->isSatisfied(*(groups_b +i), collector)){
-      return std::make_optional<bool>(false);
-    }
-
-    // passed....
-    if(collector){
-      collector->collect("PartitionsGroupsMatcherMT", "passed");
-    }
-    for(auto iter = groups_b; iter != groups_e; ++iter){
-      jetCollector.addJets((*iter).begin(), (*iter).end());
-    }
-  }
-  
-  return std::make_optional<bool>(true);  
-} 
-
-
-std::string PartitionsGroupsMatcherMT::toString() const noexcept {
-  std::stringstream ss;
-
-  ss << "PartitionsMatcherMT. No of conditions: "
-     << m_conditions.size() << '\n';
-  for(const auto& c : m_conditions){ ss <<"  "<< c->toString() << '\n';}
-  return ss.str();
-}
-
-
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/PartitionsGroupsMatcherMT.h b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/PartitionsGroupsMatcherMT.h
deleted file mode 100644
index 3e7c7aaafdd2a523f4bf23b35b4adfe2f583de8c..0000000000000000000000000000000000000000
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/PartitionsGroupsMatcherMT.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
-*/
-
-#ifndef TRIGHLTJETHYPO_PARTITIONSGROUPSMATCHERMT_H
-#define TRIGHLTJETHYPO_PARTITIONSGROUPSMATCHERMT_H
-
-// ********************************************************************
-//
-// NAME:     PartitionsGroupsMatcherMT.h
-// PACKAGE:  Trigger/TrigHypothesis/TrigHLTJetHypo
-//
-// AUTHOR:  P Sherwood
-//
-// ********************************************************************
-//
-
-#include "./IGroupsMatcherMT.h"
-#include "./ConditionsDefsMT.h"
-#include "TrigHLTJetHypo/TrigHLTJetHypoUtils/HypoJetDefs.h"
-#include "TrigHLTJetHypo/TrigHLTJetHypoUtils/IJet.h"
-#include <optional>
-
-class ITrigJetHypoInfoCollector;
-class xAODJetCollector;
-
-class PartitionsGroupsMatcherMT:
-virtual public IGroupsMatcherMT {
-
-  /* Given a two equi-length containers of HypoJetVectors
-     and Conditions , associate the ith elements, and determine if,
-     for each i, the Condition is datisfoied by the HypoJetVector.
-  */
-
-public:
-  PartitionsGroupsMatcherMT(ConditionsMT&& cs);
-  ~PartitionsGroupsMatcherMT(){}
-
-  std::optional<bool> match(const HypoJetGroupCIter&,
-			    const HypoJetGroupCIter&,
-			    xAODJetCollector&,
-			    const std::unique_ptr<ITrigJetHypoInfoCollector>&,
-			    bool debug=false) const override;
-  std::string toString() const noexcept override;
-
-private:
-  ConditionsMT m_conditions;
-  std::size_t m_nConditions{0};
-  std::size_t m_minNjets{0};
-
-};
-
-#endif
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/SingleConditionMatcherMT.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/SingleConditionMatcherMT.cxx
index bd19c59ce858d9b4f64a7296919bd7d6049e1da4..448399ad38380097578432e041fa63a0b4cc1191 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/SingleConditionMatcherMT.cxx
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/SingleConditionMatcherMT.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 // ********************************************************************
@@ -32,7 +32,10 @@ SingleConditionMatcherMT::match(const HypoJetGroupCIter& jets_b,
 
   for(auto i=jets_b; i != jets_e; ++i){
     if (m_condition->isSatisfied(*i, v)){
-      jetCollector.addJets((*i).cbegin(), (*i).cend());
+      // Note that this slightly out-of-date code does not expect
+      // chains with simple and non-simple scenarios to be present in the
+      // same chain. The leg label is hard coded here.
+      jetCollector.addJets((*i).cbegin(), (*i).cend(), "leg000");
       return std::make_optional<bool>(true);
     }
   }
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/AllJetsGrouper.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/AllJetsGrouper.cxx
index 6f2daf8f9450fe8117adde16b849c813ceaeda61..fcbfca501e77312285ce97dd51b1eae48480a0a6 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/AllJetsGrouper.cxx
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/AllJetsGrouper.cxx
@@ -1,10 +1,21 @@
 
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "TrigHLTJetHypo/TrigHLTJetHypoUtils/AllJetsGrouper.h"
 
+AllJetsGrouper:: AllJetsGrouper(){}
+
+AllJetsGrouper:: AllJetsGrouper(const HypoJetIter& b,
+				const HypoJetIter& e): m_jets(b, e){
+}
+
+AllJetsGrouper:: AllJetsGrouper(const HypoJetVector& jets): m_jets{jets}{
+}
+
+
+
 std::vector<HypoJetGroupVector> AllJetsGrouper::group(HypoJetIter& begin,
 						      HypoJetIter& end
 						      ) const {
@@ -12,10 +23,13 @@ std::vector<HypoJetGroupVector> AllJetsGrouper::group(HypoJetIter& begin,
   return std::vector<HypoJetGroupVector>{hjgv};
 }
 
-std::optional<HypoJetGroupVector> AllJetsGrouper::next(HypoJetIter& begin,
-						       HypoJetIter& end
-						       ) const {
-  HypoJetGroupVector hjgv{HypoJetVector(begin, end)};
+std::optional<HypoJetGroupVector> AllJetsGrouper::next(){
+  if (m_done){
+    return std::optional<HypoJetGroupVector>();
+  }
+  
+  HypoJetGroupVector hjgv{HypoJetVector(m_jets)};
+  m_done = true;
   return std::make_optional<HypoJetGroupVector>(hjgv);
 }
 
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/CombinationsGrouper.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/CombinationsGrouper.cxx
index c69f387e4ddf6f77d975767c0b5a2d76bf359270..e05b643e00c4e575c5bb3d70fa1dfebe2b2d97d8 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/CombinationsGrouper.cxx
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/CombinationsGrouper.cxx
@@ -1,13 +1,28 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "TrigHLTJetHypo/TrigHLTJetHypoUtils/CombinationsGrouper.h"
 #include "TrigHLTJetHypo/TrigHLTJetHypoUtils/CombinationsGen.h"
 
 #include <sstream>
+
+CombinationsGrouper::CombinationsGrouper(){}
+
 CombinationsGrouper::CombinationsGrouper(unsigned int groupSize):
-  m_groupSize(groupSize){
+  m_groupSize{groupSize}{}
+
+
+CombinationsGrouper::CombinationsGrouper(unsigned int groupSize,
+					 const HypoJetVector& jets):
+  m_groupSize(groupSize), m_jets{jets}{
+}
+
+
+CombinationsGrouper::CombinationsGrouper(unsigned int groupSize,
+					 const HypoJetCIter& b,
+					 const HypoJetCIter& e):
+  m_groupSize(groupSize), m_jets{b, e}{
 }
 
 
@@ -32,12 +47,12 @@ CombinationsGrouper::group(HypoJetIter& begin, HypoJetIter& end) const {
 }
 
 std::optional<HypoJetGroupVector>
-CombinationsGrouper::next(HypoJetIter& begin, HypoJetIter& end) const {
+CombinationsGrouper::next() {
   HypoJetGroupVector hjgv;
   
   // create a combinations generator. Used to select the jets
   // to be tested by the condition objects
-  CombinationsGen combgen(end-begin, m_groupSize);
+  CombinationsGen combgen(m_jets.size(), m_groupSize);
   
   auto combs = combgen.next();
   if (combs.second == false){
@@ -45,7 +60,7 @@ CombinationsGrouper::next(HypoJetIter& begin, HypoJetIter& end) const {
   }
   
   HypoJetVector v;
-  for(auto i : combs.first){ v.push_back(*(begin + i));}
+  for(auto i : combs.first){ v.push_back(*(m_jets.begin() + i));}
   
   return std::make_optional<HypoJetGroupVector>(hjgv);
 }
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/IndexedJetsGrouper.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/IndexedJetsGrouper.cxx
index d4619f894be4faeb63008927aec2226edc7bc859..1abd209d030ccaf7b58acdac5423e6240711ba41 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/IndexedJetsGrouper.cxx
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/IndexedJetsGrouper.cxx
@@ -22,13 +22,24 @@
 #include "TrigHLTJetHypo/TrigHLTJetHypoUtils/IndexedJetsGrouper.h"
 #include "TrigHLTJetHypo/TrigHLTJetHypoUtils/DescendingEt.h"
 
-IndexedJetsGrouper::IndexedJetsGrouper(const std::vector<unsigned int>& indices):
-  m_indices(indices){
-  if (indices.empty()) {
-    std::string m = "IndexedJetsGrouper: Attempt to iniatialize with an ";
-    m += "empty indices vector";
-    throw std::out_of_range(m); 
-  }
+
+IndexedJetsGrouper::IndexedJetsGrouper(const std::vector<unsigned int>& inds):
+  m_indices(inds){
+}
+
+IndexedJetsGrouper::IndexedJetsGrouper(const std::vector<unsigned int>& indices,
+				       const HypoJetVector& jets):
+  m_indices(indices), m_jets(jets){
+    
+  //sort the indices because the last one will be used to 
+  // check there are enough jets to process;
+  std::sort(m_indices.begin(), m_indices.end());
+}
+
+IndexedJetsGrouper::IndexedJetsGrouper(const std::vector<unsigned int>& indices,
+				       const HypoJetCIter& b,
+				       const HypoJetCIter& e):
+  m_indices(indices), m_jets(b, e){
     
   //sort the indices because the last one will be used to 
   // check there are enough jets to process;
@@ -39,6 +50,9 @@ IndexedJetsGrouper::IndexedJetsGrouper(const std::vector<unsigned int>& indices)
 std::vector<HypoJetGroupVector>
 IndexedJetsGrouper::group(HypoJetIter& begin, HypoJetIter& end) const{
   
+
+  if (m_indices.empty()) {return std::vector<HypoJetGroupVector>{};}
+
   // check if there are enough jets find the highest (last, as the vector is
   // ordered) and see if it lies within the jet vector
   
@@ -65,27 +79,36 @@ IndexedJetsGrouper::group(HypoJetIter& begin, HypoJetIter& end) const{
 
 
 std::optional<HypoJetGroupVector>
-IndexedJetsGrouper::next(HypoJetIter& begin, HypoJetIter& end) const{
+IndexedJetsGrouper::next(){
+
+  // exhausts after a single group
   
   // check if there are enough jets find the highest (last, as the vector is
   // ordered) and see if it lies within the jet vector
+
+  if (m_done) { return std::optional<HypoJetGroupVector>(); }
+  if (m_indices.empty()) { return std::optional<HypoJetGroupVector>(); }
   
   auto hjgv = HypoJetGroupVector();
   auto last_jet_pos =  m_indices.back();
-  if(end - begin - 1 < last_jet_pos){return std::optional<HypoJetGroupVector>();}
+  if (m_jets.size() <= last_jet_pos) {
+    m_done = true;
+    return std::optional<HypoJetGroupVector>();
+  }
   
   // sort jets by descending Et
-  std::partial_sort (begin,
-                     begin + last_jet_pos + 1,
-                     end,
+  std::partial_sort (m_jets.begin(),
+                     m_jets.begin() + last_jet_pos + 1,
+                     m_jets.end(),
                      DescendingEt());
   
   // place the jets at positions in the index vector into the inner vector
   HypoJetVector inner;
-  for (auto i : m_indices){inner.push_back(*(begin + i));}
+  for (auto i : m_indices){inner.push_back(*(m_jets.begin() + i));}
   
   // push the inner vector into the outer vector
   hjgv.push_back(inner);
+  m_done = true;
   return std::make_optional<HypoJetGroupVector>(hjgv);
 }
 
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/PartitionsGrouper.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/PartitionsGrouper.cxx
deleted file mode 100644
index 003caaae10d5a4254d592b7d5b2a2ad19b8639a5..0000000000000000000000000000000000000000
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/PartitionsGrouper.cxx
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-*/
-
-#include "TrigHLTJetHypo/TrigHLTJetHypoUtils/PartitionsGrouper.h"
-#include "TrigHLTJetHypo/TrigHLTJetHypoUtils/PartitionsGen.h"
-#include "TrigHLTJetHypo/TrigHLTJetHypoUtils/HypoJetDefs.h"
-
-#include <sstream>
-PartitionsGrouper::PartitionsGrouper(const std::vector<std::size_t>& mults) :
-  m_mults(mults){
-}
-
-
-std::vector<HypoJetGroupVector>
-PartitionsGrouper::group(HypoJetIter& begin,
-			 HypoJetIter& end) const {
-
-
-  
-  std::vector<HypoJetGroupVector> result;
-
-  auto pg = PartitionsGen(end-begin, m_mults);
-  while(true){
-
-    auto p = pg.next();
-    if(!p.has_value()){break;}
-
-    HypoJetGroupVector hjgv;
-    for(const auto& iv : *p){
-      // iv is a vector of indices
-      HypoJetVector hjv;
-      for(const auto i : iv) {
-	// i is an index
-	hjv.push_back(*(begin + i));
-      }
-      hjgv.push_back(hjv);
-    }
-
-    result.push_back(hjgv);
-  }
-
-  return result;
-}
-
-
-std::optional<HypoJetGroupVector>
-PartitionsGrouper::next(HypoJetIter& begin,
-			HypoJetIter& end) const {
-
-  auto pg = PartitionsGen(end-begin, m_mults);
-
-  auto p = pg.next();
-  
-  if(!p.has_value()){
-    return std::optional<HypoJetGroupVector>();
-  }
-
-  HypoJetGroupVector hjgv;
-  for(const auto& iv : *p){
-    // iv is a vector of indices
-    HypoJetVector hjv;
-    for(const auto i : iv) {
-      // i is an index
-      hjv.push_back(*(begin + i));
-    }
-    hjgv.push_back(hjv);
-  }
-  
-  return std::make_optional<HypoJetGroupVector>(hjgv);
-}
-
-
-std::string PartitionsGrouper::getName() const {
-  return "PartitionsGrouper";
-}
-
-std::string PartitionsGrouper::toString() const {
-
-  std::stringstream ss;
-
-  ss << "PartitionsGrouper - allocate jets to Conditions. jets/condition: ";
-  for(const auto & i : m_mults){ss << i << " ";}
-  ss << '\n';
-  return ss.str();
-}
-
-
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/SingleJetGrouper.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/SingleJetGrouper.cxx
index 12df76c5c21ee53a267c1fc7303763c717148f3e..80441003fc073e648cd432ff0d7c48e109d87be8 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/SingleJetGrouper.cxx
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/SingleJetGrouper.cxx
@@ -1,9 +1,20 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "TrigHLTJetHypo/TrigHLTJetHypoUtils/SingleJetGrouper.h"
 
+
+SingleJetGrouper::SingleJetGrouper(){}
+
+SingleJetGrouper::SingleJetGrouper(const HypoJetVector& v): m_jets(v){
+}
+
+SingleJetGrouper::SingleJetGrouper(const HypoJetCIter& b,
+				   const HypoJetCIter& e):
+  m_jets(b, e){
+}
+
 std::vector<HypoJetGroupVector> SingleJetGrouper::group(HypoJetIter& begin,
 							HypoJetIter& end
 							) const {
@@ -18,17 +29,14 @@ std::vector<HypoJetGroupVector> SingleJetGrouper::group(HypoJetIter& begin,
 }
 
 std::optional<HypoJetGroupVector>
-SingleJetGrouper::next(HypoJetIter& begin,
-		       HypoJetIter& end
-		       ) const {
-  HypoJetGroupVector hjgv;
-  for(; begin != end; ++begin){
-    HypoJetVector v;
-    v.push_back(*begin);
-    hjgv.push_back(v);
+SingleJetGrouper::next() {
+  if (m_index == m_size){
+    return std::optional<HypoJetGroupVector>();
   }
   
-  return std::make_optional<HypoJetGroupVector>(hjgv);
+  HypoJetGroupVector result;
+  result.push_back(HypoJetVector{m_jets[m_index++]});
+  return std::make_optional<HypoJetGroupVector>(result);
 }
 
 std::string SingleJetGrouper::getName() const {
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetConditionConfig_capacitychecked.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetConditionConfig_capacitychecked.cxx
index 94be844cd6b0673dd86622258fd6eb814892b093..7e6b83429a575f303a08c2a93ffa8d3db86cd565 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetConditionConfig_capacitychecked.cxx
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetConditionConfig_capacitychecked.cxx
@@ -35,7 +35,8 @@ TrigJetConditionConfig_capacitychecked::getCapacityCheckedCondition() const {
   auto cc =  std::make_unique<CompoundConditionMT>(elements);
 
   return std::make_unique<CapacityCheckedCondition>(std::move(cc),
-						    m_multiplicity);
+						    m_multiplicity,
+						    m_chainLegLabel);
 }
 				     
 
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetConditionConfig_capacitychecked.h b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetConditionConfig_capacitychecked.h
index 7f7b4031ef8903673fffe78762bcf95c2e317d37..c96b40a34059c35a3c48f7c60d0aa4a37ddc6376 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetConditionConfig_capacitychecked.h
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetConditionConfig_capacitychecked.h
@@ -35,6 +35,14 @@ public extends<AthAlgTool, ITrigJetCapacityCheckedConditionConfig> {
   Gaudi::Property<std::size_t> m_multiplicity {this, "multiplicity", {1},
       "no. of occurences of identical condition"};
 
+  
+  Gaudi::Property<std::string> m_chainLegLabel {this,
+    "chainLegLabel",
+    {""},
+    "identifier for chain leg - used to group jets for jet hypo clients "};
+
+
+
   StatusCode checkVals()  const;
  
 };
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoAlgMT.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoAlgMT.cxx
index 12e20c532fcad7afaa9e795f4bd75d2bb629e287..6ef03eaee4841d1675d8130e495ec028577dd381 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoAlgMT.cxx
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoAlgMT.cxx
@@ -1,9 +1,8 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #include <algorithm>
-#include "Gaudi/Property.h"
 #include "TrigJetHypoAlgMT.h"
 #include "TrigCompositeUtils/HLTIdentifier.h"
 #include "TrigCompositeUtils/TrigCompositeUtils.h"
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolConfig_fastreduction.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolConfig_fastreduction.cxx
index 06a7b234ac8b30dca7ce6f3be04860cc3878e5f5..f407bcf776c44e383135eb661b09e5397aa64acd 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolConfig_fastreduction.cxx
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolConfig_fastreduction.cxx
@@ -11,7 +11,6 @@
 
 #include "TrigHLTJetHypo/TrigHLTJetHypoUtils/SingleJetGrouper.h"
 #include "TrigHLTJetHypo/TrigHLTJetHypoUtils/xAODJetAsIJetFactory.h"
-// #include "TrigHLTJetHypo/TrigHLTJetHypoUtils/groupsMatcherFactory.h"
 #include "TrigHLTJetHypo/TrigHLTJetHypoUtils/CleanerFactory.h"
 #include "TrigHLTJetHypo/TrigHLTJetHypoUtils/TrigHLTJetHypoHelper2.h"
 #include "./groupsMatcherFactoryMT.h"
@@ -46,25 +45,6 @@ StatusCode TrigJetHypoToolConfig_fastreduction::initialize() {
     return StatusCode::FAILURE;
   }
   
-  // gymnastics as cannot pass vecor<vecotr<int>> as a Gaudi::Property
-  if(m_sharedNodesVec.empty()){
-    ATH_MSG_ERROR("shared node vector empty");
-
-    return StatusCode::FAILURE;}
-
-  std::vector<int> shared;
-  for(const auto& i : m_sharedNodesVec){
-    if(i  == -1){
-      m_sharedNodes.push_back(shared);
-      shared = std::vector<int>();
-    } else {
-      shared.push_back(i);
-    }
-  }
-  if(!shared.empty()){
-    m_sharedNodes.push_back(shared);
-  }
-
   
   /* set the capacity of the acceptAll nodes (or nay
      nodes with modifiable capciity.
@@ -176,8 +156,7 @@ TrigJetHypoToolConfig_fastreduction::getMatcher () const {
   }
 
   return groupsMatcherFactoryMT_FastReduction(std::move(*opt_conds),
-					      m_treeVec,
-					      m_sharedNodes);
+					      m_treeVec);
 }
 
 StatusCode TrigJetHypoToolConfig_fastreduction::checkVals() const {
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolConfig_fastreduction.h b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolConfig_fastreduction.h
index 008405edf4d50a944893da8a6dd1254dfc4e7dfc..26a33fe89d6c5d78534ddfbd548e17c318e5e9e3 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolConfig_fastreduction.h
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolConfig_fastreduction.h
@@ -53,10 +53,8 @@ public extends<AthAlgTool, ITrigJetHypoToolConfig> {
   Gaudi::Property<std::vector<std::size_t>> m_treeVec{
     this, "treeVector", {}, "integer sequence representation of jet hypo tree"};
 
-  Gaudi::Property<std::vector<int>> m_sharedNodesVec{
-    this, "sharedVector", {}, "nodeID groups for nodes that see input jets"};
-
-  std::vector<std::vector<int>> m_sharedNodes{};
+  Gaudi::Property<std::vector<int>> m_leafNodes{
+    this, "leafVector", {}, "node ids for leaf nodes"};
 
   std::optional<ConditionPtrs> getCapacityCheckedConditions() const;
 
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolMT.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolMT.cxx
index 63ab69cb60f45da312add040cdf573c1c7123e39..448bd35a3cd2635e16d4c473e3eeec9e5da2d0d3 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolMT.cxx
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolMT.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 // ********************************************************************
@@ -23,6 +23,8 @@
 #include "TrigCompositeUtils/HLTIdentifier.h"
 #include "TrigCompositeUtils/TrigCompositeUtils.h"
 
+#include <sstream>
+
 using TrigCompositeUtils::DecisionID;
 using TrigCompositeUtils::Decision;
 using TrigCompositeUtils::DecisionContainer;
@@ -120,8 +122,22 @@ TrigJetHypoToolMT::decide(const xAOD::JetContainer* jets,
       infocollector->
 	collect(name(),
 		"no of xAODJets " + std::to_string(participating_jets.size()));
+
+      auto labels = jetCollector.legLabels();
+      std::stringstream ss;
+      
+      for(const auto& label : labels){
+	auto jets = jetCollector.xAODJets(label);
+	ss << label << " [\n";
+	for(const auto& j : jets){
+	  ss << static_cast<const void*>(j) << '\n';
+	}
+	ss << "]\n";
+      }
+      infocollector->collect(name(), ss.str());
     }
 
+
     for (auto& pair : jetHypoInputs) { 
       auto it = std::find(participating_jets.begin(),
                           participating_jets.end(),
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolMT.h b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolMT.h
index 3eb88c784342294ca141737b865752f3067ac8bb..b16024c67da37af3ed714241892128af3d79e0d2 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolMT.h
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetHypoToolMT.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRIGJETHYPOTOOLMT_H
@@ -23,6 +23,8 @@
 #include "xAODEventInfo/EventInfo.h"
 #include "xAODJet/JetContainer.h"
 
+#include <string>
+
 struct EventSN{
   std::size_t m_id{0};
   std::size_t getSN(){return m_id++;}
@@ -60,8 +62,11 @@ public:
   ToolHandle<ITrigJetHypoToolHelperMT> m_helper {
     this, "helper_tool", {}, "Jet hypo helper AlgTool"};
   
-  Gaudi::Property<bool>
-    m_visitDebug {this, "visit_debug", false, "debug flag"};
+  Gaudi::Property<bool> m_visitDebug {
+    this, "visit_debug", false, "debug flag"};
+
+  Gaudi::Property<std::string> m_chainName {
+    this, "chain_name", {}, "chain name"};
   
   
   std::unique_ptr<EventSN> m_eventSN;
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetTLAHypoAlgMT.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetTLAHypoAlgMT.cxx
index 894cc90bcbe6a4529d4137d4db82a698f16aa1bc..950268afffe59f4485498a169323b58c7cb2b1c5 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetTLAHypoAlgMT.cxx
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigJetTLAHypoAlgMT.cxx
@@ -1,9 +1,8 @@
 /*
-   Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+   Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
    */
 
 #include <algorithm>
-#include "Gaudi/Property.h"
 #include "TrigJetTLAHypoAlgMT.h"
 #include "TrigCompositeUtils/HLTIdentifier.h"
 #include "TrigCompositeUtils/TrigCompositeUtils.h"
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/groupsMatcherFactoryMT.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/groupsMatcherFactoryMT.cxx
index a580b25257e508076ea4c922811da62bac5ac510..b34ebadffb584129d617aa6e72c7055113d2bee4 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/groupsMatcherFactoryMT.cxx
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/groupsMatcherFactoryMT.cxx
@@ -3,8 +3,6 @@
 */
 
 #include "./groupsMatcherFactoryMT.h"
-#include "./MaximumBipartiteGroupsMatcherMT.h"
-#include "./PartitionsGroupsMatcherMT.h"
 #include "./SingleConditionMatcherMT.h"
 #include "./FastReductionMatcher.h"
 
@@ -18,45 +16,16 @@ groupsMatcherFactoryMT_SingleCondition (ConditionsMT&& conditions){
   return std::make_unique<SingleConditionMatcherMT>(std::move(conditions[0]));
 }
 
-std::unique_ptr<IGroupsMatcherMT> 
-groupsMatcherFactoryMT_MaxBipartite (ConditionsMT&& conditions){
-
-  if (conditions.empty()){
-    return std::make_unique<SingleConditionMatcherMT>(nullptr);
-  }
-
-  // check the number of conditions to decide the Matcher type.
-  if (conditions.size() == 1) {
-    return std::make_unique<SingleConditionMatcherMT>(std::move(conditions[0]));
-  } else {
-    return std::make_unique<MaximumBipartiteGroupsMatcherMT>(std::move(conditions));
-  }
-  
-}
-
-
-std::unique_ptr<IGroupsMatcherMT> 
-groupsMatcherFactoryMT_Partitions (ConditionsMT&& conditions){
-  
-  if (conditions.size() == 1) {
-    return std::make_unique<SingleConditionMatcherMT>(std::move(conditions[0]));
-  } else {
-    return std::make_unique<PartitionsGroupsMatcherMT>(std::move(conditions));
-  }
-}
-
 
 std::unique_ptr<IGroupsMatcherMT> 
 groupsMatcherFactoryMT_FastReduction (ConditionPtrs&& conditions,
-				      const std::vector<std::size_t>& treeVec,
-				      const std::vector<std::vector<int>>& sharedNodes){
+				      const std::vector<std::size_t>& treeVec){
   
   if (conditions.size() == 1) {
     return std::make_unique<SingleConditionMatcherMT>(std::move(conditions[0]));
   } else {
     return std::make_unique<FastReductionMatcher>(std::move(conditions),
-						  treeVec,
-						  sharedNodes);
+						  treeVec);
   } 
 }
 
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/groupsMatcherFactoryMT.h b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/groupsMatcherFactoryMT.h
index 1865de3d94bf3f4a37849b295db109fa3c1a7924..b91b74c3df2786e801e0cf1f1c410097ed48a22b 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/groupsMatcherFactoryMT.h
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/groupsMatcherFactoryMT.h
@@ -16,12 +16,7 @@ groupsMatcherFactoryMT_SingleCondition(ConditionsMT&&);
 std::unique_ptr<IGroupsMatcherMT>
 groupsMatcherFactoryMT_MaxBipartite(ConditionsMT&&);
 
-std::unique_ptr<IGroupsMatcherMT>
-groupsMatcherFactoryMT_Partitions(ConditionsMT&&);
-
-
 std::unique_ptr<IGroupsMatcherMT>
 groupsMatcherFactoryMT_FastReduction(ConditionPtrs&&,
-				     const std::vector<std::size_t>& treeVec,
-				     const std::vector<std::vector<int>>&);
+				     const std::vector<std::size_t>& treeVec);
 #endif
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/xAODJetCollector.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/xAODJetCollector.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..646b1dbb682ac25fd1eb4fbde0cc2392b5fe4db2
--- /dev/null
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/xAODJetCollector.cxx
@@ -0,0 +1,108 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include  "xAODJetCollector.h"
+
+#include <algorithm>
+#include <cassert>
+
+void xAODJetCollector::addJets(const HypoJetCIter& begin,
+			       const HypoJetCIter& end,
+			       const std::string& label){
+  auto& jets = m_jets[label];
+  jets.insert(jets.end(), begin, end);
+}
+  
+
+std::vector<const xAOD::Jet*> xAODJetCollector::xAODJets() const {
+  
+  HypoJetVector all;
+  for (const auto& p : m_jets){
+    std::copy(p.second.cbegin(),
+	      p.second.cend(),
+	      std::back_inserter(all)
+	      );
+  }
+  return xAODJets_(all.cbegin(), all.cend());
+}
+
+
+std::vector<const xAOD::Jet*>
+xAODJetCollector::xAODJets(const std::string& label) const {
+  
+  if (m_jets.count(label) == 0){
+    std::vector<const xAOD::Jet*> empty;
+    return empty;
+  }
+  
+  const auto& jets = m_jets.at(label);
+  return xAODJets_(jets.cbegin(), jets.cend());
+}
+
+  
+HypoJetVector xAODJetCollector::hypoJets() const {
+  HypoJetVector all;
+  for (const auto& p : m_jets){
+    std::copy(p.second.cbegin(),
+	      p.second.cend(),
+	      std::back_inserter(all)
+	      );
+  }
+  HypoJetSet js(all.begin(), all.end());
+  return HypoJetVector(js.begin(), js.end());
+}
+
+  
+HypoJetVector xAODJetCollector::hypoJets(const std::string& label) const {
+  auto begin = m_jets.at(label).cbegin();
+  auto end = m_jets.at(label).cend();
+  HypoJetSet js(begin, end);
+  return HypoJetVector(js.begin(), js.end());
+}
+
+
+void xAODJetCollector::addOneJet(const pHypoJet jet,
+				 const std::string& label){
+  m_jets[label].push_back(jet);
+}
+
+
+std::size_t xAODJetCollector::size() const {return hypoJets().size();}
+
+bool xAODJetCollector::empty() const {return hypoJets().empty();}
+
+std::vector<const xAOD::Jet*>
+xAODJetCollector::xAODJets_(const HypoJetVector::const_iterator begin,
+			    const HypoJetVector::const_iterator end
+			    )  const {
+  
+  HypoJetVector hypoJets(begin, end);
+  
+  auto new_end =
+    std::partition(hypoJets.begin(),
+		   hypoJets.end(),
+		   [](const pHypoJet& j){
+		     return (j->xAODJet()).has_value();});
+  // add xAOD::Jet* to m_jets
+  std::vector<const xAOD::Jet*> xJets;
+  xJets.reserve(new_end - hypoJets.begin());
+  std::transform(hypoJets.begin(),
+		 new_end,
+		 back_inserter(xJets),
+		 [](const pHypoJet j){return *(j->xAODJet());});
+  
+  std::set<const xAOD::Jet*> js(xJets.begin(), xJets.end());
+  return std::vector<const xAOD::Jet*> (js.begin(), js.end());
+}
+
+
+std::vector<std::string>  xAODJetCollector::legLabels() const {
+  std::vector<std::string> labels;
+
+  for(auto it = m_jets.begin(); it != m_jets.end(); ++it){
+    labels.push_back(it->first);
+  }
+
+  return labels;
+}
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/xAODJetCollector.h b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/xAODJetCollector.h
index f6c6cdb026fee9071eea39ae34d1eeab66dc3699..74b03b97301b46ea8664ecd82cce1325e46d8bc3 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/xAODJetCollector.h
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/xAODJetCollector.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRIGLHLTJETHYPO_XAODJETCOLLECTOR_H
@@ -8,59 +8,49 @@
 #include  "xAODJet/Jet.h"
 #include  "TrigHLTJetHypo/TrigHLTJetHypoUtils/HypoJetDefs.h"
 
+#include <string>
 #include <vector>
-#include <algorithm>
-#include <cassert>
+#include <map>
 
 // xAODJetCollector - an object send to a (possibly recursive)
 // TrigJetHypoToolHelpers to obtain xAOD jets
 
+using CI = std::map<std::string, HypoJetVector>::const_iterator;
 
 class xAODJetCollector {
 
 public:
 
-  void addJets(const HypoJetCIter& begin, const HypoJetCIter& end){
-    m_jets.insert(m_jets.end(), begin, end);
-  }
+  void addJets(const HypoJetCIter& begin,
+	       const HypoJetCIter& end,
+	       const std::string& label="");
   
-  std::vector<const xAOD::Jet*> xAODJets() const {
+  std::vector<const xAOD::Jet*> xAODJets() const;
     
-    HypoJetVector hypoJets(m_jets.begin(), m_jets.end());
-    
-    auto new_end =
-      std::partition(hypoJets.begin(),
-		     hypoJets.end(),
-		     [](const pHypoJet& j){
-		       return (j->xAODJet()).has_value();});
-    // add xAOD::Jet* to m_jets
-    std::vector<const xAOD::Jet*> xJets;
-    xJets.reserve(new_end - hypoJets.begin());
-    std::transform(hypoJets.begin(),
-		   new_end,
-		   back_inserter(xJets),
-		   [](const pHypoJet j){return *(j->xAODJet());});
-
-    std::set<const xAOD::Jet*> js(xJets.begin(), xJets.end());
-    return std::vector<const xAOD::Jet*> (js.begin(), js.end());
-  }
-
-  
-  HypoJetVector hypoJets() const {
-    HypoJetSet js(m_jets.begin(), m_jets.end());
-    return HypoJetVector(js.begin(), js.end());
-  }
+  std::vector<const xAOD::Jet*> xAODJets(const std::string& label) const;
   
-  void addOneJet(const pHypoJet jet){
-    m_jets.push_back(jet);
-  }
+  HypoJetVector hypoJets() const;
+  HypoJetVector hypoJets(const std::string& label) const;
+
+  void addOneJet(const pHypoJet jet, const std::string& label="");
+
+  std::size_t size() const;
+  bool empty() const;
+
 
-  std::size_t size() const {return m_jets.size();}
-  bool empty() const {return m_jets.empty();}
- 
+  std::vector<std::string> legLabels() const;
+  
  private:
-  HypoJetVector m_jets;
 
+  std::map<std::string, HypoJetVector> m_jets;
+
+    
+  std::vector<const xAOD::Jet*>
+
+  xAODJets_(const HypoJetVector::const_iterator begin,
+	    const HypoJetVector::const_iterator end
+	    )  const;
+    
 };
 
 #endif
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypoUnitTests/CMakeLists.txt b/Trigger/TrigHypothesis/TrigHLTJetHypoUnitTests/CMakeLists.txt
index b04652d5be4fbc4753af892140a9c4790a2f7751..4b33b0daaaf3659e0275769404c7680e105938d1 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypoUnitTests/CMakeLists.txt
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypoUnitTests/CMakeLists.txt
@@ -33,15 +33,9 @@ atlas_add_test( TrigHLTJetHypoUnitTests
    tests/FlowNetworkTest.cxx
    tests/LlpCleanerTest.cxx
    tests/LooseCleanerTest.cxx
-   tests/MaximumBipartiteGroupsMatcherTest.cxx
-   tests/MaximumBipartiteGroupsMatcherMTTest.cxx
-   tests/MaximumBipartiteGroupsMatcherMTTest_Multijet.cxx
-   tests/PartitionsGenTest.cxx
-   tests/PartitionsGroupsMatcherMTTest.cxx
    tests/TLorentzVectorFactoryTest.cxx
    tests/TightCleanerTest.cxx
    tests/xAODJetCollectorTest.cxx
-   tests/PartitionsGrouperTest.cxx
    INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${GMOCK_INCLUDE_DIRS}
    LINK_LIBRARIES ${ROOT_LIBRARIES} GoogleTestTools ${GMOCK_LIBRARIES} TrigHLTJetHypoLib TrigHLTJetHypoUnitTestsLib )
    
diff --git a/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref b/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref
index 1e095131beaefed0fda49496984811d501b1f70a..0fdb435fcab75227fe5e7d7d1bdce68afb7ed6ff 100644
--- a/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref
+++ b/Trigger/TrigValidation/TrigAnalysisTest/share/ref_RDOtoRDOTrig_v1Dev_build.ref
@@ -1407,7 +1407,7 @@ HLT_j0_vbenfSEP30etSEP34mass35SEP50fbet_L1J20:
   stepCounts:
     0: 15
   stepFeatures:
-    0: 398
+    0: 383
 HLT_j225_subjesgscIS_ftf_bmv2c1040_split_L1J100:
   eventCount: 0
   stepCounts:
diff --git a/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref b/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref
index d13160e0eca60beee89ff1b3e1a624203a4305b9..284043489a41b0151532b3ef18af89b8dc7dff42 100644
--- a/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref
+++ b/Trigger/TrigValidation/TriggerTest/share/ref_data_v1Dev_build.ref
@@ -657,7 +657,7 @@ HLT_j0_vbenfSEP30etSEP34mass35SEP50fbet_L1J20:
   stepCounts:
     0: 2
   stepFeatures:
-    0: 24
+    0: 17
 HLT_j225_subjesgscIS_ftf_bmv2c1040_split_L1J100:
   eventCount: 0
 HLT_j260_320eta490_L1J20: