diff --git a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/JetSelectorTools/EventCleaningTool.h b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/JetSelectorTools/EventCleaningTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..e65305a9d79a78d4b092bb7ad333cfc365992b65
--- /dev/null
+++ b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/JetSelectorTools/EventCleaningTool.h
@@ -0,0 +1,77 @@
+/*
+  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef __EVENTCLEANINGTOOL__
+#define __EVENTCLEANINGTOOL__
+
+/**
+   @class EventCleaningTool
+   @brief Class for selecting jets that pass cleaning cuts
+
+   @author Julia Gonski
+   @date   Nov 2016
+*/
+
+// Stdlib includes
+#include <string>
+#include <vector>
+#include <unordered_map>
+
+// Base classes
+#include "AsgTools/AsgTool.h"
+#include "AsgTools/AnaToolHandle.h"
+
+// Local includes
+#include "PATCore/TAccept.h"
+#include "IEventCleaningTool.h"
+#include "xAODJet/Jet.h"
+#include "xAODEventInfo/EventInfo.h"
+#include "JetSelectorTools/JetCleaningTool.h"
+#include "JetInterface/IJetSelector.h"
+
+namespace ECUtils 
+{ 
+
+class EventCleaningTool : public virtual IEventCleaningTool, 
+			  public asg::AsgTool
+{
+
+    /// Create a proper constructor for Athena
+  ASG_TOOL_CLASS(EventCleaningTool,IEventCleaningTool)
+
+  public: 
+
+    /** Standard constructor */
+    EventCleaningTool(const std::string& name="EventCleaningTool");
+
+    /** Standard destructor */
+    virtual ~EventCleaningTool();   
+    
+     /** Initialize method */
+    virtual StatusCode initialize() override;
+
+    virtual bool acceptEvent(const xAOD::JetContainer* jets) const override;
+
+    virtual int keepJet(const xAOD::Jet& jet) const override; 
+    
+  private:
+    double m_pt; 
+    double m_eta; 
+    std::string m_jvt; 
+    std::string m_or; 
+    std::string m_prefix; 
+    bool m_decorate; 
+    bool m_useDecorations;
+    std::string m_cleaningLevel; 
+    asg::AnaToolHandle<IJetSelector> m_jetCleaningTool; //!
+
+    std::unique_ptr<SG::AuxElement::Decorator<char>> m_dec_jetClean;
+    std::unique_ptr<SG::AuxElement::Accessor<char>> m_acc_passJvt;
+    std::unique_ptr<SG::AuxElement::Accessor<char>> m_acc_passOR;
+
+
+}; // End: class definition
+}//ECUtils
+
+#endif
diff --git a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/JetSelectorTools/Helpers.h b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/JetSelectorTools/Helpers.h
index 75e5ccde21cb28d59da85a3842a8ac7c426d8a6b..ca6a055c77c329fc04964a3aa5a940a0b02af405 100644
--- a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/JetSelectorTools/Helpers.h
+++ b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/JetSelectorTools/Helpers.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef JETSELECTORTOOLS_HELPERS_H
diff --git a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/JetSelectorTools/IEventCleaningTool.h b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/JetSelectorTools/IEventCleaningTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..c3e270d4e4ab1d743e0b0a78cfe549161a21df94
--- /dev/null
+++ b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/JetSelectorTools/IEventCleaningTool.h
@@ -0,0 +1,43 @@
+/*
+  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef ASSOCIATIONUTILS_IEVENTCLEANINGTOOL_H
+#define ASSOCIATIONUTILS_IEVENTCLEANINGTOOL_H
+
+// Framework includes
+#include "AsgTools/IAsgTool.h"
+
+// EDM includes
+#include "xAODJet/JetContainer.h"
+
+
+namespace ECUtils
+{
+
+  /// @class IEventCleaningTool
+  /// @brief Interface for the event cleaning tool
+  ///
+  /// @author Julia Gonski <j.gonski@cern.ch>
+  ///
+  class IEventCleaningTool : public virtual asg::IAsgTool
+  {
+
+      /// Declare the interface
+      ASG_TOOL_INTERFACE(IEventCleaningTool)
+
+    public:
+
+      /// Top-level method for performing full overlap-removal.
+      /// The individual OR methods will be called in the recommended order,
+      /// and the considered objects will be decorated with the output result.
+      virtual bool
+      acceptEvent(const xAOD::JetContainer* jets) const = 0;
+  
+      virtual int keepJet(const xAOD::Jet& jet) const =0; 
+  
+}; // class IEventCleaningTool
+
+} // namespace ECUtils
+
+#endif
diff --git a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/JetSelectorTools/JetAttributeSelector.h b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/JetSelectorTools/JetAttributeSelector.h
index 971edeceb2a2f4f64406a95fae2487a3afcc0b7f..d67bb8cd6b70b6d9f89fa7801d4732e3f4ddcfbc 100644
--- a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/JetSelectorTools/JetAttributeSelector.h
+++ b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/JetSelectorTools/JetAttributeSelector.h
@@ -1,7 +1,7 @@
 //  -*- c++ -*- 
 
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef JETSELECTORTOOLS_JETSELECTORATTRIBUTE_H
diff --git a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/JetSelectorTools/JetCleaningTool.h b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/JetSelectorTools/JetCleaningTool.h
index 4f8967bbf80693034885495e177ebffdb98c8f5c..68b7a9f73a0dd6f45ff53b596d797549d84e6571 100644
--- a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/JetSelectorTools/JetCleaningTool.h
+++ b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/JetSelectorTools/JetCleaningTool.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef __JETCLEANINGTOOL__
@@ -37,7 +37,7 @@ class JetCleaningTool : public asg::AsgTool , virtual public IJetSelector
 
   public: 
     /** Levels of cut */
