diff --git a/Reconstruction/MET/METInterface/METInterface/IMETMaker.h b/Reconstruction/MET/METInterface/METInterface/IMETMaker.h
index 70b147082fb0e94fc965741f0152f42d781f6447..b59525fcfef80a7267099627b677987832f0ce16 100644
--- a/Reconstruction/MET/METInterface/METInterface/IMETMaker.h
+++ b/Reconstruction/MET/METInterface/METInterface/IMETMaker.h
@@ -22,6 +22,10 @@
 #include "xAODMissingET/MissingETContainer.h"
 #include "xAODMissingET/MissingETAssociationMap.h"
 #include "xAODJet/JetContainer.h"
+#include "xAODPFlow/PFOContainer.h" 
+#include "StoreGate/DataHandle.h" 
+#include "StoreGate/WriteHandle.h"
+
 
 class IMETMaker :  virtual public asg::IAsgTool {
   ASG_TOOL_INTERFACE(IMETMaker)
@@ -102,10 +106,33 @@ public:
                                    const xAOD::MissingET* coreSoftTrk,
                                    bool doJetJVT) = 0;
 
+
   ///////////////////////////////////////////////////////////////////
   // Additional utility commands
   ///////////////////////////////////////////////////////////////////
 
+  virtual StatusCode retrieveOverlapRemovedConstituents(const xAOD::PFOContainer* cpfo, const xAOD::PFOContainer* npfo,
+			  xAOD::MissingETAssociationHelper* metHelper,
+			  SG::WriteHandle<xAOD::PFOContainer> chargedPFOContainerWriteHandle,
+			  SG::WriteHandle<xAOD::PFOContainer> neutralPFOContainerWriteHandle,
+			  SG::WriteHandle<xAOD::PFOContainer> PFOContainerWriteHandle,
+			  bool retainMuon = false,
+			  const xAOD::IParticleContainer* collection=0) = 0;//,  
+			  //MissingETBase::UsageHandler::Policy p); //jetOR
+
+  virtual StatusCode retrieveOverlapRemovedConstituents(const xAOD::PFOContainer* pfo, 
+			  xAOD::MissingETAssociationHelper* metHelper,
+			  SG::WriteHandle<xAOD::PFOContainer> PFOContainerWriteHandle,
+			  bool retainMuon = false,
+			  const xAOD::IParticleContainer* collection=0) = 0;//,  
+			  //MissingETBase::UsageHandler::Policy p); //jetOR
+
+  virtual const xAOD::PFOContainer* retrieveOverlapRemovedConstituents(const xAOD::PFOContainer* signals,
+			  xAOD::MissingETAssociationHelper* helper,
+			  bool retainMuon = false,
+			  const xAOD::IParticleContainer* collection=0, 
+			  MissingETBase::UsageHandler::Policy p=MissingETBase::UsageHandler::ParticleFlow) = 0; //jetOR
+
   virtual StatusCode markInvisible(const xAOD::IParticleContainer* collection,
 				   xAOD::MissingETAssociationHelper* helper,
 				   xAOD::MissingETContainer* metCont) = 0;
diff --git a/Reconstruction/MET/METReconstruction/METReconstruction/METEgammaAssociator.h b/Reconstruction/MET/METReconstruction/METReconstruction/METEgammaAssociator.h
index a5639d0d599470e231a553160bd0559a13b7342a..d13ea9e1474606045d63eaa768e944f83cc793fd 100644
--- a/Reconstruction/MET/METReconstruction/METReconstruction/METEgammaAssociator.h
+++ b/Reconstruction/MET/METReconstruction/METReconstruction/METEgammaAssociator.h
@@ -19,6 +19,8 @@
 #include "METRecoInterface/METRecoCommon.h"
 #include "xAODEgamma/EgammaFwd.h"
 
