diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/cmt/requirements b/PhysicsAnalysis/AnalysisCommon/EventUtils/cmt/requirements
new file mode 100644
index 0000000000000000000000000000000000000000..b7499369f981783ebe2d4c603fd74aae91a49228
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/cmt/requirements
@@ -0,0 +1,48 @@
+## automatically generated CMT requirements file
+package EventUtils
+author  kkoeneke
+
+public
+## for athena policies: this has to be the first use statement
+use  AtlasPolicy                AtlasPolicy-*
+
+private
+use  AnalysisUtils              AnalysisUtils-*                 PhysicsAnalysis/AnalysisCommon
+use  AthContainers              AthContainers-*                 Control
+use  AthLinks                   AthLinks-*                      Control
+use  AthenaBaseComps            AthenaBaseComps-*               Control
+use  AtlasBoost                 AtlasBoost-*                    External
+use  AtlasROOT                  AtlasROOT-*                     External
+use  DerivationFrameworkInterfaces                              DerivationFrameworkInterfaces-* PhysicsAnalysis/DerivationFramework
+use  EventBookkeeperMetaData    EventBookkeeperMetaData-*       Event
+use  EventInfo                  EventInfo-*                     Event
+use  ExpressionEvaluation       ExpressionEvaluation-*          PhysicsAnalysis/CommonTools
+use  GaudiInterface             GaudiInterface-*                External
+use  TrigDecisionTool           TrigDecisionTool-*              Trigger/TrigAnalysis
+use  xAODBTagging               xAODBTagging-*                  Event/xAOD
+use  xAODBase                   xAODBase-*                      Event/xAOD
+use  xAODCaloEvent              xAODCaloEvent-*                 Event/xAOD
+use  xAODEgamma                 xAODEgamma-*                    Event/xAOD
+use  xAODEventInfo              xAODEventInfo-*                 Event/xAOD
+use  xAODJet                    xAODJet-*                       Event/xAOD
+use  xAODMissingET              xAODMissingET-*                 Event/xAOD
+use  xAODMuon                   xAODMuon-*                      Event/xAOD
+use  xAODPFlow                  xAODPFlow-*                     Event/xAOD
+use  xAODParticleEvent          xAODParticleEvent-*             Event/xAOD
+use  xAODTau                    xAODTau-*                       Event/xAOD
+use  xAODTracking               xAODTracking-*                  Event/xAOD
+use  xAODTruth                  xAODTruth-*                     Event/xAOD
+end_private
+
+
+branches src src/components python share
+
+private
+## default is to make component library
+library EventUtils *.cxx components/*.cxx
+
+apply_pattern component_library
+apply_pattern declare_joboptions files="*.py"
+apply_pattern declare_python_modules files="*.py"
+
+end_private
diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/AddVarAlg.cxx b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/AddVarAlg.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..3372d60028f6719bba730fa5312efa4d83cbbdae
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/AddVarAlg.cxx
@@ -0,0 +1,159 @@
+///////////////////////// -*- C++ -*- /////////////////////////////
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// AddVarAlg.cxx
+// Implementation file for class AddVarAlg
+// Author: Karsten Koeneke <karsten.koeneke@cern.ch>
+///////////////////////////////////////////////////////////////////
+
+// EventUtils includes
+#include "AddVarAlg.h"
+
+// STL includes
+
+// FrameWork includes
+#include "GaudiKernel/Property.h"
+#include "GaudiKernel/IJobOptionsSvc.h"
+#include "DerivationFrameworkInterfaces/IAugmentationTool.h"
+
+
+
+///////////////////////////////////////////////////////////////////
+// Public methods:
+///////////////////////////////////////////////////////////////////
+
+// Constructors
+////////////////
+AddVarAlg::AddVarAlg( const std::string& name,
+										  ISvcLocator* pSvcLocator ) :
+  ::AthFilterAlgorithm( name, pSvcLocator ),
+  m_jos("JobOptionsSvc", name),
+  m_tool("AddVarTool/AddVarTool", this),
+	m_setInCollKey(false),
+	m_setVarName(false),
+	m_setVarType(false),
+  m_setSelection(false),
+  m_nEventsProcessed(0)
+{
+  declareProperty("JobOptionsSvc",       m_jos, "The JobOptionService instance.");
+
+  declareProperty("AddVarTool",          m_tool, "The private AddVarTool" );
+
+  declareProperty("AddVarTo",   m_inCollKey="",
+								  "Name of the container or object where the new variable will be added to" );
+  m_inCollKey.declareUpdateHandler( &AddVarAlg::setupInputContainer, this );
+
+  declareProperty("VarName",             m_varName="",   "The name of the new variable" );
+  m_varName.declareUpdateHandler( &AddVarAlg::setupVarName, this );
+
+  declareProperty("VarType",             m_varType="float",
+								  "The type of the new variable (allowed values are: 'bool', 'int', 'float')" );
+  m_varType.declareUpdateHandler( &AddVarAlg::setupVarType, this );
+
+  declareProperty("Selection",         m_selection="",
+								  "The selection string that defines which xAOD::IParticles to select from the container" );
+  m_selection.declareUpdateHandler( &AddVarAlg::setupSelection, this );
+}
+
+
+
+// Destructor
+///////////////
+AddVarAlg::~AddVarAlg()
+{}
+
+
+
+// Athena Algorithm's Hooks
+////////////////////////////
+StatusCode AddVarAlg::initialize()
+{
+  ATH_MSG_DEBUG ("Initializing " << name() << "...");
+
+  // Print out the used configuration
+  ATH_MSG_DEBUG ( " using = " << m_jos );
+  ATH_MSG_DEBUG ( " using = " << m_tool );
+  ATH_MSG_DEBUG ( " using = " << m_inCollKey );
+  ATH_MSG_DEBUG ( " using = " << m_varName );
+  ATH_MSG_DEBUG ( " using = " << m_varType );
+  ATH_MSG_DEBUG ( " using = " << m_selection );
+
+
+  // Initialize the counters to zero
+  m_nEventsProcessed = 0 ;
+
+
+  // Get the JobOptionService
+  // We will use this to set the properties of our private skimming tool
+  // from the properties of this algorithm.
+  ATH_MSG_VERBOSE( "Getting the JobOptionService");
+  ATH_CHECK( m_jos.retrieve() );
+
+  // Get the full name of the private skimTool
+  ATH_MSG_VERBOSE( "Getting the full name of the tool");
+  const std::string& fullToolName = this->name() + "." + m_tool.name();
+  ATH_MSG_DEBUG( "Got the full name of the tool: " << fullToolName );
+
+
+  // Now, set all properties of the private skimTool that were acutally configured
+  if (m_setInCollKey) {
+    ATH_MSG_DEBUG( "Setting property" << m_inCollKey
+                   << " of private tool with name: '" << fullToolName << "'" );
+    ATH_CHECK( m_jos->addPropertyToCatalogue (fullToolName,m_inCollKey) );
+  }
+  if (m_setVarName) {
+    ATH_MSG_DEBUG( "Setting property" << m_varName
+                   << " of private tool with name: '" << fullToolName << "'" );
+    ATH_CHECK( m_jos->addPropertyToCatalogue (fullToolName,m_varName) );
+  }
+  if (m_setVarType) {
+    ATH_MSG_DEBUG( "Setting property" << m_varType
+                   << " of private tool with name: '" << fullToolName << "'" );
+    ATH_CHECK( m_jos->addPropertyToCatalogue (fullToolName,m_varType) );
+  }
+  if (m_setSelection) {
+    ATH_MSG_DEBUG( "Setting property" << m_selection
+                   << " of private tool with name: '" << fullToolName << "'" );
+    ATH_CHECK( m_jos->addPropertyToCatalogue (fullToolName,m_selection) );
+  }
+  ATH_MSG_DEBUG( "Done setting properties of the tool");
+
+  // Get the skimming tool
+  ATH_CHECK( m_tool.retrieve() );
+
+  ATH_MSG_DEBUG ( "==> done with initialize " << name() << "..." );
+
+  return StatusCode::SUCCESS;
+}
+
+
+
+StatusCode AddVarAlg::finalize()
+{
+  ATH_MSG_DEBUG ("Finalizing " << name() << "...");
+
+  // Release all tools and services
+  ATH_CHECK( m_jos.release() );
+  ATH_CHECK( m_tool.release() );
+
+  return StatusCode::SUCCESS;
+}
+
+
+
+StatusCode AddVarAlg::execute()
+{
+  // Increase the event counter
+  ++m_nEventsProcessed;
+
+  // Simple status message at the beginning of each event execute,
+  ATH_MSG_DEBUG ( "==> execute " << name() << " on " << m_nEventsProcessed << ". event..." );
+
+  // Call the tool
+  ATH_CHECK( m_tool->addBranches() );
+
+  return StatusCode::SUCCESS;
+}
diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/AddVarAlg.h b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/AddVarAlg.h
new file mode 100644
index 0000000000000000000000000000000000000000..1bc1ab742ca8756b4efeaec113134d893d32ba5c
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/AddVarAlg.h
@@ -0,0 +1,154 @@
+///////////////////////// -*- C++ -*- /////////////////////////////
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// AddVarAlg.h
+// Header file for class AddVarAlg
+// Author: Karsten Koeneke <karsten.koeneke@cern.ch>
+///////////////////////////////////////////////////////////////////
+#ifndef EVENTUTILS_ADDVARALG_H
+#define EVENTUTILS_ADDVARALG_H 1
+
+// STL includes
+#include <string>
+
+// FrameWork includes
+#include "GaudiKernel/ToolHandle.h"
+#include "GaudiKernel/ServiceHandle.h"
+#include "AthenaBaseComps/AthFilterAlgorithm.h"
+
+
+// forward declarations
+class IJobOptionsSvc;
+namespace DerivationFramework {
+  class IAugmentationTool;
+}
+
+
+
+class AddVarAlg
+  : public ::AthFilterAlgorithm
+{
+
+  ///////////////////////////////////////////////////////////////////
+  // Public methods:
+  ///////////////////////////////////////////////////////////////////
+ public:
+
+  // Copy constructor:
+
+  /// Constructor with parameters:
+  AddVarAlg( const std::string& name, ISvcLocator* pSvcLocator );
+
+  /// Destructor:
+  virtual ~AddVarAlg();
+
+  /// Athena algorithm's initalize hook
+  virtual StatusCode  initialize();
+
+  /// Athena algorithm's execute hook
+  virtual StatusCode  execute();
+
+  /// Athena algorithm's finalize hook
+  virtual StatusCode  finalize();
+
+
+private:
+  // The update handlers
+
+  /// This internal method will realize if a user sets the 'AddVarTo' property
+  void setupInputContainer( Property& /*prop*/ );
+
+  /// This internal method will realize if a user sets the 'VarName' property
+  void setupVarName( Property& /*prop*/ );
+
+  /// This internal method will realize if a user sets the 'VarType' property
+  void setupVarType( Property& /*prop*/ );
+
+  /// This internal method will realize if a user sets the 'Selection' property
+  void setupSelection( Property& /*prop*/ );
+
+
+
+  ///////////////////////////////////////////////////////////////////
+  // Private data:
+  ///////////////////////////////////////////////////////////////////
+ private:
+  /// The job options service (will be used to forward this algs properties to
+  /// the private tool)
+  ServiceHandle<IJobOptionsSvc> m_jos;
+
+  /// The ToolHandle to the augmentation tool
+  ToolHandle<DerivationFramework::IAugmentationTool> m_tool;
+
+
+  /// Input container name
+  StringProperty m_inCollKey;
+
+  /// This boolean is true if the user sets the 'InputContainer' property
+  bool m_setInCollKey;
+
+
+  /// The name of the new variable
+  StringProperty m_varName;
+
+  /// This boolean is true if the user sets the 'OutputContainer' property
+  bool m_setVarName;
+
+
+  /// The type of the new variable (allowed values are: 'bool', 'int', 'float')
+  StringProperty m_varType;
+
+  /// This boolean is true if the user sets the 'OutputLinkContainer' property
+  bool m_setVarType;
+
+
+  /// The string that describes how the new variable should be calculated
+  StringProperty m_selection;
+
+  /// This boolean is true if the user sets the 'Cut' property
+  bool m_setSelection;
+
+
+
+  /// Internal event counter
+  unsigned long m_nEventsProcessed;
+
+
+};
+
+// I/O operators
+//////////////////////
+
+///////////////////////////////////////////////////////////////////
+// Inline methods:
+///////////////////////////////////////////////////////////////////
+
+/// This internal method will realize if a user sets the 'AddVarTo' property
+inline void AddVarAlg::setupInputContainer( Property& /*prop*/ ) {
+  m_setInCollKey = true;
+  return;
+}
+
+/// This internal method will realize if a user sets the 'VarName' property
+inline void AddVarAlg::setupVarName( Property& /*prop*/ ) {
+  m_setVarName = true;
+  return;
+}
+
+/// This internal method will realize if a user sets the 'VarType' property
+inline void AddVarAlg::setupVarType( Property& /*prop*/ ) {
+  m_setVarType = true;
+  return;
+}
+
+/// This internal method will realize if a user sets the 'Selection' property
+inline void AddVarAlg::setupSelection( Property& /*prop*/ ) {
+  m_setSelection = true;
+  return;
+}
+
+
+#endif //> !EVENTUTILS_ADDVARALG_H
diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/AddVarTool.cxx b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/AddVarTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..adc92c2eabfd3c51c42213829f8fcc6c4017cd32
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/AddVarTool.cxx
@@ -0,0 +1,288 @@
+///////////////////////// -*- C++ -*- /////////////////////////////
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// AddVarTool.cxx
+// Implementation file for class AddVarTool
+// Author: Karsten Koeneke <karsten.koeneke@cern.ch>
+///////////////////////////////////////////////////////////////////
+
+// EventUtils includes
+#include "AddVarTool.h"
+
+// STL includes
+#include <vector>
+#include <string>
+
+// FrameWork includes
+#include "ExpressionEvaluation/ExpressionParser.h"
+#include "TrigDecisionTool/TrigDecisionTool.h"
+#include "ExpressionEvaluation/TriggerDecisionProxyLoader.h"
+#include "ExpressionEvaluation/SGxAODProxyLoader.h"
+#include "ExpressionEvaluation/SGNTUPProxyLoader.h"
+#include "ExpressionEvaluation/MultipleProxyLoader.h"
+#include "ExpressionEvaluation/StackElement.h"
+
+// EDM includes
+#include "AthContainers/AuxElement.h"
+#include "xAODEventInfo/EventInfo.h"
+#include "xAODBase/IParticleContainer.h"
+#include "xAODMissingET/MissingETContainer.h"
+#include "xAODTracking/VertexContainer.h"
+#include "xAODTruth/TruthEventContainer.h"
+#include "xAODTruth/TruthVertexContainer.h"
+#include "xAODBTagging/BTaggingContainer.h"
+// #include "xAODBTagging/BTagVertexContainer.h"
+
+
+
+///////////////////////////////////////////////////////////////////
+// Public methods:
+///////////////////////////////////////////////////////////////////
+
+// Constructors
+////////////////
+AddVarTool::AddVarTool( const std::string& type,
+											  const std::string& name,
+												const IInterface* parent ) :
+  ::AthAlgTool  ( type, name, parent ),
+	m_trigDecisionTool("Trig::TrigDecisionTool/TrigDecisionTool"),
+	m_parser(0),
+  m_inCollKey(""),
+  m_selection(""),
+	m_varTypeIndex(-1),
+	m_inContIdx(-1),
+  m_nEventsProcessed(0)
+{
+  declareInterface< DerivationFramework::IAugmentationTool >(this);
+
+  declareProperty("AddVarTo",          m_inCollKey="",
+								  "Name of the container or object where the new variable will be added to" );
+
+  declareProperty("VarName",           m_varName="",   "The name of the new variable" );
+  declareProperty("VarType",           m_varType="float",
+								  "The type of the new variable (allowed values are: 'bool', 'int', 'float')" );
+
+  declareProperty("Selection",         m_selection="",
+								  "The selection string that defines which xAOD::IParticles to select from the container" );
+}
+
+// Destructor
+///////////////
+AddVarTool::~AddVarTool()
+{}
+
+
+
+// Athena algtool's Hooks
+////////////////////////////
+StatusCode AddVarTool::initialize()
+{
+  ATH_MSG_DEBUG ("Initializing " << name() << "...");
+
+  // Print out the used configuration
+  ATH_MSG_DEBUG ( " using = " << m_inCollKey );
+  ATH_MSG_DEBUG ( " using = " << m_varName );
+  ATH_MSG_DEBUG ( " using = " << m_varType );
+  ATH_MSG_DEBUG ( " using = " << m_selection );
+
+  // Try to decode the variable type
+	if ( m_varType.value() == "int" ) {
+		m_varTypeIndex = 1;
+	}
+	else if ( m_varType.value() == "bool" ) {
+		m_varTypeIndex = 2;
+	}
+	else if ( m_varType.value() == "float" ) {
+		m_varTypeIndex = 11;
+	}
+	else {
+		ATH_MSG_ERROR("Didn't recognize the variable type. "
+									<< "Allowed values for the property 'VarType' are: "
+									<< "'bool', 'int', 'float'");
+		return StatusCode::FAILURE;
+	}
+
+  // initialize proxy loaders for expression parsing
+	ExpressionParsing::MultipleProxyLoader *proxyLoaders = new ExpressionParsing::MultipleProxyLoader();
+	proxyLoaders->push_back(new ExpressionParsing::TriggerDecisionProxyLoader(m_trigDecisionTool));
+	proxyLoaders->push_back(new ExpressionParsing::SGxAODProxyLoader(evtStore()));
+	proxyLoaders->push_back(new ExpressionParsing::SGNTUPProxyLoader(evtStore()));
+
+	// load the expressions
+	m_parser = new ExpressionParsing::ExpressionParser(proxyLoaders);
+	m_parser->loadExpression( m_selection.value() );
+
+  return StatusCode::SUCCESS;
+}
+
+
+
+
+StatusCode AddVarTool::finalize()
+{
+  ATH_MSG_DEBUG ("Finalizing " << name() << "...");
+
+	if (m_parser) {
+		delete m_parser;
+		m_parser = 0;
+	}
+
+  return StatusCode::SUCCESS;
+}
+
+
+
+
+#define EVALUATE_CONTAINERTYPE( CONTAINERTYPE )                                                        \
+else if ( evtStore()->contains< CONTAINERTYPE >( m_inCollKey.value() ) ) {                             \
+	const CONTAINERTYPE* inContainer(0);                                                                 \
+  ATH_CHECK( evtStore()->retrieve( inContainer, m_inCollKey.value() ) );                               \
+  ATH_MSG_DEBUG ( "Input collection = '" << m_inCollKey.value()                                        \
+                  << "' retrieved from StoreGate which has " << inContainer->size() << " entries." );  \
+	if ( !inContainer ) {                                                                                \
+		ATH_MSG_ERROR( "We don't have a valid pointer to "#CONTAINERTYPE"." );                             \
+		return StatusCode::FAILURE;                                                                        \
+	}                                                                                                    \
+	ExpressionParsing::StackElement selectionResult = m_parser->evaluate();                              \
+	if ( !(selectionResult.isVector()) ) {                                                               \
+		ATH_MSG_ERROR ("Some unexpected format of the expression parser result. Should be vector-type.");  \
+	  return StatusCode::FAILURE;                                                                        \
+	}                                                                                                    \
+	if ( m_varTypeIndex == 1 ) {                                                                         \
+		const std::vector<int>& resultVec( selectionResult.vectorValue<int>() );                           \
+		if ( resultVec.size() != inContainer->size() ) {                                                   \
+			ATH_MSG_ERROR("The result vector doesn't have the same size as the container to decorate!");     \
+			return StatusCode::FAILURE;                                                                      \
+		}                                                                                                  \
+		SG::AuxElement::Decorator<int> intDeco (m_varName.value());                                                \
+		for ( std::size_t i=0; i<resultVec.size(); ++i ) {                                                 \
+			ATH_MSG_VERBOSE("Got a container integer result: " << resultVec.at(i) );                         \
+			const auto* part = inContainer->at(i);                                                           \
+			intDeco(*part) = resultVec.at(i);                                                                \
+		}                                                                                                  \
+	}                                                                                                    \
+	else if ( m_varTypeIndex == 2 ) {                                                                    \
+		const std::vector<int>& resultVec( selectionResult.vectorValue<int>() );                           \
+		if ( resultVec.size() != inContainer->size() ) {                                                   \
+			ATH_MSG_ERROR("The result vector doesn't have the same size as the container to decorate!");     \
+			return StatusCode::FAILURE;                                                                      \
+		}                                                                                                  \
+		SG::AuxElement::Decorator<bool> boolDeco (m_varName.value());                                              \
+		for ( std::size_t i=0; i<resultVec.size(); ++i ) {                                                 \
+			ATH_MSG_VERBOSE("Got a container boolean result: " << static_cast<bool>(resultVec.at(i)) );      \
+			const auto* part = inContainer->at(i);                                                           \
+			boolDeco(*part) = static_cast<bool>(resultVec.at(i));                                            \
+		}                                                                                                  \
+	}                                                                                                    \
+	else if ( m_varTypeIndex == 11 ) {                                                                   \
+		const std::vector<double>& resultVec( selectionResult.vectorValue<double>() );                     \
+		if ( resultVec.size() != inContainer->size() ) {                                                   \
+			ATH_MSG_ERROR("The result vector doesn't have the same size as the container to decorate!");     \
+			return StatusCode::FAILURE;                                                                      \
+		}                                                                                                  \
+		SG::AuxElement::Decorator<float> floatDeco (m_varName.value());                                            \
+		for ( std::size_t i=0; i<resultVec.size(); ++i ) {                                                 \
+			ATH_MSG_VERBOSE("Got a container float result: " << static_cast<float>(resultVec.at(i)) );       \
+			const auto* part = inContainer->at(i);                                                           \
+			floatDeco(*part) = static_cast<float>(resultVec.at(i));                                          \
+		}                                                                                                  \
+	}                                                                                                    \
+}
+
+
+
+StatusCode AddVarTool::addBranches() const
+{
+  // Increase the event counter
+  ++m_nEventsProcessed;
+
+  // Simple status message at the beginning of each event execute,
+  ATH_MSG_DEBUG ( "==> addBranches " << name() << " on " << m_nEventsProcessed << ". event..." );
+
+
+  //-----------------------------------------
+  // Get the input container where we want to add the variable to
+  //-----------------------------------------
+	const SG::AuxElement* inAuxElement(0);
+
+  // if ( evtStore()->contains< SG::AuxElement >( m_inCollKey.value() ) ) {
+  //   // This file holds an SG::AuxElement
+  //   ATH_CHECK( evtStore()->retrieve( inAuxElement, m_inCollKey.value() ) );
+  //   ATH_MSG_DEBUG ( "Input SG::AuxElement = '" << m_inCollKey.value() << "' retrieved from StoreGate" );
+  // }
+  if ( evtStore()->contains< xAOD::EventInfo >( m_inCollKey.value() ) ) {
+    // This file holds an xAOD::EventInfo
+		const xAOD::EventInfo* eventInfo;
+    ATH_CHECK( evtStore()->retrieve( eventInfo, m_inCollKey.value() ) );
+    ATH_MSG_DEBUG ( "Input xAOD::EventInfo = '" << m_inCollKey.value() << "' retrieved from StoreGate" );
+		inAuxElement = dynamic_cast<const xAOD::EventInfo*>(eventInfo);
+		ATH_CHECK( this->evaluateAuxElement(inAuxElement) );
+	}
+
+	// Use a pre-processor macro do generate the code for all container types,
+	// i.e., DataVector< SomeObjectInheritingFrom : public SG::AuxElement >
+  EVALUATE_CONTAINERTYPE(xAOD::IParticleContainer)
+  EVALUATE_CONTAINERTYPE(xAOD::VertexContainer)
+  //EVALUATE_CONTAINERTYPE(xAOD::BTagVertexContainer)
+  EVALUATE_CONTAINERTYPE(xAOD::BTaggingContainer)
+  //EVALUATE_CONTAINERTYPE(xAOD::MissingETComponentMap)
+  EVALUATE_CONTAINERTYPE(xAOD::MissingETContainer)
+  EVALUATE_CONTAINERTYPE(xAOD::TruthEventContainer)
+  EVALUATE_CONTAINERTYPE(xAOD::TruthVertexContainer)
+
+  else {
+    if ( m_nEventsProcessed <= 10 ) {
+      ATH_MSG_WARNING ( "Input collection  = '" << m_inCollKey.value()
+                        << "' could not be retrieved from StoreGate! "
+                        << " This message will only be repeated 10 times..." );
+    }
+    else {
+      ATH_MSG_DEBUG ( "Input collection  = '" << m_inCollKey.value()
+                      << "' could not be retrieved from StoreGate! " );
+    }
+    return StatusCode::SUCCESS;
+  } // End: if/elif/else on input container type
+
+
+	return StatusCode::SUCCESS;
+}
+
+
+
+
+StatusCode AddVarTool::evaluateAuxElement( const SG::AuxElement* inAuxElement ) const
+{
+	if ( !inAuxElement ) {
+		ATH_MSG_ERROR( "We don't have a valid pointer to SG::AuxElement" );
+		return StatusCode::FAILURE;
+	}
+
+  // Evaluate the string expression for this event
+	ExpressionParsing::StackElement selectionResult = m_parser->evaluate();
+  if ( !(selectionResult.isScalar()) ) {
+		ATH_MSG_ERROR ("Some unexpected format of the expression parser result. Should be scalar-type.");
+    return StatusCode::FAILURE;
+  }
+
+	// Now, get the result and record it to the object
+	if ( m_varTypeIndex == 1 ) { // This is an integer
+		int result = selectionResult.scalarValue<int>();
+		ATH_MSG_VERBOSE("Got an integer result: " << result );
+		inAuxElement->auxdecor<int> (m_varName.value()) = result;
+	}
+	else if ( m_varTypeIndex == 2 ) { // This is a boolean
+		bool result = selectionResult.scalarValue<bool>();
+		ATH_MSG_VERBOSE("Got a boolean result: " << result );
+		inAuxElement->auxdecor<bool> (m_varName.value()) = result;
+	}
+	else if ( m_varTypeIndex == 11 ) { // This is a float
+		float result = selectionResult.scalarValue<float>();
+		ATH_MSG_VERBOSE("Got a float result: " << result );
+		inAuxElement->auxdecor<float> (m_varName.value()) = result;
+	}
+
+	return StatusCode::SUCCESS;
+}
diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/AddVarTool.h b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/AddVarTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..f8a9cedb87ec14608c9487c25b1a062fb643d834
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/AddVarTool.h
@@ -0,0 +1,114 @@
+///////////////////////// -*- C++ -*- /////////////////////////////
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// AddVarTool.h
+// Header file for class AddVarTool
+// Author: Karsten Koeneke <karsten.koeneke@cern.ch>
+///////////////////////////////////////////////////////////////////
+#ifndef EVENTUTILS_ADDVARTOOL_H
+#define EVENTUTILS_ADDVARTOOL_H 1
+
+// STL includes
+#include <vector>
+#include <string>
+
+// FrameWork includes
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "DerivationFrameworkInterfaces/IAugmentationTool.h"
+#include "TrigDecisionTool/TrigDecisionTool.h"
+
+// Forward declarations
+namespace ExpressionParsing {
+  class ExpressionParser;
+}
+namespace SG {
+  class AuxElement;
+}
+
+
+
+
+class AddVarTool
+  : virtual public ::DerivationFramework::IAugmentationTool,
+            public ::AthAlgTool
+{
+
+  ///////////////////////////////////////////////////////////////////
+  // Public methods:
+  ///////////////////////////////////////////////////////////////////
+public:
+
+  // Copy constructor:
+
+  /// Constructor with parameters:
+  AddVarTool( const std::string& type,
+              const std::string& name,
+              const IInterface* parent );
+
+  /// Destructor:
+  virtual ~AddVarTool();
+
+  /// Athena algtool's initialize
+  virtual StatusCode  initialize();
+
+  /// Athena algtool's finalize
+  virtual StatusCode  finalize();
+
+
+  /// Implement the method from the ISkimmingTool interface
+  virtual StatusCode addBranches() const final override;
+
+
+
+// Private methods
+private:
+  /// Helper methods
+  StatusCode evaluateAuxElement( const SG::AuxElement* inAuxElement ) const;
+
+
+
+  ///////////////////////////////////////////////////////////////////
+  // Private data:
+  ///////////////////////////////////////////////////////////////////
+private:
+  /// The trigger decision tool
+  ToolHandle<Trig::TrigDecisionTool> m_trigDecisionTool;
+
+  /// The expression parser
+  ExpressionParsing::ExpressionParser *m_parser;
+
+
+  /// Input container name
+  StringProperty m_inCollKey;
+
+  /// The name of the new variable
+  StringProperty m_varName;
+
+  /// The type of the new variable (allowed values are: 'bool', 'int', 'float')
+  StringProperty m_varType;
+
+  /// The string that describes how the new variable should be calculated
+  StringProperty m_selection;
+
+
+  /// Index to specify the variable type
+  mutable int m_varTypeIndex;
+
+  /// An internal integer to keep track of the type of the input container
+  mutable int m_inContIdx;
+
+  /// Internal event counter
+  mutable unsigned long m_nEventsProcessed;
+
+
+};
+
+///////////////////////////////////////////////////////////////////
+// Inline methods:
+///////////////////////////////////////////////////////////////////
+
+
+#endif //> !EVENTUTILS_ADDVARTOOL_H
diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/CutAlg.cxx b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/CutAlg.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..68873f19dae6d4a09b113586321647cab292a0c4
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/CutAlg.cxx
@@ -0,0 +1,128 @@
+///////////////////////// -*- C++ -*- /////////////////////////////
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// CutAlg.cxx
+// Implementation file for class CutAlg
+// Author: Karsten Koeneke <karsten.koeneke@cern.ch>
+///////////////////////////////////////////////////////////////////
+
+// EventUtils includes
+#include "CutAlg.h"
+
+// STL includes
+
+// FrameWork includes
+#include "GaudiKernel/Property.h"
+#include "GaudiKernel/IJobOptionsSvc.h"
+#include "DerivationFrameworkInterfaces/ISkimmingTool.h"
+
+
+
+///////////////////////////////////////////////////////////////////
+// Public methods:
+///////////////////////////////////////////////////////////////////
+
+// Constructors
+////////////////
+CutAlg::CutAlg( const std::string& name,
+							  ISvcLocator* pSvcLocator ) :
+  ::AthFilterAlgorithm( name, pSvcLocator ),
+  m_jos("JobOptionsSvc", name),
+  m_skimTool("CutTool/CutTool", this),
+  m_cut(""),
+  m_setCut(false),
+  m_nEventsProcessed(0)
+{
+  declareProperty("JobOptionsSvc",       m_jos, "The JobOptionService instance.");
+
+  declareProperty("SkimTool",            m_skimTool, "The private SkimmingTool" );
+
+  declareProperty("Cut",                 m_cut="",   "The name of the output container" );
+  m_cut.declareUpdateHandler( &CutAlg::setupCut, this );
+}
+
+
+
+// Destructor
+///////////////
+CutAlg::~CutAlg()
+{}
+
+
+
+// Athena Algorithm's Hooks
+////////////////////////////
+StatusCode CutAlg::initialize()
+{
+  ATH_MSG_DEBUG ("Initializing " << name() << "...");
+
+  // Print out the used configuration
+  ATH_MSG_DEBUG ( " using JobOptionsSvc = " << m_jos );
+  ATH_MSG_DEBUG ( " using SkimTool      = " << m_skimTool );
+  ATH_MSG_DEBUG ( " using Cut           = " << m_cut );
+
+
+  // Initialize the counters to zero
+  m_nEventsProcessed = 0 ;
+
+
+  // Get the JobOptionService
+  // We will use this to set the properties of our private skimming tool
+  // from the properties of this algorithm.
+  ATH_MSG_VERBOSE( "Getting the JobOptionService");
+  ATH_CHECK( m_jos.retrieve() );
+
+  // Get the full name of the private skimTool
+  ATH_MSG_VERBOSE( "Getting the full name of the tool");
+  const std::string& fullToolName = this->name() + "." + m_skimTool.name();
+  ATH_MSG_DEBUG( "Got the full name of the tool: " << fullToolName );
+
+  // Now, set all properties of the private skimTool that were acutally configured
+  if (m_setCut) {
+    ATH_MSG_DEBUG( "Setting property" << m_cut
+                   << " of private tool with name: '" << fullToolName << "'" );
+    ATH_CHECK( m_jos->addPropertyToCatalogue (fullToolName,m_cut) );
+  }
+  ATH_MSG_DEBUG( "Done setting properties of the tool");
+
+  // Get the skimming tool
+  ATH_CHECK( m_skimTool.retrieve() );
+
+  ATH_MSG_DEBUG ( "==> done with initialize " << name() << "..." );
+
+  return StatusCode::SUCCESS;
+}
+
+
+
+StatusCode CutAlg::finalize()
+{
+  ATH_MSG_DEBUG ("Finalizing " << name() << "...");
+
+  // Release all tools and services
+  ATH_CHECK( m_jos.release() );
+  ATH_CHECK( m_skimTool.release() );
+
+  return StatusCode::SUCCESS;
+}
+
+
+
+StatusCode CutAlg::execute()
+{
+  // Increase the event counter
+  ++m_nEventsProcessed;
+
+  // Simple status message at the beginning of each event execute,
+  ATH_MSG_DEBUG ( "==> execute " << name() << " on " << m_nEventsProcessed << ". event..." );
+
+  // Call the skimming tool and set its result
+	bool eventPasses = m_skimTool->eventPassesFilter();
+  this->setFilterPassed( eventPasses );
+	ATH_MSG_DEBUG("Event passes/fails: " << eventPasses );
+
+  return StatusCode::SUCCESS;
+}
diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/CutAlg.h b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/CutAlg.h
new file mode 100644
index 0000000000000000000000000000000000000000..4293391ad908ad7c6304e9cfdf70de2ec544a84a
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/CutAlg.h
@@ -0,0 +1,154 @@
+///////////////////////// -*- C++ -*- /////////////////////////////
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// CutAlg.h
+// Header file for class CutAlg
+// Author: Karsten Koeneke <karsten.koeneke@cern.ch>
+///////////////////////////////////////////////////////////////////
+#ifndef EVENTUTILS_CUTALG_H
+#define EVENTUTILS_CUTALG_H 1
+
+// STL includes
+#include <string>
+
+// FrameWork includes
+#include "GaudiKernel/ToolHandle.h"
+#include "GaudiKernel/ServiceHandle.h"
+#include "AthenaBaseComps/AthFilterAlgorithm.h"
+
+
+// forward declarations
+class IJobOptionsSvc;
+namespace DerivationFramework {
+  class ISkimmingTool;
+}
+
+
+
+class CutAlg
+  : public ::AthFilterAlgorithm
+{
+
+  ///////////////////////////////////////////////////////////////////
+  // Public methods:
+  ///////////////////////////////////////////////////////////////////
+ public:
+
+  // Copy constructor:
+
+  /// Constructor with parameters:
+  CutAlg( const std::string& name, ISvcLocator* pSvcLocator );
+
+  /// Destructor:
+  virtual ~CutAlg();
+
+  /// Athena algorithm's initalize hook
+  virtual StatusCode  initialize();
+
+  /// Athena algorithm's execute hook
+  virtual StatusCode  execute();
+
+  /// Athena algorithm's finalize hook
+  virtual StatusCode  finalize();
+
+
+private:
+  // The update handlers
+
+  /// This internal method will realize if a user sets the 'InputContainer' property
+  void setupInputContainer( Property& /*prop*/ );
+
+  /// This internal method will realize if a user sets the 'OutputContainer' property
+  void setupOutputContainer( Property& /*prop*/ );
+
+  /// This internal method will realize if a user sets the 'OutputLinkContainer' property
+  void setupOutputLinkContainer( Property& /*prop*/ );
+
+  /// This internal method will realize if a user sets the 'Cut' property
+  void setupCut( Property& /*prop*/ );
+
+
+  ///////////////////////////////////////////////////////////////////
+  // Private data:
+  ///////////////////////////////////////////////////////////////////
+ private:
+  /// The job options service (will be used to forward this algs properties to
+  /// the private tool)
+  ServiceHandle<IJobOptionsSvc> m_jos;
+
+  /// The ToolHandle to the SkimmingTool
+  ToolHandle<DerivationFramework::ISkimmingTool> m_skimTool;
+
+  /// Input container name
+  StringProperty m_inCollKey;
+
+  /// This boolean is true if the user sets the 'InputContainer' property
+  bool m_setInCollKey;
+
+
+  /// Output collection name (deep copies of the original ones)
+  StringProperty m_outCollKey;
+
+  /// This boolean is true if the user sets the 'OutputContainer' property
+  bool m_setOutCollKey;
+
+
+  /// Output link collection name (ElementLinks to selected IParticles)
+  StringProperty m_outLinkCollKey;
+
+  /// This boolean is true if the user sets the 'OutputLinkContainer' property
+  bool m_setOutLinkCollKey;
+
+
+  /// The cut string
+  StringProperty m_cut;
+
+  /// This boolean is true if the user sets the 'Cut' property
+  bool m_setCut;
+
+
+
+  /// Internal event counter
+  unsigned long m_nEventsProcessed;
+
+
+};
+
+// I/O operators
+//////////////////////
+
+///////////////////////////////////////////////////////////////////
+// Inline methods:
+///////////////////////////////////////////////////////////////////
+
+/// This internal method will realize if a user sets the 'InputContainer' property
+inline void CutAlg::setupInputContainer( Property& /*prop*/ ) {
+  m_setInCollKey = true;
+  return;
+}
+
+/// This internal method will realize if a user sets the 'OutputContainer' property
+inline void CutAlg::setupOutputContainer( Property& /*prop*/ ) {
+  m_setOutCollKey = true;
+  return;
+}
+
+/// This internal method will realize if a user sets the 'OutputLinkContainer' property
+inline void CutAlg::setupOutputLinkContainer( Property& /*prop*/ ) {
+  m_setOutLinkCollKey = true;
+  return;
+}
+
+/// This internal method will realize if a user sets the 'Cut' property
+inline void CutAlg::setupCut( Property& /*prop*/ ) {
+  m_setCut = true;
+  return;
+}
+
+
+
+
+#endif //> !EVENTUTILS_CUTALG_H
diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/CutTool.cxx b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/CutTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..808fc825ffac9702f7c73e9c68387f07119d4d1f
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/CutTool.cxx
@@ -0,0 +1,101 @@
+///////////////////////// -*- C++ -*- /////////////////////////////
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// CutTool.cxx
+// Implementation file for class CutTool
+// Author: Karsten Koeneke <karsten.koeneke@cern.ch>
+///////////////////////////////////////////////////////////////////
+
+// EventUtils includes
+#include "CutTool.h"
+
+// STL includes
+#include <vector>
+#include <string>
+
+// FrameWork includes
+#include "ExpressionEvaluation/ExpressionParser.h"
+#include "TrigDecisionTool/TrigDecisionTool.h"
+#include "ExpressionEvaluation/TriggerDecisionProxyLoader.h"
+#include "ExpressionEvaluation/SGxAODProxyLoader.h"
+#include "ExpressionEvaluation/SGNTUPProxyLoader.h"
+#include "ExpressionEvaluation/MultipleProxyLoader.h"
+#include "ExpressionEvaluation/StackElement.h"
+
+
+
+
+///////////////////////////////////////////////////////////////////
+// Public methods:
+///////////////////////////////////////////////////////////////////
+
+// Constructors
+////////////////
+CutTool::CutTool( const std::string& type,
+						      const std::string& name,
+									const IInterface* parent ) :
+  ::AthAlgTool  ( type, name, parent ),
+	m_trigDecisionTool("Trig::TrigDecisionTool/TrigDecisionTool"),
+	m_parser(0),
+  m_cut(""),
+  m_nEventsProcessed(0)
+{
+  declareInterface< DerivationFramework::ISkimmingTool >(this);
+
+  declareProperty("Cut", m_cut="", "The name of the output container" );
+}
+
+// Destructor
+///////////////
+CutTool::~CutTool()
+{}
+
+
+
+// Athena algtool's Hooks
+////////////////////////////
+StatusCode CutTool::initialize()
+{
+  ATH_MSG_DEBUG ("Initializing " << name() << "...");
+
+  // initialize proxy loaders for expression parsing
+	ExpressionParsing::MultipleProxyLoader *proxyLoaders = new ExpressionParsing::MultipleProxyLoader();
+	proxyLoaders->push_back(new ExpressionParsing::TriggerDecisionProxyLoader(m_trigDecisionTool));
+	proxyLoaders->push_back(new ExpressionParsing::SGxAODProxyLoader(evtStore()));
+	proxyLoaders->push_back(new ExpressionParsing::SGNTUPProxyLoader(evtStore()));
+
+	// load the expressions
+	m_parser = new ExpressionParsing::ExpressionParser(proxyLoaders);
+	m_parser->loadExpression( m_cut.value() );
+
+  return StatusCode::SUCCESS;
+}
+
+
+
+StatusCode CutTool::finalize()
+{
+  ATH_MSG_DEBUG ("Finalizing " << name() << "...");
+
+	if (m_parser) {
+		delete m_parser;
+		m_parser = 0;
+	}
+
+  return StatusCode::SUCCESS;
+}
+
+
+
+// Implement the method from the ISkimmingTool interface
+bool CutTool::eventPassesFilter() const
+{
+	ATH_MSG_DEBUG ( "==> eventPassesFilter() " << name()  );
+  ATH_MSG_VERBOSE ( "Dumping event store: " << evtStore()->dump() );
+
+  return m_parser->evaluateAsBool();
+  return true;
+}
diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/CutTool.h b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/CutTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..22fad231637a64bda38008065ca7922d164b8840
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/CutTool.h
@@ -0,0 +1,89 @@
+///////////////////////// -*- C++ -*- /////////////////////////////
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// CutTool.h
+// Header file for class CutTool
+// Author: Karsten Koeneke <karsten.koeneke@cern.ch>
+///////////////////////////////////////////////////////////////////
+#ifndef EVENTUTILS_CUTTOOL_H
+#define EVENTUTILS_CUTTOOL_H 1
+
+// STL includes
+#include <string>
+
+// FrameWork includes
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "DerivationFrameworkInterfaces/ISkimmingTool.h"
+#include "TrigDecisionTool/TrigDecisionTool.h"
+
+
+// Forward declarations
+namespace ExpressionParsing {
+  class ExpressionParser;
+}
+
+
+
+
+class CutTool
+  : virtual public ::DerivationFramework::ISkimmingTool,
+            public ::AthAlgTool
+{
+
+  ///////////////////////////////////////////////////////////////////
+  // Public methods:
+  ///////////////////////////////////////////////////////////////////
+ public:
+
+  // Copy constructor:
+
+  /// Constructor with parameters:
+  CutTool( const std::string& type,
+    	     const std::string& name,
+           const IInterface* parent );
+
+  /// Destructor:
+  virtual ~CutTool();
+
+  /// Athena algtool's initialize
+  virtual StatusCode  initialize();
+
+  /// Athena algtool's finalize
+  virtual StatusCode  finalize();
+
+
+  /// Implement the method from the ISkimmingTool interface
+  virtual bool eventPassesFilter() const final override;
+
+
+
+  ///////////////////////////////////////////////////////////////////
+  // Private data:
+  ///////////////////////////////////////////////////////////////////
+ private:
+  /// The trigger decision tool
+  ToolHandle<Trig::TrigDecisionTool> m_trigDecisionTool;
+
+  /// The expression parser
+  ExpressionParsing::ExpressionParser *m_parser;
+
+
+  /// The cut string
+  StringProperty m_cut;
+
+
+  /// Internal event counter
+  mutable unsigned long m_nEventsProcessed;
+
+
+};
+
+///////////////////////////////////////////////////////////////////
+// Inline methods:
+///////////////////////////////////////////////////////////////////
+
+
+#endif //> !EVENTUTILS_CUTTOOL_H
diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/EventQualityFilterAlg.cxx b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/EventQualityFilterAlg.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..87465c1dfc21a9971f4a692733a146da5643adfc
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/EventQualityFilterAlg.cxx
@@ -0,0 +1,104 @@
+///////////////////////// -*- C++ -*- /////////////////////////////
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// EventQualityFilterAlg.cxx 
+// Implementation file for class EventQualityFilterAlg
+// Author: Karsten Koeneke <karsten.koeneke@cern.ch>
+// Description: Algorithm to filter out events with a bad Event error
+/////////////////////////////////////////////////////////////////// 
+
+// SelectionUtils includes
+#include "EventQualityFilterAlg.h"
+
+// STL includes
+
+// FrameWork includes
+#include "GaudiKernel/Property.h"
+
+// EDM includes
+#include "EventInfo/EventInfo.h"
+#include "EventInfo/EventType.h"
+
+
+/////////////////////////////////////////////////////////////////// 
+// Public methods: 
+/////////////////////////////////////////////////////////////////// 
+
+// Constructors
+////////////////
+EventQualityFilterAlg::EventQualityFilterAlg( const std::string& name, 
+                                              ISvcLocator* pSvcLocator ) : 
+  ::AthFilterAlgorithm( name, pSvcLocator )
+{
+  //
+  // Property declaration
+  // 
+  declareProperty( "VetoLArError",  m_useLArError       = false, "Veto events with a LAr error" );
+  declareProperty( "VetoTileError", m_useTileError      = false, "Veto events with a Tile error" );
+  declareProperty( "VetoCoreError", m_useCoreError      = false, "Veto events with a Core error" );
+  declareProperty( "VetoTileTrips", m_useTileTripReader = false, "Veto events with a Tile trip error" );
+}
+
+
+
+
+// Destructor
+///////////////
+EventQualityFilterAlg::~EventQualityFilterAlg()
+{}
+
+
+
+
+// Athena Algorithm's Hooks
+////////////////////////////
+StatusCode EventQualityFilterAlg::initialize()
+{
+  ATH_MSG_DEBUG ("Initializing " << name() << "...");
+  return StatusCode::SUCCESS;
+}
+
+
+
+StatusCode EventQualityFilterAlg::finalize()
+{
+  ATH_MSG_DEBUG ("Finalizing " << name() << "...");
+  return StatusCode::SUCCESS;
+}
+
+
+
+StatusCode EventQualityFilterAlg::execute()
+{  
+  ATH_MSG_DEBUG ("Executing " << name() << "...");
+
+
+  // Get the EventInfo object
+  const EventInfo* eventInfo(NULL);
+  ATH_CHECK( evtStore()->retrieve(eventInfo) );
+
+
+  // Only do the event vetoing on data
+  bool isSim = eventInfo->event_type()->test(EventType::IS_SIMULATION);
+  if ( isSim )
+    {
+      ATH_MSG_DEBUG ("It is an MC event... not vetoing...");
+      setFilterPassed(true);
+      return StatusCode::SUCCESS;
+    }
+
+
+  // Now make the event decision
+  bool passEvent(true);
+  if ( eventInfo->errorState(EventInfo::LAr)  == EventInfo::Error ){ passEvent = false; }
+  if ( eventInfo->errorState(EventInfo::Tile) == EventInfo::Error ){ passEvent = false; }
+  if ( eventInfo->eventFlags(EventInfo::Core) & 0x40000 ){ passEvent = false; }
+
+  // Set the final decision
+  setFilterPassed(passEvent);
+  
+  return StatusCode::SUCCESS;
+}
diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/EventQualityFilterAlg.h b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/EventQualityFilterAlg.h
new file mode 100644
index 0000000000000000000000000000000000000000..4edb4215435afcb6662b602abd54f2aa529836a2
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/EventQualityFilterAlg.h
@@ -0,0 +1,74 @@
+///////////////////////// -*- C++ -*- /////////////////////////////
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// EventQualityFilterAlg.h 
+// Header file for class EventQualityFilterAlg
+// Author: Karsten Koeneke <karsten.koeneke@cern.ch>
+// Description: Algorithm to filter out events with a bad Event errors
+/////////////////////////////////////////////////////////////////// 
+#ifndef EVENTUTILS_EVENTQUALITYFILTERALG_H
+#define EVENTUTILS_EVENTQUALITYFILTERALG_H 1
+
+// STL includes
+#include <string>
+
+// FrameWork includes
+#include "AthenaBaseComps/AthFilterAlgorithm.h"
+
+
+
+class EventQualityFilterAlg
+  : public ::AthFilterAlgorithm
+{ 
+
+  /////////////////////////////////////////////////////////////////// 
+  // Public methods: 
+  /////////////////////////////////////////////////////////////////// 
+ public: 
+
+  // Copy constructor: 
+
+  /// Constructor with parameters: 
+  EventQualityFilterAlg( const std::string& name, ISvcLocator* pSvcLocator );
+
+  /// Destructor: 
+  virtual ~EventQualityFilterAlg(); 
+
+  // Athena algorithm's Hooks
+  virtual StatusCode  initialize();
+  virtual StatusCode  execute();
+  virtual StatusCode  finalize();
+
+  /////////////////////////////////////////////////////////////////// 
+  // Const methods: 
+  ///////////////////////////////////////////////////////////////////
+
+  /////////////////////////////////////////////////////////////////// 
+  // Non-const methods: 
+  /////////////////////////////////////////////////////////////////// 
+
+  /////////////////////////////////////////////////////////////////// 
+  // Private data: 
+  /////////////////////////////////////////////////////////////////// 
+ private: 
+
+  bool m_useLArError;
+  bool m_useTileError;
+  bool m_useCoreError;
+  bool m_useTileTripReader;
+
+
+}; 
+
+// I/O operators
+//////////////////////
+
+/////////////////////////////////////////////////////////////////// 
+// Inline methods: 
+/////////////////////////////////////////////////////////////////// 
+
+
+#endif //> !EVENTUTILS_EVENTQUALITYFILTERALG_H
diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleCombinerAlg.cxx b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleCombinerAlg.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..272246426b350867b99619c6b712698a8ff5a0a1
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleCombinerAlg.cxx
@@ -0,0 +1,187 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//============================================================================
+// Name: ParticleCombinerAlg.cxx
+//
+/**
+   @class ParticleCombinerAlg
+
+   @author Karsten Koeneke <karsten.koeneke@cernSPAMNOT.ch>
+
+   @date July 2014
+
+   @brief Combine particles to composite particles
+
+   Class to combine two or more particles from a given list of
+   input containers. All combinations will be tried and only the
+   ones passing the used selections will be written to StoreGate.
+*/
+//=============================================================================
+
+// This classes header
+#include "ParticleCombinerAlg.h"
+
+// STL includes
+#include <string>
+#include <vector>
+#include <cfloat>
+#include <climits>
+
+// Framework includes
+#include "GaudiKernel/IJobOptionsSvc.h"
+#include "DerivationFrameworkInterfaces/IAugmentationTool.h"
+
+
+
+//=============================================================================
+// Constructor
+//=============================================================================
+ParticleCombinerAlg::ParticleCombinerAlg(const std::string& name,
+                                         ISvcLocator* pSvcLocator) :
+  AthAlgorithm( name, pSvcLocator ),
+  m_jos("JobOptionsSvc", name),
+  m_tool("ParticleCombinerTool/ParticleCombinerTool", this),
+  m_inCollKeyList(),
+  m_setInCollKeyList(false),
+  m_outCollKey(""),
+  m_setOutCollKey(false),
+  m_metName(""),
+  m_setMetName(false),
+  m_pdgId(0),
+  m_setPdgId(false),
+  m_nEventsProcessed(0)
+{
+  declareProperty("JobOptionsSvc", m_jos, "The JobOptionService instance.");
+
+  declareProperty("ParticleCombinerTool",  m_tool, "The private tool that will do the particle combinatorics" );
+
+  declareProperty("InputContainerList", m_inCollKeyList,   "List of input collection keys" );
+  m_inCollKeyList.declareUpdateHandler( &ParticleCombinerAlg::setupInputContainerList, this );
+
+  declareProperty("MissingETObject",    m_metName="Final", "The name of the xAOD::MissingET object (default: 'Final'" );
+  m_metName.declareUpdateHandler( &ParticleCombinerAlg::setupMissingETObject, this );
+
+  declareProperty("OutputContainer",    m_outCollKey="",   "The name of the output container" );
+  m_outCollKey.declareUpdateHandler( &ParticleCombinerAlg::setupOutputContainer, this );
+
+  declareProperty("SetPdgId",           m_pdgId=0,         "PDG ID of the new output xAOD::CompositeParticle" );
+  m_pdgId.declareUpdateHandler( &ParticleCombinerAlg::setupSetPdgId, this );
+}
+
+
+
+
+
+
+
+//=============================================================================
+// Destructor
+//=============================================================================
+ParticleCombinerAlg::~ParticleCombinerAlg()
+{
+}
+
+
+
+//=============================================================================
+// Athena initialize method
+//=============================================================================
+StatusCode ParticleCombinerAlg::initialize()
+{
+  // Print the used configuration
+  ATH_MSG_DEBUG ( "==> initialize " << name() << "..." );
+
+  // Print out the used configuration
+  ATH_MSG_DEBUG ( " using JobOptionsSvc                    = " << m_jos );
+  ATH_MSG_DEBUG ( " using ParticleCombinerTool             = " << m_tool );
+  ATH_MSG_DEBUG ( " using InputContainerList               = " << m_inCollKeyList );
+  ATH_MSG_DEBUG ( " using MissingETObjectName              = " << m_metName );
+  ATH_MSG_DEBUG ( " using OutputContainer                  = " << m_outCollKey );
+  ATH_MSG_DEBUG ( " using SetPdgId                         = " << m_pdgId );
+
+
+  // Initialize the counters to zero
+  m_nEventsProcessed = 0 ;
+
+
+  // Get the JobOptionService
+  // We will use this to set the properties of our private tool
+  // from the properties of this algorithm.
+  ATH_MSG_VERBOSE( "Getting the JobOptionService");
+  ATH_CHECK( m_jos.retrieve() );
+
+  // Get the full name of the private skimTool
+  ATH_MSG_VERBOSE( "Getting the full name of the tool");
+  const std::string& fullToolName = this->name() + "." + m_tool.name();
+  ATH_MSG_DEBUG( "Got the full name of the tool: " << fullToolName );
+
+  // Now, set all properties of the private skimTool that were acutally configured
+  if (m_setInCollKeyList) {
+    ATH_MSG_DEBUG( "Setting property" << m_inCollKeyList
+                   << " of private tool with name: '" << fullToolName << "'" );
+    ATH_CHECK( m_jos->addPropertyToCatalogue (fullToolName,m_inCollKeyList) );
+  }
+  if (m_setMetName) {
+    ATH_MSG_DEBUG( "Setting property" << m_metName
+                   << " of private tool with name: '" << fullToolName << "'" );
+    ATH_CHECK( m_jos->addPropertyToCatalogue (fullToolName,m_metName) );
+  }
+  if (m_setOutCollKey) {
+    ATH_MSG_DEBUG( "Setting property" << m_outCollKey
+                   << " of private tool with name: '" << fullToolName << "'" );
+    ATH_CHECK( m_jos->addPropertyToCatalogue (fullToolName,m_outCollKey) );
+  }
+  if (m_setPdgId) {
+    ATH_MSG_DEBUG( "Setting property" << m_pdgId
+                   << " of private tool with name: '" << fullToolName << "'" );
+    ATH_CHECK( m_jos->addPropertyToCatalogue (fullToolName,m_pdgId) );
+  }
+  ATH_MSG_DEBUG( "Done setting properties of the tool");
+
+  // Get the tool
+  ATH_CHECK( m_tool.retrieve() );
+
+  ATH_MSG_DEBUG ( "==> done with initialize " << name() << "..." );
+  return StatusCode::SUCCESS;
+}
+
+
+
+//=============================================================================
+// Athena execute method
+//=============================================================================
+StatusCode ParticleCombinerAlg::execute()
+{
+  // Increase the event counter
+  ++m_nEventsProcessed;
+
+  // Simple status message at the beginning of each event execute,
+  ATH_MSG_DEBUG ( "==> execute " << name() << " on " << m_nEventsProcessed << ". event..." );
+
+  // Call the tool to build the particle combinatorics and record the result to StoreGate
+  ATH_CHECK( m_tool->addBranches() );
+
+  return StatusCode::SUCCESS;
+}
+
+
+
+
+
+//=============================================================================
+// Athena finalize method
+//=============================================================================
+StatusCode ParticleCombinerAlg::finalize()
+{
+  ATH_MSG_DEBUG ( "FINALIZING AFTER ALL EVENTS ARE PROCESSED. "
+                  << "Saw " << m_nEventsProcessed << " events." );
+
+  // Release all tools and services
+  ATH_CHECK( m_jos.release() );
+  ATH_CHECK( m_tool.release() );
+
+
+  return StatusCode::SUCCESS;
+}
diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleCombinerAlg.h b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleCombinerAlg.h
new file mode 100644
index 0000000000000000000000000000000000000000..6ddea51acb07449f8a4fbdf544eaa5d163d56a65
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleCombinerAlg.h
@@ -0,0 +1,158 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// Dear emacs, this is -*-c++-*-
+#ifndef EVENTUTILS_PARTICLECOMBINERALG_H
+#define EVENTUTILS_PARTICLECOMBINERALG_H
+
+//============================================================================
+// Name: ParticleCombinerAlg.h
+//
+/**
+   @class ParticleCombinerAlg
+
+   @author Karsten Koeneke <karsten.koeneke@cernSPAMNOT.ch>
+
+   @date July 2014
+
+   @brief Combine particles to composite particles
+
+   Class to combine two or more particles from a given list of
+   input containers. All combinations will be tried and only the
+   ones passing the used selections will be written to StoreGate.
+*/
+//=============================================================================
+
+
+// STL includes
+#include <string>
+#include <vector>
+
+// Gaudi includes
+#include "GaudiKernel/ToolHandle.h"
+#include "GaudiKernel/ServiceHandle.h"
+
+// Athena includes
+#include "AthenaBaseComps/AthAlgorithm.h"
+
+
+// forward declarations
+class IJobOptionsSvc;
+namespace DerivationFramework {
+  class IAugmentationTool;
+}
+
+
+
+class ParticleCombinerAlg : public AthAlgorithm
+{
+public:
+
+  /** Default constructor */
+  ParticleCombinerAlg(const std::string& name, ISvcLocator* pSvcLocator);
+
+  /** Default destructor */
+  virtual ~ParticleCombinerAlg() ;
+
+
+public:
+  /** Gaudi Service Interface method implementations - initialize */
+  StatusCode initialize() ;
+
+  /** Gaudi Service Interface method implementations - execute */
+  StatusCode execute() ;
+
+  /** Gaudi Service Interface method implementations - finalize */
+  StatusCode finalize() ;
+
+
+private:
+  // The update handlers
+
+  /// This internal method will realize if a user sets the 'InputContainerList' property
+  void setupInputContainerList( Property& /*prop*/ );
+
+  /// This internal method will realize if a user sets the 'MissingETObject' property
+  void setupMissingETObject( Property& /*prop*/ );
+
+  /// This internal method will realize if a user sets the 'OutputContainer' property
+  void setupOutputContainer( Property& /*prop*/ );
+
+  /// This internal method will realize if a user sets the 'SetPdgId' property
+  void setupSetPdgId( Property& /*prop*/ );
+
+
+
+private:
+  /// The job options service (will be used to forward this algs properties to
+  /// the private tool)
+  ServiceHandle<IJobOptionsSvc> m_jos;
+
+  /// The ToolHandle to the AugmentationTool
+  ToolHandle<DerivationFramework::IAugmentationTool> m_tool;
+
+  /// List of input collection names
+  StringArrayProperty m_inCollKeyList;
+
+  /// This boolean is true if the user sets the 'InputContainerList' property
+  bool m_setInCollKeyList;
+
+
+  /// Output collection name (the composite particles)
+  StringProperty m_outCollKey;
+
+  /// This boolean is true if the user sets the 'OutputContainer' property
+  bool m_setOutCollKey;
+
+
+  /// The name of the missing ET object, e.g., "Final"
+  StringProperty m_metName;
+
+  /// This boolean is true if the user sets the 'MissingETObject' property
+  bool m_setMetName;
+
+
+  /// The PDG_ID of the CompositeParticle
+  IntegerProperty m_pdgId;
+
+  /// This boolean is true if the user sets the 'SetPdgId' property
+  bool m_setPdgId;
+
+
+
+  /// Internal event counter
+  unsigned long m_nEventsProcessed;
+
+
+}; // End class ParticleCombinerAlg
+
+
+// Inline methods
+
+/// This internal method will realize if a user sets the 'InputContainerList' property
+inline void ParticleCombinerAlg::setupInputContainerList( Property& /*prop*/ ) {
+  m_setInCollKeyList = true;
+  return;
+}
+
+/// This internal method will realize if a user sets the 'MissingETObject' property
+inline void ParticleCombinerAlg::setupMissingETObject( Property& /*prop*/ ) {
+  m_setMetName = true;
+  return;
+}
+
+/// This internal method will realize if a user sets the 'OutputContainer' property
+inline void ParticleCombinerAlg::setupOutputContainer( Property& /*prop*/ ) {
+  m_setOutCollKey = true;
+  return;
+}
+
+/// This internal method will realize if a user sets the 'SetPdgId' property
+inline void ParticleCombinerAlg::setupSetPdgId( Property& /*prop*/ ) {
+  m_setPdgId = true;
+  return;
+}
+
+
+#endif // EVENTUTILS_PARTICLECOMBINERALG_H
diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleCombinerTool.cxx b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleCombinerTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..5c7cfb2ce9a0a5c1ec26ddc03f0febab7cbe449c
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleCombinerTool.cxx
@@ -0,0 +1,968 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//============================================================================
+// Name: ParticleCombinerTool.cxx
+//
+/**
+   @class ParticleCombinerTool
+
+   @author Karsten Koeneke <karsten.koeneke@cernSPAMNOT.ch>
+
+   @date July 2014
+
+   @brief Combine particles to composite particles
+
+   Class to combine two or more particles from a given list of
+   input containers. All combinations will be tried and only the
+   ones passing the used selections will be written to StoreGate.
+*/
+//=============================================================================
+
+// This classes header
+#include "ParticleCombinerTool.h"
+
+// STL includes
+#include <string>
+#include <vector>
+#include <cfloat>
+#include <climits>
+
+// The composite particle
+#include "xAODParticleEvent/CompositeParticle.h"
+#include "xAODParticleEvent/CompositeParticleContainer.h"
+#include "xAODParticleEvent/CompositeParticleAuxContainer.h"
+
+// Other EDM includes
+#include "AthLinks/ElementLink.h"
+#include "xAODBase/IParticle.h"
+#include "xAODBase/IParticleContainer.h"
+#include "xAODParticleEvent/IParticleLink.h"
+#include "xAODParticleEvent/IParticleLinkContainer.h"
+#include "xAODMissingET/MissingET.h"
+#include "xAODMissingET/MissingETContainer.h"
+
+// MC Truth includes
+// #include "GeneratorObjects/McEventCollection.h"
+// #include "McParticleEvent/TruthParticle.h"
+// #include "McParticleEvent/TruthParticleContainer.h"
+// #include "HepMC/GenParticle.h"
+// #include "HepMC/GenVertex.h"
+
+// include the Odometer Algorithm
+#include "AnalysisUtils/CombinatoricsOdometer.h"
+
+
+
+//=============================================================================
+// Constructor
+//=============================================================================
+ParticleCombinerTool::ParticleCombinerTool(const std::string& type,
+                                           const std::string& name,
+                                           const IInterface* parent ) :
+  AthAlgTool( type, name, parent ),
+  m_inCollKeyList(),
+  m_outCollKey(""),
+  m_metName(""),
+  m_pdgId(0),
+  m_nEventsProcessed(0),
+  m_anIPartLinkList(),
+  m_inputLinkContainerList(),
+  m_inputLinkContainerListToDelete(),
+  m_inputLinkContainerNames(),
+  m_alreadyUsedInputContainers(),
+  m_containerLabels(),
+  m_containerMaxN(),
+  m_alreadyUsedContainers()
+{
+  declareInterface<DerivationFramework::IAugmentationTool>(this);
+
+  declareProperty("InputContainerList", m_inCollKeyList,   "List of input collection keys" );
+  declareProperty("MissingETObject",    m_metName="Final", "The name of the xAOD::MissingET object (default: 'Final'" );
+  declareProperty("OutputContainer",    m_outCollKey="DefaultCompositeParticleContainer",
+                  "The name of the output container (default: 'DefaultCompositeParticleContainer')" );
+  declareProperty("SetPdgId",           m_pdgId=0,         "PDG ID of the new output xAOD::CompositeParticle" );
+
+  // declareProperty("mcTruthRequireSameMotherPdgID",
+  //                 m_mcTruthRequireSameMotherPdgID=false,
+  //                 "Require that the truth mother has the same PDG_ID defined with compositeParticlePDG_ID" );
+  // declareProperty("mcTruthRequireSameMotherBarcode",
+  //                 m_mcTruthRequireSameMotherBarcode=false,
+  //                 "Require that the truth mother has the identical MC Truth barcode" );
+}
+
+
+
+
+
+
+
+//=============================================================================
+// Destructor
+//=============================================================================
+ParticleCombinerTool::~ParticleCombinerTool()
+{
+}
+
+
+
+
+
+
+//=============================================================================
+// Athena initialize method
+//=============================================================================
+StatusCode ParticleCombinerTool::initialize()
+{
+  // Print the used configuration
+  ATH_MSG_DEBUG ( "==> initialize " << name() << "..." );
+
+  // Print out the used configuration
+  ATH_MSG_DEBUG ( " using = " << m_inCollKeyList );
+  ATH_MSG_DEBUG ( " using = " << m_metName );
+  ATH_MSG_DEBUG ( " using = " << m_outCollKey );
+  ATH_MSG_DEBUG ( " using = " << m_pdgId );
+
+  // ATH_MSG_DEBUG ( " using mcTruthRequireSameMotherPdgID   = " << m_mcTruthRequireSameMotherPdgID );
+  // ATH_MSG_DEBUG ( " using mcTruthRequireSameMotherBarcode = " << m_mcTruthRequireSameMotherBarcode );
+
+  // Initialize the counters to zero
+  m_nEventsProcessed = 0 ;
+
+  return StatusCode::SUCCESS;
+}
+
+
+
+//=============================================================================
+// Run once per event
+//=============================================================================
+StatusCode ParticleCombinerTool::addBranches() const
+{
+  // Increase the event counter
+  ++m_nEventsProcessed;
+
+  // Simple status message at the beginning of each event execute,
+  ATH_MSG_DEBUG ( "==> addBranches " << name() << " on " << m_nEventsProcessed << ". event..." );
+
+
+  //-----------------------------------------
+  // Retrieve and store the input containers
+  //-----------------------------------------
+
+  // Create some objects that are needed later on
+  bool allInputContainersAreFull = true;
+  const xAOD::MissingET* metObject(0);
+  int nMet(0);
+
+  // Clear the vector of LinkContainers and a map of their names.
+  //  use a map to determine if a given input container
+  //  has already been seen, and simply point to the
+  //  link container corresponding to  that already-used
+  //  input container
+  m_inputLinkContainerListToDelete.clear();
+  m_inputLinkContainerList.clear();
+  m_inputLinkContainerNames.clear();
+  m_alreadyUsedInputContainers.clear();
+
+  // Loop over the list of input containers
+  for ( const std::string& anInputCollName  :  m_inCollKeyList.value() ) {
+    // Check if the current input container name is a LinkContainer
+    if ( evtStore()->contains< xAOD::IParticleLinkContainer >( anInputCollName ) ) {
+      // Actually retrieve the LinkContainer from StoreGate
+      const xAOD::IParticleLinkContainer* aLinkContainer(0);
+      ATH_CHECK( evtStore()->retrieve( aLinkContainer , anInputCollName ) );
+      ATH_MSG_DEBUG ( "Input link collection = '" << anInputCollName
+                      << "' retrieved from StoreGate which has " << aLinkContainer->size() << " entries." );
+
+      // If any input container has zero size, we won't be able to build a
+      // CompositeParticle. Thus, we can stop here.
+      if ( aLinkContainer->size() == 0 ) {
+        allInputContainersAreFull &= false;
+        ATH_MSG_VERBOSE("Found an empty input link container");
+        break;
+      }
+
+      if ( m_inputLinkContainerNames.find(aLinkContainer)  == m_inputLinkContainerNames.end() ) {
+        m_inputLinkContainerNames[ aLinkContainer ] = &anInputCollName;
+      }
+      m_inputLinkContainerList.push_back( aLinkContainer );
+    }
+    else if ( evtStore()->contains< xAOD::IParticleContainer >( anInputCollName ) ) {
+      // This container holds an xAOD::IParticleContainer
+      const xAOD::IParticleContainer* aContainer(0);
+      ATH_CHECK( evtStore()->retrieve( aContainer, anInputCollName ) );
+      ATH_MSG_DEBUG ( "Input collection = '" << anInputCollName
+                      << "' retrieved from StoreGate which has " << aContainer->size() << " entries." );
+
+      // If any input container has zero size, we won't be able to build a
+      // CompositeParticle. Thus, we can stop here.
+      if (aContainer->size() == 0) {
+        allInputContainersAreFull &= false;
+        ATH_MSG_VERBOSE("Found an empty input container");
+        break;
+      }
+
+      // Now, create the vector of ElementLinks pointing to the real container
+      if ( m_alreadyUsedInputContainers.find( aContainer ) == m_alreadyUsedInputContainers.end() ) {
+        xAOD::IParticleLinkContainer* newLinkContainer = new xAOD::IParticleLinkContainer();
+        newLinkContainer->reserve( aContainer->size() );
+        m_inputLinkContainerListToDelete.push_back( newLinkContainer );
+
+        for ( std::size_t i=0; i < aContainer->size(); ++i ) {
+          xAOD::IParticleLink iPartLink( *aContainer, i );
+          newLinkContainer->push_back( iPartLink );
+        }
+
+        m_alreadyUsedInputContainers[ aContainer ] = newLinkContainer;
+
+
+        if ( m_inputLinkContainerNames.find( newLinkContainer ) == m_inputLinkContainerNames.end() ) {
+          m_inputLinkContainerNames[ newLinkContainer ] = &anInputCollName;
+        }
+        // Add this new container of ElementLinks to the vector
+        m_inputLinkContainerList.push_back( newLinkContainer );
+      }
+      else {
+        // Add an already existing container of ElementLinks again to the vector
+        m_inputLinkContainerList.push_back( m_alreadyUsedInputContainers[ aContainer ] );
+      }
+    }
+    else if ( evtStore()->contains< xAOD::MissingETContainer >( anInputCollName ) ) {
+      // This container holds an xAOD::IParticleContainer
+      const xAOD::MissingETContainer* aMetContainer(0);
+      ATH_CHECK( evtStore()->retrieve( aMetContainer, anInputCollName ) );
+      ATH_MSG_DEBUG ( "Input missing et container = '" << anInputCollName
+                      << "' retrieved from StoreGate." );
+
+      nMet += 1;
+      metObject = (*aMetContainer)[m_metName.value()];
+      if ( !metObject ) {
+        ATH_MSG_WARNING( "There was a problem getting the xAOD::MissingET "
+                         << " object with name '" << m_metName
+                         << "' from the xAOD::MissingETContainer with "
+                         << "name '" << anInputCollName << "'." );
+      }
+    }
+    else {
+      if ( m_nEventsProcessed <= 10 ) {
+        ATH_MSG_WARNING ( "Input link collection  = '" << anInputCollName
+                          << "' could not be retrieved from StoreGate! "
+                          << " This message will only be repeated 10 times..." );
+      }
+      else {
+        ATH_MSG_DEBUG ( "Input link collection  = '" << anInputCollName
+                        << "' could not be retrieved from StoreGate! " );
+      }
+      return StatusCode::SUCCESS;
+    } // End: if/elif/else is link container
+  } // End: Loop over the list of input containers
+
+  // Make sure that we have at most one missing ET container
+  if ( nMet > 1 ) {
+    ATH_MSG_ERROR( "We seem to have gotten " << nMet << " xAOD::MissingETContainers "
+                   << "in the InputContainerList. At most one is allowed... exiting!" );
+    return StatusCode::FAILURE;
+  }
+
+  // One more sanity check that we didn't loose a container in between
+  if ( m_inCollKeyList.value().size() != ( m_inputLinkContainerList.size() + nMet ) ) {
+    ATH_MSG_DEBUG( "Inconsistent number of input containers after some processing!"
+                   << " This should only happen when any of the input containers has zero size." );
+    ATH_MSG_DEBUG( "  m_inCollKeyList.size() = " << m_inCollKeyList.value().size() );
+    ATH_MSG_DEBUG( "  m_inputLinkContainerList.size() = " << m_inputLinkContainerList.size() );
+    ATH_MSG_DEBUG( "  nMet = " << nMet );
+    ATH_MSG_DEBUG( "  allInputContainersAreFull = " << allInputContainersAreFull );
+  }
+
+
+  // //-----------------------------------------
+  // // Retrieve the MCEventCollection, if needed
+  // //-----------------------------------------
+  // if ( !m_mcEventCollKey.empty() && (
+  //                                    m_mcTruthRequireSameMotherPdgID  ||
+  //                                    m_mcTruthRequireSameMotherBarcode
+  //                                    )
+  //      )
+  //   {
+  //     ATH_CHECK( evtStore()->retrieve( m_mcEventColl, m_mcEventCollKey ) );
+  //     ATH_MSG_DEBUG ( "MCEventCollection = '" << m_mcEventCollKey << "' retrieved from StoreGate" );
+  //   } // End: need to retrieve MCEventCollection
+
+
+
+
+  //-----------------------------------------
+  // Create the output composite particle container and record it in StoreGate
+  //-----------------------------------------
+  xAOD::CompositeParticleContainer* outContainer = new xAOD::CompositeParticleContainer( SG::OWN_ELEMENTS );
+  ATH_CHECK( evtStore()->record ( outContainer, m_outCollKey.value() ) );
+  xAOD::CompositeParticleAuxContainer* compPartAuxCont = new xAOD::CompositeParticleAuxContainer();
+  ATH_CHECK( evtStore()->record( compPartAuxCont, m_outCollKey.value() + "Aux." ) );
+  outContainer->setStore( compPartAuxCont );
+  ATH_MSG_DEBUG( "Recorded xAOD composite particles with key: " << m_outCollKey.value() );
+
+
+
+  //-----------------------------------------
+  // In case at least one of the input containers has zero size,
+  //  no CompositeParticle can be found. So only try building
+  //  CompositeParticles if every input container has at least
+  //  one entry.
+  //-----------------------------------------
+  if ( allInputContainersAreFull ) {
+
+    //-----------------------------------------
+    // Do the combinations of particles
+    //-----------------------------------------
+
+    // Use the odometer algorithm to perform the combination of particles
+    //  m_inputLinkContainerList is the std::vector of links
+
+    // get the label and number of elements in each link container.
+    // pass those to the OdoMeter, and ask the OdoMeter to return
+    // the unique sets of indices for objects in the containers
+
+    // To create the odometer object, we need to assign each container pointer
+    // a string name that uniquely idenfies that container. The same container
+    // (even used multiple times) will always have the same name. The name/entries
+    // info will be used to initialize the odometer.
+    ATH_MSG_DEBUG ( "Input LinkContainer list contains " << m_inputLinkContainerList.size() << " entries." );
+
+    // Clear needed vectors and maps
+    m_containerLabels.clear();
+    m_containerMaxN.clear();
+    m_alreadyUsedContainers.clear();
+
+    for ( const xAOD::IParticleLinkContainer* aLinkContainer  :  m_inputLinkContainerList ) {
+      const std::string& containerName = *(m_inputLinkContainerNames[ aLinkContainer ]);
+
+      // determine if this container has already been used in the list.
+      // if not, assign it a unique name. If so, get the name of the existing container
+      if ( m_containerLabels.size() == 0 ||
+           m_alreadyUsedContainers.find( aLinkContainer ) == m_alreadyUsedContainers.end() ) {
+        m_containerLabels.push_back( containerName );
+        m_containerMaxN[ containerName ] = aLinkContainer->size();
+        m_alreadyUsedContainers[ aLinkContainer ] = containerName;
+      }
+      else {
+        // already used this container. Use the old container's name
+        m_containerLabels.push_back( containerName );
+      }
+      ATH_MSG_DEBUG ( "A container/size pair for the Odometer: "
+                      << m_containerLabels.at( m_containerLabels.size() - 1) << "/"
+                      << m_containerMaxN[ m_containerLabels.at( m_containerLabels.size() - 1) ] );
+    }
+
+
+    // Create and initialize an instance of the odometer
+    OdoMeter anOdometer(m_containerLabels, m_containerMaxN);
+
+    // find all unique groupings and build composites
+    while ( anOdometer.increment() ) {
+      // Clear the vector
+      m_anIPartLinkList.clear();
+
+      // Get the current combinatoric
+      std::vector<int> aUniqueChoice = anOdometer.getVector();
+      int nContainers = static_cast<int>(aUniqueChoice.size());
+
+      if (msgLvl(MSG::VERBOSE)) {
+        msg(MSG::VERBOSE) << "Odometer - using this unique combination: ";
+        for ( unsigned int ichoice = 0; ichoice < aUniqueChoice.size(); ichoice++ ) {
+          msg(MSG::VERBOSE)  << aUniqueChoice.at(ichoice) << ",";
+        }
+        msg(MSG::VERBOSE) << endreq;
+      }
+
+      // Loop over all containers
+      for( int aContainerIndex = 0; aContainerIndex < nContainers; ++aContainerIndex ) {
+        const xAOD::IParticleLinkContainer* aLinkContainer = m_inputLinkContainerList.at( aContainerIndex );
+        int indexInContainer = aUniqueChoice.at( aContainerIndex );
+
+        const xAOD::IParticleLink& aPartLink = aLinkContainer->at( indexInContainer );
+
+        const xAOD::IParticleContainer* ptrIPartCont =
+        dynamic_cast< const xAOD::IParticleContainer* >( aPartLink.getStorableObjectPointer() );
+
+        if ( ptrIPartCont != NULL ) {
+          const xAOD::IParticleLink aParticleLink(*ptrIPartCont, aPartLink.index());
+          m_anIPartLinkList.push_back( aParticleLink );
+        }
+      } // end the loop over the available containers to build INav4MomLink objects
+
+      // Now, actually build the CompositeParticle from the list of ElementLinks to INavigable4Momentum
+      ATH_CHECK( buildComposite( outContainer, m_anIPartLinkList ) );
+
+    } // End: while ( anOdometer.increment() )
+
+  } // End: Found an empty input collection; thus no CompositeParticle can be possible... do nothing.
+
+
+  //-----------------------------------------
+  // Set the output container of composite particles as const
+  // Actually, for now, don't do this as analyzers might want to decorate the
+  // new xAOD::CompositeParticles further downstream.
+  //-----------------------------------------
+  // ATH_CHECK( evtStore()->setConst( outContainer ) );
+  // ATH_CHECK( evtStore()->setConst( compPartAuxCont ) );
+  // ATH_MSG_DEBUG ( "Output collection = '" << m_outCollKey.value() << "' set to const in StoreGate" );
+
+  // Print a final message about the composite particles
+  ATH_MSG_DEBUG ( "Found " << outContainer->size() << " composite particles in event number " << m_nEventsProcessed );
+
+  // // Delete needed things
+  for ( std::size_t i=0; i<m_inputLinkContainerListToDelete.size(); ++i ) {
+    if ( m_inputLinkContainerListToDelete[i] ) {
+      delete m_inputLinkContainerListToDelete[i];
+    }
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+
+
+
+
+//=============================================================================
+// Athena finalize method
+//=============================================================================
+StatusCode ParticleCombinerTool::finalize()
+{
+  ATH_MSG_DEBUG ( "FINALIZING AFTER ALL EVENTS ARE PROCESSED" );
+
+  return StatusCode::SUCCESS;
+}
+
+
+
+
+
+
+//=============================================================================
+// Building the composite particle
+// Here, we check if any of the potential constituents (anIPartLinkList) is
+// overlapping (is the same or share the same constituent) with any of the other
+// potential constituents
+//=============================================================================
+StatusCode ParticleCombinerTool::buildComposite( xAOD::CompositeParticleContainer* outContainer,
+                                                 xAOD::IParticleLinkContainer& anIPartLinkList ) const
+{
+  // Check if the vector does not have zero size
+  if ( anIPartLinkList.size() == 0 ) {
+    return StatusCode::SUCCESS;
+  }
+
+  // Create a list of all ParticleLinks that are already checked
+  std::vector< const xAOD::IParticleLink* > theParticleLinks;
+
+  bool ParticlesAreValid = true;
+
+  //Loop over all ElementLinks to INavigable4Momenta and get the INavigable4Momenta
+  for ( const xAOD::IParticleLink& aParticleLink  :  anIPartLinkList ) {
+    // Check if this ElementLink is valid
+    if ( aParticleLink.isValid() ) {
+      // Get the particle from the ElementLink
+      const xAOD::IParticle* aParticle = *aParticleLink;
+
+      if (aParticle) {
+        // determine if the particle has any daughter in common with
+        // a previous particle in the composite:
+        for ( const xAOD::IParticleLink* otherPartLink  :  theParticleLinks ) {
+          // Now, make the check for having any constituent shared.
+          // Note that we don't need to check if the otherPartLink is valid
+          // since this happened already when we filled that vector
+          if ( shareSameConstituents( aParticle, **otherPartLink ) ) {
+            ATH_MSG_DEBUG ( "Found aParticle overlaps with another INavigable4Momentum in the composite!" );
+            ParticlesAreValid &= false;
+            break;
+          }
+        } // End: loop over all already checked particle links
+
+        // push the particle onto the candidate's input list
+        if ( ParticlesAreValid ) {
+          theParticleLinks.push_back( &aParticleLink );
+        }
+      }
+      else {
+        ATH_MSG_DEBUG ( "Found non-valid particle at an ElementLink location!" );
+        ParticlesAreValid &= false;
+      } // check if aParticle exists at all
+    }
+    else {
+      ATH_MSG_DEBUG ( "Found non-valid ElementLink for a particle!" );
+      ParticlesAreValid &= false;
+    } // check the link to a particle
+
+    if ( false == ParticlesAreValid ) {
+      break;
+    }
+  } // End: loop over vector of ElementLinks
+
+
+  //-----------------------------------------
+  // Do the combination
+  //-----------------------------------------
+  if ( ParticlesAreValid ) {
+    // Actually create the composite particle
+    //--------------------------------------------------------------
+    xAOD::CompositeParticle* compPart = new xAOD::CompositeParticle();
+    compPart->makePrivateStore();
+    for ( const xAOD::IParticleLink& aParticleLink  :  anIPartLinkList ) {
+      compPart->addConstituent( aParticleLink );
+    }
+    compPart->setPdgId( m_pdgId.value() );
+
+    // Check if this composite particle has been found before
+    if ( !compositeParticleAlreadyFound( outContainer, compPart ) ) {
+      // Add this composite particle to the output container
+      // if it passes all the selections
+      //--------------------------------------------------------------
+      bool passAll = true;
+
+      // // charge selection
+      // if ( passAll ) {
+      //   passAll = m_filterTool->chargeFilter( compPart,
+      //                                         m_chargeMin,
+      //                                         m_chargeMax,
+      //                                         m_allowChargeConj );
+      // }
+
+      // // MC Truth selection
+      // // ONLY run this if MCTruth information is available AND
+      // // MCTruth selections are configured!
+      // if ( !m_mcEventCollKey.empty() && (
+      //                                    m_mcTruthRequireSameMotherPdgID  ||
+      //                                    m_mcTruthRequireSameMotherBarcode
+      //                                    )
+      //      )
+      //   {
+      //     if ( passAll )
+      //       {
+      //         passAll = mcTruthSelections( compPart );
+      //       }
+      //   }
+
+
+
+      // Write out the composite particles if all cuts are passed
+      if ( passAll ) {
+        outContainer->push_back( compPart );
+      }
+      else {
+        delete compPart;
+      }
+    }
+    else {
+      // Output message
+      ATH_MSG_DEBUG ( "Found this composite particle already before..." );
+      delete compPart;
+    } // End: if compositeParticleAlreadyFound
+
+  } // End: Saveguard check if all particles are valide
+
+  return StatusCode::SUCCESS;
+}
+
+
+
+
+
+
+//=============================================================================
+// Check if the composite particle at hand was already found before
+//=============================================================================
+bool ParticleCombinerTool::compositeParticleAlreadyFound( xAOD::CompositeParticleContainer* compContainer,
+                                                          xAOD::CompositeParticle* compPart ) const
+{
+  // default return
+  bool foundIdentical = false;
+
+  // Count the number of constituents of the test particle
+  std::size_t nConstituentsTest = compPart->nConstituents();
+
+  // Get the first input container and loop over it
+  for ( const xAOD::CompositeParticle* contCompPart : *compContainer ) {
+    // Check if an identical composite particle is already found
+    if ( !foundIdentical ) {
+      // Count the number of constituents of the reference particle
+      std::size_t nConstituentsReference = contCompPart->nConstituents();
+
+      // Check that both have the same number of constituents
+      if ( nConstituentsTest==nConstituentsReference ) {
+        // Loop over all constituents of the composite particle to be tested
+        bool allConstituentsSame = true;
+        for ( const xAOD::IParticleLink& constitLink : compPart->constituentLinks() ) {
+          if ( allConstituentsSame && contCompPart->contains(constitLink) ) {
+            allConstituentsSame = true;
+          }
+          else {
+            allConstituentsSame = false;
+          }
+        } // End: loop over constituents
+
+        // Now, propagete the decission
+        if ( allConstituentsSame ) {
+          foundIdentical = true;
+        }
+        else {
+          foundIdentical = false;
+        }
+      } // End: if ( nConstituentsTest==nConstituentsReference )
+      else {
+        foundIdentical = false;
+      } // End: if/else ( nConstituentsTest==nConstituentsReference )
+    } // End: if ( !foundIdentical )
+  } // End: loop over container
+
+  // Output message
+  ATH_MSG_VERBOSE ( "Checking if this composite particle was already found before..."
+                    << " foundIdentical=" << foundIdentical );
+
+  return foundIdentical;
+}
+
+
+// The test if two particles are equal.
+// One would need a barcode to do this proper
+bool ParticleCombinerTool::isEqual( const xAOD::IParticle* part1,
+                                    const xAOD::IParticle* part2 ) const
+{
+  // TODO: Add special implementation for TruthParticle, i.e., check barcode
+
+  // Since we don't have a barcode here, we have to rely on pointer equality
+  if ( part1  &&  part1 == part2 ) {
+    return true;
+  }
+  else {
+    return false;
+  }
+  // This would be better:
+  // part1->hasSameAthenaBarCodeExceptVersion(*part2);
+}
+
+
+
+//=============================================================================
+// Check that two particles are not the same or, if they are
+// composite particles, that they don't share the same constitutents
+//=============================================================================
+bool ParticleCombinerTool::shareSameConstituents( const xAOD::IParticle* part1,
+                                                  const xAOD::IParticle* part2 ) const
+{
+  const xAOD::CompositeParticle* compPart1 =
+    dynamic_cast<const xAOD::CompositeParticle*> (part1) ;
+  const xAOD::CompositeParticle* compPart2 =
+    dynamic_cast<const xAOD::CompositeParticle*> (part2) ;
+
+  // Neither of the two is a composite particle
+  if ( !compPart1 && !compPart2 ) {
+    return this->isEqual( part1, part2 );
+  }
+  // One of them is a composite
+  else if ( compPart1 && !compPart2 ) {
+    return shareSameConstituents( part2, compPart1 );
+  }
+  else if ( !compPart1 && compPart2 ) {
+    return shareSameConstituents( part1, compPart2 );
+  }
+  // Both are composite candidates
+  else if ( compPart1 && compPart2 ) {
+    return shareSameConstituents( compPart1, compPart2 );
+  }
+
+  return false;
+}
+
+
+
+//=============================================================================
+// Check that two particles are not the same or, if they are
+// composite particles, that they don't share the same constitutents
+// -------------------------- HELPER ---------------------
+//=============================================================================
+bool ParticleCombinerTool::shareSameConstituents( const xAOD::IParticle* part1,
+                                                  const xAOD::CompositeParticle* compPart2 ) const
+{
+  // Default return
+  bool isConstituent = false;
+
+  // Loop over all constituents of the composite particle to be tested
+  const std::size_t nConstit = compPart2->nConstituents();
+  for( std::size_t i=0; i<nConstit; ++i ) {
+    const xAOD::IParticle* part2 = compPart2->constituent(i);
+
+    // Check if this constituent itself is a composite particle
+    const xAOD::CompositeParticle* constitCP =
+      dynamic_cast<const xAOD::CompositeParticle*> (part2) ;
+
+    if ( !constitCP ) {
+      isConstituent = this->isEqual( part1, part2 );
+    }
+    else {
+      isConstituent = shareSameConstituents( part1, constitCP );
+    }
+    if ( isConstituent ) {
+      return true;
+    }
+  } // End: loop over constituents
+
+  return isConstituent;
+}
+
+
+
+//=============================================================================
+// Check that two particles are not the same or, if they are
+// composite particles, that they don't share the same constitutents
+// -------------------------- HELPER ---------------------
+//=============================================================================
+bool ParticleCombinerTool::shareSameConstituents( const xAOD::CompositeParticle* compPart1,
+                                                  const xAOD::CompositeParticle* compPart2 ) const
+{
+  // Default return
+  bool isConstituent = false;
+
+  // Loop over all constituents of the composite particle to be tested
+  const std::size_t nConstit1 = compPart1->nConstituents();
+  const std::size_t nConstit2 = compPart2->nConstituents();
+  for( std::size_t i=0; i<nConstit1; ++i ) {
+    const xAOD::IParticle* part1 = compPart1->constituent(i);
+
+    // Check if this constituent itself is a composite particle
+    const xAOD::CompositeParticle* constitCP1 =
+      dynamic_cast<const xAOD::CompositeParticle*> (part1) ;
+
+    for( std::size_t j=0; i<nConstit2; ++j ) {
+      const xAOD::IParticle* part2 = compPart2->constituent(j);
+
+      // Check if this constituent itself is a composite particle
+      const xAOD::CompositeParticle* constitCP2 =
+        dynamic_cast<const xAOD::CompositeParticle*> (part2) ;
+
+      if ( !constitCP1 && !constitCP1 ) {
+        isConstituent = this->isEqual( part1, part2 );
+      }
+      if ( !constitCP1 && constitCP2 ) {
+        isConstituent = shareSameConstituents( part1, constitCP2 );
+      }
+      if ( constitCP1 && !constitCP2 ) {
+        isConstituent = shareSameConstituents( part2, constitCP1 );
+      }
+      if ( constitCP1 && constitCP2 ) {
+        isConstituent = shareSameConstituents( constitCP1, constitCP2 );
+      }
+      if ( isConstituent ) {
+        return true;
+      }
+    } // End: loop over constituents 2
+  } // End: loop over constituents 1
+
+  return isConstituent;
+}
+
+
+
+//
+// //=============================================================================
+// // Do the selection based on the MC Truth record
+// // -------------------------- HELPER ---------------------
+// //=============================================================================
+// bool D2PDParticleCombiner::mcTruthSelections( const CompositeParticle* compPart ) const
+// {
+//   // Default return
+//   bool isPassed = true;
+//
+//   // If the MCEventCollection is not available, I can't do anything
+//   if ( !m_mcEventColl )
+//     {
+//       ATH_MSG_WARNING ( "No MCEventCollection available... skipping!" );
+//       return true;
+//     }
+//
+//
+//   // Get the daughters of the composite particle and check if all of them are TruthParticles
+//   unsigned int counter(0);
+//   std::vector<const TruthParticle*> truthParticles;
+//   CompositeParticle::ConstituentsIter_t cpItr    = compPart->constituents_begin();
+//   CompositeParticle::ConstituentsIter_t cpItrEnd = compPart->constituents_end();
+//   for( ; cpItr != cpItrEnd; ++cpItr )
+//     {
+//       ++counter;
+//       const TruthParticle* part = dynamic_cast<const TruthParticle*>(*cpItr);
+//
+//       // if the cast was successfull, add it to the vector of truth particles
+//       if ( part )
+//         {
+//           truthParticles.push_back( part );
+//         }
+//     }
+//
+//
+//   // If all of the constituents are TruthParticles...
+//   if ( truthParticles.size() != counter )
+//     {
+//       ATH_MSG_WARNING ( "Not all of the constituents of this CompositeParticle are TruthParticles... skipping!" );
+//       return true;
+//     }
+//
+//
+//   //------------------------------------------------
+//   // Now, do the actual selections
+//   //------------------------------------------------
+//
+//   std::vector<int> pdgIDList;
+//   std::vector<int> barcodeList;
+//
+//   // Loop over the TruthParticles
+//   std::vector<const TruthParticle*>::const_iterator partItr    = truthParticles.begin();
+//   std::vector<const TruthParticle*>::const_iterator partItrEnd = truthParticles.end();
+//   for ( ; partItr != partItrEnd; ++partItr )
+//     {
+//       // Get the GenParticle from the TruthParticle
+//       const TruthParticle* part = (*partItr);
+//       const HepMC::GenParticle* genPart = part->genParticle();
+//       const int pdgID = genPart->pdg_id();
+//
+//       // Now, get the origin of this generated particle
+//       McEventCollection::const_iterator mcEventItr = m_mcEventColl->begin();
+//       const int primaryBarcode = genPart->barcode()%1000000;
+//       const HepMC::GenParticle* primaryPart = (*mcEventItr)->barcode_to_particle(primaryBarcode);
+//
+//       // Check that we really have the primaryPart
+//       if ( !primaryPart )
+//         {
+//           ATH_MSG_WARNING ( "Could not get the primaryParticle... skipping!" );
+//           return true;
+//         }
+//
+//       // Now get the production vertex
+//       const HepMC::GenVertex*  prodVert = primaryPart->production_vertex();
+//       if ( !prodVert )
+//         {
+//           ATH_MSG_WARNING ( "Could not get the ProductionVertex... skipping!" );
+//           return true;
+//         }
+//
+//       // Check that we have only one mother
+//       if ( prodVert->particles_in_size() > 1 )
+//         {
+//           ATH_MSG_WARNING ( "The ProductionVertex has more than one incomming particles... skipping!" );
+//           return true;
+//         }
+//
+//
+//       // Loop over the mother particles
+//       // Make sure that we ignore bremsstrahlung and decays into itself
+//       const HepMC::GenVertex* originVert = prodVert ;
+//       //const HepMC::GenVertex* tmpVert(0);
+//       int originPdgID = pdgID;
+//       int originBarcode(0);
+//       int counter(0);
+//       do
+//         {
+//           ++counter;
+//           HepMC::GenVertex::particles_in_const_iterator motherItr    = originVert->particles_in_const_begin();
+//           HepMC::GenVertex::particles_in_const_iterator motherItrEnd = originVert->particles_in_const_end();
+//           for ( ; motherItr != motherItrEnd; ++motherItr )
+//             {
+//               originPdgID   = (*motherItr)->pdg_id();
+//               originVert    = (*motherItr)->production_vertex();
+//               originBarcode = (*motherItr)->barcode();
+//             }
+//
+//           // Protect against infinite loop
+//           if ( counter > 100 )
+//             {
+//               ATH_MSG_WARNING ( "Stuck in an infinite while loop... breaking out!" );
+//               break;
+//             }
+//         } while ( abs(originPdgID) == abs(pdgID) && originVert != 0 );
+//
+//       // Attach the PDG_ID and barcode of the origin particle to the vectors
+//       pdgIDList.push_back( originPdgID );
+//       barcodeList.push_back( originBarcode );
+//
+//     } // End: loop over all the daughter TruthParticles from the CompositeParticle
+//
+//   // Get the decissions
+//   bool isSamePdgID(true);
+//   bool isSameBarcode(true);
+//   std::vector<int>::const_iterator pdgItr    = pdgIDList.begin();
+//   std::vector<int>::const_iterator pdgItrEnd = pdgIDList.end();
+//   for ( ; pdgItr != pdgItrEnd; ++pdgItr )
+//     {
+//       if ( m_pdgId != (*pdgItr) )
+//         {
+//           isSamePdgID = false;
+//         }
+//     } // End: Loop over pdg_ID list
+//
+//   std::vector<int>::const_iterator barcodeItr    = barcodeList.begin();
+//   std::vector<int>::const_iterator barcodeItrEnd = barcodeList.end();
+//   for ( ; barcodeItr != barcodeItrEnd; ++barcodeItr )
+//     {
+//       if ( barcodeList[0] != (*barcodeItr) )
+//         {
+//           isSameBarcode = false;
+//         }
+//     } // End: Loop over barcode list
+//
+//
+//
+//   // Now, do the final decission
+//   if ( m_mcTruthRequireSameMotherPdgID && !isSamePdgID )
+//     {
+//       isPassed = false;
+//     }
+//   if ( m_mcTruthRequireSameMotherBarcode && !isSameBarcode )
+//     {
+//       isPassed = false;
+//     }
+//
+//
+//   return isPassed;
+// }
+
+
+
+//       const HepMC::GenVertex* MothVert(0);
+//       long  NumOfParents(-1);
+//       int MotherBarcode(0);
+//       m_MotherPDG=0;
+//       m_PhotonMotherPDG=0;
+
+//       const HepMC::GenVertex* oriMothVert(0);
+//       HepMC::GenVertex::particles_in_const_iterator itrMother = PriOriVert->particles_in_const_begin();
+//       for ( ; itrMother != PriOriVert->particles_in_const_end();
+//             ++itrMother)
+//         {
+//           m_MotherPDG   = (*itrMother)->pdg_id();
+//           MothVert      = (*itrMother)->production_vertex();
+//           oriMothVert   = (*itrMother)->production_vertex();
+//           MotherBarcode = (*itrMother)->barcode();
+//         }// cycle itrMother
+
+//       // radiation in the final state
+//       if ( abs(m_MotherPDG)==11 && PriBarcode<200000 && oriMothVert!=0 )
+//         {
+//           int itr=0;
+//           do
+//             {
+//               PriOriVert = oriMothVert;
+//               PriBarcode = MotherBarcode;
+//               for (HepMC::GenVertex::particles_in_const_iterator
+//                      itrMother = PriOriVert->particles_in_const_begin();
+//                    itrMother!=PriOriVert->particles_in_const_end(); ++itrMother){
+
+//                 m_MotherPDG = (*itrMother)->pdg_id();
+//                 MothVert    = (*itrMother)->production_vertex();
+//                 oriMothVert = (*itrMother)->production_vertex();
+//                 MotherBarcode=(*itrMother)->barcode();
+//               }// cycle itrMother
+//               itr++;
+//               if(itr>100) {std::cout<<"infinite while"<<std::endl;break;}
+//             }  while ( oriMothVert!=0 && abs(m_MotherPDG)==11 );
+//         }
diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleCombinerTool.h b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleCombinerTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..ea60fe5587f18e6e3c143a6e0cb95b6e35c12f94
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleCombinerTool.h
@@ -0,0 +1,177 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// Dear emacs, this is -*-c++-*-
+#ifndef EVENTUTILS_PARTICLECOMBINERTOOL_H
+#define EVENTUTILS_PARTICLECOMBINERTOOL_H
+
+//============================================================================
+// Name: ParticleCombinerTool.h
+//
+/**
+   @class ParticleCombinerTool
+
+   @author Karsten Koeneke <karsten.koeneke@cernSPAMNOT.ch>
+
+   @date July 2014
+
+   @brief Combine particles to composite particles
+
+   Class to combine two or more particles from a given list of
+   input containers. All combinations will be tried and the unique ones will
+   be written to StoreGate.
+*/
+//=============================================================================
+
+
+// STL includes
+#include <string>
+#include <vector>
+
+// Athena includes
+#include "GaudiKernel/Property.h"
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "DerivationFrameworkInterfaces/IAugmentationTool.h"
+
+// CompositeParticle
+#include "xAODParticleEvent/CompositeParticleContainerFwd.h"
+#include "xAODParticleEvent/CompositeParticleFwd.h"
+#include "xAODParticleEvent/IParticleLinkContainer.h"
+
+// MC Truth
+// #include "GeneratorObjects/McEventCollection.h"
+
+
+class ParticleCombinerTool : public AthAlgTool,
+                             virtual public DerivationFramework::IAugmentationTool
+{
+public:
+
+  /** Default constructor */
+  ParticleCombinerTool(const std::string& type,
+                       const std::string& name,
+                       const IInterface* parent);
+
+  /** Default destructor */
+  virtual ~ParticleCombinerTool() ;
+
+
+public:
+  /** Gaudi Service Interface method implementations - initialize */
+  StatusCode initialize() ;
+
+  /** Gaudi Service Interface method implementations - finalize */
+  StatusCode finalize() ;
+
+  /// Implement the method from the IAugmentationTool interface
+  virtual StatusCode addBranches() const final override;
+
+
+
+
+private:
+  /// The test if two particles are equal.
+  /// One would need a barcode, i.e., particle-unique identifier, to do this proper
+  bool isEqual( const xAOD::IParticle* part1, const xAOD::IParticle* part2 ) const;
+
+  /** Build the composite candidates */
+  StatusCode buildComposite( xAOD::CompositeParticleContainer* outContainer,
+                             xAOD::IParticleLinkContainer& anIPartLinkList ) const;
+
+  /** Check if the composite particle at hand was already found before */
+  bool compositeParticleAlreadyFound( xAOD::CompositeParticleContainer* compContainer,
+                                      xAOD::CompositeParticle* compPart ) const;
+
+  /** Check that two particles are not the same or, if they are
+      composite particles, that they don't share the same constitutents */
+  bool shareSameConstituents( const xAOD::IParticle* part1,
+                              const xAOD::IParticle* part2 ) const;
+
+  /** Check that two particles are not the same or, if they are
+      composite particles, that they don't share the same constitutents */
+  bool shareSameConstituents( const xAOD::IParticle* part1,
+                              const xAOD::CompositeParticle* compPart2 ) const;
+
+  /** Check that two particles are not the same or, if they are
+      composite particles, that they don't share the same constitutents */
+  bool shareSameConstituents( const xAOD::CompositeParticle* compPart1,
+                              const xAOD::CompositeParticle* compPart2 ) const;
+
+  /** Do the MC Truth selections */
+  // bool mcTruthSelections( const xAOD::CompositeParticle* compPart );
+
+
+
+private:
+  //------------------------------------------------------
+  // Tools and Containers
+  //------------------------------------------------------
+
+  /// List of input collection names
+  StringArrayProperty m_inCollKeyList;
+
+  /// Output collection name (the composite particles)
+  StringProperty m_outCollKey;
+
+  /// The name of the missing ET object, e.g., "Final"
+  StringProperty m_metName;
+
+  /// The PDG_ID of the CompositeParticle
+  IntegerProperty m_pdgId;
+
+  // /** MCEventCollection name */
+  // StringProperty m_mcEventCollKey;
+  //
+  // /** MCEventCollection */
+  // const McEventCollection* m_mcEventColl;
+
+
+
+private:
+  /** Internal event counter */
+  mutable unsigned long m_nEventsProcessed;
+
+
+private:
+  //------------------------------------------------------
+  // Internal variables
+  //------------------------------------------------------
+  /** Create a vector that will hold all the INav4MomLinks for one CompositeParticle */
+  mutable xAOD::IParticleLinkContainer m_anIPartLinkList;
+
+
+  /** Create a vector of LinkContainers and a map of their names */
+  mutable std::vector< const xAOD::IParticleLinkContainer* > m_inputLinkContainerList;
+
+  /** create a vector that will contain pointers to the
+   *  xAOD::IParticleLinkContainers that need to be deleted manually.
+   *  This is because these containers never get registered to StoreGate and
+   *  thus, the ownership resides inside this class instance. */
+  mutable std::vector< const xAOD::IParticleLinkContainer* > m_inputLinkContainerListToDelete;
+
+  /** A map to store the name associated to each input link container object */
+  mutable std::map< const xAOD::IParticleLinkContainer*, const std::string* > m_inputLinkContainerNames;
+
+  /** A map to store the input container that are already used.
+   *  use a map to determine if a given input container
+   *  has already been seen, and simply point to the
+   *  link container corresponding to  that already-used
+   *  input container   */
+  mutable std::map< const xAOD::IParticleContainer*, const xAOD::IParticleLinkContainer* > m_alreadyUsedInputContainers;
+
+
+  /** Vector of the labels/keys of all input containers (all converted to link containers) */
+  mutable std::vector<std::string> m_containerLabels;
+
+  /** A map to store the size of each input container */
+  mutable std::map<std::string, int> m_containerMaxN;
+
+  /** A map to store the container that are already used */
+  mutable std::map< const xAOD::IParticleLinkContainer*, std::string > m_alreadyUsedContainers;
+
+
+}; // End class ParticleCombinerTool
+
+
+#endif // EVENTUTILS_PARTICLECOMBINERTOOL_H
diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSelectionAlg.cxx b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSelectionAlg.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..a3c7fa0095ed5b7a92cbc04a3b7d4a4f39af35a4
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSelectionAlg.cxx
@@ -0,0 +1,184 @@
+///////////////////////// -*- C++ -*- /////////////////////////////
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// ParticleSelectionAlg.cxx
+// Implementation file for class ParticleSelectionAlg
+// Author: Karsten Koeneke <karsten.koeneke@cern.ch>
+///////////////////////////////////////////////////////////////////
+
+// EventUtils includes
+#include "ParticleSelectionAlg.h"
+
+// STL includes
+
+// FrameWork includes
+#include "GaudiKernel/Property.h"
+#include "GaudiKernel/IJobOptionsSvc.h"
+#include "DerivationFrameworkInterfaces/IAugmentationTool.h"
+
+
+
+///////////////////////////////////////////////////////////////////
+// Public methods:
+///////////////////////////////////////////////////////////////////
+
+// Constructors
+////////////////
+ParticleSelectionAlg::ParticleSelectionAlg( const std::string& name,
+                                            ISvcLocator* pSvcLocator ) :
+  ::AthAlgorithm( name, pSvcLocator ),
+  m_jos("JobOptionsSvc", name),
+  m_tool("ParticleSelectionTool/ParticleSelectionTool", this),
+  m_inCollKey(""),
+  m_setInCollKey(false),
+  m_outCollKey(""),
+  m_setOutCollKey(false),
+  m_outCollType(""),
+  m_setOutCollType(false),
+  m_setOwnPolicy(false),
+  m_outLinkCollKey(""),
+  m_setOutLinkCollKey(false),
+  m_selection(""),
+  m_setSelection(false),
+  m_nEventsProcessed(0)
+{
+  declareProperty("JobOptionsSvc",       m_jos, "The JobOptionService instance.");
+
+  declareProperty("SelectionTool",       m_tool, "The private tool that will select the particles within a container" );
+
+  declareProperty("InputContainer",      m_inCollKey="",   "Input container name" );
+  m_inCollKey.declareUpdateHandler( &ParticleSelectionAlg::setupInputContainer, this );
+
+  declareProperty("OutputContainer",     m_outCollKey="",
+                  "The name of the output container with the deep copy of selected xAOD::IParticles" );
+  m_outCollKey.declareUpdateHandler( &ParticleSelectionAlg::setupOutputContainer, this );
+
+  declareProperty("OutputContainerType", m_outCollType="",
+                  "The type of the output container, e.g., 'xAOD::JetContainer'" );
+  m_outCollType.declareUpdateHandler( &ParticleSelectionAlg::setupOutputContainerType, this );
+
+  declareProperty("OutputContainerOwnershipPolicy", m_outOwnPolicyName="OWN_ELEMENTS",
+                  "Defines the ownership policy of the output container (default: 'OWN_ELEMENTS'; also allowed: 'VIEW_ELEMENTS')" );
+  m_outOwnPolicyName.declareUpdateHandler( &ParticleSelectionAlg::setupOutputContainerOwnPolicy, this );
+
+  declareProperty("OutputLinkContainer", m_outLinkCollKey="",
+                  "The name of the output container of ElementLinks to the selected xAOD::IParticles" );
+  m_outLinkCollKey.declareUpdateHandler( &ParticleSelectionAlg::setupOutputLinkContainer, this );
+
+  declareProperty("Selection",           m_selection="",
+                  "The selection string that defines which xAOD::IParticles to select from the container" );
+  m_selection.declareUpdateHandler( &ParticleSelectionAlg::setupSelection, this );
+}
+
+
+
+// Destructor
+///////////////
+ParticleSelectionAlg::~ParticleSelectionAlg()
+{}
+
+
+
+// Athena Algorithm's Hooks
+////////////////////////////
+StatusCode ParticleSelectionAlg::initialize()
+{
+  ATH_MSG_DEBUG ("Initializing " << name() << "...");
+
+  // Print out the used configuration
+  ATH_MSG_DEBUG ( " using = " << m_jos );
+  ATH_MSG_DEBUG ( " using = " << m_tool );
+  ATH_MSG_DEBUG ( " using = " << m_inCollKey );
+  ATH_MSG_DEBUG ( " using = " << m_outCollKey );
+  ATH_MSG_DEBUG ( " using = " << m_outCollType );
+  ATH_MSG_DEBUG ( " using = " << m_outLinkCollKey );
+  ATH_MSG_DEBUG ( " using = " << m_selection );
+
+
+  // Initialize the counters to zero
+  m_nEventsProcessed = 0 ;
+
+
+  // Get the JobOptionService
+  // We will use this to set the properties of our private skimming tool
+  // from the properties of this algorithm.
+  ATH_MSG_VERBOSE( "Getting the JobOptionService");
+  ATH_CHECK( m_jos.retrieve() );
+
+  // Get the full name of the private skimTool
+  ATH_MSG_VERBOSE( "Getting the full name of the tool");
+  const std::string& fullToolName = this->name() + "." + m_tool.name();
+  ATH_MSG_DEBUG( "Got the full name of the tool: " << fullToolName );
+
+  // Now, set all properties of the private skimTool that were acutally configured
+  if (m_setInCollKey) {
+    ATH_MSG_DEBUG( "Setting property" << m_inCollKey
+                   << " of private tool with name: '" << fullToolName << "'" );
+    ATH_CHECK( m_jos->addPropertyToCatalogue (fullToolName,m_inCollKey) );
+  }
+  if (m_setOutCollKey) {
+    ATH_MSG_DEBUG( "Setting property" << m_outCollKey
+                   << " of private tool with name: '" << fullToolName << "'" );
+    ATH_CHECK( m_jos->addPropertyToCatalogue (fullToolName,m_outCollKey) );
+  }
+  if (m_setOutCollType) {
+    ATH_MSG_DEBUG( "Setting property" << m_outCollType
+                   << " of private tool with name: '" << fullToolName << "'" );
+    ATH_CHECK( m_jos->addPropertyToCatalogue (fullToolName,m_outCollType) );
+  }
+  if (m_setOwnPolicy) {
+    ATH_MSG_DEBUG( "Setting property" << m_outOwnPolicyName
+                   << " of private tool with name: '" << fullToolName << "'" );
+    ATH_CHECK( m_jos->addPropertyToCatalogue (fullToolName,m_outOwnPolicyName) );
+  }
+  if (m_setOutLinkCollKey) {
+    ATH_MSG_DEBUG( "Setting property" << m_outLinkCollKey
+                   << " of private tool with name: '" << fullToolName << "'" );
+    ATH_CHECK( m_jos->addPropertyToCatalogue (fullToolName,m_outLinkCollKey) );
+  }
+  if (m_setSelection) {
+    ATH_MSG_DEBUG( "Setting property" << m_selection
+                   << " of private tool with name: '" << fullToolName << "'" );
+    ATH_CHECK( m_jos->addPropertyToCatalogue (fullToolName,m_selection) );
+  }
+  ATH_MSG_DEBUG( "Done setting properties of the tool");
+
+  // Get the skimming tool
+  ATH_CHECK( m_tool.retrieve() );
+
+  ATH_MSG_DEBUG ( "==> done with initialize " << name() << "..." );
+
+  return StatusCode::SUCCESS;
+}
+
+
+
+StatusCode ParticleSelectionAlg::finalize()
+{
+  ATH_MSG_DEBUG ("Finalizing " << name() << "...");
+
+  // Release all tools and services
+  ATH_CHECK( m_jos.release() );
+  ATH_CHECK( m_tool.release() );
+
+  return StatusCode::SUCCESS;
+}
+
+
+
+StatusCode ParticleSelectionAlg::execute()
+{
+  // Increase the event counter
+  ++m_nEventsProcessed;
+
+  // Simple status message at the beginning of each event execute,
+  ATH_MSG_DEBUG ( "==> execute " << name() << " on " << m_nEventsProcessed << ". event..." );
+
+  // Call the tool and record resulting containers into StoreGate
+  ATH_CHECK( m_tool->addBranches() );
+
+  return StatusCode::SUCCESS;
+}
diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSelectionAlg.h b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSelectionAlg.h
new file mode 100644
index 0000000000000000000000000000000000000000..dffc6aec97ec00bd7bd326a0aca31faa438cdaf9
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSelectionAlg.h
@@ -0,0 +1,189 @@
+///////////////////////// -*- C++ -*- /////////////////////////////
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// ParticleSelectionAlg.h
+// Header file for class ParticleSelectionAlg
+// Author: Karsten Koeneke <karsten.koeneke@cern.ch>
+///////////////////////////////////////////////////////////////////
+#ifndef EVENTUTILS_PARTICLESELECTIONALG_H
+#define EVENTUTILS_PARTICLESELECTIONALG_H 1
+
+// STL includes
+#include <string>
+
+// FrameWork includes
+#include "GaudiKernel/ToolHandle.h"
+#include "GaudiKernel/ServiceHandle.h"
+#include "AthenaBaseComps/AthAlgorithm.h"
+
+
+// forward declarations
+class IJobOptionsSvc;
+namespace DerivationFramework {
+  class IAugmentationTool;
+}
+
+
+
+class ParticleSelectionAlg
+  : public ::AthAlgorithm
+{
+
+  ///////////////////////////////////////////////////////////////////
+  // Public methods:
+  ///////////////////////////////////////////////////////////////////
+ public:
+
+  // Copy constructor:
+
+  /// Constructor with parameters:
+  ParticleSelectionAlg( const std::string& name, ISvcLocator* pSvcLocator );
+
+  /// Destructor:
+  virtual ~ParticleSelectionAlg();
+
+
+  /// Athena algorithm's initalize hook
+  virtual StatusCode  initialize();
+
+  /// Athena algorithm's execute hook
+  virtual StatusCode  execute();
+
+  /// Athena algorithm's finalize hook
+  virtual StatusCode  finalize();
+
+
+private:
+  // The update handlers
+
+  /// This internal method will realize if a user sets the 'InputContainer' property
+  void setupInputContainer( Property& /*prop*/ );
+
+  /// This internal method will realize if a user sets the 'OutputContainer' property
+  void setupOutputContainer( Property& /*prop*/ );
+
+  /// This internal method will realize if a user sets the 'OutputContainerType' property
+  void setupOutputContainerType( Property& /*prop*/ );
+
+  /// This internal method will realize if a user sets the 'OutputContainerOwnershipPolicy' property
+  void setupOutputContainerOwnPolicy( Property& /*prop*/ );
+
+  /// This internal method will realize if a user sets the 'OutputLinkContainer' property
+  void setupOutputLinkContainer( Property& /*prop*/ );
+
+  /// This internal method will realize if a user sets the 'Selection' property
+  void setupSelection( Property& /*prop*/ );
+
+
+  ///////////////////////////////////////////////////////////////////
+  // Private data:
+  ///////////////////////////////////////////////////////////////////
+ private:
+  /// The job options service (will be used to forward this algs properties to
+  /// the private tool)
+  ServiceHandle<IJobOptionsSvc> m_jos;
+
+  /// The ToolHandle to the SkimmingTool
+  ToolHandle<DerivationFramework::IAugmentationTool> m_tool;
+
+  /// Input container name
+  StringProperty m_inCollKey;
+
+  /// This boolean is true if the user sets the 'InputContainer' property
+  bool m_setInCollKey;
+
+
+  /// Output collection name (deep copies of the original ones)
+  StringProperty m_outCollKey;
+
+  /// This boolean is true if the user sets the 'OutputContainer' property
+  bool m_setOutCollKey;
+
+
+  /// The type of the output container, e.g., 'xAOD::JetContainer'
+  StringProperty m_outCollType;
+
+  /// This boolean is true if the user sets the 'OutputContainerType' property
+  bool m_setOutCollType;
+
+
+  /// Defines the ownership policy of the output container
+  /// (default: 'OWN_ELEMENTS'; also allowed: 'VIEW_ELEMENTS')"
+  StringProperty m_outOwnPolicyName;
+
+  /// This boolean is true if the user sets the 'OutputContainerOwnershipPolicy' property
+  bool m_setOwnPolicy;
+
+
+  /// Output link collection name (ElementLinks to selected IParticles)
+  StringProperty m_outLinkCollKey;
+
+  /// This boolean is true if the user sets the 'OutputLinkContainer' property
+  bool m_setOutLinkCollKey;
+
+
+  /// The selection string that will select which xAOD::IParticles to keep from
+  /// an xAOD::IParticleContainer
+  StringProperty m_selection;
+
+  /// This boolean is true if the user sets the 'Selection' property
+  bool m_setSelection;
+
+
+
+  /// Internal event counter
+  unsigned long m_nEventsProcessed;
+
+
+};
+
+// I/O operators
+//////////////////////
+
+///////////////////////////////////////////////////////////////////
+// Inline methods:
+///////////////////////////////////////////////////////////////////
+
+/// This internal method will realize if a user sets the 'InputContainer' property
+inline void ParticleSelectionAlg::setupInputContainer( Property& /*prop*/ ) {
+  m_setInCollKey = true;
+  return;
+}
+
+/// This internal method will realize if a user sets the 'OutputContainer' property
+inline void ParticleSelectionAlg::setupOutputContainer( Property& /*prop*/ ) {
+  m_setOutCollKey = true;
+  return;
+}
+
+/// This internal method will realize if a user sets the 'OutputContainerType' property
+inline void ParticleSelectionAlg::setupOutputContainerType( Property& /*prop*/ ) {
+  m_setOutCollType = true;
+  return;
+}
+
+/// This internal method will realize if a user sets the 'OutputContainerOwnPolicy' property
+inline void ParticleSelectionAlg::setupOutputContainerOwnPolicy( Property& /*prop*/ ) {
+  m_setOwnPolicy = true;
+  return;
+}
+
+/// This internal method will realize if a user sets the 'OutputLinkContainer' property
+inline void ParticleSelectionAlg::setupOutputLinkContainer( Property& /*prop*/ ) {
+  m_setOutLinkCollKey = true;
+  return;
+}
+
+/// This internal method will realize if a user sets the 'Selection' property
+inline void ParticleSelectionAlg::setupSelection( Property& /*prop*/ ) {
+  m_setSelection = true;
+  return;
+}
+
+
+
+
+#endif //> !EVENTUTILS_PARTICLESELECTIONALG_H
diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSelectionTool.cxx b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSelectionTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..1b202576ff393ba8a3f9f0d69c835974c92c35ee
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSelectionTool.cxx
@@ -0,0 +1,570 @@
+///////////////////////// -*- C++ -*- /////////////////////////////
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// ParticleSelectionTool.cxx
+// Implementation file for class ParticleSelectionTool
+// Author: Karsten Koeneke <karsten.koeneke@cern.ch>
+///////////////////////////////////////////////////////////////////
+
+
+// EventUtils includes
+#include "ParticleSelectionTool.h"
+
+// STL includes
+#include <vector>
+#include <string>
+
+// FrameWork includes
+#include "ExpressionEvaluation/ExpressionParser.h"
+#include "TrigDecisionTool/TrigDecisionTool.h"
+#include "ExpressionEvaluation/TriggerDecisionProxyLoader.h"
+#include "ExpressionEvaluation/SGxAODProxyLoader.h"
+#include "ExpressionEvaluation/SGNTUPProxyLoader.h"
+#include "ExpressionEvaluation/MultipleProxyLoader.h"
+#include "ExpressionEvaluation/StackElement.h"
+
+// EDM includes
+#include "AthLinks/ElementLink.h"
+#include "xAODBase/IParticle.h"
+#include "xAODBase/IParticleContainer.h"
+#include "xAODParticleEvent/IParticleLink.h"
+#include "xAODParticleEvent/IParticleLinkContainer.h"
+#include "xAODMuon/Muon.h"
+#include "xAODMuon/MuonContainer.h"
+#include "xAODMuon/MuonAuxContainer.h"
+#include "xAODJet/Jet.h"
+#include "xAODJet/JetContainer.h"
+#include "xAODJet/JetAuxContainer.h"
+#include "xAODEgamma/Electron.h"
+#include "xAODEgamma/ElectronContainer.h"
+#include "xAODEgamma/ElectronAuxContainer.h"
+#include "xAODEgamma/Photon.h"
+#include "xAODEgamma/PhotonContainer.h"
+#include "xAODEgamma/PhotonAuxContainer.h"
+#include "xAODTau/TauJet.h"
+#include "xAODTau/TauJetContainer.h"
+#include "xAODTau/TauJetAuxContainer.h"
+#include "xAODPFlow/PFO.h"
+#include "xAODPFlow/PFOContainer.h"
+#include "xAODPFlow/PFOAuxContainer.h"
+#include "xAODTracking/NeutralParticle.h"
+#include "xAODTracking/NeutralParticleContainer.h"
+#include "xAODTracking/NeutralParticleAuxContainer.h"
+#include "xAODTracking/TrackParticle.h"
+#include "xAODTracking/TrackParticleContainer.h"
+#include "xAODTracking/TrackParticleAuxContainer.h"
+#include "xAODTruth/TruthParticle.h"
+#include "xAODTruth/TruthParticleContainer.h"
+#include "xAODTruth/TruthParticleAuxContainer.h"
+#include "xAODParticleEvent/CompositeParticle.h"
+#include "xAODParticleEvent/CompositeParticleContainer.h"
+#include "xAODParticleEvent/CompositeParticleAuxContainer.h"
+#include "xAODParticleEvent/Particle.h"
+#include "xAODParticleEvent/ParticleContainer.h"
+#include "xAODParticleEvent/ParticleAuxContainer.h"
+#include "xAODCaloEvent/CaloCluster.h"
+#include "xAODCaloEvent/CaloClusterContainer.h"
+#include "xAODCaloEvent/CaloClusterAuxContainer.h"
+
+
+
+///////////////////////////////////////////////////////////////////
+// Public methods:
+///////////////////////////////////////////////////////////////////
+
+// Constructors
+////////////////
+ParticleSelectionTool::ParticleSelectionTool( const std::string& type,
+                                              const std::string& name,
+                                              const IInterface* parent ) :
+  ::AthAlgTool  ( type, name, parent ),
+  m_trigDecisionTool("Trig::TrigDecisionTool/TrigDecisionTool"),
+  m_parser(0),
+  m_inCollKey(""),
+  m_outCollKey(""),
+  m_outCollType(""),
+  m_outLinkCollKey(""),
+  m_selection(""),
+  m_contID(0),
+  m_nEventsProcessed(0)
+{
+  declareInterface< DerivationFramework::IAugmentationTool >(this);
+
+  declareProperty("InputContainer",      m_inCollKey="",   "Input container name" );
+
+  declareProperty("OutputContainer",     m_outCollKey="",
+                  "The name of the output container with the copy of the selected xAOD::IParticles" );
+
+  declareProperty("OutputContainerType", m_outCollType="",
+                  "The type of the output container, e.g., 'xAOD::JetContainer'" );
+
+  declareProperty("OutputContainerOwnershipPolicy", m_outOwnPolicyName="OWN_ELEMENTS",
+                  "Defines the ownership policy of the output container (default: 'OWN_ELEMENTS'; also allowed: 'VIEW_ELEMENTS')" );
+
+  declareProperty("OutputLinkContainer", m_outLinkCollKey="",
+                  "The name of the output container of ElementLinks to the selected xAOD::IParticles" );
+
+  declareProperty("Selection",           m_selection="",
+                  "The selection string that defines which xAOD::IParticles to select from the container" );
+}
+
+// Destructor
+///////////////
+ParticleSelectionTool::~ParticleSelectionTool()
+{}
+
+
+
+// Athena algtool's Hooks
+////////////////////////////
+StatusCode ParticleSelectionTool::initialize()
+{
+  ATH_MSG_DEBUG ("Initializing " << name() << "...");
+
+  // Print out the used configuration
+  ATH_MSG_DEBUG ( " using = " << m_inCollKey );
+  ATH_MSG_DEBUG ( " using = " << m_outCollKey );
+  ATH_MSG_DEBUG ( " using = " << m_outCollType );
+  ATH_MSG_DEBUG ( " using = " << m_outOwnPolicyName );
+  ATH_MSG_DEBUG ( " using = " << m_outLinkCollKey );
+  ATH_MSG_DEBUG ( " using = " << m_selection );
+
+
+  // initialize proxy loaders for expression parsing
+  ExpressionParsing::MultipleProxyLoader *proxyLoaders = new ExpressionParsing::MultipleProxyLoader();
+  proxyLoaders->push_back(new ExpressionParsing::TriggerDecisionProxyLoader(m_trigDecisionTool));
+  proxyLoaders->push_back(new ExpressionParsing::SGxAODProxyLoader(evtStore()));
+  proxyLoaders->push_back(new ExpressionParsing::SGNTUPProxyLoader(evtStore()));
+
+  // load the expressions
+  m_parser = new ExpressionParsing::ExpressionParser(proxyLoaders);
+  m_parser->loadExpression( m_selection.value() );
+
+  // initialize the counters
+  m_contID = 0;
+  m_nEventsProcessed = 0;
+
+  // Determine the output container type
+  if ( !(m_outCollType.value().empty()) ) {
+    if ( m_outCollType.value() == "xAOD::MuonContainer" ) { m_contID = 1; }
+    else if ( m_outCollType.value() == "xAOD::JetContainer" ) { m_contID = 2; }
+    else if ( m_outCollType.value() == "xAOD::ElectronContainer" ) { m_contID = 3; }
+    else if ( m_outCollType.value() == "xAOD::PhotonContainer" ) { m_contID = 4; }
+    else if ( m_outCollType.value() == "xAOD::TauJetContainer" ) { m_contID = 5; }
+    else if ( m_outCollType.value() == "xAOD::PFOContainer" ) { m_contID = 6; }
+    else if ( m_outCollType.value() == "xAOD::NeutralParticleContainer" ) { m_contID = 7; }
+    else if ( m_outCollType.value() == "xAOD::TrackParticleContainer" ) { m_contID = 8; }
+    else if ( m_outCollType.value() == "xAOD::TruthParticleContainer" ) { m_contID = 9; }
+    else if ( m_outCollType.value() == "xAOD::CompositeParticleContainer" ) { m_contID = 10; }
+    else if ( m_outCollType.value() == "xAOD::ParticleContainer" ) { m_contID = 11; }
+    else if ( m_outCollType.value() == "xAOD::CaloClusterContainer" ) { m_contID = 12; }
+    else {
+      ATH_MSG_WARNING("I got a non-empty string for the OutputContainerType property "
+                      << "with value " << m_outCollType.value()
+                      << " which I don't understand. Possible values are: "
+                      << "'xAOD::MuonContainer', "
+                      << "'xAOD::JetContainer', "
+                      << "'xAOD::ElectronContainer', "
+                      << "'xAOD::PhotonContainer', "
+                      << "'xAOD::TauJetContainer', "
+                      << "'xAOD::PFOContainer', "
+                      << "'xAOD::NeutralParticleContainer', "
+                      << "'xAOD::TrackParticleContainer', "
+                      << "'xAOD::TruthParticleContainer', "
+                      << "'xAOD::CompositeParticleContainer', "
+                      << "'xAOD::ParticleContainer', "
+                      << "'xAOD::CaloClusterContainer'" );
+    }
+  }
+
+  // Determine the ownership policy of the output container
+  if ( m_outOwnPolicyName.value() == "OWN_ELEMENTS" ) {
+    m_outOwnPolicy = SG::OWN_ELEMENTS;
+  }
+  else if ( m_outOwnPolicyName.value() == "VIEW_ELEMENTS" ) {
+    m_outOwnPolicy = SG::VIEW_ELEMENTS;
+  }
+  else {
+    ATH_MSG_ERROR("Unrecognized ownership policy for the output container: " << m_outOwnPolicyName );
+    return StatusCode::FAILURE;
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+
+
+
+StatusCode ParticleSelectionTool::finalize()
+{
+  ATH_MSG_DEBUG ("Finalizing " << name() << "...");
+
+  if (m_parser) {
+    delete m_parser;
+    m_parser = 0;
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+
+
+
+StatusCode ParticleSelectionTool::addBranches() const
+{
+  // Increase the event counter
+  ++m_nEventsProcessed;
+
+  // Simple status message at the beginning of each event execute,
+  ATH_MSG_DEBUG ( "==> addBranches " << name() << " on " << m_nEventsProcessed << ". event..." );
+
+  //-----------------------------------------
+  // The meat happens here
+  //-----------------------------------------
+  ExpressionParsing::StackElement selectionResult = m_parser->evaluate();
+
+  if ( selectionResult.isScalar() ) {
+    ATH_MSG_ERROR( "We are expecting a vector result such that we can deduct "
+                   << "which xAOD::IParticle inside the container passes and which doesn't. "
+                   << "For example: 'Muons.pt>10*GeV', but NOT 'count(Muons.pt>10*GeV)>1'; here, "
+                   << "the former gives us a boolean answer for every muon while "
+                   << "the later gives us a boolean answer for the whole container of muons." );
+    return StatusCode::FAILURE;
+  }
+
+  if ( selectionResult.isVector() ) {
+    // We found a vector. Now, we can go ahead and retrieve the input container
+    // and book the output container(s)
+    const std::vector<int>& resultVec( selectionResult.vectorValue<int>() );
+
+
+    // Get the input container and create the output containers
+    const xAOD::IParticleLinkContainer* inLinkContainer(0);
+    const xAOD::IParticleContainer* inContainer(0);
+    xAOD::IParticleLinkContainer* outLinkContainer(0);
+
+    // Prepare all containers as needed
+    ATH_CHECK( this->prepareContainers( inLinkContainer,
+                                        inContainer,
+                                        outLinkContainer ) );
+
+
+    // Check that the lengths are the same
+    if ( inLinkContainer && inLinkContainer->size() != resultVec.size() ) {
+      ATH_MSG_ERROR("We got an input link container, but its size (" << inLinkContainer->size()
+                    << ") doesn't match the size of the result vector: " << resultVec.size() );
+      return StatusCode::FAILURE;
+    }
+    if ( inContainer && inContainer->size() != resultVec.size() ) {
+      ATH_MSG_ERROR("We got an input container, but its size (" << inContainer->size()
+                    << ") doesn't match the size of the result vector: " << resultVec.size() );
+      return StatusCode::FAILURE;
+    }
+
+
+
+
+    // Actually, evaluate the result
+    ATH_CHECK( this->evaluate( resultVec, inLinkContainer, inContainer, outLinkContainer ) );
+
+
+  }
+  else {
+    // what we found in the event store is neither a scalar nor a vector
+    // it must be of some awkward type that can't be used.
+    // Therefore, we fail
+    ATH_MSG_ERROR ("Some unexpected format of the expression parser result");
+    return StatusCode::FAILURE;
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+
+
+
+StatusCode
+ParticleSelectionTool::prepareContainers( const xAOD::IParticleLinkContainer*& inLinkContainer,
+                                          const xAOD::IParticleContainer*& inContainer,
+                                          xAOD::IParticleLinkContainer*& outLinkContainer ) const
+{
+  if ( evtStore()->contains< xAOD::IParticleLinkContainer >( m_inCollKey ) ) {
+    // Actually retrieve the LinkContainer from StoreGate
+    ATH_CHECK( evtStore()->retrieve( inLinkContainer , m_inCollKey ) );
+    ATH_MSG_DEBUG ( "Input link collection = '" << m_inCollKey
+                    << "' retrieved from StoreGate which has " << inLinkContainer->size() << " entries." );
+  }
+  else if ( evtStore()->contains< xAOD::IParticleContainer >( m_inCollKey ) ) {
+    // This container holds an xAOD::IParticleContainer
+    ATH_CHECK( evtStore()->retrieve( inContainer, m_inCollKey ) );
+    ATH_MSG_DEBUG ( "Input collection = " << m_inCollKey
+                    << " retrieved from StoreGate which has " << inContainer->size() << " entries." );
+  }
+  else {
+    if ( m_nEventsProcessed <= 10 ) {
+      ATH_MSG_WARNING ( "Input collection  = " << m_inCollKey
+                        << " could not be retrieved from StoreGate! "
+                        << " This message will only be repeated 10 times..." );
+    }
+    else {
+      ATH_MSG_DEBUG ( "Input collection  = " << m_inCollKey
+                      << " could not be retrieved from StoreGate! " );
+    }
+    return StatusCode::SUCCESS;
+  } // End: if/elif/else is link container
+
+
+  // Create the IParticleLinkContainer for the output, if requested
+  if ( !(m_outLinkCollKey.value().empty()) ) {
+    outLinkContainer = new xAOD::IParticleLinkContainer();
+    ATH_CHECK( evtStore()->record( outLinkContainer, m_outLinkCollKey.value() ) );
+    ATH_MSG_DEBUG( "Recorded xAOD::IParticleLinkContainer with key: "<< m_outLinkCollKey.value() );
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+
+// Define a pre-processor macro to easily create the new output containers.
+// First, create all needed zero pointers.
+// Second, create the output container and record it in StoreGate.
+// Finally, try to figure out the most derived type of the input container and
+// create the xAOD container and its auxiliary store:
+#define CREATE_OUT_CONTAINERS( CONTAINERTYPE, AUXCONTAINERTYPE,                                  \
+                               INCONTAINERNAME, OUTCONTAINERNAME, CONTID )                       \
+  const CONTAINERTYPE* INCONTAINERNAME(0);                                                       \
+  CONTAINERTYPE*  OUTCONTAINERNAME(0);                                                           \
+  if ( (m_contID==0 || m_contID==CONTID) && !(m_outCollKey.value().empty())  ) {                 \
+    if ( inContainer ) {                                                                         \
+      ATH_MSG_VERBOSE("Trying to cast input container to type const "#CONTAINERTYPE"*" );        \
+      INCONTAINERNAME = dynamic_cast<const CONTAINERTYPE*>(inContainer);                         \
+      if ( INCONTAINERNAME ) {                                                                   \
+        ATH_MSG_VERBOSE("Successfully casted input container to type const "#CONTAINERTYPE"*" ); \
+        OUTCONTAINERNAME = new CONTAINERTYPE( m_outOwnPolicy );                                  \
+        ATH_CHECK( evtStore()->record ( OUTCONTAINERNAME, m_outCollKey.value() ) );              \
+        if ( m_outOwnPolicy == SG::OWN_ELEMENTS ) {                                              \
+          AUXCONTAINERTYPE* outAuxContainer = new AUXCONTAINERTYPE();                            \
+          ATH_CHECK( evtStore()->record( outAuxContainer, m_outCollKey.value() + "Aux." ) );     \
+          OUTCONTAINERNAME->setStore( outAuxContainer );                                         \
+        }                                                                                        \
+        m_contID=CONTID;                                                                         \
+        ATH_MSG_DEBUG( "Recorded "#CONTAINERTYPE" with key: " << m_outCollKey.value()            \
+                       << ", container identifier " << m_contID                                  \
+                       << " and address " << OUTCONTAINERNAME );                                 \
+      }                                                                                          \
+      else {                                                                                     \
+        ATH_MSG_DEBUG("Couldn't cast input container to type const "#CONTAINERTYPE"*" );         \
+      }                                                                                          \
+    }                                                                                            \
+    else if ( inLinkContainer && m_contID==CONTID ) {                                            \
+      OUTCONTAINERNAME = new CONTAINERTYPE( m_outOwnPolicy );                                    \
+      ATH_CHECK( evtStore()->record ( OUTCONTAINERNAME, m_outCollKey.value() ) );                \
+      if ( m_outOwnPolicy == SG::OWN_ELEMENTS ) {                                                \
+        AUXCONTAINERTYPE* outAuxContainer = new AUXCONTAINERTYPE();                              \
+        ATH_CHECK( evtStore()->record( outAuxContainer, m_outCollKey.value() + "Aux." ) );       \
+        OUTCONTAINERNAME->setStore( outAuxContainer );                                           \
+      }                                                                                          \
+      m_contID=CONTID;                                                                           \
+      ATH_MSG_DEBUG( "Recorded "#CONTAINERTYPE" with key: " << m_outCollKey.value()              \
+                     << ", container identifier " << m_contID                                    \
+                     << " and address " << OUTCONTAINERNAME );                                   \
+    }                                                                                            \
+  }
+
+
+
+// Fill the output container, if requested
+#define FILL_OUT_CONTAINER( CONTAINERTYPE, PARTICLETYPE,                                       \
+                            INCONTAINERNAME, OUTCONTAINERNAME )                                \
+  if ( OUTCONTAINERNAME ) {                                                                    \
+    if ( inLinkContainer ) {                                                                   \
+      ATH_MSG_VERBOSE(" Going to fill output container of type "#CONTAINERTYPE" from link input" ); \
+      const xAOD::IParticleLink& partLink = inLinkContainer->at(i);                            \
+      if ( partLink.isValid() ) {                                                              \
+        const PARTICLETYPE* partPtr = dynamic_cast<const PARTICLETYPE*>(*partLink);            \
+        if (partPtr) {                                                                         \
+          if ( m_outOwnPolicy == SG::OWN_ELEMENTS ) {                                          \
+            PARTICLETYPE* newPart = new PARTICLETYPE();                                        \
+            newPart->makePrivateStore(*partPtr);                                               \
+            OUTCONTAINERNAME->push_back( newPart );                                            \
+          }                                                                                    \
+          else {                                                                               \
+            OUTCONTAINERNAME->push_back( const_cast<PARTICLETYPE*>(partPtr) );                 \
+          }                                                                                    \
+          ATH_MSG_VERBOSE("Adding an "#PARTICLETYPE" to the output "                           \
+                          "from the input xAOD::IParticleLinkContainer");                      \
+        }                                                                                      \
+        else {                                                                                 \
+          ATH_MSG_WARNING("Couldn't cast to a "#PARTICLETYPE". This should NOT happen!");      \
+        }                                                                                      \
+      }                                                                                        \
+      else {                                                                                   \
+        ATH_MSG_WARNING("Couldn't add an xAOD::IParticle to the output "                       \
+                        << "because the input ElementLink is not valid!");                     \
+      }                                                                                        \
+    }                                                                                          \
+    if ( INCONTAINERNAME ) {                                                                   \
+      ATH_MSG_VERBOSE(" Going to fill output container of type "#CONTAINERTYPE" from input" ); \
+      const PARTICLETYPE* partPtr = INCONTAINERNAME->at(i);                                    \
+      if ( m_outOwnPolicy == SG::OWN_ELEMENTS ) {                                              \
+        PARTICLETYPE* newPart = new PARTICLETYPE();                                            \
+        newPart->makePrivateStore(*partPtr);                                                   \
+        OUTCONTAINERNAME->push_back( newPart );                                                \
+      }                                                                                        \
+      else {                                                                                   \
+        OUTCONTAINERNAME->push_back( const_cast<PARTICLETYPE*>(partPtr) );                     \
+      }                                                                                        \
+      ATH_MSG_VERBOSE("Adding an "#PARTICLETYPE" to the output "                               \
+                      "from the input "#CONTAINERTYPE );                                       \
+    }                                                                                          \
+  } /* End: if ( outContainer ) */
+
+
+
+
+
+StatusCode
+ParticleSelectionTool::evaluate( const std::vector<int>& resultVec,
+                                 const xAOD::IParticleLinkContainer* inLinkContainer,
+                                 const xAOD::IParticleContainer* inContainer,
+                                 xAOD::IParticleLinkContainer* outLinkContainer  ) const
+{
+  // See if we already found the right container type
+  CREATE_OUT_CONTAINERS( xAOD::MuonContainer, xAOD::MuonAuxContainer,
+                         muonInCont, muonOutContainer, 1 )
+  CREATE_OUT_CONTAINERS( xAOD::JetContainer, xAOD::JetAuxContainer,
+                         jetInCont, jetOutContainer, 2 )
+  CREATE_OUT_CONTAINERS( xAOD::ElectronContainer, xAOD::ElectronAuxContainer,
+                         electronInCont, electronOutContainer, 3 )
+  CREATE_OUT_CONTAINERS( xAOD::PhotonContainer, xAOD::PhotonAuxContainer,
+                         photonInCont, photonOutContainer, 4 )
+  CREATE_OUT_CONTAINERS( xAOD::TauJetContainer, xAOD::TauJetAuxContainer,
+                         tauJetInCont, tauJetOutContainer, 5 )
+  CREATE_OUT_CONTAINERS( xAOD::PFOContainer, xAOD::PFOAuxContainer,
+                         pfoInCont, pfoOutContainer, 6 )
+  CREATE_OUT_CONTAINERS( xAOD::NeutralParticleContainer, xAOD::NeutralParticleAuxContainer,
+                         neutralParticleInCont, neutralParticleOutContainer, 7 )
+  CREATE_OUT_CONTAINERS( xAOD::TrackParticleContainer, xAOD::TrackParticleAuxContainer,
+                         trackParticleInCont, trackParticleOutContainer, 8 )
+  CREATE_OUT_CONTAINERS( xAOD::TruthParticleContainer, xAOD::TruthParticleAuxContainer,
+                         truthParticleInCont, truthParticleOutContainer, 9 )
+  CREATE_OUT_CONTAINERS( xAOD::CompositeParticleContainer, xAOD::CompositeParticleAuxContainer,
+                         compositeParticleInCont, compositeParticleOutContainer, 10 )
+  CREATE_OUT_CONTAINERS( xAOD::ParticleContainer, xAOD::ParticleAuxContainer,
+                         particleInCont, particleOutContainer, 11 )
+  CREATE_OUT_CONTAINERS( xAOD::CaloClusterContainer, xAOD::CaloClusterAuxContainer,
+                         caloClusterInCont, caloClusterOutContainer, 12 )
+
+
+  // Now, loop over the result vector and check which particles to write out
+  for ( std::size_t i=0; i<resultVec.size(); ++i ) {
+    // If this particle is not accepted, go to the next one
+    if ( !(resultVec[i]) ) { continue; }
+
+    // Fill the output IParticleLinkContainer, if requested
+    if ( outLinkContainer ) {
+      ATH_MSG_VERBOSE("Going to fill output link container");
+      if ( inLinkContainer ) {
+        outLinkContainer->push_back( inLinkContainer->at(i) );
+        ATH_MSG_VERBOSE("Adding an xAOD::IParticleLink to the output "
+                        "from the input xAOD::IParticleLinkContainer");
+      }
+      if ( inContainer ) {
+        xAOD::IParticleLink partLink = xAOD::IParticleLink( *inContainer, i );
+        outLinkContainer->push_back( partLink );
+        ATH_MSG_VERBOSE("Adding an xAOD::IParticleLink to the output "
+                        "from the input xAOD::IParticleContainer");
+      }
+    } // End: if ( outLinkContainer )
+
+    if ( !(m_outCollKey.value().empty()) ) {
+      ATH_MSG_VERBOSE("Going to fill output container");
+      FILL_OUT_CONTAINER( xAOD::MuonContainer, xAOD::Muon,
+                          muonInCont, muonOutContainer )
+      FILL_OUT_CONTAINER( xAOD::JetContainer, xAOD::Jet,
+                          jetInCont, jetOutContainer )
+      FILL_OUT_CONTAINER( xAOD::ElectronContainer, xAOD::Electron,
+                          electronInCont, electronOutContainer )
+      FILL_OUT_CONTAINER( xAOD::PhotonContainer, xAOD::Photon,
+                          photonInCont, photonOutContainer )
+      FILL_OUT_CONTAINER( xAOD::TauJetContainer, xAOD::TauJet,
+                          tauJetInCont, tauJetOutContainer )
+      FILL_OUT_CONTAINER( xAOD::PFOContainer, xAOD::PFO,
+                          pfoInCont, pfoOutContainer )
+      FILL_OUT_CONTAINER( xAOD::NeutralParticleContainer, xAOD::NeutralParticle,
+                          neutralParticleInCont, neutralParticleOutContainer )
+      FILL_OUT_CONTAINER( xAOD::TrackParticleContainer, xAOD::TrackParticle,
+                          trackParticleInCont, trackParticleOutContainer )
+      FILL_OUT_CONTAINER( xAOD::TruthParticleContainer, xAOD::TruthParticle,
+                          truthParticleInCont, truthParticleOutContainer )
+      FILL_OUT_CONTAINER( xAOD::CompositeParticleContainer, xAOD::CompositeParticle,
+                          compositeParticleInCont, compositeParticleOutContainer )
+      FILL_OUT_CONTAINER( xAOD::ParticleContainer, xAOD::Particle,
+                          particleInCont, particleOutContainer )
+      FILL_OUT_CONTAINER( xAOD::CaloClusterContainer, xAOD::CaloCluster,
+                          caloClusterInCont, caloClusterOutContainer )
+    }
+
+  } // End: Loop over result vector (and input particle(link) vector)
+
+  // Some final debug messages
+  if ( !(m_outLinkCollKey.value().empty()) ) {
+    ATH_MSG_DEBUG("Output link container with name " << m_outLinkCollKey.value()
+                  << " has " << outLinkContainer->size() << " entries." );
+  }
+  if ( !(m_outCollKey.value().empty()) && msgLvl(MSG::DEBUG) ) {
+    if (muonOutContainer) {
+      ATH_MSG_DEBUG("Output container with name " << m_outCollKey.value()
+                    << " has " << muonOutContainer->size() << " entries." );
+    }
+    else if (jetOutContainer) {
+      ATH_MSG_DEBUG("Output container with name " << m_outCollKey.value()
+                    << " has " << jetOutContainer->size() << " entries." );
+    }
+    else if (electronOutContainer) {
+      ATH_MSG_DEBUG("Output container with name " << m_outCollKey.value()
+                    << " has " << electronOutContainer->size() << " entries." );
+    }
+    else if (photonOutContainer) {
+      ATH_MSG_DEBUG("Output container with name " << m_outCollKey.value()
+                    << " has " << photonOutContainer->size() << " entries." );
+    }
+    else if (tauJetOutContainer) {
+      ATH_MSG_DEBUG("Output container with name " << m_outCollKey.value()
+                    << " has " << tauJetOutContainer->size() << " entries." );
+    }
+    else if (pfoOutContainer) {
+      ATH_MSG_DEBUG("Output container with name " << m_outCollKey.value()
+                    << " has " << pfoOutContainer->size() << " entries." );
+    }
+    else if (neutralParticleOutContainer) {
+      ATH_MSG_DEBUG("Output container with name " << m_outCollKey.value()
+                    << " has " << neutralParticleOutContainer->size() << " entries." );
+    }
+    else if (trackParticleOutContainer) {
+      ATH_MSG_DEBUG("Output container with name " << m_outCollKey.value()
+                    << " has " << trackParticleOutContainer->size() << " entries." );
+    }
+    else if (truthParticleOutContainer) {
+      ATH_MSG_DEBUG("Output container with name " << m_outCollKey.value()
+                    << " has " << truthParticleOutContainer->size() << " entries." );
+    }
+    else if (compositeParticleOutContainer) {
+      ATH_MSG_DEBUG("Output container with name " << m_outCollKey.value()
+                    << " has " << compositeParticleOutContainer->size() << " entries." );
+    }
+    else if (particleOutContainer) {
+      ATH_MSG_DEBUG("Output container with name " << m_outCollKey.value()
+                    << " has " << particleOutContainer->size() << " entries." );
+    }
+    else if (caloClusterOutContainer) {
+      ATH_MSG_DEBUG("Output container with name " << m_outCollKey.value()
+                    << " has " << caloClusterOutContainer->size() << " entries." );
+    }
+  }
+
+  return StatusCode::SUCCESS;
+}
diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSelectionTool.h b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSelectionTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..69767598a1f6ad0a2694114bac1a858c70b3f4e7
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSelectionTool.h
@@ -0,0 +1,137 @@
+///////////////////////// -*- C++ -*- /////////////////////////////
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// ParticleSelectionTool.h
+// Header file for class ParticleSelectionTool
+// Author: Karsten Koeneke <karsten.koeneke@cern.ch>
+///////////////////////////////////////////////////////////////////
+#ifndef EVENTUTILS_PARTICLESELECTIONTOOL_H
+#define EVENTUTILS_PARTICLESELECTIONTOOL_H 1
+
+// STL includes
+#include <vector>
+#include <string>
+
+// FrameWork includes
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "DerivationFrameworkInterfaces/IAugmentationTool.h"
+#include "TrigDecisionTool/TrigDecisionTool.h"
+
+// EDM includes
+#include "AthContainers/OwnershipPolicy.h"
+#include "xAODBase/IParticleContainer.h"
+#include "xAODParticleEvent/IParticleLinkContainer.h"
+
+
+// Forward declarations
+namespace ExpressionParsing {
+  class ExpressionParser;
+}
+
+
+
+class ParticleSelectionTool
+  : virtual public ::DerivationFramework::IAugmentationTool,
+            public ::AthAlgTool
+{
+
+  ///////////////////////////////////////////////////////////////////
+  // Public methods:
+  ///////////////////////////////////////////////////////////////////
+public:
+
+  // Copy constructor:
+
+  /// Constructor with parameters:
+  ParticleSelectionTool( const std::string& type,
+                         const std::string& name,
+                         const IInterface* parent );
+
+  /// Destructor:
+  virtual ~ParticleSelectionTool();
+
+  /// Athena algtool's initialize
+  virtual StatusCode  initialize();
+
+  /// Athena algtool's finalize
+  virtual StatusCode  finalize();
+
+
+  /// Implement the method from the ISkimmingTool interface
+  virtual StatusCode addBranches() const final override;
+
+
+
+// Private methods
+private:
+
+  /// A helper method to get the input containers is and
+  /// create and record the output link container
+  StatusCode
+  prepareContainers( const xAOD::IParticleLinkContainer*& inLinkContainer,
+                     const xAOD::IParticleContainer*& inContainer,
+                     xAOD::IParticleLinkContainer*& outLinkContainer ) const;
+
+
+  /// Helper method to actually iterate over the input particles and selection
+  /// results and fill the output container(s)
+  StatusCode
+  evaluate( const std::vector<int>& resultVec,
+            const xAOD::IParticleLinkContainer* inLinkContainer,
+            const xAOD::IParticleContainer* inContainer,
+            xAOD::IParticleLinkContainer* outLinkContainer  ) const;
+
+
+  ///////////////////////////////////////////////////////////////////
+  // Private data:
+  ///////////////////////////////////////////////////////////////////
+private:
+  /// The trigger decision tool
+  ToolHandle<Trig::TrigDecisionTool> m_trigDecisionTool;
+
+  /// The expression parser
+  ExpressionParsing::ExpressionParser *m_parser;
+
+
+  /// Input container name
+  StringProperty m_inCollKey;
+
+  /// Output collection name (deep copies of the original ones)
+  StringProperty m_outCollKey;
+
+  /// The type of the output container, e.g., 'xAOD::JetContainer'
+  StringProperty m_outCollType;
+
+  /// Defines the ownership policy of the output container
+  /// (default: 'OWN_ELEMENTS'; also allowed: 'VIEW_ELEMENTS')"
+  StringProperty m_outOwnPolicyName;
+
+  /// The internally used translation for the ownership policy
+  SG::OwnershipPolicy m_outOwnPolicy;
+
+  /// Output link collection name (ElementLinks to selected IParticles)
+  StringProperty m_outLinkCollKey;
+
+  /// The cut string
+  StringProperty m_selection;
+
+
+  /// Internal container type identifier
+  mutable unsigned int m_contID;
+
+
+  /// Internal event counter
+  mutable unsigned long m_nEventsProcessed;
+
+
+};
+
+///////////////////////////////////////////////////////////////////
+// Inline methods:
+///////////////////////////////////////////////////////////////////
+
+
+#endif //> !EVENTUTILS_PARTICLESELECTIONTOOL_H
diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSortingAlg.cxx b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSortingAlg.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..5893e290a0bb4ef9c137547657076e11727ec052
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSortingAlg.cxx
@@ -0,0 +1,162 @@
+///////////////////////// -*- C++ -*- /////////////////////////////
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// ParticleSortingAlg.cxx
+// Implementation file for class ParticleSortingAlg
+// Author: Karsten Koeneke <karsten.koeneke@cern.ch>
+///////////////////////////////////////////////////////////////////
+
+// EventUtils includes
+#include "ParticleSortingAlg.h"
+
+// STL includes
+
+// FrameWork includes
+#include "GaudiKernel/Property.h"
+#include "GaudiKernel/IJobOptionsSvc.h"
+#include "DerivationFrameworkInterfaces/IAugmentationTool.h"
+
+
+
+///////////////////////////////////////////////////////////////////
+// Public methods:
+///////////////////////////////////////////////////////////////////
+
+// Constructors
+////////////////
+ParticleSortingAlg::ParticleSortingAlg( const std::string& name,
+                                        ISvcLocator* pSvcLocator ) :
+  ::AthAlgorithm( name, pSvcLocator ),
+  m_jos("JobOptionsSvc", name),
+  m_tool("ParticleSortingTool/ParticleSortingTool", this),
+  m_inCollKey(""),
+  m_setInCollKey(false),
+  m_outCollKey(""),
+  m_setOutCollKey(false),
+  m_sortVar("pt"),
+  m_setSortVar(false),
+  m_sortDecending(true),
+  m_setSortDecending(false),
+  m_nEventsProcessed(0)
+{
+  declareProperty("JobOptionsSvc",   m_jos, "The JobOptionService instance.");
+
+  declareProperty("SkimTool",        m_tool, "The private ParticleSortingTool" );
+
+  declareProperty("InputContainer",  m_inCollKey="",   "Input container name" );
+  m_inCollKey.declareUpdateHandler( &ParticleSortingAlg::setupInputContainer, this );
+
+  declareProperty("OutputContainer", m_outCollKey="",
+                  "The name of the output container with the sorted deep copy of input objects" );
+  m_outCollKey.declareUpdateHandler( &ParticleSortingAlg::setupOutputContainer, this );
+
+  declareProperty("SortVariable",    m_sortVar="pt",
+                  "Define by what parameter to sort (default: 'pt'; allowed: 'pt', 'eta', 'phi', 'm', 'e', 'rapidity')" );
+  m_sortVar.declareUpdateHandler( &ParticleSortingAlg::setupSortVar, this );
+
+  declareProperty("SortDecending",   m_sortDecending=true,
+                  "Define if the container should be sorted in a decending order (default=true)" );
+  m_sortDecending.declareUpdateHandler( &ParticleSortingAlg::setupSortDecending, this );
+}
+
+
+
+// Destructor
+///////////////
+ParticleSortingAlg::~ParticleSortingAlg()
+{}
+
+
+
+// Athena Algorithm's Hooks
+////////////////////////////
+StatusCode ParticleSortingAlg::initialize()
+{
+  ATH_MSG_DEBUG ("Initializing " << name() << "...");
+
+  // Print out the used configuration
+  ATH_MSG_DEBUG ( " using = " << m_jos );
+  ATH_MSG_DEBUG ( " using = " << m_tool );
+  ATH_MSG_DEBUG ( " using = " << m_inCollKey );
+  ATH_MSG_DEBUG ( " using = " << m_outCollKey );
+  ATH_MSG_DEBUG ( " using = " << m_sortVar );
+  ATH_MSG_DEBUG ( " using = " << m_sortDecending );
+
+
+  // Initialize the counters to zero
+  m_nEventsProcessed = 0 ;
+
+
+  // Get the JobOptionService
+  // We will use this to set the properties of our private skimming tool
+  // from the properties of this algorithm.
+  ATH_MSG_VERBOSE( "Getting the JobOptionService");
+  ATH_CHECK( m_jos.retrieve() );
+
+  // Get the full name of the private skimTool
+  ATH_MSG_VERBOSE( "Getting the full name of the tool");
+  const std::string& fullToolName = this->name() + "." + m_tool.name();
+  ATH_MSG_DEBUG( "Got the full name of the tool: " << fullToolName );
+
+  // Now, set all properties of the private skimTool that were acutally configured
+  if (m_setInCollKey) {
+    ATH_MSG_DEBUG( "Setting property" << m_inCollKey
+                   << " of private tool with name: '" << fullToolName << "'" );
+    ATH_CHECK( m_jos->addPropertyToCatalogue (fullToolName,m_inCollKey) );
+  }
+  if (m_setOutCollKey) {
+    ATH_MSG_DEBUG( "Setting property" << m_outCollKey
+                   << " of private tool with name: '" << fullToolName << "'" );
+    ATH_CHECK( m_jos->addPropertyToCatalogue (fullToolName,m_outCollKey) );
+  }
+  if (m_setSortVar) {
+    ATH_MSG_DEBUG( "Setting property" << m_sortVar
+                   << " of private tool with name: '" << fullToolName << "'" );
+    ATH_CHECK( m_jos->addPropertyToCatalogue (fullToolName,m_sortVar) );
+  }
+  if (m_setSortDecending) {
+    ATH_MSG_DEBUG( "Setting property" << m_sortDecending
+                   << " of private tool with name: '" << fullToolName << "'" );
+    ATH_CHECK( m_jos->addPropertyToCatalogue (fullToolName,m_sortDecending) );
+  }
+  ATH_MSG_DEBUG( "Done setting properties of the tool");
+
+  // Get the skimming tool
+  ATH_CHECK( m_tool.retrieve() );
+
+  ATH_MSG_DEBUG ( "==> done with initialize " << name() << "..." );
+
+  return StatusCode::SUCCESS;
+}
+
+
+
+StatusCode ParticleSortingAlg::finalize()
+{
+  ATH_MSG_DEBUG ("Finalizing " << name() << "...");
+
+  // Release all tools and services
+  ATH_CHECK( m_jos.release() );
+  ATH_CHECK( m_tool.release() );
+
+  return StatusCode::SUCCESS;
+}
+
+
+
+StatusCode ParticleSortingAlg::execute()
+{
+  // Increase the event counter
+  ++m_nEventsProcessed;
+
+  // Simple status message at the beginning of each event execute,
+  ATH_MSG_DEBUG ( "==> execute " << name() << " on " << m_nEventsProcessed << ". event..." );
+
+  // Call the tool
+  ATH_CHECK( m_tool->addBranches() );
+
+  return StatusCode::SUCCESS;
+}
diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSortingAlg.h b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSortingAlg.h
new file mode 100644
index 0000000000000000000000000000000000000000..b07ac4afb0c233fd38ad16858f26e98dccd56d99
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSortingAlg.h
@@ -0,0 +1,153 @@
+///////////////////////// -*- C++ -*- /////////////////////////////
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// ParticleSortingAlg.h
+// Header file for class ParticleSortingAlg
+// Author: Karsten Koeneke <karsten.koeneke@cern.ch>
+///////////////////////////////////////////////////////////////////
+#ifndef EVENTUTILS_PARTICLESORTINGALG_H
+#define EVENTUTILS_PARTICLESORTINGALG_H 1
+
+// STL includes
+#include <string>
+
+// FrameWork includes
+#include "GaudiKernel/ToolHandle.h"
+#include "GaudiKernel/ServiceHandle.h"
+#include "AthenaBaseComps/AthAlgorithm.h"
+
+
+// forward declarations
+class IJobOptionsSvc;
+namespace DerivationFramework {
+  class IAugmentationTool;
+}
+
+
+
+
+class ParticleSortingAlg
+  : public ::AthAlgorithm
+{
+
+  ///////////////////////////////////////////////////////////////////
+  // Public methods:
+  ///////////////////////////////////////////////////////////////////
+ public:
+
+  // Copy constructor:
+
+  /// Constructor with parameters:
+  ParticleSortingAlg( const std::string& name, ISvcLocator* pSvcLocator );
+
+  /// Destructor:
+  virtual ~ParticleSortingAlg();
+
+  /// Athena algorithm's initalize hook
+  virtual StatusCode  initialize();
+
+  /// Athena algorithm's execute hook
+  virtual StatusCode  execute();
+
+  /// Athena algorithm's finalize hook
+  virtual StatusCode  finalize();
+
+
+private:
+  // The update handlers
+
+  /// This internal method will realize if a user sets the 'InputContainer' property
+  void setupInputContainer( Property& /*prop*/ );
+
+  /// This internal method will realize if a user sets the 'OutputContainer' property
+  void setupOutputContainer( Property& /*prop*/ );
+
+  /// This internal method will realize if a user sets the 'SortVariable' property
+  void setupSortVar( Property& /*prop*/ );
+
+  /// This internal method will realize if a user sets the 'SortDeceding' property
+  void setupSortDecending( Property& /*prop*/ );
+
+
+
+  ///////////////////////////////////////////////////////////////////
+  // Private data:
+  ///////////////////////////////////////////////////////////////////
+ private:
+  /// The job options service (will be used to forward this algs properties to
+  /// the private tool)
+  ServiceHandle<IJobOptionsSvc> m_jos;
+
+  /// The ToolHandle to the private ParticleSortingTool
+  ToolHandle<DerivationFramework::IAugmentationTool> m_tool;
+
+  /// Input container name
+  StringProperty m_inCollKey;
+
+  /// This boolean is true if the user sets the 'InputContainer' property
+  bool m_setInCollKey;
+
+
+  /// Output collection name (deep copies of the original ones)
+  StringProperty m_outCollKey;
+
+  /// This boolean is true if the user sets the 'OutputContainer' property
+  bool m_setOutCollKey;
+
+
+  /// Define by what parameter to sort (default: 'pt')
+  StringProperty m_sortVar;
+
+  /// This boolean is true if the user sets the 'SortVariable' property
+  bool m_setSortVar;
+
+
+  /// Define if the container should be sorted in a decending order (default=true)
+  BooleanProperty m_sortDecending;
+
+  /// This boolean is true if the user sets the 'SortDecending' property
+  bool m_setSortDecending;
+
+
+  /// Internal event counter
+  unsigned long m_nEventsProcessed;
+
+};
+
+
+
+///////////////////////////////////////////////////////////////////
+// Inline methods:
+///////////////////////////////////////////////////////////////////
+
+/// This internal method will realize if a user sets the 'InputContainer' property
+inline void ParticleSortingAlg::setupInputContainer( Property& /*prop*/ ) {
+  m_setInCollKey = true;
+  return;
+}
+
+/// This internal method will realize if a user sets the 'OutputContainer' property
+inline void ParticleSortingAlg::setupOutputContainer( Property& /*prop*/ ) {
+  m_setOutCollKey = true;
+  return;
+}
+
+/// This internal method will realize if a user sets the 'SortVariable' property
+inline void ParticleSortingAlg::setupSortVar( Property& /*prop*/ )
+{
+  m_setSortVar = true;
+  return;
+}
+
+/// This internal method will realize if a user sets the 'SortDeceding' property
+inline void ParticleSortingAlg::setupSortDecending( Property& /*prop*/ )
+{
+  m_setSortDecending = true;
+  return;
+}
+
+
+#endif //> !EVENTUTILS_PARTICLESORTINGALG_H
diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSortingTool.cxx b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSortingTool.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..8e38247f585d16ea507d693bc034e40a9bfec89b
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSortingTool.cxx
@@ -0,0 +1,269 @@
+///////////////////////// -*- C++ -*- /////////////////////////////
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// ParticleSortingTool.cxx
+// Implementation file for class ParticleSortingTool
+// Author: Karsten Koeneke <karsten.koeneke@cern.ch>
+///////////////////////////////////////////////////////////////////
+
+
+// EventUtils includes
+#include "ParticleSortingTool.h"
+
+// STL includes
+#include <vector>
+#include <string>
+
+// FrameWork includes
+
+// EDM includes
+#include "xAODBase/IParticle.h"
+#include "xAODBase/IParticleContainer.h"
+#include "xAODMuon/MuonContainer.h"
+#include "xAODJet/JetContainer.h"
+#include "xAODEgamma/ElectronContainer.h"
+#include "xAODEgamma/PhotonContainer.h"
+#include "xAODTau/TauJetContainer.h"
+#include "xAODPFlow/PFOContainer.h"
+#include "xAODTracking/NeutralParticleContainer.h"
+#include "xAODTracking/TrackParticleContainer.h"
+#include "xAODTruth/TruthParticleContainer.h"
+#include "xAODParticleEvent/CompositeParticleContainer.h"
+#include "xAODParticleEvent/ParticleContainer.h"
+#include "xAODCaloEvent/CaloClusterContainer.h"
+
+
+
+// Constructors
+////////////////
+ParticleSortingTool::ParticleSortingTool( const std::string& type,
+                                          const std::string& name,
+                                          const IInterface* parent ) :
+  ::AthAlgTool  ( type, name, parent ),
+  m_inCollKey(""),
+  m_outCollKey(""),
+  m_sortVar("pt"),
+  m_sortDecending(true),
+  m_contID(0),
+  m_sortID(0),
+  m_nEventsProcessed(0)
+{
+  declareInterface< DerivationFramework::IAugmentationTool >(this);
+
+  declareProperty("InputContainer",  m_inCollKey="",   "Input container name" );
+
+  declareProperty("OutputContainer", m_outCollKey="",
+                  "The name of the output container with the sorted deep copy of input objects" );
+
+  declareProperty("SortVariable",    m_sortVar="pt",
+                  "Define by what parameter to sort (default: 'pt'; allowed: 'pt', 'eta', 'phi', 'm', 'e', 'rapidity')" );
+
+  declareProperty("SortDecending",   m_sortDecending=true,
+                  "Define if the container should be sorted in a decending order (default=true)" );
+}
+
+
+// Destructor
+///////////////
+ParticleSortingTool::~ParticleSortingTool()
+{}
+
+
+
+// Athena algtool's Hooks
+////////////////////////////
+StatusCode ParticleSortingTool::initialize()
+{
+  ATH_MSG_DEBUG ("Initializing " << name() << "...");
+
+  // Print out the used configuration
+  ATH_MSG_DEBUG ( " using = " << m_inCollKey );
+  ATH_MSG_DEBUG ( " using = " << m_outCollKey );
+
+  // initialize the counters
+  m_contID           = 0;
+  m_sortID           = 0;
+  m_nEventsProcessed = 0;
+
+  // Figure out how to sort
+  if ( m_sortVar.value() == "pt" )            { m_sortID = 1; }
+  else if ( m_sortVar.value() == "eta" )      { m_sortID = 2; }
+  else if ( m_sortVar.value() == "phi" )      { m_sortID = 3; }
+  else if ( m_sortVar.value() == "m" )        { m_sortID = 4; }
+  else if ( m_sortVar.value() == "e" )        { m_sortID = 5; }
+  else if ( m_sortVar.value() == "rapidity" ) { m_sortID = 6; }
+  else {
+    ATH_MSG_ERROR("Didn't find a valid value for 'SortVariable'."
+                  << " Allowed values are: 'pt', 'eta', 'phi', 'm', 'e', 'rapidity'");
+    return StatusCode::FAILURE;
+  }
+  if ( m_sortDecending.value() ) { m_sortID *= -1; }
+
+  return StatusCode::SUCCESS;
+}
+
+
+
+
+StatusCode ParticleSortingTool::finalize()
+{
+  ATH_MSG_DEBUG ("Finalizing " << name() << "...");
+
+  return StatusCode::SUCCESS;
+}
+
+
+
+// Declare a short pre-processor macro to deal with the different container types
+#define COPY_AND_SORT_CONTAINER( CONTAINERTYPE )                                     \
+ATH_MSG_DEBUG("Trying to copy, sort, and record container of type "#CONTAINERTYPE ); \
+if ( evtStore()->contains<CONTAINERTYPE>( m_inCollKey.value() ) ) {                  \
+  const CONTAINERTYPE* inCont;                                                       \
+  ATH_CHECK( evtStore()->retrieve( inCont, m_inCollKey.value() ) );                  \
+  CONTAINERTYPE* outCont = new CONTAINERTYPE( SG::VIEW_ELEMENTS );                   \
+  *outCont = *inCont;                                                                \
+  ATH_CHECK( evtStore()->record ( outCont, m_outCollKey.value() ) );                 \
+  ATH_CHECK( this->doSort(outCont) );                                                \
+}
+
+
+
+
+StatusCode ParticleSortingTool::addBranches() const
+{
+  // Increase the event counter
+  ++m_nEventsProcessed;
+
+  // Simple status message at the beginning of each event execute,
+  ATH_MSG_DEBUG ( "==> addBranches " << name() << " on " << m_nEventsProcessed << ". event..." );
+
+  if ( m_outCollKey.value().empty() ) {
+    // Try to get the input container as non-const
+    ATH_MSG_DEBUG("Got an empty 'OutputCollection' property. "
+                  << "Trying to retrieve a non-const version of the 'InputContainer'...");
+    xAOD::IParticleContainer* inCont = evtStore()->tryRetrieve<xAOD::IParticleContainer>( m_inCollKey.value() );
+    ATH_CHECK( this->doSort(inCont) );
+  }
+  else {
+    ATH_MSG_DEBUG("Got a non-empty 'OutputCollection' property. "
+                  << "Trying to retrieve a const version of the 'InputContainer'...");
+
+    // Now, do the copy and sorting of all known container types
+    COPY_AND_SORT_CONTAINER(xAOD::MuonContainer);
+    COPY_AND_SORT_CONTAINER(xAOD::ElectronContainer);
+    COPY_AND_SORT_CONTAINER(xAOD::PhotonContainer);
+    COPY_AND_SORT_CONTAINER(xAOD::TauJetContainer);
+    COPY_AND_SORT_CONTAINER(xAOD::JetContainer);
+    COPY_AND_SORT_CONTAINER(xAOD::PFOContainer);
+    COPY_AND_SORT_CONTAINER(xAOD::NeutralParticleContainer);
+    COPY_AND_SORT_CONTAINER(xAOD::TrackParticleContainer);
+    COPY_AND_SORT_CONTAINER(xAOD::TruthParticleContainer);
+    COPY_AND_SORT_CONTAINER(xAOD::CompositeParticleContainer);
+    COPY_AND_SORT_CONTAINER(xAOD::ParticleContainer);
+    COPY_AND_SORT_CONTAINER(xAOD::CaloClusterContainer);
+
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+
+
+StatusCode ParticleSortingTool::doSort( xAOD::IParticleContainer* cont ) const
+{
+  if ( !cont ) {
+    ATH_MSG_ERROR("No container to be sorted");
+    return StatusCode::FAILURE;
+  }
+  // Actually do the sorting, using a C++11 lambda function construct
+  // to be able to use the member function here
+  if ( abs(m_sortID) == 1 ) {
+    cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) {
+                  return this->comparePt(a,b);
+                } );
+  }
+  else if ( abs(m_sortID) == 2 ) {
+    cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) {
+                  return this->compareEta(a,b);
+                } );
+  }
+  else if ( abs(m_sortID) == 3 ) {
+    cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) {
+                  return this->comparePhi(a,b);
+                } );
+  }
+  else if ( abs(m_sortID) == 4 ) {
+    cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) {
+                  return this->compareMass(a,b);
+                } );
+  }
+  else if ( abs(m_sortID) == 5 ) {
+    cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) {
+                  return this->compareEnergy(a,b);
+                } );
+  }
+  else if ( abs(m_sortID) == 6 ) {
+    cont->sort( [this](const xAOD::IParticle* a, const xAOD::IParticle* b) {
+                  return this->compareRapidity(a,b);
+                } );
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+
+bool ParticleSortingTool::comparePt( const xAOD::IParticle* partA,
+                                     const xAOD::IParticle* partB ) const
+{
+  const double a = partA->pt();
+  const double b = partB->pt();
+  return this->compareDouble(a,b);
+}
+
+
+bool ParticleSortingTool::compareEta( const xAOD::IParticle* partA,
+                                      const xAOD::IParticle* partB ) const
+{
+  const double a = partA->eta();
+  const double b = partB->eta();
+  return this->compareDouble(a,b);
+}
+
+
+bool ParticleSortingTool::comparePhi( const xAOD::IParticle* partA,
+                                      const xAOD::IParticle* partB ) const
+{
+  const double a = partA->phi();
+  const double b = partB->phi();
+  return this->compareDouble(a,b);
+}
+
+
+bool ParticleSortingTool::compareMass( const xAOD::IParticle* partA,
+                                       const xAOD::IParticle* partB ) const
+{
+  const double a = partA->m();
+  const double b = partB->m();
+  return this->compareDouble(a,b);
+}
+
+
+bool ParticleSortingTool::compareEnergy( const xAOD::IParticle* partA,
+                                         const xAOD::IParticle* partB ) const
+{
+  const double a = partA->e();
+  const double b = partB->e();
+  return this->compareDouble(a,b);
+}
+
+
+bool ParticleSortingTool::compareRapidity( const xAOD::IParticle* partA,
+                                           const xAOD::IParticle* partB ) const
+{
+  const double a = partA->rapidity();
+  const double b = partB->rapidity();
+  return this->compareDouble(a,b);
+}
diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSortingTool.h b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSortingTool.h
new file mode 100644
index 0000000000000000000000000000000000000000..d4b8bb66f6e22a39fd168326d869a2a41c2d5a2f
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/ParticleSortingTool.h
@@ -0,0 +1,124 @@
+///////////////////////// -*- C++ -*- /////////////////////////////
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// ParticleSortingTool.h
+// Header file for class ParticleSortingTool
+// Author: Karsten Koeneke <karsten.koeneke@cern.ch>
+///////////////////////////////////////////////////////////////////
+#ifndef EVENTUTILS_PARTICLESORTINGTOOL_H
+#define EVENTUTILS_PARTICLESORTINGTOOL_H 1
+
+// STL includes
+#include <vector>
+#include <string>
+
+// FrameWork includes
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "DerivationFrameworkInterfaces/IAugmentationTool.h"
+
+// EDM inlcudes
+#include "xAODBase/IParticle.h"
+#include "xAODBase/IParticleContainer.h"
+
+
+
+class ParticleSortingTool
+  : virtual public ::DerivationFramework::IAugmentationTool,
+            public ::AthAlgTool
+{
+
+  ///////////////////////////////////////////////////////////////////
+  // Public methods:
+  ///////////////////////////////////////////////////////////////////
+public:
+
+  // Copy constructor:
+
+  /// Constructor with parameters:
+  ParticleSortingTool( const std::string& type,
+                       const std::string& name,
+                       const IInterface* parent );
+
+  /// Destructor:
+  virtual ~ParticleSortingTool();
+
+  /// Athena algtool's initialize
+  virtual StatusCode  initialize();
+
+  /// Athena algtool's finalize
+  virtual StatusCode  finalize();
+
+
+  /// Implement the method from the ISkimmingTool interface
+  virtual StatusCode addBranches() const final override;
+
+
+
+// Private methods
+private:
+
+  /// Helper method that implements the call to the right sort function
+  StatusCode doSort( xAOD::IParticleContainer* cont ) const;
+
+  /// The method to compare the particle's pt
+  bool comparePt( const xAOD::IParticle* partA, const xAOD::IParticle* partB ) const;
+
+  /// The method to compare the particle's eta
+  bool compareEta( const xAOD::IParticle* partA, const xAOD::IParticle* partB ) const;
+
+  /// The method to compare the particle's phi
+  bool comparePhi( const xAOD::IParticle* partA, const xAOD::IParticle* partB ) const;
+
+  /// The method to compare the particle's mass
+  bool compareMass( const xAOD::IParticle* partA, const xAOD::IParticle* partB ) const;
+
+  /// The method to compare the particle's energy
+  bool compareEnergy( const xAOD::IParticle* partA, const xAOD::IParticle* partB ) const;
+
+  /// The method to compare the particle's rapidity
+  bool compareRapidity( const xAOD::IParticle* partA, const xAOD::IParticle* partB ) const;
+
+  /// Method to compare two doubles
+  inline bool compareDouble( double a, double b ) const;
+
+
+  ///////////////////////////////////////////////////////////////////
+  // Private data:
+  ///////////////////////////////////////////////////////////////////
+private:
+
+  /// Input container name
+  StringProperty m_inCollKey;
+
+  /// Output collection name (deep copies of the original ones)
+  StringProperty m_outCollKey;
+
+  /// Define by what parameter to sort (default: 'pt')
+  StringProperty m_sortVar;
+
+  /// Define if the container should be sorted in a decending order (default=true)
+  BooleanProperty m_sortDecending;
+
+
+  /// Internal container type identifier
+  mutable unsigned int m_contID;
+
+  /// Internal identifier for the type of sorting
+  mutable int m_sortID;
+
+  /// Internal event counter
+  mutable unsigned long m_nEventsProcessed;
+
+};
+
+
+inline bool ParticleSortingTool::compareDouble( double a, double b ) const
+{
+  if ( m_sortID < 0 ) { return ( a > b ); }
+  else { return ( a < b ); }
+}
+
+#endif //> !EVENTUTILS_PARTICLESORTINGTOOL_H
diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/SkimDecisionRunPeriodAwareFilterAlg.cxx b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/SkimDecisionRunPeriodAwareFilterAlg.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..dd979d4bbb16b0d8e177d672b2be082aaf8db022
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/SkimDecisionRunPeriodAwareFilterAlg.cxx
@@ -0,0 +1,361 @@
+///////////////////////// -*- C++ -*- /////////////////////////////
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// SkimDecisionRunPeriodAwareFilterAlg.cxx 
+// Implementation file for class SkimDecisionRunPeriodAwareFilterAlg
+// Author: Karsten Koeneke karsten.koeneke@cern.ch
+/////////////////////////////////////////////////////////////////// 
+
+// SelectionUtils includes
+#include "SkimDecisionRunPeriodAwareFilterAlg.h"
+
+// STL includes
+#include <string>
+#include <vector>
+
+// boost includes
+#include <boost/algorithm/string.hpp>
+
+// FrameWork includes
+#include "GaudiKernel/Property.h"
+
+// EDM includes
+#include "EventBookkeeperMetaData/SkimDecisionCollection.h"
+#include "EventBookkeeperMetaData/SkimDecision.h"
+#include "EventInfo/EventInfo.h"
+#include "EventInfo/EventType.h"
+#include "EventInfo/EventID.h"
+
+// ROOT includes
+#include "TRandom3.h"
+
+
+/////////////////////////////////////////////////////////////////// 
+// Public methods: 
+/////////////////////////////////////////////////////////////////// 
+
+// Constructors
+////////////////
+SkimDecisionRunPeriodAwareFilterAlg::SkimDecisionRunPeriodAwareFilterAlg( const std::string& name, 
+                                                                          ISvcLocator* pSvcLocator ) : 
+  ::AthFilterAlgorithm( name, pSvcLocator )
+{
+  //
+  // Property declaration
+  // 
+  declareProperty( "SkimDecisionCollection", m_skimDecContName,     "The name (key) of the SkimDecisionCollection to use" );
+  declareProperty( "SkimDecisionNameList",   m_skimDecNameList,
+                   "The list of SkimDecision names to accept; within one run number block, use ',' as seperator" );
+  declareProperty( "DataBeginRunNumberList", m_dataBeginRunNumList, "The list of run numbers where a block begins (for data)" );
+  declareProperty( "DataEndRunNumberList",   m_dataEndRunNumList,   "The list of run numbers where a block ends (for data)" );
+  declareProperty( "MCBeginRunNumberList",   m_mcBeginRunNumList,   "The list of run numbers where a block begins (for MC)" );
+  declareProperty( "MCEndRunNumberList",     m_mcEndRunNumList,     "The list of run numbers where a block ends (for MC)" );
+  declareProperty( "MCRelativeLumiList",     m_mcRelLumiList,
+                   "The list of relate integrated luminosities (fractional) for each MC run-number block (set to something larger than 1.0 if valid for a whole range)" );
+}
+
+
+
+// Destructor
+///////////////
+SkimDecisionRunPeriodAwareFilterAlg::~SkimDecisionRunPeriodAwareFilterAlg()
+{}
+
+
+
+// Athena Algorithm's Hooks
+////////////////////////////
+
+// Called once before the event loop starts by the Athena framework
+StatusCode SkimDecisionRunPeriodAwareFilterAlg::initialize()
+{
+  ATH_MSG_DEBUG ("Initializing " << name() << "...");
+  ATH_MSG_DEBUG (" using SkimDecisionCollection = " << m_skimDecContName );
+  ATH_MSG_DEBUG (" using SkimDecisionNameList   = " << m_skimDecNameList );
+  ATH_MSG_DEBUG (" using DataBeginRunNumberList = " << m_dataBeginRunNumList );
+  ATH_MSG_DEBUG (" using DataEndRunNumberList   = " << m_dataEndRunNumList );
+  ATH_MSG_DEBUG (" using MCBeginRunNumberList   = " << m_mcBeginRunNumList );
+  ATH_MSG_DEBUG (" using MCEndRunNumberList     = " << m_mcEndRunNumList );
+  ATH_MSG_DEBUG (" using MCRelativeLumiList     = " << m_mcRelLumiList );
+
+  // Try to find the commas in the SkimDecisionNameList and make a list of lists
+  // and initialize the index vectors to -1
+  for ( unsigned int i=0; i<m_skimDecNameList.size(); ++i )
+    {
+      std::vector<std::string> tokens;
+      boost::split(tokens, m_skimDecNameList[i], boost::is_any_of(","));
+      m_skimDecNameListList.push_back(tokens);
+      std::vector<int> indices;
+      for ( unsigned int j=0; j<tokens.size(); ++j )
+        {
+          indices.push_back(-1);
+        }
+      m_skimDecIdxListList.push_back(indices);
+    }
+
+  // Make some sanity checks
+  bool allOK(true);
+  if ( m_skimDecNameListList.size() != m_dataBeginRunNumList.size()
+       || m_skimDecNameListList.size() != m_dataEndRunNumList.size() )
+    {
+      ATH_MSG_FATAL ("SkimDecisionNameList has different size from DataBeginRunNumberList or DataEndRunNumberList" );
+      allOK = false;
+    }
+  if ( m_mcBeginRunNumList.size() != 0 || m_mcEndRunNumList.size() != 0 )
+    {
+      if ( m_skimDecNameListList.size() != m_mcBeginRunNumList.size()
+           || m_skimDecNameListList.size() != m_mcEndRunNumList.size()
+           || m_skimDecNameListList.size() != m_mcRelLumiList.size() )
+        {
+          ATH_MSG_FATAL ("SkimDecisionNameList has different size from MCBeginRunNumberList or MCEndRunNumberList or MCRelativeLumiList" );
+          allOK = false;
+        }
+    }
+
+  if ( !allOK )
+    {
+      return StatusCode::FAILURE; 
+    }
+
+  return StatusCode::SUCCESS;
+}
+
+
+
+// Called once after the event loop is finished by the Athena framework
+StatusCode SkimDecisionRunPeriodAwareFilterAlg::finalize()
+{
+  ATH_MSG_DEBUG ("Finalizing " << name() << "...");
+
+  return StatusCode::SUCCESS;
+}
+
+
+
+// Called once per event by the Athena framework
+StatusCode SkimDecisionRunPeriodAwareFilterAlg::execute()
+{  
+  ATH_MSG_DEBUG ("Executing " << name() << "...");
+
+  // Get the EventInfo object
+  const EventInfo* eventInfo(NULL);
+  ATH_CHECK( evtStore()->retrieve(eventInfo) );
+
+  // Get the SkimDecisionCollection
+  const SkimDecisionCollection* skimDecCont(NULL);
+  ATH_CHECK( evtStore()->retrieve( skimDecCont, m_skimDecContName ) );
+
+
+  // See if we have MC or data and get the run number
+  bool isSim = eventInfo->event_type()->test(EventType::IS_SIMULATION);
+  unsigned int runnumber = eventInfo->event_ID()->run_number();
+  unsigned int eventnumber = eventInfo->event_ID()->event_number();
+
+
+  // Event pass decision
+  bool passAccept(false);
+
+  // For data ===================================================
+  if ( !isSim )
+    {
+      ATH_MSG_VERBOSE( "Detected that I am running on data. Current run number=" << runnumber );
+      unsigned int outerSize( m_dataBeginRunNumList.size() );
+      if ( outerSize == 0 ) passAccept = true;
+      for ( unsigned int i=0; i<outerSize; ++i )
+        {
+          // Get the right run number range
+          if ( runnumber >= m_dataBeginRunNumList[i] && runnumber <= m_dataEndRunNumList[i] )
+            {
+              ATH_MSG_VERBOSE( "Found right run number range with index i=" << i );
+              // Now, loop over the inner list for the current run-number range
+              unsigned int innerSize( m_skimDecNameListList[i].size() );
+              for ( unsigned int j=0; j<innerSize; ++j )
+                {
+                  if ( this->skimDecisionNameIsAccepted( skimDecCont, m_skimDecNameListList[i][j], m_skimDecIdxListList, i, j ) )
+                    {
+                      ATH_MSG_DEBUG( "Found SkimDecision in data with name " << m_skimDecNameListList[i][j]
+                                     << " from SkimDecisionNameList in SkimDecisionCollection with key " << m_skimDecContName );
+                      setFilterPassed( true );
+                      return StatusCode::SUCCESS;
+                    }
+                } // End: inner loop over all accept requests
+            } // End: check that we are in the right run number range
+        } // End: loop over run number ranges
+    }
+  // For MC   ===================================================
+  else
+    {
+      ATH_MSG_VERBOSE( "Detected that I am running on simulation. Current run number=" << runnumber );
+      // First, get the MC channel number and calculate the seed for the random number generator
+      unsigned int mcchannelnumber = eventInfo->event_type()->mc_channel_number();
+      unsigned int seed = mcchannelnumber * eventnumber;
+
+      // Get the random number generator
+      TRandom3 random3;
+
+      unsigned int outerSize( m_mcBeginRunNumList.size() );
+      if ( outerSize == 0 ) passAccept = true;
+      for ( unsigned int i=0; i<outerSize; ++i )
+        {
+          // Get the right run number range
+          if ( runnumber >= m_mcBeginRunNumList[i] && runnumber <= m_mcEndRunNumList[i] )
+            {
+              ATH_MSG_VERBOSE( "Found right run number range with index i=" << i );
+              // Get the current fraction of lumi for this range
+              double lumiFrac = m_mcRelLumiList[i];
+              bool needIncrement(false);
+              if ( lumiFrac < 1.0 )
+                {
+                  random3.SetSeed(seed);
+                  double rdmNum = random3.Uniform();
+                  if ( rdmNum >= lumiFrac ) // go to the next outer index
+                    {
+                      i += 1;
+                    }
+                  else
+                    {
+                      needIncrement = true;
+                    }
+                }
+
+              // Check that we didn't leave the boundary of the vector
+              if ( i >= outerSize )
+                {
+                  ATH_MSG_FATAL ("We ran over the lenghts of the vector of the SkimDecisionNameList!" );
+                  setFilterPassed( false );
+                  return StatusCode::FAILURE;
+                }
+
+              // Now, loop over the inner list for the current run-number range
+              unsigned int innerSize( m_skimDecNameListList[i].size() );
+              for ( unsigned int j=0; j<innerSize; ++j )
+                {
+                  if ( this->skimDecisionNameIsAccepted( skimDecCont, m_skimDecNameListList[i][j], m_skimDecIdxListList, i, j ) )
+                    {
+                      ATH_MSG_DEBUG( "Found SkimDecision in MC with name " << m_skimDecNameListList[i][j]
+                                     << " from SkimDecisionNameList in SkimDecisionCollection with key " << m_skimDecContName );
+                      setFilterPassed( true );
+                      return StatusCode::SUCCESS;
+                    }
+                } // End: inner loop over all accept requests
+              
+              // Increment to jump over the next entry in this run period
+              if ( needIncrement )
+                {
+                  i += 1;
+                }
+
+            } // End: check that we are in the right run number range
+        } // End: loop over run number ranges
+
+    } // End: if/else !isMC
+
+
+  // Determine the global event passing decision
+  setFilterPassed( passAccept );
+
+  return StatusCode::SUCCESS;
+}
+
+
+
+
+
+
+
+
+
+// Private helper method to find the SkimDecision isAccepted() answer
+bool SkimDecisionRunPeriodAwareFilterAlg::skimDecisionNameIsAccepted( const SkimDecisionCollection* skimDecCont,
+                                                                      std::string& skimDecName,
+                                                                      std::vector< std::vector<int> >& skimDecIdxList,
+                                                                      unsigned int idxA,
+                                                                      unsigned int idxB )
+{
+  // Pointer check
+  if ( !skimDecCont )
+    {
+      ATH_MSG_WARNING( "Got a zero pointer of type SkimDecisionCollection with key " << m_skimDecContName );
+      return false;
+    }
+
+  // Get the size of the SkimDecisionCollection
+  const unsigned int skimCollSize = skimDecCont->size();
+
+  // If we already have an index, choose the fast path 
+  if ( skimDecIdxList[idxA][idxB] >= 0 && skimDecIdxList[idxA][idxB] < (int)skimCollSize )
+    {
+      const SkimDecision* skimDec = skimDecCont->at(skimDecIdxList[idxA][idxB]);
+      if ( !skimDec )
+        {
+          ATH_MSG_WARNING( "Couldn't find SkimDecision with name " << skimDecName
+                           << " in SkimDecisionCollection with key " << m_skimDecContName );
+          return false;
+        }
+
+      // If the name is correct for the given index
+      if ( skimDec->getName() == skimDecName )
+        {
+          return skimDec->isAccepted();
+        }
+      else // The index was wrong and we need to search for the name 
+        {
+          // Loop over all SkimDecisions in the SkimDecisionCollection
+          bool foundSkimDec(false);
+          for ( unsigned int i=0; i<skimCollSize; ++i )
+            {
+              // Get the current SkimDecision
+              const SkimDecision* skimDec = skimDecCont->at(i);
+              if ( !skimDec ) continue;
+
+              // Found the right skim decision
+              if ( skimDecName == skimDec->getName() )
+                {
+                  skimDecIdxList[idxA][idxB] = (int)i; // Set the index to the found one
+                  foundSkimDec = true;
+                  return skimDec->isAccepted();
+                }
+            }
+          // If none of the SkimDecision names matched
+          if ( !foundSkimDec )
+            {
+              ATH_MSG_WARNING( "Couldn't find SkimDecision with name " << skimDecName
+                               << " in SkimDecisionCollection with key " << m_skimDecContName );
+              return false;
+            }
+        }
+    } // End: if we have a valid index
+  else // The index was wrong and we need to search for the name 
+    {
+      // Loop over all SkimDecisions in the SkimDecisionCollection
+      bool foundSkimDec(false);
+      for ( unsigned int i=0; i<skimCollSize; ++i )
+        {
+          // Get the current SkimDecision
+          const SkimDecision* skimDec = skimDecCont->at(i);
+          if ( !skimDec ) continue;
+          
+          // Found the right skim decision
+          if ( skimDecName == skimDec->getName() )
+            {
+              skimDecIdxList[idxA][idxB] = (int)i; // Set the index to the found one
+              foundSkimDec = true;
+              return skimDec->isAccepted();
+            }
+        }
+      // If none of the SkimDecision names matched
+      if ( !foundSkimDec )
+        {
+          ATH_MSG_WARNING( "Couldn't find SkimDecision with name " << skimDecName
+                           << " in SkimDecisionCollection with key " << m_skimDecContName );
+          return false;
+        }
+    }
+  // If we got to here, something went wrong
+  ATH_MSG_WARNING( "We should have never reached this part of the code! Tried to search for SkimDecision with name " << skimDecName
+                   << " in SkimDecisionCollection with key " << m_skimDecContName );
+  return false;
+}
diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/SkimDecisionRunPeriodAwareFilterAlg.h b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/SkimDecisionRunPeriodAwareFilterAlg.h
new file mode 100644
index 0000000000000000000000000000000000000000..537c75f14189e9369ce93390cce5a76051aa07af
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/SkimDecisionRunPeriodAwareFilterAlg.h
@@ -0,0 +1,122 @@
+///////////////////////// -*- C++ -*- /////////////////////////////
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// SkimDecisionRunPeriodAwareFilterAlg.h 
+// Header file for class SkimDecisionRunPeriodAwareFilterAlg
+// Author: Karsten Koeneke
+/////////////////////////////////////////////////////////////////// 
+#ifndef EVENTUTILS_SKIMDECISIONRUNPERIODAWAREFILTERALG_H
+#define EVENTUTILS_SKIMDECISIONRUNPERIODAWAREFILTERALG_H 1
+
+// STL includes
+#include <string>
+
+// FrameWork includes
+#include "AthenaBaseComps/AthFilterAlgorithm.h"
+
+// Forward declarations
+class SkimDecisionCollection;
+
+
+
+class SkimDecisionRunPeriodAwareFilterAlg
+  : public ::AthFilterAlgorithm
+{ 
+
+  /////////////////////////////////////////////////////////////////// 
+  // Public methods: 
+  /////////////////////////////////////////////////////////////////// 
+ public: 
+
+  // Copy constructor: 
+
+  /// Constructor with parameters: 
+  SkimDecisionRunPeriodAwareFilterAlg( const std::string& name, ISvcLocator* pSvcLocator );
+
+  /// Destructor: 
+  virtual ~SkimDecisionRunPeriodAwareFilterAlg(); 
+
+  // Assignment operator: 
+  //SkimDecisionRunPeriodAwareFilterAlg &operator=(const SkimDecisionRunPeriodAwareFilterAlg &alg); 
+
+  // Athena algorithm's Hooks
+  virtual StatusCode  initialize();
+  virtual StatusCode  execute();
+  virtual StatusCode  finalize();
+
+  /////////////////////////////////////////////////////////////////// 
+  // Const methods: 
+  ///////////////////////////////////////////////////////////////////
+
+  /////////////////////////////////////////////////////////////////// 
+  // Non-const methods: 
+  /////////////////////////////////////////////////////////////////// 
+private:
+
+  /// Private method to determine the accept decission
+  bool skimDecisionNameIsAccepted( const SkimDecisionCollection* skimDecCont,
+                                   std::string& skimDecName,
+                                   std::vector< std::vector<int> >& skimDecIdxList,
+                                   unsigned int idxA,
+                                   unsigned int idxB );
+
+
+
+  /////////////////////////////////////////////////////////////////// 
+  // Private data: 
+  /////////////////////////////////////////////////////////////////// 
+ private: 
+
+  /// Default constructor: 
+  //SkimDecisionRunPeriodAwareFilterAlg();
+
+  /// Containers
+
+  /// SkimDecisionCollection name
+  std::string m_skimDecContName;
+
+
+  /// The list of SkimDecision names to accept 
+  std::vector< std::string > m_skimDecNameList;
+
+
+  /// The list of SkimDecision names to accept for each run period (can be multiple in each run period)
+  std::vector< std::vector< std::string > > m_skimDecNameListList;
+
+
+  /// The list of run numbers where a block begins (for data)
+  std::vector< unsigned int > m_dataBeginRunNumList;
+
+  /// The list of run numbers where a block ends (for data)
+  std::vector< unsigned int > m_dataEndRunNumList;
+
+
+  /// The list of run numbers where a block begins (for MC)
+  std::vector< unsigned int > m_mcBeginRunNumList;
+
+  /// The list of run numbers where a block ends (for MC)
+  std::vector< unsigned int > m_mcEndRunNumList;
+
+  /// The list of relate integrated luminosities (fractional) for each MC run-number block
+  std::vector< double > m_mcRelLumiList;
+
+
+  /// List of the indices where the correct SkimDecision is in the container for the accept (logical OR) method
+  //std::vector<int> m_skimDecIdxList;
+  std::vector< std::vector< int > > m_skimDecIdxListList;
+
+
+}; 
+
+// I/O operators
+//////////////////////
+
+/////////////////////////////////////////////////////////////////// 
+// Inline methods: 
+/////////////////////////////////////////////////////////////////// 
+
+
+#endif //> !EVENTUTILS_SKIMDECISIONRUNPERIODAWAREFILTERALG_H
diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/components/EventUtils_entries.cxx b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/components/EventUtils_entries.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..b7cef176dd7a0161c67a0753c74976522532b0ee
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/components/EventUtils_entries.cxx
@@ -0,0 +1,43 @@
+#include "GaudiKernel/DeclareFactoryEntries.h"
+
+#include "../ParticleSortingTool.h"
+#include "../ParticleSortingAlg.h"
+#include "../AddVarTool.h"
+#include "../AddVarAlg.h"
+#include "../CutTool.h"
+#include "../CutAlg.h"
+#include "../ParticleSelectionTool.h"
+#include "../ParticleSelectionAlg.h"
+#include "../ParticleCombinerTool.h"
+#include "../ParticleCombinerAlg.h"
+#include "../EventQualityFilterAlg.h"
+#include "../SkimDecisionRunPeriodAwareFilterAlg.h"
+
+DECLARE_TOOL_FACTORY( ParticleSortingTool )
+DECLARE_ALGORITHM_FACTORY( ParticleSortingAlg )
+DECLARE_TOOL_FACTORY( AddVarTool )
+DECLARE_ALGORITHM_FACTORY( AddVarAlg )
+DECLARE_TOOL_FACTORY( CutTool )
+DECLARE_ALGORITHM_FACTORY( CutAlg )
+DECLARE_TOOL_FACTORY( ParticleSelectionTool )
+DECLARE_ALGORITHM_FACTORY( ParticleSelectionAlg )
+DECLARE_TOOL_FACTORY( ParticleCombinerTool )
+DECLARE_ALGORITHM_FACTORY( ParticleCombinerAlg )
+DECLARE_ALGORITHM_FACTORY( EventQualityFilterAlg )
+DECLARE_ALGORITHM_FACTORY( SkimDecisionRunPeriodAwareFilterAlg )
+
+DECLARE_FACTORY_ENTRIES( EventUtils )
+{
+  DECLARE_TOOL( ParticleSortingTool );
+  DECLARE_ALGORITHM( ParticleSortingAlg );
+  DECLARE_TOOL( AddVarTool );
+  DECLARE_ALGORITHM( AddVarAlg );
+  DECLARE_TOOL( CutTool );
+  DECLARE_ALGORITHM( CutAlg );
+  DECLARE_TOOL( ParticleSelectionTool );
+  DECLARE_ALGORITHM( ParticleSelectionAlg );
+  DECLARE_TOOL( ParticleCombinerTool );
+  DECLARE_ALGORITHM( ParticleCombinerAlg );
+  DECLARE_ALGORITHM( EventQualityFilterAlg );
+  DECLARE_ALGORITHM( SkimDecisionRunPeriodAwareFilterAlg );
+}
diff --git a/PhysicsAnalysis/AnalysisCommon/EventUtils/src/components/EventUtils_load.cxx b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/components/EventUtils_load.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..ab3a5223455fd642a6671fcd3d2bacaea277b6d1
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/EventUtils/src/components/EventUtils_load.cxx
@@ -0,0 +1,2 @@
+#include "GaudiKernel/LoadFactoryEntries.h"
+LOAD_FACTORY_ENTRIES(EventUtils)