-    enum CleaningLevel{ LooseBad , LooseBadLLP, LooseBadTrigger, TightBad , UnknownCut };
+    enum CleaningLevel{ VeryLooseBadLLP , LooseBad , LooseBadLLP, LooseBadTrigger, TightBad , UnknownCut };
 
     /** Standard constructor */
     JetCleaningTool(const std::string& name="JetCleaningTool");
@@ -54,12 +54,22 @@ class JetCleaningTool : public asg::AsgTool , virtual public IJetSelector
     /** Initialize method */
     virtual StatusCode initialize();
 
+    /** The DFCommonJets decoration accept method */
+    const Root::TAccept& accept( const int isJetClean, const int fmaxIndex ) const;
+    
+    /** The DFCommonJets decoration + tight method  */
+    const Root::TAccept& accept( const int isJetClean,
+                                              const double sumpttrk, //in MeV, same as sumpttrk
+                                              const double fmax,
+					      const double eta,
+					      const double pt, 
+                                              const int    fmaxIndex ) const;
+
     /** The main accept method: the actual cuts are applied here */
     const Root::TAccept& accept( const double emf,
                  const double hecf,
                  const double larq,
                  const double hecq,
-                 //const double time,     //in ns
                  const double sumpttrk, //in MeV, same as sumpttrk
                  const double eta,      //emscale Eta  
                  const double pt,       //in MeV, same as sumpttrk
@@ -89,6 +99,10 @@ class JetCleaningTool : public asg::AsgTool , virtual public IJetSelector
     std::string m_cutName; 
     CleaningLevel m_cutLevel;
     bool m_doUgly;
+    bool m_useDecorations;
+    std::string m_jetCleanDFName; //new implementation with derivation level event cleaning decision
+    SG::AuxElement::ConstAccessor<char> m_acc_jetClean;
+    SG::AuxElement::ConstAccessor<char> m_acc_looseClean;
 
     /** Previous decision */
     mutable Root::TAccept m_accept;
@@ -97,6 +111,8 @@ class JetCleaningTool : public asg::AsgTool , virtual public IJetSelector
     std::string m_hotCellsFile;
     std::unordered_map<unsigned int, std::vector<JCT::HotCell*>*>* m_hotCellsMap;
     StatusCode readHotCells();
+    
+    void missingVariable(const std::string& varName) const;
 
 }; // End: class definition
 
diff --git a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/JetSelectorTools/JetSelectorToolsDict.h b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/JetSelectorTools/JetSelectorToolsDict.h
index 06fb16f0c35c523ebd1769221d2eb1e59974dabf..0d2d745b7d80ea94ebbd8606b742914329451465 100644
--- a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/JetSelectorTools/JetSelectorToolsDict.h
+++ b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/JetSelectorTools/JetSelectorToolsDict.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef JETSELECTORTOOLS_JETSELECTORTOOLSDICT_H
@@ -11,7 +11,7 @@
 
 // Includes for the dictionary generation:
 #include "JetSelectorTools/JetCleaningTool.h"
-
+#include "JetSelectorTools/EventCleaningTool.h"
 #include "JetSelectorTools/JetAttributeSelector.h"
 
 #endif // JETSELECTORTOOLS_JETSELECTORTOOLSDICT_H
diff --git a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/JetSelectorTools/selection.xml b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/JetSelectorTools/selection.xml
index 8bcb8ccad471f2474012334f5f6ab8584bfb3ce0..efe974762b8ee9e044bbff90c144b36eb2de2347 100644
--- a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/JetSelectorTools/selection.xml
+++ b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/JetSelectorTools/selection.xml
@@ -1,6 +1,7 @@
 <lcgdict>
   <!-- Jet cleaning tools -->
   <class name="JetCleaningTool" />
+  <class name="ECUtils::EventCleaningTool" />
   <class name="JetAttributeSelector" />
   <class name="JetAttributeRatioSelector" />
   <class name="JetAbsAttributeSelector" />