+#include "StoreGate/ReadDecorHandle.h"
+
 #include <set>
 
 namespace met{
@@ -64,10 +66,21 @@ namespace met{
                           const met::METAssociator::ConstitHolder& constits,
                           std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t> &momenta) const final;
 
+    StatusCode extractPFOsFromLinks(const xAOD::Egamma* eg,
+    				    std::vector<const xAOD::IParticle*>& pfolist,
+				    const met::METAssociator::ConstitHolder& constits) const;
+
+
+    StatusCode extractPFOs(const xAOD::Egamma* eg,
+				 std::vector<const xAOD::IParticle*>& pfolist,
+				 const met::METAssociator::ConstitHolder& constits) const;
+
+
     StatusCode extractFE(const xAOD::IParticle* obj,
                          std::vector<const xAOD::IParticle*>& felist,
                          const met::METAssociator::ConstitHolder& constits,
-                         std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t> &momenta) const final;
+                         std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t> &momenta) const final; //TODO: split in extractFEsFromLinks and extractFEs, similarly to PFOs, to use links
+
 
     StatusCode extractTracks(const xAOD::IParticle* obj,
                              std::vector<const xAOD::IParticle*>& constlist,
@@ -80,6 +93,8 @@ namespace met{
     StatusCode selectEgammaTracks(const xAOD::Egamma* el,
                                   const xAOD::TrackParticleContainer* trkCont,
                                   std::set<const xAOD::TrackParticle*>& tracklist) const;
+ 
+    bool hasUnmatchedClusters(const xAOD::Egamma* eg, const xAOD::PFO* pfo) const;
 
     double m_tcMatch_dR;
     double m_tcMatch_maxRat;
@@ -87,6 +102,23 @@ namespace met{
 
     double m_extraTrkMatch_dR;
 
+    SG::ReadDecorHandleKey<xAOD::ElectronContainer> m_electronNeutralPFOReadDecorKey;
+    SG::ReadDecorHandleKey<xAOD::ElectronContainer> m_electronChargedPFOReadDecorKey;
+    SG::ReadDecorHandleKey<xAOD::PhotonContainer> m_photonNeutralPFOReadDecorKey; 
+    SG::ReadDecorHandleKey<xAOD::PhotonContainer> m_photonChargedPFOReadDecorKey; 
+
+    SG::ReadDecorHandleKey<xAOD::ElectronContainer> m_electronNeutralFEReadDecorKey;
+    SG::ReadDecorHandleKey<xAOD::ElectronContainer> m_electronChargedFEReadDecorKey;
+    SG::ReadDecorHandleKey<xAOD::PhotonContainer> m_photonNeutralFEReadDecorKey; 
+    SG::ReadDecorHandleKey<xAOD::PhotonContainer> m_photonChargedFEReadDecorKey; 
+
+
+    bool m_usePFOElectronLinks;
+    bool m_usePFOPhotonLinks; 
+    bool m_useFEElectronLinks;
+    bool m_useFEPhotonLinks;
+    bool m_checkUnmatched; 
+
     private:
  
     /// Default constructor: 
@@ -97,3 +129,4 @@ namespace met{
 }
 
 #endif //> !METRECONSTRUCTION_METEGAMMAASSOCIATOR_H
+
diff --git a/Reconstruction/MET/METReconstruction/METReconstruction/METMuonAssociator.h b/Reconstruction/MET/METReconstruction/METReconstruction/METMuonAssociator.h
index 60cacc269128f24f2a4ac90091dcaf762f9f36bd..e49e701036a2a052ed90841fa122f6279f6968d1 100644
--- a/Reconstruction/MET/METReconstruction/METReconstruction/METMuonAssociator.h
+++ b/Reconstruction/MET/METReconstruction/METReconstruction/METMuonAssociator.h
@@ -71,6 +71,9 @@ namespace met{
     private:
 
     bool m_doMuonClusterMatch;
+    SG::ReadDecorHandleKey<xAOD::MuonContainer> m_muonNeutralFEReadDecorKey;
+    SG::ReadDecorHandleKey<xAOD::MuonContainer> m_muonChargedFEReadDecorKey;
+    bool m_useFEMuonLinks; 
 
     /// Default constructor: 
     METMuonAssociator();  
diff --git a/Reconstruction/MET/METReconstruction/METReconstruction/METTauAssociator.h b/Reconstruction/MET/METReconstruction/METReconstruction/METTauAssociator.h
index 1a41e1a510d5f0ac56545b68af8ec7658e0362fb..3eb54813bafdb21a6f0093e7f4b9144e6229edf3 100644
--- a/Reconstruction/MET/METReconstruction/METReconstruction/METTauAssociator.h
+++ b/Reconstruction/MET/METReconstruction/METReconstruction/METTauAssociator.h
@@ -67,7 +67,7 @@ namespace met{
     StatusCode extractFE(const xAOD::IParticle* obj,
                          std::vector<const xAOD::IParticle*>& felist,
                          const met::METAssociator::ConstitHolder& constits,
-                         std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t> &momenta) const final;
+                         std::map<const xAOD::IParticle*,MissingETBase::Types::constvec_t> &momenta) const final;   // TODO: split in extractFEsFromLinks and extractFEs, similarly to extractPFO in METEgammaAssociator, to use links
     
     StatusCode extractTracks(const xAOD::IParticle* obj,
                              std::vector<const xAOD::IParticle*>& constlist,
@@ -78,6 +78,9 @@ namespace met{
     /// Default constructor: 
     METTauAssociator();
     SG::ReadHandleKey<xAOD::TauJetContainer> m_tauContKey;
+    SG::ReadDecorHandleKey<xAOD::TauJetContainer> m_tauNeutralFEReadDecorKey;
+    SG::ReadDecorHandleKey<xAOD::TauJetContainer> m_tauChargedFEReadDecorKey;
+    bool m_useFETauLinks;
 
   }; 
 
diff --git a/Reconstruction/MET/METReconstruction/Root/METEgammaAssociator.cxx b/Reconstruction/MET/METReconstruction/Root/METEgammaAssociator.cxx
index 92f077f6ae757949ed488e2e346c68a7ef442b9e..ffbd514512c32d0909f490e581560adc0502ce4f 100644
--- a/Reconstruction/MET/METReconstruction/Root/METEgammaAssociator.cxx
+++ b/Reconstruction/MET/METReconstruction/Root/METEgammaAssociator.cxx
@@ -26,6 +26,11 @@
 // DeltaR calculation
 #include "FourMomUtils/xAODP4Helpers.h"
 
+typedef ElementLink<xAOD::ElectronContainer> ElectronLink_t;
+typedef ElementLink<xAOD::PhotonContainer> PhotonLink_t;
+typedef ElementLink<xAOD::PFOContainer> PFOLink_t;
+typedef ElementLink<xAOD::FlowElementContainer> FELink_t;
+
 namespace met {
 
   using namespace xAOD;
@@ -44,6 +49,21 @@ namespace met {
     declareProperty( "TCMatchDeltaR",     m_tcMatch_dR     = 0.1    );
 
     declareProperty( "ExtraTrackMatchDeltaR", m_extraTrkMatch_dR = 0.05 );
+
+    declareProperty( "ElectronNeutralPFOReadDecorKey", m_electronNeutralPFOReadDecorKey = "Electrons.neutralpfoLinks" );
+    declareProperty( "ElectronChargedPFOReadDecorKey", m_electronChargedPFOReadDecorKey = "Electrons.chargedpfoLinks" );
+    declareProperty( "PhotonNeutralPFOReadDecorKey", m_photonNeutralPFOReadDecorKey = "Photon.neutralpfoLinks" ); 
+    declareProperty( "PhotonChargedPFOReadDecorKey", m_photonChargedPFOReadDecorKey = "Photon.chargedpfoLinks" ); 
+    declareProperty( "ElectronNeutralFEReadDecorKey", m_electronNeutralFEReadDecorKey = "Electrons.neutralFELinks" );
+    declareProperty( "ElectronChargedFEReadDecorKey", m_electronChargedFEReadDecorKey = "Electrons.chargedFELinks" );
+    declareProperty( "PhotonNeutralFEReadDecorKey", m_photonNeutralFEReadDecorKey = "Photon.neutralFELinks" ); 
+    declareProperty( "PhotonChargedFEReadDecorKey", m_photonChargedFEReadDecorKey = "Photon.chargedFELinks" ); 
+
+    declareProperty( "UsePFOElectronLinks", m_usePFOElectronLinks = false );
+    declareProperty( "UsePFOPhotonLinks", m_usePFOPhotonLinks = false);
+    declareProperty( "UseFEElectronLinks", m_useFEElectronLinks = false ); 
+    declareProperty( "UseFEPhotonLinks", m_useFEPhotonLinks = false); 
+    declareProperty( "CheckUnmatched", m_checkUnmatched = false); 
   }
 
   // Destructor
@@ -64,6 +84,16 @@ namespace met {
       ATH_MSG_WARNING( "Invalid topocluster match method configured!" );
       return StatusCode::FAILURE;
     } 
+
+    ATH_CHECK(m_electronNeutralPFOReadDecorKey.initialize());
+    ATH_CHECK(m_electronChargedPFOReadDecorKey.initialize());
+    ATH_CHECK(m_photonNeutralPFOReadDecorKey.initialize());
+    ATH_CHECK(m_photonChargedPFOReadDecorKey.initialize());
+    ATH_CHECK(m_electronNeutralFEReadDecorKey.initialize());
+    ATH_CHECK(m_electronChargedFEReadDecorKey.initialize());
+    ATH_CHECK(m_photonNeutralFEReadDecorKey.initialize());
+    ATH_CHECK(m_photonChargedFEReadDecorKey.initialize());
+
     return StatusCode::SUCCESS;
   }
 
@@ -151,9 +181,88 @@ namespace met {
                                              std::map<const IParticle*,MissingETBase::Types::constvec_t> &/*momenta*/) const
   {
     const xAOD::Egamma *eg = static_cast<const xAOD::Egamma*>(obj);
+
+    if ((m_usePFOElectronLinks && eg->type() == xAOD::Type::Electron) || (m_usePFOPhotonLinks && eg->type() == xAOD::Type::Photon)) { 
+      ATH_CHECK( extractPFOsFromLinks(eg, pfolist,constits) );
+    } 
+    else {
+      ATH_CHECK( extractPFOs(eg, pfolist, constits) );
+    }
+
+    return StatusCode::SUCCESS;
+  }
+
+  StatusCode METEgammaAssociator::extractPFOsFromLinks(const xAOD::Egamma* eg,
+						       std::vector<const xAOD::IParticle*>& pfolist,
+						       const met::METAssociator::ConstitHolder& constits) const
+  {
+
+    ATH_MSG_VERBOSE("Extract PFOs From Links for " << eg->type()  << " with pT " << eg->pt());
+
+    SG::ReadDecorHandle<xAOD::ElectronContainer, std::vector<PFOLink_t> > electronNeutralPFOReadDecorHandle (m_electronNeutralPFOReadDecorKey);
+    SG::ReadDecorHandle<xAOD::ElectronContainer, std::vector<PFOLink_t> > electronChargedPFOReadDecorHandle (m_electronChargedPFOReadDecorKey);
+    SG::ReadDecorHandle<xAOD::PhotonContainer, std::vector<PFOLink_t> > photonNeutralPFOReadDecorHandle (m_photonNeutralPFOReadDecorKey);
+    SG::ReadDecorHandle<xAOD::PhotonContainer, std::vector<PFOLink_t> > photonChargedPFOReadDecorHandle (m_photonChargedPFOReadDecorKey);
+
+    const std::vector<PFOLink_t> nPFOLinks = (eg->type() == xAOD::Type::Electron)? electronNeutralPFOReadDecorHandle (*eg) :  photonNeutralPFOReadDecorHandle (*eg);
+    const std::vector<PFOLink_t> cPFOLinks = (eg->type() == xAOD::Type::Electron)? electronChargedPFOReadDecorHandle (*eg) :  photonChargedPFOReadDecorHandle (*eg);
+
+
+    // Charged PFOs
+    for (PFOLink_t pfoLink : cPFOLinks) {
+      if (pfoLink.isValid()){
+	const xAOD::PFO* pfo_init = *pfoLink;
+	for (const auto& pfo : *constits.pfoCont){
+	  if (pfo->index() == pfo_init->index() && pfo->isCharged()){ //index-based match between JetETmiss and CHSParticleFlow collections
+	    const static SG::AuxElement::ConstAccessor<char> PVMatchedAcc("matchedToPV");
+	    if(  pfo->isCharged() && PVMatchedAcc(*pfo)&& ( !m_cleanChargedPFO || isGoodEoverP(pfo->track(0)) ) ) {
+	      ATH_MSG_DEBUG("Accept cPFO with pt " << pfo->pt() << ", e " << pfo->e() << ", eta " << pfo->eta() << ", phi " << pfo->phi() );
+	      if (!m_checkUnmatched) {pfolist.push_back(pfo);} 
+	      else {
+	        bool has_unmatched=hasUnmatchedClusters(eg,pfo_init);
+	        if (!has_unmatched) {pfolist.push_back(pfo);} 
+	      }
+	    } 
+	  }
+	}
+      }
+    } // end cPFO loop
+
+    // Neutral PFOs
+    double eg_cl_e = eg->caloCluster()->e();
+    double sumE_pfo = 0.;
+
+    for (PFOLink_t pfoLink : nPFOLinks) {
+      if (pfoLink.isValid()){
+        const xAOD::PFO* pfo_init = *pfoLink;
+	for (const auto& pfo : *constits.pfoCont){
+	  if (pfo->index() == pfo_init->index() && !pfo->isCharged()){ //index-based match between JetETmiss and CHSParticleFlow collections
+	    double pfo_e = pfo->eEM();
+	    if( ( !pfo->isCharged()&& pfo->e() > FLT_MIN ) ){   
+	      sumE_pfo += pfo_e;
+	      ATH_MSG_DEBUG("E match with new nPFO: " << fabs(sumE_pfo+pfo_e - eg_cl_e) / eg_cl_e);
+	      ATH_MSG_DEBUG("Accept nPFO with pt " << pfo->pt() << ", e " << pfo->e() << ", eta " << pfo->eta() << ", phi " << pfo->phi() << " in sum.");
+	      ATH_MSG_DEBUG("Energy ratio of nPFO to eg: " << pfo_e / eg_cl_e);
+	      pfolist.push_back(pfo);
+	    }   
+	  }
+	}
+      }
+    } // end nPFO links loop
+
+
+    return StatusCode::SUCCESS;
+  }
+
+  StatusCode METEgammaAssociator::extractPFOs(const xAOD::Egamma* eg,
+						    std::vector<const xAOD::IParticle*>& pfolist,
+						    const met::METAssociator::ConstitHolder& constits) const
+
+  {
     // safe to assume a single SW cluster?
     // will do so for now...
     const xAOD::IParticle* swclus = eg->caloCluster();
+    ANA_MSG_INFO("Extract PFOs with DeltaR for " << eg->type()  << " with pT " << eg->pt());
 
     // Preselect PFOs based on proximity: dR<0.4
     std::vector<const xAOD::PFO*> nearbyPFO;
@@ -223,6 +332,9 @@ namespace met {
     return StatusCode::SUCCESS;
   }
 
+
+  // TODO: split in extractFEsFromLinks and extractFEs, similarly to PFOs, to use links
+
   StatusCode METEgammaAssociator::extractFE(const xAOD::IParticle* obj,
                                             std::vector<const xAOD::IParticle*>& felist,
                                             const met::METAssociator::ConstitHolder& constits,
@@ -405,4 +517,69 @@ namespace met {
     return StatusCode::SUCCESS;
   }
 
+
+  bool METEgammaAssociator::hasUnmatchedClusters(const xAOD::Egamma* eg, const xAOD::PFO* pfo) const{
+
+          bool   has_unmatched=false;
+	  float  totSumpt=0;
+	  float  unmatchedSumpt=0;
+	  float  unmatchedE=0;
+	  float  unmatchedTotEMFrac=0;
+	  double emfrac=0;
+
+    	  static SG::AuxElement::Decorator<Float_t> dec_unmatchedFrac("unmatchedFrac");
+    	  static SG::AuxElement::Decorator<Float_t> dec_unmatchedFracSumpt("unmatchedFracSumpt");
+    	  static SG::AuxElement::Decorator<Float_t> dec_unmatchedFracPt("unmatchedFracPt");
+    	  static SG::AuxElement::Decorator<Float_t> dec_unmatchedFracE("unmatchedFracE");
+    	  static SG::AuxElement::Decorator<Float_t> dec_unmatchedFracEClusterPFO("unmatchedFracEClusterPFO");
+    	  static SG::AuxElement::Decorator<Float_t> dec_unmatchedFracPtClusterPFO("unmatchedFracPtClusterPFO");
+    	  static SG::AuxElement::Decorator<Float_t> dec_unmatchedTotEMFrac("unmatchedTotEMFrac");
+
+	  TLorentzVector totVec(0.,0.,0.,0.), unmatchedVec(0.,0.,0.,0.);
+	  const std::vector<const xAOD::CaloCluster*> egClusters = xAOD::EgammaHelpers::getAssociatedTopoClusters(eg->caloCluster());
+	  std::set<const xAOD::CaloCluster*> cPFOClusters;
+	  int nCluscPFO = pfo->nCaloCluster();
+
+	  for (int cl = 0; cl < nCluscPFO; ++cl) {
+	      if (pfo->cluster(cl)) cPFOClusters.insert( pfo->cluster(cl) );
+	  }
+
+	  std::vector<const xAOD::CaloCluster*> unmatchedClusters;
+	  for (const xAOD::CaloCluster* pfoclus : cPFOClusters) {
+	      TLorentzVector tmpVec;
+	      tmpVec.SetPtEtaPhiE(pfoclus->pt(),pfoclus->eta(),pfoclus->phi(),pfoclus->e());
+	      totSumpt+=pfoclus->pt();
+	      totVec+=tmpVec;
+	      bool inEgamma = false;
+	      for (const xAOD::CaloCluster* phclus : egClusters) {
+	        if (pfoclus == phclus) {
+		   inEgamma = true;
+	        }
+	    }
+	    if (!inEgamma) {
+	        unmatchedClusters.push_back(pfoclus);
+		unmatchedSumpt+=pfoclus->pt();
+		unmatchedE+=pfoclus->e();
+		unmatchedVec+=tmpVec;
+		pfoclus->retrieveMoment(xAOD::CaloCluster::ENG_FRAC_EM ,emfrac);
+		unmatchedTotEMFrac=unmatchedTotEMFrac+emfrac*pfoclus->e(); 
+	    }
+
+	  }
+
+	  ATH_MSG_DEBUG("PFO associated to "<<nCluscPFO<< " cluster, of which " << unmatchedClusters.size() << "unmatched one and unmatched pt "<<unmatchedSumpt);
+	  dec_unmatchedFrac(*pfo)=nCluscPFO>0 ?  float(unmatchedClusters.size())/float(nCluscPFO) : -1;
+	  dec_unmatchedFracPt(*pfo)= totVec.Pt()>0 ? float(unmatchedVec.Pt()/totVec.Pt()): -1;
+	  dec_unmatchedFracSumpt(*pfo)= totSumpt>0 ? float(unmatchedSumpt/totSumpt): -1;
+	  dec_unmatchedFracE(*pfo)= totVec.E()>0 ? float(unmatchedE/totVec.E()): -1;
+	  dec_unmatchedTotEMFrac(*pfo)= totVec.E()>0 ? float(unmatchedTotEMFrac/totVec.E()): -1; 
+	  dec_unmatchedFracEClusterPFO(*pfo)= pfo->e()>0 ? float(unmatchedE/pfo->e()): -1;
+	  dec_unmatchedFracPtClusterPFO(*pfo)= pfo->pt()>0 ? float(unmatchedE/pfo->pt()): -1;
+                                                                                                                                           	  
+   return has_unmatched;
+  }
+
+
+
 }
+
diff --git a/Reconstruction/MET/METReconstruction/Root/METMuonAssociator.cxx b/Reconstruction/MET/METReconstruction/Root/METMuonAssociator.cxx
index 7d00b4456544d38828796d906a5840303b07d4ec..9ca70fe45eb295f2463a9ba74fbdc2a2eedf457d 100644
--- a/Reconstruction/MET/METReconstruction/Root/METMuonAssociator.cxx
+++ b/Reconstruction/MET/METReconstruction/Root/METMuonAssociator.cxx
@@ -22,6 +22,10 @@
 // Tracking EDM
 #include "xAODTracking/Vertex.h"
 
+
+typedef ElementLink<xAOD::MuonContainer> MuonLink_t;
+typedef ElementLink<xAOD::FlowElementContainer> FELink_t;
+
 namespace met {
 
   using namespace xAOD;
@@ -36,6 +40,9 @@ namespace met {
   {
     declareProperty("DoClusterMatch", m_doMuonClusterMatch=true);
     declareProperty("MuonKey",m_muContKey);
+    declareProperty( "MuonNeutralFEReadDecorKey", m_muonNeutralFEReadDecorKey = "Muons.neutralFELinks" );
+    declareProperty( "MuonChargedFEReadDecorKey", m_muonChargedFEReadDecorKey = "Muons.chargedFELinks" );
+    declareProperty( "UseFEMuonLinks", m_useFEMuonLinks = false ); 
   }
 
   // Destructor
@@ -51,6 +58,10 @@ namespace met {
     ATH_MSG_VERBOSE ("Initializing " << name() << "...");
     ATH_CHECK( m_muContKey.assign(m_input_data_key));
     ATH_CHECK( m_muContKey.initialize());
+
+    ATH_CHECK(m_muonNeutralFEReadDecorKey.initialize());
+    ATH_CHECK(m_muonChargedFEReadDecorKey.initialize());
+
     if (m_doMuonClusterMatch) {
       ATH_CHECK(m_elementLinkName.initialize());
     }
@@ -213,6 +224,8 @@ namespace met {
     return StatusCode::SUCCESS;
   }
 
+  // TODO: split in extractFEsFromLinks and extractFEs, similarly to extractPFO in METEgammaAssociator, to use links
+
   StatusCode METMuonAssociator::extractFE(const xAOD::IParticle* obj,
                                           std::vector<const xAOD::IParticle*>& felist,
                                           const met::METAssociator::ConstitHolder& constits,
diff --git a/Reconstruction/MET/METReconstruction/Root/METTauAssociator.cxx b/Reconstruction/MET/METReconstruction/Root/METTauAssociator.cxx
index d5b0abf104c5dbecc541e92038ef20fd49f1e566..17f8a27646403f7b19f6f403181abb6b1b4b114f 100644
--- a/Reconstruction/MET/METReconstruction/Root/METTauAssociator.cxx
+++ b/Reconstruction/MET/METReconstruction/Root/METTauAssociator.cxx
@@ -33,6 +33,10 @@
 #include "xAODCaloEvent/CaloVertexedTopoCluster.h"
 #include "PFlowUtils/IWeightPFOTool.h"
 
+
+typedef ElementLink<xAOD::TauJetContainer> TauLink_t;
+typedef ElementLink<xAOD::FlowElementContainer> FELink_t;
+
 namespace met {
 
   using namespace xAOD;
@@ -45,6 +49,9 @@ namespace met {
     m_tauContKey("")
   {
     declareProperty("tauContainer",m_tauContKey);
+    declareProperty( "TauNeutralFEReadDecorKey", m_tauNeutralFEReadDecorKey = "TauJets.neutralFELinks" );
+    declareProperty( "TauChargedFEReadDecorKey", m_tauChargedFEReadDecorKey = "TauJets.chargedFELinks" );
+    declareProperty( "UseFETauLinks", m_useFETauLinks = false ); //?
   }
 
   // Destructor
@@ -61,6 +68,9 @@ namespace met {
     ATH_CHECK( m_tauContKey.assign(m_input_data_key));
     ATH_CHECK( m_tauContKey.initialize());
 
+    ATH_CHECK(m_tauNeutralFEReadDecorKey.initialize());
+    ATH_CHECK(m_tauChargedFEReadDecorKey.initialize());
+
     return StatusCode::SUCCESS;
   }
 
@@ -187,6 +197,7 @@ namespace met {
     return StatusCode::SUCCESS;
   }
 
+  // TODO: split in extractFEsFromLinks and extractFEs, similarly to extractPFO in METEgammaAssociator, to use links
   StatusCode METTauAssociator::extractFE(const xAOD::IParticle* obj,
                                          std::vector<const xAOD::IParticle*>& felist,
                                          const met::METAssociator::ConstitHolder& constits,
diff --git a/Reconstruction/MET/METReconstruction/python/LegacyRunII/METAssocConfig.py b/Reconstruction/MET/METReconstruction/python/LegacyRunII/METAssocConfig.py
index 6f2972858f92f1534b1ce2b0f9911e4a3d50f75d..c0d0e3aab1da58c946bff51a7ad35c022439ed0a 100644
--- a/Reconstruction/MET/METReconstruction/python/LegacyRunII/METAssocConfig.py
+++ b/Reconstruction/MET/METReconstruction/python/LegacyRunII/METAssocConfig.py
@@ -2,7 +2,9 @@
 
 from __future__ import print_function
 from AthenaCommon import CfgMgr
+
 from GaudiKernel.Constants import INFO
+
 import six
 
 #################################################################################
@@ -16,12 +18,14 @@ defaultInputKey = {
    'EMJet'     :'AntiKt4EMTopoJets',
    'PFlowJet'  :'AntiKt4EMPFlowJets',
    'PFlowFEJet':'AntiKt4EMPFlowFEJets',
+   'ORPFlowJet':'AntiKt4OverlapRemovedEMPFlowJets',
    'Muon'      :'Muons',
    'Soft'      :'',
    'Clusters'  :'CaloCalTopoClusters',
    'Tracks'    :'InDetTrackParticles',
    'PFlowObj'  :'CHSParticleFlowObjects',
    'PFlowObjFE':'CHSFlowElements',
+   'ORPFlowObj':'OverlapRemovedCHSParticleFlowObjects',
    'PrimVxColl':'PrimaryVertices',
    'Truth'     :'TruthEvents',
    }
@@ -36,7 +40,9 @@ class AssocConfig:
         self.objType = objType
         self.inputKey = inputKey
 
-def getAssociator(config,suffix,doPFlow=False,
+def getAssociator(config,suffix,doPFlow=False,usePFOElectronLinks=False,usePFOPhotonLinks=False,
+                  useFEElectronLinks=False,useFEPhotonLinks=False,
+                  useFEMuonLinks=False,useFETauLinks=False,
                   trkseltool=None,trkisotool=None,caloisotool=None,
                   modConstKey="",
                   modClusColls={}):
@@ -44,31 +50,49 @@ def getAssociator(config,suffix,doPFlow=False,
 
     import cppyy
     cppyy.include("METRecoInterface/METRecoCommon.h")
-  
+
     doModClus = (modConstKey!="" and not doPFlow)
     if doModClus:
         modLCClus = modClusColls['LC{0}Clusters'.format(modConstKey)]
         modEMClus = modClusColls['EM{0}Clusters'.format(modConstKey)]
-
     # Construct tool and set defaults for case-specific configuration
     if config.objType == 'Ele':
         from ROOT import met
         tool = CfgMgr.met__METElectronAssociator('MET_ElectronAssociator_'+suffix,TCMatchMethod=met.ClusterLink)
+        #tool.OutputLevel=VERBOSE
+        if usePFOElectronLinks:
+            tool.UsePFOElectronLinks = True
+        if useFEElectronLinks:
+            tool.UseFEElectronLinks = True
+
+
     if config.objType == 'Gamma':
+
         from ROOT import met
         tool = CfgMgr.met__METPhotonAssociator('MET_PhotonAssociator_'+suffix,TCMatchMethod=met.ClusterLink)
+
+        if usePFOPhotonLinks:
+            tool.UsePFOPhotonLinks = True
+        if useFEPhotonLinks: 
+            tool.UseFEPhotonLinks = True
+
     if config.objType == 'Tau':
         tool = CfgMgr.met__METTauAssociator('MET_TauAssociator_'+suffix)
+        if useFETauLinks: 
+            tool.UseFETauLinks = True
     if config.objType == 'LCJet':
         tool = CfgMgr.met__METJetAssocTool('MET_LCJetAssocTool_'+suffix)
     if config.objType == 'EMJet':
         tool = CfgMgr.met__METJetAssocTool('MET_EMJetAssocTool_'+suffix)
     if config.objType == 'PFlowJet':
         tool = CfgMgr.met__METJetAssocTool('MET_PFlowJetAssocTool_'+suffix)
-    if config.objType == 'PFlowFEJet':
-        tool = CfgMgr.met__METJetAssocTool('MET_PFlowFEJetAssocTool_'+suffix)
+    if config.objType == 'ORPFlowJet':
+        tool = CfgMgr.met__METJetAssocTool('MET_OverlapRemovedPFlowJetAssocTool_'+suffix)
     if config.objType == 'Muon':
         tool = CfgMgr.met__METMuonAssociator('MET_MuonAssociator_'+suffix)
+        if useFEMuonLinks: 
+            tool.UseFEMuonLinks = True
+        #tool.OutputLevel=VERBOSE
     if config.objType == 'Soft':
         tool = CfgMgr.met__METSoftAssociator('MET_SoftAssociator_'+suffix)
         tool.DecorateSoftConst = True
@@ -79,13 +103,16 @@ def getAssociator(config,suffix,doPFlow=False,
         tool = CfgMgr.met__METTruthAssociator('MET_TruthAssociator_'+suffix)
         tool.RecoJetKey = config.inputKey
 
+
+
+
     from METReconstruction.METRecoFlags import metFlags
     if doPFlow:
         tool.PFlow = True
         if metFlags.UseFlowElements() :
             tool.FlowElementCollection = modConstKey if modConstKey!="" else defaultInputKey["PFlowObjFE"]
         else:
-            tool.PFlowColl = modConstKey if modConstKey!="" else defaultInputKey["PFlowObj"]
+            tool.PFlowColl = modConstKey if modConstKey!="" else (defaultInputKey["PFlowObj"]  if suffix!='AntiKt4OverlapRemovedEMPFlow' else defaultInputKey["ORPFlowObj"])
     else:
         tool.UseModifiedClus = doModClus
     # set input/output key names
@@ -107,8 +134,6 @@ def getAssociator(config,suffix,doPFlow=False,
     tool.TrackIsolationTool = trkisotool
     tool.CaloIsolationTool = caloisotool
 
-    #if not hasattr(ToolSvc,tool.name()):
-    #   ToolSvc += tool
     return tool
 
 #################################################################################
@@ -132,6 +157,12 @@ class METAssocConfig:
             else:
                 associator = getAssociator(config=config,suffix=self.suffix,
                                            doPFlow=self.doPFlow,
+                                           usePFOElectronLinks=self.usePFOElectronLinks,
+                                           usePFOPhotonLinks=self.usePFOPhotonLinks,
+                                           useFEElectronLinks=self.useFEElectronLinks, 
+                                           useFEPhotonLinks=self.useFEPhotonLinks, 
+                                           useFEMuonLinks=self.useFEMuonLinks, 
+                                           useFETauLinks=self.useFETauLinks, 
                                            trkseltool=self.trkseltool,
                                            trkisotool=self.trkisotool,
                                            caloisotool=self.caloisotool,
@@ -147,6 +178,12 @@ class METAssocConfig:
     #
     def __init__(self,suffix,buildconfigs=[],
                  doPFlow=False,doTruth=False,
+                 usePFOElectronLinks=False,
+                 usePFOPhotonLinks=False, 
+                 useFEElectronLinks=False, 
+                 useFEPhotonLinks=False,  
+                 useFEMuonLinks=False, 
+                 useFETauLinks=False, 
                  trksel=None,
                  modConstKey="",
                  modClusColls={}
@@ -159,7 +196,7 @@ class METAssocConfig:
             if metFlags.UseFlowElements():
                 if modConstKey_tmp == "": modConstKey_tmp = "CHSFlowElements"
             else:
-                if modConstKey_tmp == "": modConstKey_tmp = "CHSParticleFlowObjects"
+                if modConstKey_tmp == "": modConstKey_tmp = "CHSParticleFlowObjects" if 'OverlapRemoved' not in suffix else "OverlapRemovedCHSParticleFlowObjects"
         else:
             if modConstKey_tmp == "": modConstKey_tmp = "OriginCorr"
             if modClusColls_tmp == {}: modClusColls_tmp = {'LCOriginCorrClusters':'LCOriginTopoClusters',
@@ -169,11 +206,16 @@ class METAssocConfig:
         else:
             print (prefix, 'Creating MET Assoc config \''+suffix+'\'')
         self.suffix = suffix
-        self.doPFlow = doPFlow                
+        self.doPFlow = doPFlow
+        self.usePFOElectronLinks = usePFOElectronLinks
+        self.usePFOPhotonLinks = usePFOPhotonLinks 
+        self.useFEElectronLinks = useFEElectronLinks 
+        self.useFEPhotonLinks = useFEPhotonLinks 
+        self.useFEMuonLinks = useFEMuonLinks 
+        self.useFETauLinks = useFETauLinks 
         self.modConstKey=modConstKey_tmp
         self.modClusColls=modClusColls_tmp
         self.doTruth = doTruth
-
         if trksel:
             self.trkseltool = trksel
         else:
@@ -233,11 +275,11 @@ def getMETAssocAlg(algName='METAssociation',configs={},tools=[],msglvl=INFO):
 
     from METReconstruction.METRecoFlags import metFlags
     if configs=={} and tools==[]:
-        print( prefix, 'Taking configurations from METRecoFlags')
+        print (prefix, 'Taking configurations from METRecoFlags')
         configs = metFlags.METAssocConfigs()
-        print(configs)
+        print (configs)
     for key,conf in six.iteritems(configs):
-        print( prefix, 'Generate METAssocTool for MET_'+key)
+        print (prefix, 'Generate METAssocTool for MET_'+key)
         assoctool = getMETAssocTool(conf,msglvl)
         assocTools.append(assoctool)
         metFlags.METAssocTools()[key] = assoctool
@@ -249,3 +291,4 @@ def getMETAssocAlg(algName='METAssociation',configs={},tools=[],msglvl=INFO):
                                       RecoTools=assocTools)
 #    assocAlg.OutputLevel=DEBUG
     return assocAlg
+
diff --git a/Reconstruction/MET/METReconstruction/python/LegacyRunII/METConfig_Associator.py b/Reconstruction/MET/METReconstruction/python/LegacyRunII/METConfig_Associator.py
index de6c00f8784d0b986e836194e497096bee7197b4..1e9e4cab872e31a85c1589130102f391c20dd208 100644
--- a/Reconstruction/MET/METReconstruction/python/LegacyRunII/METConfig_Associator.py
+++ b/Reconstruction/MET/METReconstruction/python/LegacyRunII/METConfig_Associator.py
@@ -65,7 +65,9 @@ if metFlags.DoPFlow() and metFlags.UseTracks():
                    AssocConfig('Soft')]
     cfg_akt4pf = METAssocConfig('AntiKt4EMPFlow',
                                 associators,
-                                doPFlow=True
+                                doPFlow=True,
+                                usePFOElectronLinks=metFlags.UsePFOElectronLinks(), 
+                                usePFOPhotonLinks=metFlags.UsePFOPhotonLinks() 
                                 )
 
     metFlags.METAssocConfigs()[cfg_akt4pf.suffix] = cfg_akt4pf
@@ -85,8 +87,13 @@ if metFlags.DoPFlow() and metFlags.UseTracks() and metFlags.UseFlowElements():
                    AssocConfig('Soft')]
     cfg_akt4pffe = METAssocConfig('AntiKt4EMPFlowFE',
                                   associators,
-                                  doPFlow=True
+                                  doPFlow=True,
+                                  useFEElectronLinks=metFlags.UseFEElectronLinks(), 
+                                  useFEPhotonLinks=metFlags.UseFEPhotonLinks(),  
+                                  useFEMuonLinks=metFlags.UseFEMuonLinks(),  
+                                  useFETauLinks=metFlags.UseFETauLinks()
                                   )
 
     metFlags.METAssocConfigs()[cfg_akt4pffe.suffix] = cfg_akt4pffe
-    metFlags.METAssocOutputList().append(cfg_akt4pffe.suffix)
\ No newline at end of file
+    metFlags.METAssocOutputList().append(cfg_akt4pffe.suffix)
+
diff --git a/Reconstruction/MET/METReconstruction/python/LegacyRunII/METRecoFlags.py b/Reconstruction/MET/METReconstruction/python/LegacyRunII/METRecoFlags.py
index 99b0482d4042531a1c7f1e61341f2d525ecb9e5d..e22f3ac90551871efba9c5e14ba922e0cab8cb6d 100644
--- a/Reconstruction/MET/METReconstruction/python/LegacyRunII/METRecoFlags.py
+++ b/Reconstruction/MET/METReconstruction/python/LegacyRunII/METRecoFlags.py
@@ -66,10 +66,54 @@ class METAssocOutputList(JobProperty):
     allowedTypes = ['list'] 
     StoredValue  = []
 
+class UsePFOElectronLinks(JobProperty): 
+    statusOn = True
+    allowedTypes = ['bool'] 
+    StoredValue  = False
+
+class UsePFOPhotonLinks(JobProperty): 
+    statusOn = True
+    allowedTypes = ['bool'] 
+    StoredValue  = False
+
+class UseFEElectronLinks(JobProperty):
+    statusOn = True
+    allowedTypes = ['bool'] 
+    StoredValue  = False
+
+class UseFEPhotonLinks(JobProperty): 
+    statusOn = True
+    allowedTypes = ['bool'] 
+    StoredValue  = False
+
+class UseFETauLinks(JobProperty): 
+    statusOn = True
+    allowedTypes = ['bool'] 
+    StoredValue  = False
+
+class UseFEMuonLinks(JobProperty): 
+    statusOn = True
+    allowedTypes = ['bool'] 
+    StoredValue  = False
+
+class DoORMet(JobProperty): 
+    statusOn = True
+    allowedTypes = ['bool'] 
+    StoredValue  = False
+
+
+
 jobproperties.add_Container(METRecoFlags)
 
 jobproperties.METRecoFlags.add_JobProperty(DoRegions)
 jobproperties.METRecoFlags.add_JobProperty(DoPFlow)
+jobproperties.METRecoFlags.add_JobProperty(UsePFOElectronLinks) 
+jobproperties.METRecoFlags.add_JobProperty(UsePFOPhotonLinks) 
+jobproperties.METRecoFlags.add_JobProperty(UseFEElectronLinks) 
+jobproperties.METRecoFlags.add_JobProperty(UseFEPhotonLinks) 
+jobproperties.METRecoFlags.add_JobProperty(UseFETauLinks) 
+jobproperties.METRecoFlags.add_JobProperty(UseFEMuonLinks) 
+jobproperties.METRecoFlags.add_JobProperty(DoORMet) 
 jobproperties.METRecoFlags.add_JobProperty(UseFlowElements)
 jobproperties.METRecoFlags.add_JobProperty(UseTracks)
 jobproperties.METRecoFlags.add_JobProperty(DecorateSoftConst)
@@ -82,3 +126,4 @@ jobproperties.METRecoFlags.add_JobProperty(METAssocOutputList)
 jobproperties.METRecoFlags.add_JobProperty(METAssocTools)
 
 metFlags = jobproperties.METRecoFlags
+
diff --git a/Reconstruction/MET/METReconstruction/share/RunORMETReco.py b/Reconstruction/MET/METReconstruction/share/RunORMETReco.py
new file mode 100644
index 0000000000000000000000000000000000000000..df8308ca13381e48d6386c55b08d72699d1a2143
--- /dev/null
+++ b/Reconstruction/MET/METReconstruction/share/RunORMETReco.py
@@ -0,0 +1,197 @@
+from AthenaCommon import Logging
+log = Logging.logging.getLogger('run_fromAOD.py')
+
+from AthenaCommon.AthenaCommonFlags import athenaCommonFlags
+athenaCommonFlags.FilesInput=[""]
+
+theApp.EvtMax = -1
+
+import AthenaPoolCnvSvc.ReadAthenaPool
+from AthenaCommon.AlgSequence import AlgSequence
+topSequence = AlgSequence()
+
+electronPT		= 10000
+muonPT 			= 10000
+photonPT 		= 10000
+electronWP 		= "Medium"
+muonWP 			= 1
+photonWP 		= "Tight"
+electronETA 		= 2.47
+muonETA 		= 2.7
+photonETA 		= 2.47
+soft			= "Clus"
+metWP			= "PFlow"
+
+usePFOElectronLinks	= True
+usePFOPhotonLinks	= True
+retainMuon		= True
+
+############################################################################
+# Set up detector description 
+from AthenaCommon.GlobalFlags import globalflags
+from IOVDbSvc.CondDB import conddb
+if len(globalflags.ConditionsTag())!=0:
+    conddb.setGlobalTag(globalflags.ConditionsTag())
+include("RecExCond/AllDet_detDescr.py")
+
+############################################################################
+# MET reco and extract OR PFOs 
+
+include("eflowRec/jetAlgs.py")  # std jet reco (AntiKt4EMPFlowJets)
+
+from METReconstruction.METRecoFlags import jobproperties, metFlags
+metFlags.UsePFOElectronLinks=usePFOElectronLinks
+metFlags.UsePFOPhotonLinks=usePFOPhotonLinks
+metFlags.DoORMet = False  # used by ORMETAssoc.py
+
+include("METUtilities/ORMETAssoc.py")
+
+# doRetrieveORconstit 	= True to extract OR PFOs collection
+# retainMuonConstit 	= True to include constituents associated to overlapping muons in OR PFOs collection
+#			  (needed to recover standard muon-jet overlap removal)
+# doORMet		= True for OR MET reco
+
+from METUtilities.ORMETMakerConfig import getMETMakerAlg
+makerAlg = getMETMakerAlg("AntiKt4EMPFlow", jetSelection=metWP, doRetrieveORconstit = True,retainMuonConstit = retainMuon, doORMet=False, muonID=muonWP, electronID=electronWP, photonID=photonWP)
+makerAlg.ElectronPT = electronPT;
+makerAlg.MuonPT = muonPT; 
+makerAlg.PhotonPT = photonPT
+makerAlg.ElectronETA = electronETA;
+makerAlg.MuonETA = muonETA;
+makerAlg.PhotonETA = photonETA;
+makerAlg.Soft = soft
+makerAlg.OutputLevel = DEBUG 
+topSequence += makerAlg
+metFlags.METOutputList().append("AntiKt4EMPFlow")
+
+############################################################################
+# OR MET reco 
+
+include("METUtilities/ORjetReco.py")  # OR jets reco (AntiKt4OverlapRemovedEMPFlowJets)
+
+from METReconstruction.METRecoFlags import jobproperties, metFlags
+metFlags.UsePFOElectronLinks=usePFOElectronLinks
+metFlags.UsePFOPhotonLinks=usePFOPhotonLinks
+metFlags.DoORMet = True #used by ORMETAssoc.py
+
+include("METUtilities/ORMETAssoc.py")
+
+# doRetrieveORconstit 	= True to extract OR PFOs collection
+# retainMuonConstit 	= True to include constituents associated to overlapping muons in OR PFOs collection
+#			  (needed to recover standard muon-jet overlap removal)
+# doORMet		= True for OR MET reco
+
+from METUtilities.ORMETMakerConfig import getMETMakerAlg
+makerAlg = getMETMakerAlg("AntiKt4OverlapRemovedEMPFlow", jetSelection=metWP, doRetrieveORconstit = False, retainMuonConstit = retainMuon, doORMet=True, muonID=muonWP, electronID=electronWP, photonID=photonWP)
+makerAlg.ElectronPT = electronPT;
+makerAlg.MuonPT = muonPT; 
+makerAlg.PhotonPT = photonPT
+makerAlg.ElectronETA = electronETA;
+makerAlg.MuonETA = muonETA;
+makerAlg.PhotonETA = photonETA;
+makerAlg.Soft = soft
+makerAlg.OutputLevel = DEBUG
+topSequence += makerAlg
+metFlags.METOutputList().append("AntiKt4OverlapRemovedEMPFlow")
+
+log.warning('AssocOutputLists: %s', metFlags.METAssocOutputList())
+log.warning('OutputLists: %s', metFlags.METOutputList())
+include("METReconstruction/METReconstructionOutputAODList_jobOptions.py")
+
+############################################################################
+
+from OutputStreamAthenaPool.MultipleStreamManager import MSMgr
+xaodStream = MSMgr.NewStream( "StreamAOD" )
+xaodStream.AddItem("xAOD::JetContainer#AntiKt4OverlapRemovedEMPFlowJets")
+xaodStream.AddItem("xAOD::JetAuxContainer#AntiKt4OverlapRemovedEMPFlowJetsAux.")
+xaodStream.AddItem("xAOD::JetContainer#AntiKt4EMPFlowJets")
+xaodStream.AddItem("xAOD::JetAuxContainer#AntiKt4EMPFlowJetsAux.")
+for met in MissingETAODList: xaodStream.AddItem(met)
+
+
+
+out_dir = "/storage_tmp/atlas/fpiazza/QT/run_analysis/test_nullEleTerm/v15/"
+message = ""
+sample = "Wenu"
+
+
+
+#print sample 
+out_file = 'met.root' #out_dir+'%s_%s_test.root' %(svcMgr.EventSelector.InputCollections[0].split("/")[9],soft)
+
+
+
+
+print("outfile", out_file)
+
+from MCTruthClassifier.MCTruthClassifierConf import MCTruthClassifier
+
+BkgElectronMCTruthClassifier = MCTruthClassifier(name = "BkgElectronMCTruthClassifier",
+                                                 ParticleCaloExtensionTool = "")
+
+
+
+
+alg = CfgMgr.Analysis(MCTruthClassifier = BkgElectronMCTruthClassifier, RetainMuon=True)
+
+
+
+#Configuration
+# alg.SelectElectrons = False;
+alg.ElectronID = "LHMedium";
+alg.MuonID = "LHMedium";
+alg.PhotonID = "Tight";
+alg.ElectronPT = 10000
+alg.MuonPT = 10000; #!!! 2500
+alg.PhotonPT = 10000
+alg.ElectronETA = 2.47;
+alg.MuonETA = 2.7;
+alg.PhotonETA = 2.47;
+alg.SoftTerm = soft
+#alg.InputJets = "AntiKt4EMPflowJets" #unass
+# alg.PVtxMatchingCPFOs = True;
+
+
+alg.OutfileName = out_file;
+# alg.OutfileName = "/data/jmacdonald/QT/eflowRecBugFix/histograms/Zee/" + ID + "/METHistograms_useLinks" + useMETLinks + ".root";
+
+topSequence += alg
+
+
+
+#tool=CfgMgr.met__METMaker("METMaker", OutputLevel=VERBOSE,JetSelection="Expert", CustomJetJvtCut=1.0,CustomJetJvtPtMax=1000000000)
+
+from METUtilities.METUtilitiesConf import met__METMaker
+METmakerTool=met__METMaker(OutputLevel=VERBOSE, DoPFlow=True, JetSelection="PFlow")
+
+from AthenaCommon.AppMgr import ToolSvc
+ToolSvc += METmakerTool
+
+muonSel = CfgMgr.CP__MuonSelectionTool("MuonSelectionTool",
+                                           MuQuality=1, # Medium
+                                           MaxEta=2.4)
+ToolSvc += muonSel
+
+elecSelLH = CfgMgr.AsgElectronLikelihoodTool("ElectronLHSelectionTool",
+                                         WorkingPoint="MediumLHElectron")
+ToolSvc += elecSelLH
+
+photonSelIsEM = CfgMgr.AsgPhotonIsEMSelector("PhotonIsEMSelectionTool",
+                                         WorkingPoint="TightPhoton")
+ToolSvc += photonSelIsEM
+
+tauSel = CfgMgr.TauAnalysisTools__TauSelectionTool("TauSelectionTool")
+ToolSvc += tauSel
+
+
+#METmakerTool.DoPFlow=False
+#print METmakerTool.DoPFlow
+alg.METMaker=METmakerTool
+alg.MuonSelectionTool=muonSel
+alg.ElectronLHSelectionTool=elecSelLH
+alg.PhotonIsEMSelectionTool=photonSelIsEM
+alg.TauSelectionTool=tauSel
+
+
+ServiceMgr.MessageSvc.defaultLimit = 9999999
+
diff --git a/Reconstruction/MET/METUtilities/METUtilities/METMaker.h b/Reconstruction/MET/METUtilities/METUtilities/METMaker.h
index 22157ea0ba3c48234aab0aa7f1045ee1ca29a04c..95ad07a05422107e6c41c8c3550d4cd185899c43 100644
--- a/Reconstruction/MET/METUtilities/METUtilities/METMaker.h
+++ b/Reconstruction/MET/METUtilities/METUtilities/METMaker.h
@@ -18,12 +18,16 @@
 #include "AsgDataHandles/ReadHandleKey.h"
 #include "AsgTools/ToolHandle.h"
 #include "AsgTools/AsgTool.h"
+#include "StoreGate/DataHandle.h" 
+#include "StoreGate/ReadDecorHandle.h" 
 
 // METInterface includes
 #include "METInterface/IMETMaker.h"
 
 // EDM includes
 #include "xAODJet/JetContainer.h"
+#include "xAODPFlow/PFOContainer.h" 
+
 
 // Tracking Tool
 #include "InDetTrackSelectionTool/IInDetTrackSelectionTool.h"
@@ -112,6 +116,28 @@ namespace met {
                              const xAOD::MissingETContainer* metCoreCont,
                              xAOD::MissingETAssociationHelper* helper,
                              bool doJetJVT);
+
+    StatusCode retrieveOverlapRemovedConstituents(const xAOD::PFOContainer* cpfo, const xAOD::PFOContainer* npfo,
+			  xAOD::MissingETAssociationHelper* metHelper,
+			  SG::WriteHandle<xAOD::PFOContainer> chargedPFOContainerWriteHandle,
+			  SG::WriteHandle<xAOD::PFOContainer> neutralPFOContainerWriteHandle,
+			  SG::WriteHandle<xAOD::PFOContainer> PFOContainerWriteHandle,
+			  bool retainMuon = false,
+			  const xAOD::IParticleContainer* collection=0);//,  
+			  //MissingETBase::UsageHandler::Policy p); //jetOR
+
+    StatusCode retrieveOverlapRemovedConstituents(const xAOD::PFOContainer* pfo, 
+			  xAOD::MissingETAssociationHelper* metHelper,
+			  SG::WriteHandle<xAOD::PFOContainer> PFOContainerWriteHandle,
+			  bool retainMuon = false,
+			  const xAOD::IParticleContainer* collection=0);
+
+    const xAOD::PFOContainer* retrieveOverlapRemovedConstituents(const xAOD::PFOContainer* signals,
+			  xAOD::MissingETAssociationHelper* helper,
+			  bool retainMuon = false,
+ 			  const xAOD::IParticleContainer* collection=0, 
+			  MissingETBase::UsageHandler::Policy p=MissingETBase::UsageHandler::ParticleFlow);
+
     StatusCode rebuildTrackMET(xAOD::MissingET* metJet,
                              const xAOD::JetContainer* jets,
                              xAOD::MissingETAssociationHelper* helper,
@@ -173,6 +199,7 @@ namespace met {
     bool m_greedyPhotons;
     bool m_veryGreedyPhotons;
 
+
     ToolHandle<InDet::IInDetTrackSelectionTool> m_trkseltool;
     /// Default constructor:
     METMaker();
diff --git a/Reconstruction/MET/METUtilities/Root/METMaker.cxx b/Reconstruction/MET/METUtilities/Root/METMaker.cxx
index 5bb1b9e416fa70d5ebf1c157686f2b518776be5c..00b9978bef65f429b6821088b2c5a91603186b98 100644
--- a/Reconstruction/MET/METUtilities/Root/METMaker.cxx
+++ b/Reconstruction/MET/METUtilities/Root/METMaker.cxx
@@ -39,6 +39,9 @@
 
 // framework includes
 #include "AsgDataHandles/ReadHandle.h"
+#include "xAODPFlow/PFOAuxContainer.h"
+#include <xAODCore/AuxContainerBase.h>
+#include <AthContainers/AuxElement.h>
 
 namespace met {
 
@@ -80,6 +83,8 @@ namespace met {
   // Implement dphi as well if we start correcting the jet phi.
   // static const SG::AuxElement::Decorator< std::vector<float> > dec_constitObjDphis("ConstitObjectDphis");
 
+
+
   ///////////////////////////////////////////////////////////////////
   // Public methods:
   ///////////////////////////////////////////////////////////////////
@@ -129,6 +134,7 @@ namespace met {
     declareProperty("DoRemoveElecTrksEM", m_doRemoveElecTrksEM = false               );    
 
     declareProperty("TrackSelectorTool",  m_trkseltool                               );
+
   }
 
   // Destructor
@@ -589,6 +595,7 @@ namespace met {
     bool originalInputs = jets->empty() ? false : !acc_originalObject.isAvailable(*jets->front());
 
     for(const auto& jet : *jets) {
+
       const MissingETAssociation* assoc = 0;
       if(originalInputs) {
         assoc = MissingETComposition::getAssociation(map,jet);
@@ -834,6 +841,7 @@ namespace met {
         ATH_MSG_VERBOSE( "Jet OR px, py, pt, E = " << opx << ", " << opy << ", " << opt << ", " << constjet.E() - calvec.ce() );
           
         if(isMuFSRJet) {
+
           if(met_muonEloss) {
             met_muonEloss->add(opx,opy,opt);
           } else {
@@ -1079,6 +1087,154 @@ namespace met {
     return rebuildMET(met,collection,helper,MissingETBase::UsageHandler::PhysicsObject);
   }
 
+
+
+  // Retrieve non overlapping constituents  //fede ?
+  ////////////////////////////////////////
+
+  // Fill OverlapRemovedCHSParticleFlowObjects: view container
+  // and  OverlapRemovedCHSCharged/NeutralParticleFlowObjects: should be writable to AODs
+  StatusCode METMaker::retrieveOverlapRemovedConstituents(const xAOD::PFOContainer* cpfo, const xAOD::PFOContainer* npfo,
+			  xAOD::MissingETAssociationHelper* metHelper,
+			  SG::WriteHandle<xAOD::PFOContainer> chargedPFOContainerWriteHandle,
+			  SG::WriteHandle<xAOD::PFOContainer> neutralPFOContainerWriteHandle,
+			  SG::WriteHandle<xAOD::PFOContainer> PFOContainerWriteHandle,
+			  bool retainMuon,
+			  const xAOD::IParticleContainer* collection)//, 
+			  //MissingETBase::UsageHandler::Policy p); //
+  {
+
+    const xAOD::PFOContainer *OR_cpfos = retrieveOverlapRemovedConstituents(cpfo, metHelper,retainMuon,collection);
+    const xAOD::PFOContainer *OR_npfos = retrieveOverlapRemovedConstituents(npfo, metHelper,retainMuon,collection);
+
+    for (const auto tmp_constit : *cpfo){ 
+      xAOD::PFO* constit=new xAOD::PFO();
+      chargedPFOContainerWriteHandle->push_back(constit); 
+      *constit=*tmp_constit;
+
+      bool keep=false;
+      for (const auto ORconstit : *OR_cpfos){
+	if (ORconstit->index()==tmp_constit->index() && ORconstit->charge()==tmp_constit->charge()) {keep=true;}
+      }
+      if (keep==false){constit->setP4(0., 0., 0., 0.);} 
+			
+      ATH_MSG_VERBOSE("Constituent with index " << tmp_constit->index() << ", charge " << tmp_constit->charge()<< " pT " << tmp_constit->pt() << ((keep==true) ? "" : "not ") <<" in OverlapRemovedCHSParticleFlowObjects");
+    } // end cPFO loop
+
+    for (const auto tmp_constit : *npfo){ 
+      xAOD::PFO* constit=new xAOD::PFO();
+      neutralPFOContainerWriteHandle->push_back(constit);
+      *constit=*tmp_constit;
+
+      bool keep=false;
+      for (const auto ORconstit : *OR_npfos){
+	if (ORconstit->index()==tmp_constit->index() && ORconstit->charge()==tmp_constit->charge()) {keep=true;}
+      }
+      if (keep==false){constit->setP4(0., 0., 0., 0.);}
+			
+      ATH_MSG_VERBOSE("Constituent with index " << tmp_constit->index() << ", charge " << tmp_constit->charge()<< " pT " << tmp_constit->pt() << ((keep==true) ? "" : "not ") <<" in OverlapRemovedCHSParticleFlowObjects");
+    } // end nPFO loop
+	
+    // Merge charged & neutral PFOs into the global view container
+    PFOContainerWriteHandle->assign(neutralPFOContainerWriteHandle->begin(), neutralPFOContainerWriteHandle->end());
+    PFOContainerWriteHandle->insert(PFOContainerWriteHandle->end(),
+		  chargedPFOContainerWriteHandle->begin(), 
+		  chargedPFOContainerWriteHandle->end());
+
+    return StatusCode::SUCCESS;
+  }
+
+
+
+  // Fill only OverlapRemovedCHSParticleFlowObjects, view container
+  StatusCode METMaker::retrieveOverlapRemovedConstituents(const xAOD::PFOContainer* pfo, 
+			  xAOD::MissingETAssociationHelper* metHelper,
+			  SG::WriteHandle<xAOD::PFOContainer> PFOContainerWriteHandle,
+			  bool retainMuon,
+			  const xAOD::IParticleContainer* collection)
+  {	
+    const xAOD::PFOContainer *OR_pfos = retrieveOverlapRemovedConstituents(pfo, metHelper,retainMuon,collection);
+    *PFOContainerWriteHandle.ptr()=*OR_pfos;
+
+    for (const auto tmp_constit : *PFOContainerWriteHandle.ptr()){ATH_MSG_VERBOSE("Constituent with index " << tmp_constit->index() << ", charge " << tmp_constit->charge()<< " pT " << tmp_constit->pt() << " in OverlapRemovedCHSParticleFlowObjects");}
+
+    return StatusCode::SUCCESS;
+  }
+
+
+
+  const xAOD::PFOContainer* METMaker::retrieveOverlapRemovedConstituents(const xAOD::PFOContainer* signals,  xAOD::MissingETAssociationHelper* helper, bool retainMuon, const xAOD::IParticleContainer* collection, MissingETBase::UsageHandler::Policy p)
+  {
+
+    ATH_MSG_VERBOSE("Policy " << p <<" " <<MissingETBase::UsageHandler::ParticleFlow);
+    const xAOD::MissingETAssociationMap* map = helper->map();
+
+
+    // If muon is selected, flag it as non selected to retain its constituents in OR jets (to recover std. muon-jet overlap)
+    std::vector<size_t> muon_index;
+    if (retainMuon){
+      bool originalInputs = !acc_originalObject.isAvailable(*collection->front());
+
+      for(const auto& obj : *collection) {
+	const IParticle* orig = obj;
+	bool selected = false;
+	if(!originalInputs) { orig = *acc_originalObject(*obj); }
+	std::vector<const xAOD::MissingETAssociation*> assocs = xAOD::MissingETComposition::getAssociations(map,orig);
+	if(assocs.empty()) {
+	  ATH_MSG_WARNING("Object is not in association map. Did you make a deep copy but fail to set the \"originalObjectLinks\" decoration?");
+	  ATH_MSG_WARNING("If not, Please apply xAOD::setOriginalObjectLinks() from xAODBase/IParticleHelpers.h");
+	}
+	if(MissingETComposition::objSelected(helper,orig)) {
+	  ATH_MSG_DEBUG("Muon with index "<<orig->index() << " is selected. Flag it as non selected before getOverlapRemovedSignals");
+	  muon_index.push_back(orig->index()); 
+	  for(size_t i = 0; i < assocs.size(); i++) helper->setObjSelectionFlag(assocs[i],orig,false);
+	}
+      }
+
+      /*ATH_MSG_VERBOSE("Check selected muons before getOverlapRemovedSignals");
+      for(const auto& obj : *collection) {
+	const IParticle* orig = obj;
+	if(!originalInputs) { orig = *acc_originalObject(*obj); }
+	ATH_MSG_VERBOSE("Muon with index "<<orig->index() << " is " << (MissingETComposition::objSelected(helper,orig) ? "" : "non-") << "selected" );
+      }*/
+    } // end retainMuon
+
+    const xAOD::PFOContainer* ORsignals =static_cast<const xAOD::PFOContainer*>(map->getOverlapRemovedSignals(helper,signals,p));
+
+    /*for (const auto tmp_const : *signals){ // printout overlap removed constituents
+      bool keep=false;
+      for (const auto constit : *ORsignals){
+	if (constit->index()==tmp_const->index() && constit->charge()==tmp_const->charge()){keep=true;}
+      }
+      if (keep==false){ANA_MSG_DEBUG("Retrieve OR constituents: DON'T keep " << tmp_const->index() << " with charge " <<  tmp_const->charge() << " and pt "<<tmp_const->pt());}
+    }*/
+
+    // Flag back muons as selected
+    if (retainMuon && muon_index.size()>0){
+      bool originalInputs = !acc_originalObject.isAvailable(*collection->front());
+      for(const auto& obj : *collection) {
+	const IParticle* orig = obj;
+	bool selected = false;
+	if(!originalInputs) { orig = *acc_originalObject(*obj); }
+	std::vector<const xAOD::MissingETAssociation*> assocs = xAOD::MissingETComposition::getAssociations(map,orig);
+	for (size_t ind=0; ind<muon_index.size();ind++){
+	  if(orig->index()==muon_index.at(ind)) {
+	    for(size_t i = 0; i < assocs.size(); i++) helper->setObjSelectionFlag(assocs[i],orig,true);
+	  }
+	}
+      }
+      /*ATH_MSG_VERBOSE("Check selected muons after getOverlapRemovedSignals");
+      for(const auto& obj : *collection) {
+	const IParticle* orig = obj;
+	if(!originalInputs) { orig = *acc_originalObject(*obj); }
+	ATH_MSG_VERBOSE("Muon with index "<<orig->index() << " is selected?" << MissingETComposition::objSelected(helper,orig));
+      }*/
+    }
+
+    return ORsignals;  
+  }
+
+
   // Accept Track
   ////////////////
   bool METMaker::acceptTrack(const xAOD::TrackParticle* trk, const xAOD::Vertex* vx) const
diff --git a/Reconstruction/MET/METUtilities/python/ORMETMakerConfig.py b/Reconstruction/MET/METUtilities/python/ORMETMakerConfig.py
new file mode 100644
index 0000000000000000000000000000000000000000..4dfdef96dd366f98dad6372a03eafb7499939f23
--- /dev/null
+++ b/Reconstruction/MET/METUtilities/python/ORMETMakerConfig.py
@@ -0,0 +1,51 @@
+# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+
+from __future__ import print_function
+from AthenaConfiguration.ComponentFactory import CompFactory
+
+
+def getMETMakerAlg(suffix,jetSelection="Tier0",jetColl="",doRetrieveORconstit=False, retainMuonConstit=False, doORMet=False, muonID=1, electronID="Medium", photonID="Tight"):
+
+    print ("Generate METMaker and METMakerAlg for METAssoc_"+suffix)
+
+    doPFlow = 'PFlow' in suffix
+    doTruth = suffix.startswith('Truth')
+    metMaker = CompFactory.getComp("met::METMaker")('METMaker_'+suffix,
+                                    DoPFlow=doPFlow,
+                                    DoSoftTruth=doTruth,
+                                    JetSelection=jetSelection,
+                                    )
+
+    muonSel = CompFactory.getComp("CP::MuonSelectionTool")("MuonSelectionTool_METMakerAlg",
+                                           MuQuality=muonID, # Medium
+                                           MaxEta=2.4)
+
+    elecSelLH = CompFactory.AsgElectronLikelihoodTool("EleSelLikelihood_METMakerAlg",
+                                                 WorkingPoint=electronID+"LHElectron")
+
+    photonSelIsEM = CompFactory.AsgPhotonIsEMSelector("PhotonSelIsEM_METMakerAlg",
+                                                 WorkingPoint=photonID+"Photon")
+
+    tauSel = CompFactory.getComp("TauAnalysisTools::TauSelectionTool")("TauSelectionTool_METMakerAlg")
+
+    if jetColl=="":
+        jetColl = suffix+'Jets'
+        if doTruth:
+            jetColl = suffix.split('_')[1]+'Jets'
+    makerAlg = CompFactory.getComp("met::ORMETMakerAlg")('ORMETMakerAlg_'+suffix,
+                                       METMapName='METAssoc_AntiKt4EMPFlow',
+                                       ORMETMapName='METAssoc_'+suffix,
+                                       METCoreName='MET_Core_'+suffix,
+                                       METName='MET_Reference_'+suffix,
+                                       InputJets=jetColl,
+                                       Maker=metMaker,
+                                       MuonSelectionTool=muonSel,
+                                       ElectronLHSelectionTool=elecSelLH,
+                                       PhotonIsEMSelectionTool=photonSelIsEM,
+                                       TauSelectionTool=tauSel,
+                                       DoRetrieveORconstit=doRetrieveORconstit,
+                                       RetainMuonConstit=retainMuonConstit,
+                                       DoORMet=doORMet,
+                                       )
+    return makerAlg
+
diff --git a/Reconstruction/MET/METUtilities/share/ORMETAssoc.py b/Reconstruction/MET/METUtilities/share/ORMETAssoc.py
new file mode 100644
index 0000000000000000000000000000000000000000..2e5b5ff074e6273c240a1f6d46069ec767e66055
--- /dev/null
+++ b/Reconstruction/MET/METUtilities/share/ORMETAssoc.py
@@ -0,0 +1,28 @@
+from METReconstruction.METRecoFlags import jobproperties, metFlags
+from METReconstruction.METAssocConfig import AssocConfig, METAssocConfig, getMETAssocAlg
+from METReconstruction.METRecoConfig import getMETRecoAlg
+
+JetType = 'PFlowJet' if metFlags.DoORMet==False else 'ORPFlowJet'
+
+#if metFlags.DoORMet==True : modConstKey = "OverlapRemovedCHSParticleFlowObjects" 
+
+associators = [AssocConfig(JetType),
+                   AssocConfig('Muon'),
+                   AssocConfig('Ele'),
+                   AssocConfig('Gamma'),
+                   #AssocConfig('Tau'), # TODO, need to fix links in METTauAssociator
+                   AssocConfig('Soft')]
+cfg_akt4pf = METAssocConfig('AntiKt4EMPFlow' if metFlags.DoORMet==False else 'AntiKt4OverlapRemovedEMPFlow',
+                                associators,
+                                doPFlow=True,
+                                usePFOElectronLinks=metFlags.UsePFOElectronLinks, 
+                                usePFOPhotonLinks=metFlags.UsePFOPhotonLinks 
+                            )
+
+metFlags.METAssocConfigs()[cfg_akt4pf.suffix] = cfg_akt4pf
+metFlags.METAssocOutputList().append(cfg_akt4pf.suffix)
+metAlg = getMETAssocAlg('METAssociation' if metFlags.DoORMet==False else 'METAssociationOR',configs={cfg_akt4pf.suffix:cfg_akt4pf})
+topSequence += metAlg
+
+
+
diff --git a/Reconstruction/MET/METUtilities/share/ORjetReco.py b/Reconstruction/MET/METUtilities/share/ORjetReco.py
new file mode 100644
index 0000000000000000000000000000000000000000..802ef57eab2bbd018a5fa78c810ce17c40d22adf
--- /dev/null
+++ b/Reconstruction/MET/METUtilities/share/ORjetReco.py
@@ -0,0 +1,165 @@
+from JetRec.JetRecFlags import jetFlags
+jetFlags.usePFlow = True
+
+#########################################
+# PseudoJet algorithms
+
+gtrackget = CfgMgr.PseudoJetAlgorithm(
+  "orgtrackget",
+  InputContainer = "JetSelectedTracks",
+  Label = "GhostTrack",
+  OutputContainer = "ORPseudoJetGhostTracks",
+  SkipNegativeEnergy = True,
+  #GhostScale = 0.0,
+  #OutputLevel=VERBOSE,
+)
+topSequence += gtrackget
+
+pflowget = CfgMgr.PseudoJetAlgorithm(
+  "orpflowget",
+  InputContainer = "OverlapRemovedCHSParticleFlowObjects",
+  Label = "EMPFlow", 
+  OutputContainer = "ORPseudoJetPFlow",
+  SkipNegativeEnergy = True,
+  #GhostScale = 0.0,
+  #OutputLevel=VERBOSE,
+)
+
+topSequence += pflowget
+
+#########################################
+# Modifiers
+
+# Jet vertex fraction with selection.
+JVFTool = CfgMgr.JetVertexFractionTool(
+  "jvfOR",
+  VertexContainer = "PrimaryVertices",
+  AssociatedTracks = "GhostTrack",
+  TrackVertexAssociation = "JetTrackVtxAssoc",
+  TrackParticleContainer  = "InDetTrackParticles",
+  #TrackSelector = trackselloose,
+  JVFName = "JVF",
+  K_JVFCorrScale = 0.01,
+  #Z0Cut = 3.0,
+  PUTrkPtCut = 30000.0,
+)
+
+JVFTool.JetContainer="AntiKt4OverlapRemovedEMPFlowJets"
+ToolSvc += JVFTool
+
+# Jet vertex tagger.
+JVTTool = CfgMgr.JetVertexTaggerTool(
+  "jvtOR",
+  VertexContainer = "PrimaryVertices",
+  # AssociatedTracks = "GhostTrack",
+  # TrackVertexAssociation = tvassoc.TrackVertexAssociation,
+  # TrackSelector = trackselloose,
+  JVTName = "Jvt",
+
+)
+
+JVTTool.JetContainer="AntiKt4OverlapRemovedEMPFlowJets"
+
+ToolSvc += JVTTool
+
+# Jet track info.
+JetTrackMomentsTool = CfgMgr.JetTrackMomentsTool(
+  "trkmomsOR",
+  JetContainer="AntiKt4OverlapRemovedEMPFlowJets",
+  VertexContainer = "PrimaryVertices",
+  AssociatedTracks = "GhostTrack",
+  TrackVertexAssociation = "JetTrackVtxAssoc",
+  TrackMinPtCuts = [500, 1000],
+  #TrackSelector = trackselloose,
+)
+
+ToolSvc += JetTrackMomentsTool
+
+# Jet track vector sum info
+JetTrackSumMomentsTool = CfgMgr.JetTrackSumMomentsTool(
+  "trksummomsOR",
+  JetContainer="AntiKt4OverlapRemovedEMPFlowJets",
+  VertexContainer = "PrimaryVertices",
+  AssociatedTracks = "GhostTrack",
+  TrackVertexAssociation = "JetTrackVtxAssoc",#tvassoc.TrackVertexAssociation,
+  #InputContainer  = "InDetTrackParticles",
+  RequireTrackPV = True,
+  #TrackSelector = trackselloose,
+)
+
+ToolSvc+=JetTrackSumMomentsTool 
+
+
+constitfourmom_pflow = CfgMgr.JetConstitFourMomTool(
+  "constitfourmom_pflowOR",
+  JetScaleNames = ["DetectorEtaPhi"],
+  AltConstitColls = [""],
+  AltConstitScales = [0],
+  AltJetScales = ["JetConstitScaleMomentum"]
+  )
+ToolSvc+=constitfourmom_pflow
+
+jetens = CfgMgr.JetCaloEnergies("jetensOR",
+  JetContainer="AntiKt4OverlapRemovedEMPFlowJets"
+)
+ToolSvc+=jetens
+
+ecpfsfrac = CfgMgr.JetECPSFractionTool("ecpsfracOR",
+  JetContainer="AntiKt4OverlapRemovedEMPFlowJets"
+)
+ToolSvc+=ecpfsfrac
+
+width= CfgMgr.JetWidthTool("widthOR",
+  JetContainer="AntiKt4OverlapRemovedEMPFlowJets"
+)
+ToolSvc+=width
+
+jetfilter=CfgMgr.JetFilterTool("jetfilter", PtMin=10000)
+ToolSvc+=jetfilter
+
+#########################################
+# Calibration
+
+from JetRec.JetRecCalibrationFinder import jrcf
+
+JetRecCalibrationFinder = CfgMgr.JetCalibrationTool("JetCalibOR", 
+		JetCollection="AntiKt4EMPFlow", 
+		ConfigFile="JES_MC15cRecommendation_PFlow_Aug2016_rel21.config", 
+		CalibSequence="JetArea_Residual_AbsoluteEtaJES", 
+		RhoKey="Kt4EMPFlowEventShape",
+		CalibArea="00-04-77")
+ToolSvc+=JetRecCalibrationFinder
+
+
+#########################################
+# Set up the jet finder
+JetFinder_AntiKt4 = CfgMgr.JetFinder("AntiKt4OverlapRemovedEMPFlowJetsFinder",
+                                     JetAlgorithm = "AntiKt",
+                                     JetRadius = 0.4,
+                                     GhostArea = 0.01,
+                                     PtMin = 5000,
+                                     OutputLevel=INFO,
+                                     )
+
+#########################################
+# Setup a jet builder 
+
+JetBuilder_AntiKt4 = CfgMgr.JetFromPseudojet("jblda", Attributes = ["ActiveArea", "ActiveArea4vec"],
+                                             OutputLevel=INFO)
+JetFinder_AntiKt4.JetBuilder = JetBuilder_AntiKt4
+
+#########################################
+# Setup a JetRecTool 
+
+JetRecTool = CfgMgr.JetRecTool("AntiKt4OREMPFlowJets",
+			       InputPseudoJets = ["ORPseudoJetGhostTracks","ORPseudoJetPFlow"],
+                               OutputLevel=INFO)
+JetRecTool.JetFinder = JetFinder_AntiKt4
+JetRecTool.OutputContainer = "AntiKt4OverlapRemovedEMPFlowJets"
+JetRecTool.JetModifiers = [constitfourmom_pflow,jetens,JetTrackMomentsTool,JetTrackSumMomentsTool,JetRecCalibrationFinder,JVFTool,JVTTool,jetfilter,ecpfsfrac,width]
+#JetRecTool.JetModifiers = [constitfourmom_pflow,jetens,JetTrackMomentsTool,JetTrackSumMomentsTool,JVFTool,JVTTool,jetfilter,ecpfsfrac,width]
+
+#########################################
+# JetAlgorithm
+topSequence += CfgMgr.JetAlgorithm("jetalgAntiKt4OREMPFlowJets",Tools = [JetRecTool])
+
diff --git a/Reconstruction/MET/METUtilities/src/ORMETMakerAlg.cxx b/Reconstruction/MET/METUtilities/src/ORMETMakerAlg.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..64de6fd3c72ef494f4a3ef3513f16b175acb96e2
--- /dev/null
+++ b/Reconstruction/MET/METUtilities/src/ORMETMakerAlg.cxx
@@ -0,0 +1,420 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "ORMETMakerAlg.h"
+#include "METInterface/IMETMaker.h"
+#include "METUtilities/METHelpers.h"
+
+#include "xAODMissingET/MissingETAuxContainer.h"
+#include "xAODMissingET/MissingETComposition.h"
+#include "xAODMissingET/MissingETAssociationMap.h"
+#include "xAODMissingET/MissingETAssociationHelper.h"
+
+#include "MuonAnalysisInterfaces/IMuonSelectionTool.h"
+#include "EgammaAnalysisInterfaces/IAsgElectronLikelihoodTool.h"
+#include "EgammaAnalysisInterfaces/IAsgPhotonIsEMSelector.h"
+#include "PATCore/AcceptData.h"
+#include "TauAnalysisTools/ITauSelectionTool.h"
+#include <xAODCore/ShallowCopy.h>
+
+#include "xAODPFlow/PFOAuxContainer.h"  //jetOR
+
+
+using std::string;
+using namespace xAOD;
+
+namespace met {
+
+  typedef ElementLink<xAOD::IParticleContainer> iplink_t;
+  static const SG::AuxElement::ConstAccessor< std::vector<iplink_t > > acc_constitObjLinks("ConstitObjectLinks");
+
+  //**********************************************************************
+
+  ORMETMakerAlg::ORMETMakerAlg(const std::string& name,
+			   ISvcLocator* pSvcLocator )
+    : ::AthAlgorithm( name, pSvcLocator ),
+    m_metKey(""),
+    m_metmaker(this),  
+    m_muonSelTool(this,""),
+    m_elecSelLHTool(this,""),
+    m_photonSelIsEMTool(this,""),
+    m_tauSelTool(this,"")
+
+
+ {
+    declareProperty( "Maker",          m_metmaker                        );
+    declareProperty( "METCoreName",    m_CoreMetKey  = "MET_Core"        );
+    declareProperty("METName",         m_metKey = std::string("MET_Reference"),"MET container");
+    declareProperty("METMapName",      m_metMapKey = "METAssoc" );
+    declareProperty("ORMETMapName",    m_ORMetMapKey = "ORMETAssoc" );
+
+    declareProperty( "METSoftClName",  m_softclname  = "SoftClus"        );
+    declareProperty( "METSoftTrkName", m_softtrkname = "PVSoftTrk"       );
+
+    declareProperty( "InputJets",      m_JetContainerKey      = "AntiKt4EMPFlowJets" );
+    declareProperty( "InputElectrons", m_ElectronContainerKey = "Electrons" );
+    declareProperty( "InputPhotons",   m_PhotonContainerKey   = "Photons"   );
+    declareProperty( "InputTaus",      m_TauJetContainerKey   = "TauJets"   );
+    declareProperty( "InputMuons",     m_MuonContainerKey     = "Muons"     );
+
+    declareProperty( "MuonSelectionTool",        m_muonSelTool           );
+    declareProperty( "ElectronLHSelectionTool",  m_elecSelLHTool         );
+    declareProperty( "PhotonIsEMSelectionTool" , m_photonSelIsEMTool     );
+    declareProperty( "TauSelectionTool",         m_tauSelTool            );
+
+    declareProperty( "DoTruthLeptons", m_doTruthLep = false              );
+
+    declareProperty( "DoRetrieveORconstit", m_doRetrieveORconstit = false              );
+    declareProperty( "RetainMuonConstit", m_retainMuonConstit = false              );
+    declareProperty( "DoORMet", m_doORMet = false              );
+
+    //pT thresholds
+    declareProperty("ElectronPT", m_electronPT = 10000, "pT for electrons");
+    declareProperty("MuonPT", m_muonPT = 10000, "pT for muons");
+    declareProperty("PhotonPT", m_photonPT = 10000, "pT for photons");
+    declareProperty("TauPT", m_tauPT = 10000, "pT for photons");
+
+    //eta thresholds
+    declareProperty("ElectronETA", m_electronETA = 2.47, "eta for electrons");
+    declareProperty("MuonETA", m_muonETA = 2.7, "eta for muons");
+    declareProperty("PhotonETA", m_photonETA = 2.47, "eta for photons");
+    declareProperty("TauETA", m_tauETA = 2.47, "eta for photons");
+
+    // True or fake electrons / muons
+    declareProperty("UsePromptElectrons", m_usePromptElectrons = "True", "To use true (prompt) electrons in MET or not");
+    declareProperty("UseUnmatched", m_useUnmatched = "True", "Include or reject egamma with unmatched clusters");
+    declareProperty("DoBadMuon", m_doBadMuon = "False", "To reject BadMuon or not");
+
+    declareProperty("DoJVT", m_doJVT = "False");
+    declareProperty("Soft", m_soft = "Clus");
+
+
+  }
+
+  //**********************************************************************
+
+  ORMETMakerAlg::~ORMETMakerAlg() { }
+
+  //**********************************************************************
+
+  StatusCode ORMETMakerAlg::initialize() {
+    ATH_MSG_INFO("Initializing " << name() << "...");
+    ATH_MSG_INFO("Retrieving tools...");
+
+    // retrieve tools
+    if( m_metmaker.retrieve().isFailure() ) {
+      ATH_MSG_ERROR("Failed to retrieve tool: " << m_metmaker->name());
+      return StatusCode::FAILURE;
+    };
+
+    if( m_muonSelTool.retrieve().isFailure() ) {
+      ATH_MSG_ERROR("Failed to retrieve tool: " << m_muonSelTool->name());
+      return StatusCode::FAILURE;
+    };
+
+    if( m_elecSelLHTool.retrieve().isFailure() ) {
+      ATH_MSG_ERROR("Failed to retrieve tool: " << m_elecSelLHTool->name());
+      return StatusCode::FAILURE;
+    };
+
+    if( m_photonSelIsEMTool.retrieve().isFailure() ) {
+      ATH_MSG_ERROR("Failed to retrieve tool: " << m_photonSelIsEMTool->name());
+      return StatusCode::FAILURE;
+    };
+
+    if( m_tauSelTool.retrieve().isFailure() ) {
+      ATH_MSG_ERROR("Failed to retrieve tool: " << m_tauSelTool->name());
+      return StatusCode::FAILURE;
+    };
+    ATH_CHECK( m_ElectronContainerKey.initialize() );
+    ATH_CHECK( m_PhotonContainerKey.initialize() );
+    ATH_CHECK( m_TauJetContainerKey.initialize() );
+    ATH_CHECK( m_MuonContainerKey.initialize() );
+    ATH_CHECK( m_JetContainerKey.initialize() );
+    ATH_CHECK( m_CoreMetKey.initialize() );
+    ATH_CHECK( m_metKey.initialize() );
+    ATH_CHECK( m_metMapKey.initialize() );
+    ATH_CHECK( m_ORMetMapKey.initialize() );
+    ATH_CHECK(m_chargedPFOContainerWriteHandleKey.initialize()); 
+    ATH_CHECK(m_neutralPFOContainerWriteHandleKey.initialize()); 
+    ATH_CHECK(m_PFOContainerWriteHandleKey.initialize()); 
+
+    return StatusCode::SUCCESS;
+  }
+
+  //**********************************************************************
+
+  StatusCode ORMETMakerAlg::finalize() {
+    ATH_MSG_INFO ("Finalizing " << name() << "...");
+    return StatusCode::SUCCESS;
+  }
+
+  //**********************************************************************
+
+  StatusCode ORMETMakerAlg::execute() {
+    ATH_MSG_VERBOSE("Executing " << name() << "...");
+
+    // Create a MissingETContainer with its aux store
+    auto ctx = getContext();
+    auto metHandle= SG::makeHandle (m_metKey,ctx);
+    ATH_CHECK( metHandle.record (std::make_unique<xAOD::MissingETContainer>(),                      std::make_unique<xAOD::MissingETAuxContainer>()) );
+    xAOD::MissingETContainer* newMet=metHandle.ptr();
+
+
+    SG::ReadHandle<xAOD::MissingETAssociationMap> metMap(m_metMapKey);
+    if (!metMap.isValid()) {
+      ATH_MSG_WARNING("Unable to retrieve MissingETAssociationMap: " << m_metMapKey.key());
+      return StatusCode::FAILURE;
+    }
+
+    MissingETAssociationHelper metHelper(&(*metMap));
+
+    SG::ReadHandle<xAOD::MissingETAssociationMap> ORMetMap(m_ORMetMapKey);
+    if (m_doORMet && !ORMetMap.isValid()) {
+      ATH_MSG_WARNING("Unable to retrieve MissingETAssociationMap: " << m_ORMetMapKey.key());
+      return StatusCode::FAILURE;
+    }
+
+    
+    MissingETAssociationHelper ORMetHelper((m_doORMet ? &(*ORMetMap) : 0));
+
+    // Retrieve containers ***********************************************
+
+    /// MET
+    SG::ReadHandle<xAOD::MissingETContainer> coreMet(m_CoreMetKey);
+    if (!coreMet.isValid()) {
+      ATH_MSG_WARNING("Unable to retrieve MissingETContainer: " << m_CoreMetKey.key());
+      return StatusCode::FAILURE;
+    }
+
+    /// Jets
+    SG::ReadHandle<xAOD::JetContainer> Jets(m_JetContainerKey);
+    if (!Jets.isValid()) {
+      ATH_MSG_WARNING("Unable to retrieve JetContainer: " << Jets.key());
+      return StatusCode::FAILURE;
+    }
+
+    /// Electrons
+    SG::ReadHandle<xAOD::ElectronContainer> Electrons(m_ElectronContainerKey);
+    if (!Electrons.isValid()) {
+      ATH_MSG_WARNING("Unable to retrieve ElectronContainer: " << Electrons.key());
+      return StatusCode::FAILURE;
+    }
+
+    /// Photons
+    SG::ReadHandle<xAOD::PhotonContainer> Gamma(m_PhotonContainerKey);
+    if (!Gamma.isValid()) {
+      ATH_MSG_WARNING("Unable to retrieve GammaContainer: " << Gamma.key());
+      return StatusCode::FAILURE;
+    }
+
+    /// Taus
+    SG::ReadHandle<xAOD::TauJetContainer> TauJets(m_TauJetContainerKey);
+    if (!TauJets.isValid()) {
+      ATH_MSG_WARNING("Unable to retrieve TauJetContainer: " << TauJets.key());
+      return StatusCode::FAILURE;
+    }
+
+    /// Muons
+    SG::ReadHandle<xAOD::MuonContainer> Muons(m_MuonContainerKey);
+    if (!Muons.isValid()) {
+      ATH_MSG_WARNING("Unable to retrieve MuonContainer: "  << Muons.key());
+      return StatusCode::FAILURE;
+    }
+
+    ///PFOs for OR constituents
+    SG::ReadHandle<xAOD::PFOContainer> PFOs("CHSParticleFlowObjects");
+    if (!PFOs.isValid() && m_doRetrieveORconstit ) {
+      ATH_MSG_WARNING("Unable to retrieve PFOContainer: " << PFOs.key());
+      return StatusCode::FAILURE;
+    }
+
+    // Select and flag objects for final MET building ***************************
+
+    MissingETBase::UsageHandler::Policy objScale = MissingETBase::UsageHandler::PhysicsObject;
+    if(m_doTruthLep) objScale = MissingETBase::UsageHandler::TruthParticle;
+    // Electrons
+    if(!m_ElectronContainerKey.empty()) {
+      ConstDataVector<ElectronContainer> metElectrons(SG::VIEW_ELEMENTS);
+      for(const auto& el : *Electrons) {
+    	if(accept(el)) {
+    	  metElectrons.push_back(el);
+
+    	}
+      }
+      if( m_metmaker->rebuildMET("RefEle", xAOD::Type::Electron, newMet,
+    				 metElectrons.asDataVector(),
+    				 &metHelper, objScale).isFailure() ) {
+    	ATH_MSG_WARNING("Failed to build electron term.");
+      }
+      ATH_MSG_DEBUG("Selected " << metElectrons.size() << " MET electrons. "
+    		    << acc_constitObjLinks(*(*newMet)["RefEle"]).size() << " are non-overlapping.");
+    }
+
+    // Photons
+    if(!m_PhotonContainerKey.empty()) {
+      ConstDataVector<PhotonContainer> metPhotons(SG::VIEW_ELEMENTS);
+      for(const auto& ph : *Gamma) {
+    	if(accept(ph)) {
+    	  metPhotons.push_back(ph);
+    	}
+      }
+      if( m_metmaker->rebuildMET("RefGamma", xAOD::Type::Photon, newMet,
+    				 metPhotons.asDataVector(),
+    				 &metHelper, objScale).isFailure() ) {
+    	ATH_MSG_WARNING("Failed to build photon term.");
+      }
+      ATH_MSG_DEBUG("Selected " << metPhotons.size() << " MET photons. "
+    		    << acc_constitObjLinks(*(*newMet)["RefGamma"]).size() << " are non-overlapping.");
+    }
+
+    // Taus
+    if(!m_TauJetContainerKey.empty()) {
+      ConstDataVector<TauJetContainer> metTaus(SG::VIEW_ELEMENTS);
+      for(const auto& tau : *TauJets) {
+    	if(accept(tau)) {
+    	  metTaus.push_back(tau);
+    	}
+      }
+      if( m_metmaker->rebuildMET("RefTau", xAOD::Type::Tau, newMet,
+    				 metTaus.asDataVector(),
+    				 &metHelper, objScale).isFailure() ){
+    	ATH_MSG_WARNING("Failed to build tau term.");
+      }
+      ATH_MSG_DEBUG("Selected " << metTaus.size() << " MET taus. "
+    		    << acc_constitObjLinks(*(*newMet)["RefTau"]).size() << " are non-overlapping.");
+    }
+
+    // Muons
+    ConstDataVector<MuonContainer> metMuons(SG::VIEW_ELEMENTS);
+    if(!m_MuonContainerKey.empty()) {
+      for(const auto& mu : *Muons) {
+    	if(accept(mu)) {
+    	  metMuons.push_back(mu);
+    	}
+      }
+      
+      if(m_doTruthLep) objScale = MissingETBase::UsageHandler::OnlyTrack;
+
+      if (m_doORMet && m_retainMuonConstit) {
+        if( m_metmaker->rebuildMET("Muons", xAOD::Type::Muon, newMet,
+    				 metMuons.asDataVector(),
+    				 &ORMetHelper, objScale).isFailure() ) {
+    	  ATH_MSG_WARNING("Failed to build muon term.");
+        }
+      } else {
+        if( m_metmaker->rebuildMET("Muons", xAOD::Type::Muon, newMet,
+    				 metMuons.asDataVector(),
+    				 &metHelper, objScale).isFailure() ) {
+    	  ATH_MSG_WARNING("Failed to build muon term.");
+        }
+      }
+      ATH_MSG_DEBUG("Selected " << metMuons.size() << " MET muons. "
+    		    << acc_constitObjLinks(*(*newMet)["Muons"]).size() << " are non-overlapping.");
+    }
+
+    if (m_doRetrieveORconstit) {
+
+      SG::WriteHandle<xAOD::PFOContainer> PFOContainerWriteHandle(m_PFOContainerWriteHandleKey,ctx); //jetOR
+      ATH_CHECK(PFOContainerWriteHandle.record(std::make_unique<xAOD::PFOContainer>(SG::VIEW_ELEMENTS)));//jetOR
+
+      /**** If want to write CHScharged/neutralOverlapRemovedPFlowObjects container to AOD ****
+
+      SG::WriteHandle<xAOD::PFOContainer> PFOContainerWriteHandle(m_PFOContainerWriteHandleKey,ctx); //jetOR
+      ATH_CHECK(PFOContainerWriteHandle.record(std::make_unique<xAOD::PFOContainer>(),std::make_unique<xAOD::PFOAuxContainer>())); //jetOR
+  
+      ///jetOR  cPFO
+      SG::ReadHandle<xAOD::PFOContainer> cPFO("CHSChargedParticleFlowObjects");
+      if (!cPFO.isValid()) {
+        ATH_MSG_WARNING("Unable to retrieve PFOContainer: " << cPFO.key());
+        return StatusCode::FAILURE;
+      }
+      ///jetOR  nPFO
+      SG::ReadHandle<xAOD::PFOContainer> nPFO("CHSNeutralParticleFlowObjects");
+      if (!nPFO.isValid()) {
+        ATH_MSG_WARNING("Unable to retrieve PFOContainer: " << nPFO.key());
+         return StatusCode::FAILURE;
+      }
+      SG::WriteHandle<xAOD::PFOContainer> chargedPFOContainerWriteHandle(m_chargedPFOContainerWriteHandleKey,ctx); //jetOR
+      SG::WriteHandle<xAOD::PFOContainer> neutralPFOContainerWriteHandle(m_neutralPFOContainerWriteHandleKey,ctx); //jetOR
+      ATH_CHECK(chargedPFOContainerWriteHandle.record(std::make_unique<xAOD::PFOContainer>(),std::make_unique<xAOD::PFOAuxContainer>())); //jetOR
+      ATH_CHECK(neutralPFOContainerWriteHandle.record(std::make_unique<xAOD::PFOContainer>(),std::make_unique<xAOD::PFOAuxContainer>())); //jetOR
+      */
+
+
+      ATH_MSG_INFO("Retrieve OR constituents");
+      ConstDataVector<PFOContainer> met_PFO(SG::VIEW_ELEMENTS);
+      for(const auto& pfo : *PFOs) {met_PFO.push_back(pfo);}
+      if (metMuons.size()>0 && m_retainMuonConstit) {ATH_CHECK(m_metmaker->retrieveOverlapRemovedConstituents(met_PFO.asDataVector(),&metHelper,PFOContainerWriteHandle,true, metMuons.asDataVector()));}
+      else {ATH_CHECK(m_metmaker->retrieveOverlapRemovedConstituents(met_PFO.asDataVector(),&metHelper,PFOContainerWriteHandle,false));}
+
+      /**** If want to write CHScharged/neutralOverlapRemovedPFlowObjects container to AOD ****
+
+      ConstDataVector<PFOContainer> met_cPFO(SG::VIEW_ELEMENTS);
+      for(const auto& pfo : *cPFOs) {met_cPFO.push_back(pfo);}
+      ConstDataVector<PFOContainer> met_nPFO(SG::VIEW_ELEMENTS);
+      for(const auto& pfo : *nPFOs) {met_nPFO.push_back(pfo);}
+      if (metMuons.size()>0 && m_retainMuonConstit) {ATH_CHECK(m_metmaker->retrieveOverlapRemovedConstituents(met_cPFO.asDataVector(), met_nPFO.asDataVector(),&metHelper,chargedPFOContainerWriteHandle,neutralPFOContainerWriteHandle,PFOContainerWriteHandle,true, metMuons.asDataVector()));}
+      else {ATH_CHECK(m_metmaker->retrieveOverlapRemovedConstituents(met_cPFO.asDataVector(), met_nPFO.asDataVector(),&metHelper,chargedPFOContainerWriteHandle,neutralPFOContainerWriteHandle,PFOContainerWriteHandle,false));}*/
+    }
+
+    
+    m_doJVT= (m_soft=="Clus" ? false : true);
+    if (m_doORMet) {
+      if( m_metmaker->rebuildJetMET("RefJet", (m_soft=="Clus" ? m_softclname : m_softtrkname), newMet,
+				  Jets.cptr(), coreMet.cptr(), &ORMetHelper, m_doJVT ).isFailure() ) {
+        ATH_MSG_WARNING("Failed to build jet and soft terms.");
+      } 
+      ATH_MSG_DEBUG("Of " << Jets.cptr()->size()  << " jets, "
+		  << acc_constitObjLinks(*(*newMet)["RefJet"]).size() << " are non-overlapping, "
+		  << acc_constitObjLinks(*(*newMet)[(m_soft=="Clus" ? m_softclname : m_softtrkname)]).size() << " are soft");
+    } else {
+      if( m_metmaker->rebuildJetMET("RefJet", (m_soft=="Clus" ? m_softclname : m_softtrkname), newMet,
+				  Jets.cptr(), coreMet.cptr(), &metHelper, m_doJVT ).isFailure() ) {
+        ATH_MSG_WARNING("Failed to build jet and soft terms.");
+      }
+      ATH_MSG_DEBUG("Of " << Jets.cptr()->size()  << " jets, "
+		  << acc_constitObjLinks(*(*newMet)["RefJet"]).size() << " are non-overlapping, "
+		  << acc_constitObjLinks(*(*newMet)[(m_soft=="Clus" ? m_softclname : m_softtrkname)]).size() << " are soft");
+    }
+
+
+    ATH_CHECK( buildMETSum("Final"+m_soft, 
+			    newMet,
+			    (m_soft=="Clus")? (*newMet)["SoftClus"]->source() : (*newMet)["PVSoftTrk"]->source()) 
+  	     ); 
+
+ xAOD::MissingET* metSum = (*newMet)["Final"+m_soft];
+  std::cout << "MET sum = " << 0.001 * metSum->met() << " GeV" << std::endl;
+  std::cout << "MET jet = " << 0.001 * (*newMet)["RefJet"]->met() << " GeV" << std::endl;
+  std::cout << "MET mu = " << 0.001 * (*newMet)["Muons"]->met() << " GeV" << std::endl;
+  std::cout << "MET el = " << 0.001 * (*newMet)["RefEle"]->met() << " GeV" << std::endl;
+  std::cout << "MET ph = " << 0.001 * (*newMet)["RefGamma"]->met() << " GeV" << std::endl;
+  std::cout << "MET tau = " << 0.001 * (*newMet)["RefTau"]->met() << " GeV" << std::endl;
+  std::cout << "MET soft = " << 0.001 * (*newMet)["Soft"+m_soft]->met() << " GeV" << std::endl;
+
+    return StatusCode::SUCCESS;
+  }
+
+
+  bool ORMETMakerAlg::accept(const xAOD::Muon* mu){
+        if( mu->pt()<m_muonPT && fabs(mu->eta())>m_muonETA)  return false;
+	return static_cast<bool>(m_muonSelTool->accept(*mu));
+  }
+
+  bool ORMETMakerAlg::accept(const xAOD::Electron* el){
+	if( fabs(el->eta())>m_electronETA || el->pt()<m_electronPT) return false;
+	return static_cast<bool> (m_elecSelLHTool->accept(el));
+  }
+
+  bool ORMETMakerAlg::accept(const xAOD::Photon* ph){
+	if( !(ph->author()&20) || fabs(ph->eta())>m_photonETA || ph->pt()<m_photonPT) return false;
+	return static_cast<bool> (m_photonSelIsEMTool->accept(ph));
+  }
+
+  bool ORMETMakerAlg::accept(const xAOD::TauJet* tau){ 
+	return static_cast<bool>(m_tauSelTool->accept( *tau ));
+  }
+}
+
diff --git a/Reconstruction/MET/METUtilities/src/ORMETMakerAlg.h b/Reconstruction/MET/METUtilities/src/ORMETMakerAlg.h
new file mode 100644
index 0000000000000000000000000000000000000000..f33812e64b8552a3d0241a53219a0df86c7ee58d
--- /dev/null
+++ b/Reconstruction/MET/METUtilities/src/ORMETMakerAlg.h
@@ -0,0 +1,134 @@
+///////////////////////// -*- C++ -*- /////////////////////////////
+
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+// ORMETMakerAlg.h
+
+#ifndef ORMETMakerAlg_H
+#define ORMETMakerAlg_H
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "StoreGate/DataHandle.h"
+
+#include "xAODEgamma/Electron.h"
+#include "xAODEgamma/Photon.h"
+#include "xAODMuon/Muon.h"
+#include "xAODTau/TauJet.h"
+
+#include "xAODJet/JetContainer.h"
+#include "xAODMuon/MuonContainer.h"
+#include "xAODEgamma/ElectronContainer.h"
+#include "xAODEgamma/PhotonContainer.h"
+#include "xAODTau/TauJetContainer.h"
+
+#include "xAODMissingET/MissingETContainer.h"
+#include "xAODMissingET/MissingETAssociationMap.h"
+
+
+class IMETMaker;
+class IAsgElectronLikelihoodTool;
+class IAsgPhotonIsEMSelector;
+namespace CP {
+  class IMuonSelectionTool;
+}
+namespace TauAnalysisTools {
+  class ITauSelectionTool;
+}
+
+namespace met {
+  class ORMETMakerAlg : public AthAlgorithm {
+
+  public: 
+
+    /// Constructor with parameters:
+    ORMETMakerAlg(const std::string& name, ISvcLocator* pSvcLocator);
+
+    /// Destructor:
+    virtual ~ORMETMakerAlg(); 
+
+    /// Athena algorithm's Hooks
+    virtual StatusCode  initialize() override;
+    virtual StatusCode  execute() override;
+    virtual StatusCode  finalize() override;
+
+  private: 
+
+    /// Default constructor:
+    ORMETMakerAlg();
+
+    bool accept(const xAOD::Electron* el);
+    bool accept(const xAOD::Photon* ph);
+    bool accept(const xAOD::TauJet* tau);
+    bool accept(const xAOD::Muon* muon);
+
+    std::string m_softclname;
+    std::string m_softtrkname;
+    std::string m_soft;
+
+    //In release 21 need to replace the names of the containers by the appropriate data handles
+    SG::ReadHandleKey<xAOD::ElectronContainer>      m_ElectronContainerKey;
+    SG::ReadHandleKey<xAOD::PhotonContainer>        m_PhotonContainerKey;
+    SG::ReadHandleKey<xAOD::TauJetContainer>        m_TauJetContainerKey;
+    SG::ReadHandleKey<xAOD::MuonContainer>          m_MuonContainerKey;
+    SG::ReadHandleKey<xAOD::JetContainer>           m_JetContainerKey;
+
+    SG::ReadHandleKey<xAOD::MissingETContainer>           m_CoreMetKey;
+
+    SG::WriteHandleKey<xAOD::MissingETContainer> m_metKey;
+    SG::ReadHandleKey<xAOD::MissingETAssociationMap> m_metMapKey;
+    SG::ReadHandleKey<xAOD::MissingETAssociationMap> m_ORMetMapKey;
+
+    SG::WriteHandleKey<xAOD::PFOContainer> m_chargedPFOContainerWriteHandleKey{this,"PFOChargedOutputName","OverlapRemovedCHSChargedParticleFlowObjects","WriteHandleKey for charged PFO"}; //jetOR
+    SG::WriteHandleKey<xAOD::PFOContainer> m_neutralPFOContainerWriteHandleKey{this,"PFONeutralOutputName","OverlapRemovedCHSNeutralParticleFlowObjects","WriteHandleKey for charged PFO"}; //jetOR
+    SG::WriteHandleKey<xAOD::PFOContainer> m_PFOContainerWriteHandleKey{this,"PFOOutputName","OverlapRemovedCHSParticleFlowObjects","WriteHandleKey for PFO"}; //jetOR
+
+
+SG::ReadHandleKey<xAOD::PFOContainer> m_inPFOKey{this, "InPFOKey", "", "ReadHandleKey for modified  PFlow Objects"};
+SG::WriteHandleKey<xAOD::PFOContainer> m_outPFOKey{this, "OutPFOKey", "", "WriteHandleKey for modified PFlow Objects"};
+
+
+
+
+
+    bool m_doTruthLep;
+    bool m_doRetrieveORconstit;
+    bool m_retainMuonConstit;
+    bool m_doORMet;
+
+
+    double m_electronPT;
+    double m_muonPT;
+    double m_photonPT;
+    double m_tauPT;
+
+    double m_electronETA;
+    double m_muonETA;
+    double m_photonETA;
+    double m_tauETA;
+
+    bool m_selectElectrons;
+
+    bool m_usePromptElectrons;
+
+    bool m_doBadMuon;
+    bool m_useUnmatched;
+    bool m_doJVT;
+
+    
+    /// Athena configured tools
+    ToolHandle<IMETMaker> m_metmaker;
+
+    ToolHandle<CP::IMuonSelectionTool> m_muonSelTool;
+    ToolHandle<IAsgElectronLikelihoodTool> m_elecSelLHTool;
+    ToolHandle<IAsgPhotonIsEMSelector>     m_photonSelIsEMTool;
+    ToolHandle<TauAnalysisTools::ITauSelectionTool> m_tauSelTool;
+
+  }; 
+
+}
+
+#endif
+
diff --git a/Reconstruction/MET/METUtilities/src/components/METUtilities_entries.cxx b/Reconstruction/MET/METUtilities/src/components/METUtilities_entries.cxx
index fe20a9a707eefa077c41a1d692af8b95c1910878..94926277c49db9d4f513beb2337acc581a551f25 100644
--- a/Reconstruction/MET/METUtilities/src/components/METUtilities_entries.cxx
+++ b/Reconstruction/MET/METUtilities/src/components/METUtilities_entries.cxx
@@ -6,6 +6,7 @@
 // Algs
 #include "../METUtilAlg.h"
 #include "../METMakerAlg.h"
+#include "../ORMETMakerAlg.h"
 
 using namespace met;
 
@@ -16,4 +17,6 @@ DECLARE_COMPONENT( METSignificance )
 
 DECLARE_COMPONENT( METUtilAlg )
 DECLARE_COMPONENT( METMakerAlg )
+DECLARE_COMPONENT( ORMETMakerAlg )
+