diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/CMakeLists.txt b/Trigger/TrigHypothesis/TrigHLTJetHypo/CMakeLists.txt
index db084379c835ed86ea22a74d064f2e3418ce0167..cc54850ec42a38d961abb1bab5c34d9ee9ded075 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/CMakeLists.txt
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/CMakeLists.txt
@@ -31,3 +31,6 @@ atlas_add_component( TrigHLTJetHypo
                      INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
                      LINK_LIBRARIES ${ROOT_LIBRARIES} xAODJet GaudiKernel TrigParticle TrigSteeringEvent TrigInterfacesLib TrigTimeAlgsLib TrigHLTJetHypoLib )
 
+# Install files from the package:
+atlas_install_python_modules( python/*.py )
+
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypo.h b/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypo.h
index 4361b7790eb0aa95caccbd869656a539988237dd..17a681456522a0a38ffad060f8991857b3866f88 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypo.h
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypo.h
@@ -122,7 +122,13 @@ class TrigHLTJetHypo : public HLT::HypoAlgo {
   float m_hecqLlpThreshold;
   float m_avLarQFLlpThreshold;
 
-  // std::shared_ptr<ICleaner> m_cleaner;
+  //Heavy Particle 2016
+  double m_innerMassMin0;
+  double m_innerMassMax0;
+  double m_innerMassMin1;
+  double m_innerMassMax1;
+  double m_outerMassMin;
+  double m_outerMassMax;
 
   // Timing:
 
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/CombinationsGen.h b/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/CombinationsGen.h
index 8decc27a1d58f474ebf48101a30cda91751a31c9..11320c09c3fdde0f8ecea54aea9aedcff15bb46f 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/CombinationsGen.h
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/CombinationsGen.h
@@ -8,6 +8,7 @@
 #include <algorithm>
 #include <string>
 #include <vector>
+#include <sstream>
 
 /* 
 Combinations generator. Given n, k > 0, n>= k, next() returns the
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/HeavyMass2016Condition.h b/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/HeavyMass2016Condition.h
new file mode 100644
index 0000000000000000000000000000000000000000..46dc5abfbc3969de2c5d8794a90d8e2797cc6789
--- /dev/null
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/HeavyMass2016Condition.h
@@ -0,0 +1,57 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TRIGHLTJETHYPO_HEAVYMASS2016CONDITION_H
+#define TRIGHLTJETHYPO_HEAVYMASS2016CONDITION_H
+
+/********************************************************************
+ *
+ * NAME:     TrigHLTJetHypo.h
+ * PACKAGE:  Trigger/TrigHypothesis/TrigHLTJetHypo
+ *
+ * AUTHOR:   P. Sherwood
+ * CREATED:  May 09, 2016
+ *           
+ *
+ * Conditions object that searches for a particle P0 that decays to particles
+ * P1 and P2  that decay to two jets each. Mass window cuts are applied
+ * to P0, P1, P2.
+ *
+ *********************************************************************/
+
+#include <string>
+#include "TrigHLTJetHypo/TrigHLTJetHypoUtils/ICondition.h"
+
+namespace HypoJet{
+  class IJet;
+}
+
+class HeavyMass2016Condition: public ICondition{
+ public:
+  HeavyMass2016Condition(double innerMassMin0, 
+                         double innerMassMax0,
+                         double innerMassMin1, 
+                         double innerMassMax1, 
+                         double outerMassMin, 
+                         double outerMassMax);
+
+  ~HeavyMass2016Condition() override {}
+
+  bool isSatisfied(const HypoJetVector&) const override;
+
+  double orderingParameter() const noexcept override;
+
+  std::string toString() const noexcept override;
+
+ private:
+
+  double m_innerMassMin0;
+  double m_innerMassMax0;
+  double m_innerMassMin1;
+  double m_innerMassMax1;
+  double m_outerMassMin;
+  double m_outerMassMax;
+};
+
+#endif
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/SimpleJetsMatcher.h b/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/SimpleJetsMatcher.h
new file mode 100644
index 0000000000000000000000000000000000000000..b6c118bcba81d4e3986d314fbd9d2c3227ebcb21
--- /dev/null
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/SimpleJetsMatcher.h
@@ -0,0 +1,49 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TRIGHLTJETHYPO_SIMPLEJETSMATCHER_H
+#define TRIGHLTJETHYPO_SIMPLEJETSMATCHER_H
+
+
+// ********************************************************************
+//
+// NAME:     SimpleJetsMatcher.h
+// PACKAGE:  Trigger/TrigHypothesis/TrigHLTJetHypo
+//
+// AUTHOR:  P Sherwood
+//
+// ********************************************************************
+//
+
+
+#include "TrigHLTJetHypo/TrigHLTJetHypoUtils/IMatcher.h"
+#include "TrigHLTJetHypo/TrigHLTJetHypoUtils/Matcher.h"
+#include "TrigHLTJetHypo/TrigHLTJetHypoUtils/ConditionsDefs.h"
+#include "TrigHLTJetHypo/TrigHLTJetHypoUtils/HypoJetDefs.h"
+#include <utility>
+#include <sstream>
+
+class SimpleJetsMatcher: virtual public IMatcher, private Matcher{
+  /* Match by ordering all jets in the single eta region
+     in Et, pair of with the Conditions objects also ordered
+     in Et. Event pass if the Et of each jet >= to the threshold
+     of the paired Condition.
+   */
+public:
+  SimpleJetsMatcher(const Conditions& cs, 
+		      const std::string& name);
+  ~SimpleJetsMatcher(){}
+  void match(const HypoJetIter&, const HypoJetIter&) override;
+  bool pass() const override;
+  const HypoJetVector& passedJets() const noexcept override;
+  const HypoJetVector& failedJets() const noexcept override;
+  std::string toString() const noexcept override;
+  const Conditions& getConditions() const noexcept override;
+private:
+  Conditions m_conditions;
+  HypoJetVector m_passed_jets;
+  HypoJetVector m_failed_jets;
+  bool m_pass;
+};
+#endif
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/matcherFactory.h b/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/matcherFactory.h
index b2e4a8e90343e6e5ee5562a5a31719f557dc4bed..6e6f3b77ddd9e8f8daa8cdb61d4a004de987119e 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/matcherFactory.h
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/TrigHLTJetHypo/TrigHLTJetHypoUtils/matcherFactory.h
@@ -43,11 +43,23 @@ class OrderedCollectionsMatcherFactory: public IMatcherFactory {
 };
 
 
+class SimpleJetsMatcherFactory: public IMatcherFactory {
+ public:
+  SimpleJetsMatcherFactory(const Conditions&, 
+                           const std::string&);
+
+  std::shared_ptr<IMatcher> make() const override;
+ private:
+  Conditions m_conditions;
+  std::string m_name;
+};
+
+
 class SelectedJetsMatcherFactory: public IMatcherFactory {
  public:
   SelectedJetsMatcherFactory(const Conditions&, 
-			     const std::vector<unsigned int>& indices,
-			     const std::string&);
+                             const std::vector<unsigned int>& indices,
+                             const std::string&);
 
   std::shared_ptr<IMatcher> make() const override;
  private:
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/cmt/requirements b/Trigger/TrigHypothesis/TrigHLTJetHypo/cmt/requirements
index 346269bc7f467ac955b44b256274230563b58633..b694003d8bc5d3c969823e742a82f7f8befe91ea 100755
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/cmt/requirements
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/cmt/requirements
@@ -23,6 +23,7 @@ macro_append TrigHLTJetHypo_include_dirs /TrigHLTJetHypoUtils
 # application TrigHLTJetHypoTests TrigHLTJetHypoTests.cxx
 # macro_append  TrigHLTJetHypoTests_dependencies TrigHLTJetHypoLib
 
+
 private
 # for TLorentzVector
 use     AtlasROOT               AtlasROOT-*             External
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/python/__init__.py b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..74583d364ec2ca794156596c7254d9b234a940c6
--- /dev/null
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/python/__init__.py
@@ -0,0 +1,2 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypo.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypo.cxx
index cdb2542cff2a644713ff5383016c997f6c982779..da9fe4340ee2eb3149ae44fa8f1a78362866bb2c 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypo.cxx
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypo.cxx
@@ -66,6 +66,14 @@ TrigHLTJetHypo::TrigHLTJetHypo(const std::string& name,
   declareProperty("mass_maxs", m_massMaxs);
   declareProperty("jetvec_indices",   m_jetvec_indices);
 
+  // Heavy object parameters
+  declareProperty("innerMassMin0", m_innerMassMin0);
+  declareProperty("innerMassMax0", m_innerMassMax0);
+  declareProperty("innerMassMin1", m_innerMassMin1);
+  declareProperty("innerMassMax1", m_innerMassMax1);
+  declareProperty("outerMassMin", m_outerMassMin);
+  declareProperty("outerMassMax", m_outerMassMax);
+
   // cleaning
   declareProperty("cleaningAlg", m_cleaningAlg = "noCleaning");
 
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/HeavyMass2016Condition.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/HeavyMass2016Condition.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..2e689469ac5028e4106c9407c76d894e25dc106c
--- /dev/null
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/HeavyMass2016Condition.cxx
@@ -0,0 +1,107 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "TrigHLTJetHypo/TrigHLTJetHypoUtils/HeavyMass2016Condition.h"
+#include "TrigHLTJetHypo/TrigHLTJetHypoUtils/IJet.h"
+#include "TrigHLTJetHypo/TrigHLTJetHypoUtils/CombinationsGen.h"
+
+
+#include <sstream>
+#include <cmath>
+#include <TLorentzVector.h>
+#include <set>
+#include <vector>
+
+bool in_mass_window(const std::vector<int>& indices,
+                    const HypoJetVector& jets,
+                    double mass_lo,
+                    double mass_hi){
+
+  std::vector<TLorentzVector> selected;
+  auto first = jets.begin();
+
+  TLorentzVector sumVector;
+  for(auto i : indices){sumVector += (*(first+i))->p4();}
+
+  auto mass = sumVector.M();
+  return mass >= mass_lo and mass < mass_hi;
+}
+
+HeavyMass2016Condition::HeavyMass2016Condition(double innerMassMin0, 
+                                                   double innerMassMax0,
+                                                   double innerMassMin1, 
+                                                   double innerMassMax1,
+                                                   double outerMassMin,
+                                                   double outerMassMax):
+  m_innerMassMin0(innerMassMin0),
+  m_innerMassMax0(innerMassMax0),
+  m_innerMassMin1(innerMassMin1),
+  m_innerMassMax1(innerMassMax1),
+  m_outerMassMin(outerMassMin),
+  m_outerMassMax(outerMassMax){
+  }
+  
+bool HeavyMass2016Condition::isSatisfied(const HypoJetVector& ips) const {
+
+  auto njets = ips.size();
+  
+  CombinationsGen combgen0(njets, 2);
+  
+  while(true){
+    auto combs0 = combgen0.next();
+    if(!combs0.second){break;} // combination indices are  invalid
+    auto daughters0 = combs0.first;
+
+    if(!in_mass_window(daughters0, ips, m_innerMassMin0, m_innerMassMax0)){
+      continue;
+    }
+
+    CombinationsGen combgen1(njets, 2);
+    while(true){
+      auto combs1 = combgen1.next();
+      if(!combs1.second){break;} // combination indices are  invalid
+      auto daughters1 = combs1.first;
+      
+      if(!in_mass_window(daughters1, ips, m_innerMassMin1, m_innerMassMax1)){
+        continue;
+      }
+        
+      std::vector<int> all_indices(daughters0.begin(), daughters0.end());
+      all_indices.insert(all_indices.end(),
+                         daughters1.begin(),
+                         daughters1.end());
+
+      // remove daughter collections that share jets
+      std::set<int> unique(all_indices.begin(), all_indices.end());
+      if (unique.size() != all_indices.size()){continue;}
+
+      return in_mass_window(all_indices, ips, m_outerMassMin, m_outerMassMax);
+    }
+  }
+  return false;
+}
+
+
+std::string HeavyMass2016Condition::toString() const noexcept {
+  std::stringstream ss;
+  ss << " HeavyMass2016Condition:"
+     << " inner mass window0 min "
+     <<  m_innerMassMin0
+     << " inner mass window0 max "
+     <<  m_innerMassMax0
+     << " inner mass window1 min "
+     <<  m_innerMassMin1
+     << " inner mass window1 max "
+     <<  m_innerMassMax1
+     << " outer mass window min "
+     <<  m_outerMassMin
+     << " outer mass window max "
+     <<  m_outerMassMax
+     <<'\n';
+
+  return ss.str();
+}
+
+
+double HeavyMass2016Condition::orderingParameter() const noexcept {return 0.0;}
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/SimpleJetsMatcher.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/SimpleJetsMatcher.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..37435ec20a1828a72f2e9e135edac79a615529eb
--- /dev/null
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/SimpleJetsMatcher.cxx
@@ -0,0 +1,86 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// ********************************************************************
+//
+// NAME:     SimpleJetsMatcher.cxx
+// PACKAGE:  Trigger/TrigHypothesis/TrigHLTJetHypo
+//
+// AUTHOR:   P Sherwood
+//
+// Passes all jets to all conditions objects.
+//
+// ********************************************************************
+//
+
+#include <algorithm>
+#include <stdexcept>
+#include <vector>
+
+#include "TrigHLTJetHypo/TrigHLTJetHypoUtils/SimpleJetsMatcher.h"
+#include "TrigHLTJetHypo/TrigHLTJetHypoUtils/IJet.h"
+#include "TrigHLTJetHypo/TrigHLTJetHypoUtils/DescendingEt.h"
+
+SimpleJetsMatcher::SimpleJetsMatcher(const Conditions& cs,
+					 const std::string& name
+					 ): Matcher(name), m_conditions(cs), m_pass(false){
+}
+
+  
+void SimpleJetsMatcher::match(const HypoJetIter& jets_b,
+				const HypoJetIter& jets_e){
+  
+  m_passed_jets.clear(); // allow monitoring of the jets that pass conditions.
+  m_failed_jets.clear();
+
+  HypoJetVector selected_jets(jets_b, jets_e);
+  
+  //  Hypo passes if at least one condition object accepts the
+  // selected jets.
+  m_pass = false;
+  for(auto c : m_conditions){
+    if (c.isSatisfied(selected_jets)){
+      m_pass = true;
+      break;
+    }
+  }
+  
+  if(m_pass){
+    m_passed_jets.assign(selected_jets.begin(),
+			 selected_jets.end());
+  } else {
+    m_failed_jets.assign(selected_jets.begin(),
+			 selected_jets.end());
+  }
+}
+
+
+bool SimpleJetsMatcher::pass() const {return m_pass;}
+
+const HypoJetVector &
+SimpleJetsMatcher::passedJets() const  noexcept {return m_passed_jets;}
+
+const HypoJetVector &
+SimpleJetsMatcher::failedJets() const noexcept {return m_failed_jets;}
+
+std::string SimpleJetsMatcher::toString() const noexcept{
+  std::stringstream ss;
+  ss << "SimpleJetsMatcher/" << Matcher::toString() << '\n'
+     << "Conditions: \n";
+  for(auto c : m_conditions){ ss <<  c.toString() << '\n';}
+  ss << '\n';
+
+  ss << "Passed jets [" << m_passed_jets.size() << "]\n";
+  for (auto j : m_passed_jets) {ss << j->toString() << '\n';}
+
+  ss << "Failed jets [" << m_failed_jets.size() << "]\n";
+  for (auto j : m_failed_jets) {ss << j->toString() << '\n';}
+
+  return ss.str();
+}
+
+
+const Conditions& SimpleJetsMatcher::getConditions() const noexcept {
+  return m_conditions;
+}
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/matcherFactory.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/matcherFactory.cxx
index 8c8925e3c12c4162311738f17d3f3d4cffcb0751..23fb6110c0ae9171a958c1428669686b85e80b4c 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/matcherFactory.cxx
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/matcherFactory.cxx
@@ -29,6 +29,7 @@
 #include "TrigHLTJetHypo/TrigHLTJetHypoUtils/MaximumBipartiteMatcher.h"
 #include "TrigHLTJetHypo/TrigHLTJetHypoUtils/OrderedCollectionsMatcher.h"
 #include "TrigHLTJetHypo/TrigHLTJetHypoUtils/SelectedJetsMatcher.h"
+#include "TrigHLTJetHypo/TrigHLTJetHypoUtils/SimpleJetsMatcher.h"
 
 using pIM = std::shared_ptr<IMatcher>;
 
@@ -59,3 +60,13 @@ SelectedJetsMatcherFactory::SelectedJetsMatcherFactory(const Conditions& conditi
 pIM SelectedJetsMatcherFactory::make() const { 
   return pIM(new SelectedJetsMatcher(m_conditions, m_indices, m_name));
 }
+
+
+SimpleJetsMatcherFactory::SimpleJetsMatcherFactory(const Conditions& conditions,
+                                                   const std::string& key) : 
+  m_conditions(conditions), m_name(key){
+}
+
+pIM SimpleJetsMatcherFactory::make() const { 
+  return pIM(new SimpleJetsMatcher(m_conditions, m_name));
+}
diff --git a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/matcherFactoryFactory.cxx b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/matcherFactoryFactory.cxx
index fe9c95b1326e39c547846b9a39fe02f8a26c4283..d2a093c5f1c7923809b9fd7fdb7d2cd810d48a27 100644
--- a/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/matcherFactoryFactory.cxx
+++ b/Trigger/TrigHypothesis/TrigHLTJetHypo/src/TrigHLTJetHypoUtils/matcherFactoryFactory.cxx
@@ -34,6 +34,9 @@ matcherFactoryFactory(const Conditions & conditions,
     IMatcherFactory* imf = new OrderedCollectionsMatcherFactory(conditions,
 								key);
     return std::shared_ptr<IMatcherFactory>(imf);
+  } else if (key == "simple"){
+    IMatcherFactory* imf = new SimpleJetsMatcherFactory(conditions, key);
+    return std::shared_ptr<IMatcherFactory>(imf);
   } else {
     std::stringstream ss;
     auto m =  "matcherFactory: unknown key to make a matcher factory" + key;