diff --git a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/Root/EventCleaningTool.cxx b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/Root/EventCleaningTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..5e7cdad30b0a6ed6f401643f86549bbf49a3ce08
--- /dev/null
+++ b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/Root/EventCleaningTool.cxx
@@ -0,0 +1,134 @@
+/*
+  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+*/
+
+/******************************************************************************
+Name:        EventCleaningTool
+
+Author:      Julia Gonski
+Created:     Nov 2016
+
+Description: Class for selecting events that pass recommended jet cleaning procedure
+******************************************************************************/
+
+// This class header and package headers
+#include "JetSelectorTools/EventCleaningTool.h"
+#include "JetSelectorTools/JetCleaningTool.h"
+#include "JetSelectorTools/Helpers.h"
+
+// The xAOD jet type
+#include "xAODJet/Jet.h"
+#include "xAODEventInfo/EventInfo.h"
+
+// xAOD/ASG includes
+#include "AsgTools/AsgMessaging.h"
+
+// STL includes
+#include <iostream>
+#include <cmath>
+#include <cfloat>
+
+// ROOT includes
+#include "TEnv.h"
+
+namespace ECUtils {
+
+//=============================================================================
+// Constructors
+//=============================================================================
+EventCleaningTool::EventCleaningTool(const std::string& name)
+  : asg::AsgTool(name)
+  , m_pt()
+  , m_eta()
+  , m_jvt()
+  , m_or()
+  , m_prefix()
+  , m_decorate()
+  , m_useDecorations()
+  , m_cleaningLevel()
+  , m_jetCleaningTool("JetCleaningTool/JetCleaningTool")
+{
+  declareProperty( "PtCut" , m_pt = 20000.0 );
+  declareProperty( "EtaCut" , m_eta = 4.5 );
+  declareProperty( "JvtDecorator" , m_jvt = "passJvt" );
+  declareProperty( "OrDecorator" , m_or = "passOR" );
+  declareProperty( "JetCleanPrefix", m_prefix = "" );
+  declareProperty( "DoDecorations", m_decorate = true );
+  declareProperty( "UseDecorations" , m_useDecorations=false);
+  declareProperty( "CleaningLevel" , m_cleaningLevel = "LooseBad");
+  m_jetCleaningTool.declarePropertyFor(this, "JetCleaningTool");
+}
+
+
+//=============================================================================
+// Destructor
+//=============================================================================
+EventCleaningTool::~EventCleaningTool() {}
+
+//=============================================================================
+// Initialize
+//=============================================================================
+StatusCode EventCleaningTool::initialize()
+{
+  if(m_jvt == "" || m_or == ""){
+    ATH_MSG_ERROR( "Tool initialized with unknown decorator names." );
+    return StatusCode::FAILURE;
+  }
+  if (m_cleaningLevel == ""){
+    ATH_MSG_ERROR( "Tool initialized with unknown cleaning level." );
+    return StatusCode::FAILURE;
+  }
+
+  //initialize jet cleaning tool
+  ATH_CHECK(m_jetCleaningTool.setProperty("CutLevel", m_cleaningLevel ));
+  ATH_CHECK(m_jetCleaningTool.setProperty("UseDecorations", m_useDecorations ));  //for AODs we can't use decorations
+  ATH_CHECK(m_jetCleaningTool.retrieve());
+  ATH_MSG_INFO( "Event cleaning tool configured with cut level " << m_cleaningLevel  );
+
+  //create the decorators
+  m_acc_passJvt = std::make_unique<SG::AuxElement::Accessor<char>>(m_prefix + m_jvt);
+  m_acc_passOR = std::make_unique<SG::AuxElement::Accessor<char>>(m_prefix + m_or);
+  if(m_decorate) m_dec_jetClean = std::make_unique<SG::AuxElement::Decorator<char>>(m_prefix + "jetClean_" + m_cleaningLevel);
+
+  return StatusCode::SUCCESS;
+}
+
+bool EventCleaningTool::acceptEvent(const xAOD::JetContainer* jets) const
+{
+	bool pass_pt = 0;
+	bool pass_eta = 0;
+	bool pass_accept = 0;
+	int jvtDecision = 0;
+	int orDecision = 0;
+	bool isThisJetGood = 0;
+	bool isEventAllGood = 1;
+	ATH_MSG_DEBUG("m_or: " << m_or << ", m_jvt: " << m_jvt);
+
+	for (auto thisJet : *jets){  //loop over decorated jet collection
+		pass_pt = thisJet->pt() > m_pt;
+		pass_eta = fabs(thisJet->eta()) < m_eta;
+		pass_accept = keepJet(*thisJet);
+		jvtDecision = (*m_acc_passJvt)(*thisJet);
+		orDecision = !(*m_acc_passOR)(*thisJet);  //recall, passOR==0 means that the jet is not an overlap and should be kept!
+
+		ATH_MSG_DEBUG("Jet info: pT: " << pass_pt << ", eta: " << pass_eta << ", accept? " << pass_accept << ", jvt: " << jvtDecision << ", or: " << orDecision);
+		if(pass_pt && pass_eta && jvtDecision && orDecision){//only consider jets for cleaning if they pass these requirements.
+			isThisJetGood = pass_accept;
+			isEventAllGood = isEventAllGood && isThisJetGood; //any event with a bad jet is rejected
+		}
+		else isThisJetGood = pass_accept;     //if it fails any one of these, it shouldn't be able to kill the whole event, but we still need to know cleaning
+		ATH_MSG_DEBUG("Is jet good? " << isThisJetGood);
+		if(m_decorate) (*m_dec_jetClean)(*thisJet) = isThisJetGood;
+ 	}
+	ATH_MSG_DEBUG("Is event good? " << isEventAllGood);
+	return isEventAllGood;
+}
+
+int EventCleaningTool::keepJet(const xAOD::Jet& jet) const
+{
+	return m_jetCleaningTool->keep(jet);
+}
+
+}//ECUtils
+
+
diff --git a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/Root/Helpers.cxx b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/Root/Helpers.cxx
index edf56e7dd04ded841c65ef6a174872db14ca7a90..bc5211cb71750fe19e3eb59a670e7ebd70f2f14c 100644
--- a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/Root/Helpers.cxx
+++ b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/Root/Helpers.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "JetSelectorTools/Helpers.h"
diff --git a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/Root/JetAttributeSelector.cxx b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/Root/JetAttributeSelector.cxx
index aa42f5155e39757c9235d770f22b4b0e4aa0b0ea..62ae68055824196dbc02ece03534acf7990c69b9 100644
--- a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/Root/JetAttributeSelector.cxx
+++ b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/Root/JetAttributeSelector.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "JetSelectorTools/JetAttributeSelector.h"
diff --git a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/Root/JetCleaningTool.cxx b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/Root/JetCleaningTool.cxx
index f44c8987a6cc61a4a8e09436b7679c8f74953efa..5979a9c0181cc1a453382d2e569e112baf45ec3c 100644
--- a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/Root/JetCleaningTool.cxx
+++ b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/Root/JetCleaningTool.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
 */
 
 /******************************************************************************
@@ -22,7 +22,7 @@ Description: Class for selecting jets that pass some cleaning cuts
 #include <iostream>
 #include <cmath>
 #include <cfloat>
-
+#include <stdexcept>
 // ROOT includes
 #include "TEnv.h"
 
@@ -103,11 +103,16 @@ JetCleaningTool::JetCleaningTool(const std::string& name)
   , m_cutName("")
   , m_cutLevel(LooseBad)
   , m_doUgly(false)
+  , m_useDecorations(true)
+  , m_jetCleanDFName("")
+  , m_acc_jetClean("DFCommonJets_jetClean_LooseBad")
+  , m_acc_looseClean("DFCommonJets_jetClean_LooseBad")
   , m_hotCellsFile("")
-  , m_hotCellsMap(NULL)
+  , m_hotCellsMap(nullptr)
 {
   declareProperty( "CutLevel" , m_cutName = "" );
   declareProperty( "DoUgly"   , m_doUgly = false);
+  declareProperty( "UseDecorations"   , m_useDecorations = true);
   declareProperty( "HotCellsFile" , m_hotCellsFile = "");
 }
 
@@ -145,7 +150,7 @@ JetCleaningTool::~JetCleaningTool()
                     if (cellVec->at(index))
                     {
                         delete cellVec->at(index);
-                        cellVec->at(index) = NULL;
+                        cellVec->at(index) = nullptr;
                     }
                 delete cellVec;
             }
@@ -166,6 +171,10 @@ StatusCode JetCleaningTool::initialize()
 
   if (m_cutName!="") m_cutLevel = getCutLevel( m_cutName );
   ATH_MSG_INFO( "Configured with cut level " << getCutName( m_cutLevel ) );
+  m_jetCleanDFName = "DFCommonJets_jetClean_"+getCutName(m_cutLevel);
+  m_acc_jetClean = m_jetCleanDFName;
+  m_acc_looseClean = "DFCommonJets_jetClean_"+getCutName(LooseBad);
+  ATH_MSG_DEBUG( "Initialized decorator name: " << m_jetCleanDFName );
 
   m_accept.addCut( "Cleaning", "Cleaning of the jet" );
     
@@ -180,6 +189,69 @@ StatusCode JetCleaningTool::initialize()
 
   return StatusCode::SUCCESS;
 }
+//===============================================================
+// Calculate the accept from the DFCommonJets_jetClean decorator
+//===============================================================
+const Root::TAccept& JetCleaningTool::accept( const int isJetClean, const int fmaxIndex ) const
+{                
+    m_accept.clear();
+    m_accept.setCutResult( "Cleaning", false );
+
+    //=============================================================
+    //Run-II ugly cuts
+    //=============================================================
+    if(m_doUgly && fmaxIndex==17) return m_accept;
+
+    //=============================================================
+    //Loose/tight cleaning taken from decoration
+    //=============================================================
+    if(isJetClean==0) return m_accept; 
+    else{
+        m_accept.setCutResult( "Cleaning", true );
+        return m_accept;
+    }
+
+    // We should never arrive here!
+    ATH_MSG_ERROR( "Unknown cut name: " << getCutName( m_cutLevel ) << " in JetCleaningTool" );
+    return m_accept;
+
+}
+//===============================================================
+// Calculate tight cleaning from loose decoration + variables
+//===============================================================
+const Root::TAccept& JetCleaningTool::accept( const int isJetClean,
+        const double sumpttrk, //in MeV, same as sumpttrk
+        const double fmax,
+        const double eta,
+        const double pt,
+        const int    fmaxIndex                        
+        ) const
+{                
+    m_accept.clear();
+    m_accept.setCutResult( "Cleaning", false );
+    const double chf=sumpttrk/pt;
+
+    //=============================================================
+    //Run-II ugly cuts
+    //=============================================================
+    if(m_doUgly && fmaxIndex==17) return m_accept;
+
+    //=============================================================
+    //Tight cleaning taken from decoration
+    //=============================================================
+    if(isJetClean==0) return m_accept;  //fails Loose cleaning
+    else if (fmax<DBL_MIN) return m_accept;
+        else if(std::fabs(eta)<2.4 && chf/fmax<0.1) return m_accept;    
+    else{
+        m_accept.setCutResult( "Cleaning", true );
+        return m_accept;
+    }
+
+    // We should never arrive here!
+    ATH_MSG_ERROR( "Unknown cut name: " << getCutName( m_cutLevel ) << " in JetCleaningTool" );
+    return m_accept;
+
+}
 
 //=============================================================================
 // Calculate the actual accept of each cut individually.
@@ -211,6 +283,17 @@ const Root::TAccept& JetCleaningTool::accept( const double emf,
   //=============================================================
   if(m_doUgly && fmaxIndex==17) return m_accept;
 
+  //=============================================================
+  //Run-II very loose LLP cuts
+  // From https://indico.cern.ch/event/642438/contributions/2704590/attachments/1514445/2362870/082117a_HCW_NCB_LLP.pdf
+  //=============================================================
+  if (VeryLooseBadLLP == m_cutLevel){
+    if (fmax>0.80) return m_accept;
+    if (emf>0.96) return m_accept;
+    m_accept.setCutResult( "Cleaning", true );
+    return m_accept;
+  }
+
   //=============================================================
   //Run-II loose cuts
   //=============================================================
@@ -222,13 +305,10 @@ const Root::TAccept& JetCleaningTool::accept( const double emf,
     if(emf<0.05 && std::fabs(eta)>=2)                       return m_accept;
   }
   if(fmax>0.99 && std::fabs(eta)<2)                       return m_accept;
-  //HEC spike
-  if(std::fabs(negE*0.001)>60)                            return m_accept;
+  //HEC spike-- gone as of 2017! 
   if(hecf>0.5 && std::fabs(hecq)>0.5 && AverageLArQF/65535>0.8)                     return m_accept;
   //EM calo noise
   if(emf>0.95 && std::fabs(larq)>0.8 && std::fabs(eta)<2.8 && AverageLArQF/65535>0.8)    return m_accept;
-  //// New pre-sampler topoclustering algorithm cut
-  //if(fmaxIndex==0 && fmax>0.6) return m_accept;
   // LLP cleaning uses negative energy cut
   // (https://indico.cern.ch/event/472320/contribution/8/attachments/1220731/1784456/JetTriggerMeeting_20160102.pdf)
   if (useLLP && std::fabs(negE*0.001)>4 && fmax >0.85) return m_accept;
@@ -238,15 +318,6 @@ const Root::TAccept& JetCleaningTool::accept( const double emf,
     return m_accept;
   }
 
-  //=============================================================
-  //Run-II medium cuts
-  //=============================================================
-  // Medium == loose right now
-  //if(MediumBad==m_cutLevel){
-  //  m_accept.setCutResult( "Cleaning", true );
-  //  return m_accept;
-  //}
-  
   //=============================================================
   //Run-II tight cuts
   //=============================================================
@@ -259,16 +330,16 @@ const Root::TAccept& JetCleaningTool::accept( const double emf,
     return m_accept;
   }
 
-
   // We should never arrive here!
   ATH_MSG_ERROR( "Unknown cut name: " << getCutName( m_cutLevel ) << " in JetCleaningTool" );
   return m_accept;
 }
 
 
-void missingVariable(const char* varName)
+void JetCleaningTool::missingVariable(const std::string& varName) const
 {
-    throw std::string(Form("JetCleaningTool failed to retrieve a required variable - please confirm that the xAOD::Jet being passed contains the variable named %s",varName));
+    ATH_MSG_FATAL(Form("JetCleaningTool failed to retrieve a required variable - please confirm that the xAOD::Jet being passed contains the variable named %s",varName.c_str()));
+    throw std::runtime_error(Form("JetCleaningTool failed to retrieve a required variable - please confirm that the xAOD::Jet being passed contains the variable named %s",varName.c_str()));
 }
 
 const Root::TAccept& JetCleaningTool::accept( const xAOD::Jet& jet) const
@@ -277,59 +348,70 @@ const Root::TAccept& JetCleaningTool::accept( const xAOD::Jet& jet) const
   jet.getAttribute( xAOD::JetAttribute::SumPtTrkPt500, sumPtTrkvec );
   double sumpttrk = 0;
   if( ! sumPtTrkvec.empty() ) sumpttrk = sumPtTrkvec[0];
-
-  // Get all of the required variables
-  // Do it this way so we can gracefully handle missing variables (rather than segfaults)
-  float EMFrac = 0;
-  if (!jet.getAttribute(xAOD::JetAttribute::EMFrac,EMFrac))
-    missingVariable("EMFrac");
-  float HECFrac = 0;
-  if (!jet.getAttribute(xAOD::JetAttribute::HECFrac,HECFrac))
-    missingVariable("HECFrac");
-  float LArQuality = 0;
-  if (!jet.getAttribute(xAOD::JetAttribute::LArQuality,LArQuality))
-    missingVariable("LArQuality");
-  float HECQuality = 0;
-  if (!jet.getAttribute(xAOD::JetAttribute::HECQuality,HECQuality))
-    missingVariable("HECQuality");
-  float FracSamplingMax = 0;
-  if (!jet.getAttribute(xAOD::JetAttribute::FracSamplingMax,FracSamplingMax))
-    missingVariable("FracSamplingMax");
-  float NegativeE = 0;
-  if (!jet.getAttribute(xAOD::JetAttribute::NegativeE,NegativeE))
-    missingVariable("NegativeE");
-  float AverageLArQF = 0;
-  if (!jet.getAttribute(xAOD::JetAttribute::AverageLArQF,AverageLArQF))
-    missingVariable("AverageLArQF");
-
   // fmax index is not necessarily required
   // This is only used if doUgly is set
   // Handle it gracefully if the variable is not present but doUgly is false
   int FracSamplingMaxIndex = -1;
   if (!jet.getAttribute(xAOD::JetAttribute::FracSamplingMaxIndex,FracSamplingMaxIndex) && m_doUgly)
-    missingVariable("FracSamplingMaxIndex");
-
-  
-  return accept (EMFrac,
-                 HECFrac,
-                 LArQuality,
-                 HECQuality,
-                 //jet.getAttribute<float>(xAOD::JetAttribute::Timing),
-                 sumpttrk,
-                 jet.eta(),
-                 jet.pt(),
-                 FracSamplingMax,
-                 NegativeE,
-                 AverageLArQF,
-                 FracSamplingMaxIndex);
+      missingVariable("FracSamplingMaxIndex"); 
+  // get tight cleaning variables
+  float FracSamplingMax = 0;
+  if (!jet.getAttribute(xAOD::JetAttribute::FracSamplingMax,FracSamplingMax))
+      missingVariable("FracSamplingMax");
+ 
+  //start jet cleaning 
+  int isJetClean = 0; 
+  if( m_useDecorations && m_acc_jetClean.isAvailable(jet) ) { //decoration is already available for all jets 
+          isJetClean = m_acc_jetClean(jet);
+          return accept (isJetClean, FracSamplingMaxIndex);
+  }
+  else{   //running over AOD, need to use all variables
+      ATH_MSG_DEBUG("DFCommon jet cleaning variable not available ... Using jet cleaning tool");
+      // Get all of the required variables
+      // Do it this way so we can gracefully handle missing variables (rather than segfaults)
+      
+      float EMFrac = 0;
+      if (!jet.getAttribute(xAOD::JetAttribute::EMFrac,EMFrac))
+          missingVariable("EMFrac");
+      
+      float HECFrac = 0;
+      if (!jet.getAttribute(xAOD::JetAttribute::HECFrac,HECFrac))
+          missingVariable("HECFrac");
+      
+      float LArQuality = 0;
+      if (!jet.getAttribute(xAOD::JetAttribute::LArQuality,LArQuality))
+          missingVariable("LArQuality");
+    
+     
+      float HECQuality = 0;
+      if (!jet.getAttribute(xAOD::JetAttribute::HECQuality,HECQuality))
+          missingVariable("HECQuality");
+
+     
+      float NegativeE = 0;
+      if (!jet.getAttribute(xAOD::JetAttribute::NegativeE,NegativeE))
+          missingVariable("NegativeE");
+
+     
+
+      float AverageLArQF = 0;
+      if (!jet.getAttribute(xAOD::JetAttribute::AverageLArQF,AverageLArQF))
+          missingVariable("AverageLArQF");
+
+      return accept (EMFrac,
+              HECFrac,
+              LArQuality,
+              HECQuality,
+              sumpttrk,
+              jet.eta(),
+              jet.pt(),
+              FracSamplingMax,
+              NegativeE,
+              AverageLArQF,
+              FracSamplingMaxIndex);}
 }
 
 /** Hot cell checks */
-//const bool containsHotCells( const xAOD::Jet& jet, const xAOD::EventInfo& eInfo) const
-//{
-//    return containsHotCells(jet,eInfo.runNumber());
-//}
-
 bool JetCleaningTool::containsHotCells( const xAOD::Jet& jet, const unsigned int runNumber) const
 {
     // Check if the runNumber contains bad cells
@@ -348,11 +430,10 @@ bool JetCleaningTool::containsHotCells( const xAOD::Jet& jet, const unsigned int
 /** Helpers for cut names */
 JetCleaningTool::CleaningLevel JetCleaningTool::getCutLevel( const std::string s ) const
 {
-  //if (s=="VeryLooseBad") return VeryLooseBad;
+  if (s=="VeryLooseBadLLP") return VeryLooseBadLLP;
   if (s=="LooseBad")     return LooseBad;
   if (s=="LooseBadLLP")     return LooseBadLLP;
   if (s=="LooseBadTrigger")     return LooseBadTrigger;
-  //if (s=="MediumBad")    return MediumBad;
   if (s=="TightBad")     return TightBad;
   ATH_MSG_ERROR( "Unknown cut level requested: " << s );
   return UnknownCut;  
@@ -360,11 +441,10 @@ JetCleaningTool::CleaningLevel JetCleaningTool::getCutLevel( const std::string s
 
 std::string JetCleaningTool::getCutName( const CleaningLevel c) const
 {
-  //if (c==VeryLooseBad) return "VeryLooseBad";
+  if (c==VeryLooseBadLLP) return "VeryLooseBadLLP";
   if (c==LooseBad)     return "LooseBad";
   if (c==LooseBadLLP)     return "LooseBadLLP";
   if (c==LooseBadTrigger)     return "LooseBadTrigger";
-  //if (c==MediumBad)    return "MediumBad";
   if (c==TightBad)     return "TightBad";
   return "UnknownCut";
 }
@@ -445,6 +525,3 @@ StatusCode JetCleaningTool::readHotCells()
     // Done
     return StatusCode::SUCCESS;
 }
-
-
-
diff --git a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/python/ConfiguredJetCleaningTools.py b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/python/ConfiguredJetCleaningTools.py
index 9902790edf8d05d94ed2b928640b68e56b0c2aee..54ebd8fc2c0eb550438964de62bf08c8123aeedc 100644
--- a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/python/ConfiguredJetCleaningTools.py
+++ b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/python/ConfiguredJetCleaningTools.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
 
 ##=============================================================================
 ## Name:        ConfiguredJetCleaningTools
@@ -17,30 +17,20 @@ from AthenaCommon import CfgMgr
 
 # Import the needed stuff specific to the JetCleaning
 from JetSelectorTools.JetSelectorToolsConf import JetCleaningTool
+from JetSelectorTools.JetSelectorToolsConf import ECUtils__EventCleaningTool as EventCleaningTool
 from JetSelectorTools.JetCleaningCutDefs import *
 
 
 
-#def ConfiguredJetCleaningTool_VeryLoose( name, **kw ):
-#    """
-#    Configure the JetCleaningTool with the default VeryLoose cuts
-#    and allow for (re-)setting of all provided cuts.
-#    """
-#    # Set some default properties, but don't overwrite them if they already exist
-#    kw["CutLevel"] = kw.get( "CutLevel" , "VeryLooseBad" )
-#
-#    # Create and instance of the tool
-#    tool = CfgMgr.JetCleaningTool(name, **kw)
-#
-#    # Configure it with the standard configuration
-#    JetCleaningToolConfig_VeryLoose( tool )
-#
-#    # Get all provided properties and overwrite the default values with them
-#    SetToolProperties( tool, **kw )
-#
-#    return tool
-
-
+def recEventCleaningTool(name='EventCleaningTool'):
+    """
+    Arguments:
+      name                  - set the name of the master tool.
+    """
+    # Configure the master tool
+    ecTool = EventCleaningTool(name)
+    
+    return ecTool
 
 
 def ConfiguredJetCleaningTool_Loose( name, **kw ):
@@ -64,29 +54,6 @@ def ConfiguredJetCleaningTool_Loose( name, **kw ):
 
 
 
-
-#def ConfiguredJetCleaningTool_Medium( name, **kw ):
-#    """
-#    Configure the JetCleaningTool with the default Medium cuts
-#    and allow for (re-)setting of all provided cuts.
-#    """
-#    # Set some default properties, but don't overwrite them if they already exist
-#    kw["CutLevel"] = kw.get( "CutLevel" , "MediumBad" )
-#    
-#    # Create and instance of the tool
-#    tool = CfgMgr.JetCleaningTool(name, **kw)
-#
-#    # Configure it with the standard configuration
-#    JetCleaningToolConfig_Medium( tool )
-#
-#    # Get all provided properties and overwrite the default values with them
-#    SetToolProperties( tool, **kw )
-#    
-#    return tool
-
-
-
-
 def ConfiguredJetCleaningTool_Tight( name, **kw ):
     """
     Configure the JetCleaningTool with the default Tight cuts
diff --git a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/python/JetCleaningCutDefs.py b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/python/JetCleaningCutDefs.py
index aa74ff01887a7b0446a874d2558cdd0758dbd992..c9bef129a9fb3e20fe6dbb5dae80fd5ccedefa36 100644
--- a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/python/JetCleaningCutDefs.py
+++ b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/python/JetCleaningCutDefs.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
 
 ##=============================================================================
 ## Name:        JetCleaningCutDefs
@@ -14,14 +14,6 @@
 from PATCore.HelperUtils import GetTool
 
 
-#def JetCleaningToolConfig_VeryLoose(theTool) :
-#    """
-#    This defines the jet cleaning cut values for the very Loose (Looser) operating point
-#    """
-#    theTool = GetTool(theTool)
-#    theTool.CutLevel = 'VeryLooseBad'
-#    pass
-
 def JetCleaningToolConfig_Loose(theTool) :
     """
     This defines the jet cleaning cut values for the Loose operating point.
@@ -30,14 +22,6 @@ def JetCleaningToolConfig_Loose(theTool) :
     theTool.CutLevel = 'LooseBad'
     pass
 
-#def JetCleaningToolConfig_Medium(theTool) :
-#    """
-#    This defines the jet cleaning cut values for the Medium operating point.
-#    """
-#    theTool = GetTool(theTool)
-#    theTool.CutLevel = 'MediumBad'
-#    pass
-
 def JetCleaningToolConfig_Tight(theTool) :
     """
     This defines the jet cleaning cut values for the Tight operating point.
diff --git a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/python/__init__.py b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/python/__init__.py
index 74583d364ec2ca794156596c7254d9b234a940c6..10eda52d21555e116affa250b4cc4c7110c820f1 100644
--- a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/python/__init__.py
+++ b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/python/__init__.py
@@ -1,2 +1,2 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
 
diff --git a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/share/EventCleaningTest_jobOptions.py b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/share/EventCleaningTest_jobOptions.py
new file mode 100644
index 0000000000000000000000000000000000000000..7882bf63f1976b1e6344ab7843f692eb32ed14dd
--- /dev/null
+++ b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/share/EventCleaningTest_jobOptions.py
@@ -0,0 +1,34 @@
+#
+# This job options file defines an Athena testing job for the EventCleaningTool
+#
+
+import os
+
+# Specify input file
+input_file = os.getenv('ASG_TEST_FILE_MC', '/afs/cern.ch/user/a/asgbase/patspace/xAODs/r6630/mc15_13TeV.410000.PowhegPythiaEvtGen_P2012_ttbar_hdamp172p5_nonallhad.recon.AOD.e3698_s2608_s2183_r6630_tid05352803_00/AOD.05352803._000242.pool.root.1')
+
+# Setup input
+import AthenaPoolCnvSvc.ReadAthenaPool
+ServiceMgr.EventSelector.InputCollections = [input_file]
+theApp.EvtMax = 100
+
+# Access the algorithm sequence
+from AthenaCommon.AlgSequence import AlgSequence
+theJob = AlgSequence()
+
+# Configure the tools using the helper module
+from JetSelectorTools.ConfiguredJetCleaningTools import recEventCleaningTool
+ecTool = recEventCleaningTool()
+
+# Override properties as desired
+ecTool.JvtDecorator = "passJvt"
+ecTool.OrDecorator = "passOR"
+ecTool.CleaningLevel = "LooseBad"
+
+# Configure the test algorithm
+from JetSelectorTools.JetSelectorToolsConf import EventCleaningTestAlg
+alg = EventCleaningTestAlg('EventCleaningTestAlg',
+                            EventCleaningTool=ecTool)
+
+# Add to the alg sequence
+theJob += alg
diff --git a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/src/EventCleaningTestAlg.cxx b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/src/EventCleaningTestAlg.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..08f3c23cb974b1146cd77c7727de44922081fed0
--- /dev/null
+++ b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/src/EventCleaningTestAlg.cxx
@@ -0,0 +1,80 @@
+/*
+  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+*/
+
+// EDM includes
+
+// Local includes
+#include "EventCleaningTestAlg.h"
+
+static const float GeV = 1000.;
+static const float invGeV = 1./GeV;
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+EventCleaningTestAlg::EventCleaningTestAlg(const std::string& name,
+                                             ISvcLocator* svcLoc)
+    : AthAlgorithm(name, svcLoc),
+      m_ecTool("ECUtils::EventCleaningTool/EventCleaningTool", this)
+{
+  m_ecTool.declarePropertyFor( this, "EventCleaningTool" );
+  declareProperty("EventCleanPrefix", m_prefix = "",
+                  "Input name of event cleaning decorator prefix");
+  declareProperty("CleaningLevel", m_cleaningLevel = "LooseBad",
+                  "Input cleaning level");
+  declareProperty("JetCollectionName", m_collection = "AntiKt4EMTopoJets",
+                  "Jet collection name");
+  declareProperty("doEvent",m_doEvent = true,
+                  "Decorate the EventInfo");
+}
+
+//-----------------------------------------------------------------------------
+// Initialize
+//-----------------------------------------------------------------------------
+StatusCode EventCleaningTestAlg::initialize()
+{
+  ATH_MSG_INFO("Initialize");
+
+  // Try to retrieve the tool
+  ATH_CHECK( m_ecTool.retrieve() );
+
+  // Create the decorator
+  if(m_doEvent) m_dec_eventClean = std::make_unique<SG::AuxElement::Decorator<char>>(m_prefix + "eventClean_" + m_cleaningLevel);
+
+  return StatusCode::SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// Execute
+//-----------------------------------------------------------------------------
+StatusCode EventCleaningTestAlg::execute()
+{
+  // Jets
+  const xAOD::JetContainer* jets = nullptr;
+  ATH_CHECK( evtStore()->retrieve(jets, m_collection) );
+
+  // Apply the event cleaning
+  bool result = 0;
+  result = m_ecTool->acceptEvent(jets) ;
+
+  //Decorate event
+  if(m_doEvent){
+    const xAOD::EventInfo* eventInfo = nullptr;
+    ATH_CHECK( evtStore()->retrieve(eventInfo, "EventInfo") );
+    (*m_dec_eventClean)(*eventInfo) = result;
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+//-----------------------------------------------------------------------------
+// Finalize
+//-----------------------------------------------------------------------------
+StatusCode EventCleaningTestAlg::finalize()
+{
+  ATH_MSG_INFO("Finalize");
+
+  return StatusCode::SUCCESS;
+}
+
diff --git a/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/src/EventCleaningTestAlg.h b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/src/EventCleaningTestAlg.h
new file mode 100644
index 0000000000000000000000000000000000000000..d57a5bc73832caf6a049d04b00580169e9f24ffe
--- /dev/null
+++ b/PhysicsAnalysis/JetMissingEtID/JetSelectorTools/src/EventCleaningTestAlg.h
@@ -0,0 +1,54 @@
+/*
+  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef ASSOCIATIONUTILS_OVERLAPREMOVALTESTALG_H
+#define ASSOCIATIONUTILS_OVERLAPREMOVALTESTALG_H
+
+// Framework includes
+#include "GaudiKernel/ToolHandle.h"
+#include "AsgTools/AnaToolHandle.h"
+#include "AthenaBaseComps/AthAlgorithm.h"
+
+// EDM includes
+#include "xAODBase/IParticleContainer.h"
+#include "xAODEventInfo/EventInfo.h"
+
+// Local includes
+#include "JetSelectorTools/IEventCleaningTool.h"
+
+/// A testing algorithm for the dual-use event cleaning tool in Athena
+///
+/// @author Julia Gonski <j.gonski@cern.ch>
+///
+class EventCleaningTestAlg : public AthAlgorithm
+{
+
+  public:
+
+    /// Standard algorithm constructor
+    EventCleaningTestAlg(const std::string& name, ISvcLocator* svcLoc) override;
+
+    /// Initialize the algorithm
+    virtual StatusCode initialize() override;
+
+    /// Finalize the algorithm
+    virtual StatusCode finalize() override;
+
+    /// Execute the algorithm
+    virtual StatusCode execute() override;
+
+  private:
+
+    /// Handle to the tool
+    asg::AnaToolHandle<ECUtils::IEventCleaningTool> m_ecTool;
+
+    /// Configuration
+    std::string m_prefix;
+    std::string m_cleaningLevel;
+    std::string m_collection;
+    bool m_doEvent; //boolean to save event-level decoration
+    std::unique_ptr<SG::AuxElement::Decorator<char>> m_dec_eventClean;
+};
+
+#endif