diff --git a/PhysicsAnalysis/AnalysisCommon/AnalysisTools/AnalysisTools/AANTEventContext.h b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/AnalysisTools/AANTEventContext.h
new file mode 100755
index 0000000000000000000000000000000000000000..f86e58b5a19c95395cc4d1fa8eaf926c0b0c3bb2
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/AnalysisTools/AANTEventContext.h
@@ -0,0 +1,31 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef ANALYSISTOOLS_AANTEVENTCONTEXT_H
+#define ANALYSISTOOLS_AANTEVENTCONTEXT_H
+
+
+#include "GaudiKernel/IEvtSelector.h"
+
+class IOpaqueAddress;
+
+class AANTEventContext : virtual public IEvtSelector::Context {
+
+public:
+   /// Constructor
+   AANTEventContext(const IEvtSelector* selector);
+   /// Copy constructor
+   AANTEventContext(const AANTEventContext& ctxt);
+   /// Assignment
+   AANTEventContext& operator= (const AANTEventContext& ctxt);
+   /// Destructor
+   virtual ~AANTEventContext();
+
+   /// Inequality operator.
+   virtual void* identifier() const;
+
+private:
+   const IEvtSelector* m_evtSelector;
+};
+#endif
diff --git a/PhysicsAnalysis/AnalysisCommon/AnalysisTools/AnalysisTools/AANTEventSelector.h b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/AnalysisTools/AANTEventSelector.h
new file mode 100755
index 0000000000000000000000000000000000000000..ab6feda278cc675a5f40cb0ae41dc05f53857f32
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/AnalysisTools/AANTEventSelector.h
@@ -0,0 +1,102 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef ANALYSISTOOLS_AANTEVENTSELECTOR_H
+#define ANALYSISTOOLS_AANTEVENTSELECTOR_H
+
+//  AANTEventSelector
+
+// Include files.
+#include "Python.h"
+
+#include "AthenaBaseComps/AthService.h"
+#include "GaudiKernel/IEvtSelector.h"
+#include "GaudiKernel/IProperty.h"
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/Bootstrap.h"
+
+#include "Rtypes.h"
+
+// Forward declarations.
+class ISvcLocator;
+class StoreGateSvc;
+class TChain;
+
+// Class AANTEventSelector.
+class AANTEventSelector : virtual public AthService, 
+			  virtual public IEvtSelector, 
+			  virtual public IProperty 
+{
+public:
+
+  // Standard Constructor.
+  AANTEventSelector(const std::string& name, ISvcLocator* svcloc);
+  
+  // Standard Destructor.
+  ~AANTEventSelector();
+
+  // Implementation of Service base class methods.
+  virtual StatusCode initialize();
+  
+  // Implementation of the IEvtSelector interface methods.
+  virtual StatusCode createContext(Context*& it) const;
+  virtual StatusCode next(Context& it) const;
+  virtual StatusCode next(Context& it, int jump) const;
+  virtual StatusCode previous(Context& it) const;
+  virtual StatusCode previous(Context& it, int jump) const;
+  
+  virtual StatusCode last(Context& it) const;
+  virtual StatusCode rewind(Context& it) const;
+
+  virtual StatusCode createAddress(const Context& it,IOpaqueAddress*& iop) const;
+  virtual StatusCode releaseContext(Context*& it) const;
+  virtual StatusCode resetCriteria(const std::string& criteria, Context& context) const;
+
+  // Implementation of IInterface methods.
+  virtual StatusCode queryInterface(const InterfaceID& riid, void** ppvInterface);
+
+private:
+  // StoreGateSvc
+  StoreGateSvc *m_storeGate;
+
+  // property 
+  StringArrayProperty m_inputCollectionsProp;
+  
+  // Number of events to skip at the beginning 
+  int m_skipEvents;
+
+  // Number of Events read so far.
+  mutable long m_numEvents;
+
+  // Total number of events
+  long m_totalNEvents;
+
+  // name of converter for TTree
+  std::string m_strConverter;
+
+  // name of selection criteria
+  std::string m_strSelection;
+
+  // TChain
+  TChain *m_tree;
+
+  Long64_t m_runNumber;
+  Long64_t m_eventNumber;
+
+  // Py I/F
+  PyObject *m_convFunc;
+  PyObject *m_selectionFunc;
+};
+
+
+struct AANTTreeGate
+{
+public:
+  static void setTree (TChain *chain) { m_tree = chain;}
+  static TChain * getTree () { return m_tree; }
+private:
+  static TChain *m_tree;
+};
+
+#endif  
diff --git a/PhysicsAnalysis/AnalysisCommon/AnalysisTools/AnalysisTools/AANTupleParams.h b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/AnalysisTools/AANTupleParams.h
new file mode 100755
index 0000000000000000000000000000000000000000..c7cd9897367805579fbd31bb6ec217bceb559067
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/AnalysisTools/AANTupleParams.h
@@ -0,0 +1,25 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef ANALYSISTOOLS_AANTUPLEPARAMS_H
+#define ANALYSISTOOLS_AANTUPLEPARAMS_H
+
+namespace AANTupleParams
+{
+  /// constants for AANTupleStream
+  static const char* c_tokenBranchName         __attribute__((unused)) = "Token";
+  static const char* c_attributeListLayoutName __attribute__((unused)) = "Schema"; 
+  static const std::string c_treeName          = "CollectionTree";
+  static const std::string c_streamName        = "AANT";
+  
+  /// ID of TTree
+  static const std::string c_TreeID = "/"+c_streamName+"/"+c_treeName;
+  
+  // attributes
+  static const char* name_RunNumber   __attribute__((unused)) = "RunNumber";
+  static const char* name_EventNumber __attribute__((unused)) = "EventNumber";
+}
+
+#endif
+
diff --git a/PhysicsAnalysis/AnalysisCommon/AnalysisTools/AnalysisTools/AANTupleStream.h b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/AnalysisTools/AANTupleStream.h
new file mode 100755
index 0000000000000000000000000000000000000000..ad9ab67df5337d279dec7997bf1f5db8644f4605
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/AnalysisTools/AANTupleStream.h
@@ -0,0 +1,151 @@
+// dear emacs, this is -*- C++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef ANALYSISTOOLS_AANTUPLESTREAM_H
+#define ANALYSISTOOLS_AANTUPLESTREAM_H 1
+
+#include "GaudiKernel/IAddressCreator.h"
+#include "GaudiKernel/ServiceHandle.h"
+#include "GaudiKernel/IIoComponent.h"
+#include "AthenaBaseComps/AthAlgorithm.h"
+
+#include <map>
+#include <vector>
+
+namespace coral
+{
+  class AttributeList;
+  class AttributeListSpecification;
+}
+
+class StoreGateSvc;
+
+class ITHistSvc;
+
+class TFile;
+class TTree;
+class TBranch;
+
+class AANTupleStream : virtual public IIoComponent,
+                               public AthAlgorithm
+{
+public:
+    
+  /// Standard AANTupleStream Constructor
+  AANTupleStream(const std::string& name, ISvcLocator* pSvcLocator); 
+
+  /// Standard Destructor
+  virtual ~AANTupleStream();
+
+  /// Initialize AANTupleStream
+  virtual StatusCode initialize();
+
+  /// Terminate AANTupleStream
+  virtual StatusCode finalize();
+
+  /// Working entry point
+  virtual StatusCode execute();
+
+private:
+
+  /// Initialize the output collection
+  StatusCode initCollection();
+
+  /// Get ref from a proxy
+  StatusCode getRef(CLID id, const std::string& key,
+		    std::string& ref);
+
+  /// Split the address to get pool token
+  StatusCode splitAddress( const std::string& address,
+			   const std::string& match,
+			   std::string&       address_header,
+			   std::string&       address_data ) const;
+
+  /// initialize sub-algos
+  StatusCode initialize_subAlgos ();
+
+  /// execute sub-algos
+  StatusCode execute_subAlgos ();
+
+  /// write schema of AttributeList
+  void writeAttributeListSpecification();
+
+  /// setup Tree
+  void setupTree();
+
+  /// write Token and AttributeList
+  bool writeTokenAttrList( const std::string& token, const coral::AttributeList& attributeList );
+  
+  /// get filter alogs
+  StatusCode getFilters();
+
+  /// check filters passed
+  bool isEventAccepted() const;
+
+  StatusCode initSchema();
+
+  /** @brief callback method to reinitialize the internal state of
+   *         the component for I/O purposes (e.g. upon @c fork(2))
+   */
+  StatusCode io_reinit ();
+
+  /// Persistency service
+  ServiceHandle<IAddressCreator> m_persSvc;
+
+  /// Collection attribute specification
+  coral::AttributeListSpecification* m_attribSpec;
+
+  /// Name of the output collection
+  std::string m_fileName;
+  
+  /// Vector of extra parent ref names to register in collection
+  StringArrayProperty m_extraRefNames;
+
+  /// Flag to signal whether or not to write input data header
+  BooleanProperty          m_writeInputDH;
+
+  /// Flag to signal whether data header exists
+  BooleanProperty          m_existDH;
+
+  /// Name of Stream
+  std::string m_streamName;
+
+  /// write schema in execute()
+  BooleanProperty m_lateSchema;
+
+  /// macro
+  std::string m_macro;
+
+  /// first event
+  bool m_schemaDone;
+
+  /// Name of the output tree
+  std::string m_treeName;
+
+  /// Vector of names of Algorithms that this stream accepts
+  std::vector<std::string> m_acceptNames;
+
+  /// Vector of Algorithms that this stream accepts
+  std::vector<Algorithm*> m_acceptAlgs;
+
+  /// TTree
+  TTree * m_tree;
+
+  /// TBranch which contains Token info
+  TBranch * m_tokenBranch;
+
+  /// THistSvc
+  ServiceHandle<ITHistSvc> m_tHistSvc;
+
+  // Sub-algorithms  as given in jobOptions type/name
+  std::vector<std::string> m_membersNames;
+
+  /// for string branches
+  static const unsigned int c_maxLengthOfStrings = 5000;
+  char m_tokenCString[c_maxLengthOfStrings];
+};
+
+#endif
diff --git a/PhysicsAnalysis/AnalysisCommon/AnalysisTools/AnalysisTools/AnalysisTools.h b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/AnalysisTools/AnalysisTools.h
new file mode 100755
index 0000000000000000000000000000000000000000..9002a38bde0b6cc59ff67107a0dbdca705bd3cf6
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/AnalysisTools/AnalysisTools.h
@@ -0,0 +1,40 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef ANALYSISTOOLS_ANALYSISTOOLS_H
+#define ANALYSISTOOLS_ANALYSISTOOLS_H
+
+/**
+   This class structure is needed for component library
+
+   @author Tadashi Maeno
+ */
+
+#include "AnalysisTools/IAnalysisTools.h"
+
+// interface ID
+static const InterfaceID IID_IAnalysisTools("AnalysisTools", 1, 0);
+
+class AnalysisTools : public IAnalysisTools
+{
+public:
+
+  /** constructor
+   */
+  AnalysisTools ( const std::string& type, const std::string& name,
+		  const IInterface* parent ) ;
+
+  /** initialize
+   */
+  StatusCode initialize();
+
+  /** InterfaceID
+   */
+  static const InterfaceID& interfaceID( )
+  { return IID_IAnalysisTools; }
+
+
+};
+
+#endif
diff --git a/PhysicsAnalysis/AnalysisCommon/AnalysisTools/AnalysisTools/AnalysisToolsDict.h b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/AnalysisTools/AnalysisToolsDict.h
new file mode 100755
index 0000000000000000000000000000000000000000..1730755947c77316aea56acfb86c87b56f198907
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/AnalysisTools/AnalysisToolsDict.h
@@ -0,0 +1,11 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef ANALYSISTOOLS_ANALYSISTOOLSDICT_H
+#define ANALYSISTOOLS_ANALYSISTOOLSDICT_H 1
+
+#include "AnalysisTools/AANTEventSelector.h"
+#include "AnalysisTools/IAnalysisTools.h"
+
+#endif
diff --git a/PhysicsAnalysis/AnalysisCommon/AnalysisTools/AnalysisTools/IAnalysisTools.h b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/AnalysisTools/IAnalysisTools.h
new file mode 100755
index 0000000000000000000000000000000000000000..8dacc84865a4c82d2d8feb2cca2af033bf798220
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/AnalysisTools/IAnalysisTools.h
@@ -0,0 +1,337 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef ANALYSISTOOLS_IANALYSISTOOLS_H
+#define ANALYSISTOOLS_IANALYSISTOOLS_H
+
+/**
+   This class provides a common interface to Analysis Tools
+
+   @author Tadashi Maeno
+*/
+
+#include <vector>
+
+#include "AthenaBaseComps/AthAlgTool.h"
+
+#include "NavFourMom/INavigable4MomentumCollection.h"
+#include "McParticleEvent/TruthParticleContainer.h"
+#include "AnalysisUtils/AnalysisMisc.h"
+
+//class INavigable4Momentum;
+
+//class INavigable4MomentumCollection; //this causes a problem in client packages (eg. AnalysisExamples) because it is now a typedef
+
+class StoreGateSvc;
+
+class IAnalysisTools : public AthAlgTool
+{
+public:
+
+  /** constructor
+   */
+  IAnalysisTools ( const std::string& type, const std::string& name,
+		   const IInterface* parent )
+    : AthAlgTool(type,name,parent)
+   {}
+
+  /** destructor
+   */
+  virtual ~IAnalysisTools () {}
+
+  /** \Delta\phi
+   */
+  double deltaPhi (const INavigable4Momentum *p1, const INavigable4Momentum *p2) const;
+  
+  /** \Delta{R}
+   */
+  double deltaR (const INavigable4Momentum *p1, const INavigable4Momentum *p2) const;
+
+  /** Invariant mass : 2 body
+   */
+  double imass2 (const INavigable4Momentum *p1, const INavigable4Momentum *p2) const;
+
+  /** Invariant mass : 4 body
+   */
+  double imass4 (const INavigable4Momentum *p1, const INavigable4Momentum *p2,
+		 const INavigable4Momentum *p3, const INavigable4Momentum *p4) const;
+
+  /** find the closest (in R) element in a collection to an INavigable4Momentum
+      not check PDG ID
+      @param index [out] index of the closest element
+      @param deltaR [out] \Delta{R}
+      @return true if found
+  */
+  template <class COLL> bool matchR
+    (const INavigable4Momentum *t, COLL *coll, int &index, double &deltaR) const;
+
+  template <class COLL> bool matchR
+    (const double eta, const double phi, COLL *coll, int &index, double &deltaR) const;
+
+   bool matchR (const INavigable4Momentum *t, const TruthParticleContainer *coll, 
+		int &index, double &deltaR, const bool genOnly=true) const
+     {
+       return AnalysisUtils::Match::R(t->eta(), t->phi(), coll, index, deltaR, genOnly);
+     }
+
+   bool matchR (const double eta, const double phi, const TruthParticleContainer *coll, 
+		int &index, double &deltaR, const bool genOnly=true) const
+     {
+       return AnalysisUtils::Match::R(eta, phi, coll, index, deltaR, genOnly);
+     }
+
+  /** find the closest (in R) element in a collection to an INavigable4Momentum
+      not check PDG ID but a condition on E
+      @param index [out] index of the closest element
+      @param deltaR [out] \Delta{R}
+      @return true if found
+  */
+  template <class COLL> bool matchR
+    (const INavigable4Momentum *t, COLL *coll, int &index, double &deltaR, double &deltaE) const;
+
+  template <class COLL> bool matchR
+    (const double eta, const double phi, const double e, COLL *coll, int &index, 
+     double &deltaR, double &deltaE) const;
+
+  bool matchR (const double eta, const double phi, const double e, const TruthParticleContainer *coll, int &index, 
+	       double &deltaR, double &deltaE, const bool genOnly=true) const 
+    {
+      return AnalysisUtils::Match::R(eta, phi, e, coll, index, deltaR, deltaE, genOnly);
+    }
+
+  bool matchR (const INavigable4Momentum *t, const TruthParticleContainer *coll, int &index, 
+	       double &deltaR, double &deltaE, const bool genOnly=true) const 
+    {
+      return AnalysisUtils::Match::R(t->eta(), t->phi(), t->e(), coll, index, deltaR, deltaE, genOnly);
+    }
+
+  /** find the closest (in R) element in a collection to an INavigable4Momentum
+      not check PDG ID
+      @param element [out] pointer to the closest element
+      @param deltaR  [out] \Delta{R}
+      @return true if found
+  */
+  template <class COLL, class ELEMENT> bool matchR
+    (const INavigable4Momentum *t, COLL *coll, ELEMENT *&element, double &deltaR) const;
+
+  template <class COLL, class ELEMENT> bool matchR
+    (const double eta, const double phi, COLL *coll, ELEMENT *&element, double &deltaR) const;
+
+  bool matchR (const INavigable4Momentum *t, const TruthParticleContainer *coll, const TruthParticle *&element, 
+	       double &deltaR, const bool genOnly=true) const
+    {
+      int index = 0;
+      bool ret = AnalysisUtils::Match::R(t,coll,index,deltaR, genOnly);
+      if (!ret) return false;
+      element = (*coll)[index];
+      return true;
+    }
+
+  bool matchR (const double eta, const double phi, const TruthParticleContainer *coll, const TruthParticle *&element, 
+	       double &deltaR, const bool genOnly=true) const
+    {
+      int index;
+      bool ret = AnalysisUtils::Match::R(eta,phi,coll,index,deltaR,genOnly);
+      if (!ret) return false;
+      element = (*coll)[index];
+      return true;
+    }
+
+  /** find the closest (in R) element in a collection to an INavigable4Momentum
+      not check PDG ID - with a condition on E
+      @param element [out] pointer to the closest element
+      @param deltaR  [out] \Delta{R}
+      @return true if found
+  */
+  template <class COLL, class ELEMENT> bool matchR
+    (const INavigable4Momentum *t, COLL *coll, ELEMENT *&element, double &deltaR, double &deltaE) const;
+
+  template <class COLL, class ELEMENT> bool matchR
+    (const double eta, const double phi, const double e, COLL *coll, ELEMENT *&element, 
+     double &deltaR, double &deltaE) const;
+
+  bool matchR (const INavigable4Momentum *t, const TruthParticleContainer *coll, const TruthParticle *&element, 
+	       double &deltaR, double &deltaE, const bool genOnly=true) const 
+    {
+      int index = -1;
+      bool ret = AnalysisUtils::Match::R(t,coll,index,deltaR, deltaE, genOnly);
+      if (!ret || index == -1) return false;
+      element = (*coll)[index];
+      return true;
+    }
+
+  bool matchR (const double eta, const double phi, const double e, const TruthParticleContainer *coll, 
+	       const TruthParticle *&element, double &deltaR, double &deltaE, const bool genOnly=true) const
+    {
+      int index = -1;
+      bool ret = AnalysisUtils::Match::R(eta,phi,e,coll,index,deltaR,deltaE,genOnly);
+      if (!ret || -1 == index) return false;
+      element = (*coll)[index];
+      return true;
+    }
+
+  /** find the closest (in R) element in a collection to an INavigable4Momentum
+      @param index [out] index of the closest element
+      @param deltaR [out] \Delta{R}
+      @return true if found
+  */
+  template <class COLL> bool matchR
+    (const INavigable4Momentum *t, COLL *coll, int &index, double &deltaR, const int pdg) const;
+
+  template <class COLL> bool matchR
+    (const double eta, const double phi, COLL *coll, int &index, double &deltaR, const int pdg) const;
+
+  bool matchR (const double eta, const double phi, const TruthParticleContainer *coll, int &index, 
+	       double &deltaR, const int pdg, const bool genOnly=true) const
+    {
+      return AnalysisUtils::Match::R(eta, phi, coll, index, deltaR, pdg, genOnly);
+    }
+
+  bool matchR (const INavigable4Momentum *t, const TruthParticleContainer *coll, int &index, 
+	       double &deltaR, const int pdg, const bool genOnly=true) const
+    {
+      return AnalysisUtils::Match::R(t->eta(), t->phi(), coll, index, deltaR, pdg, genOnly);
+    }
+
+  /** find the closest (in R) element in a collection to an INavigable4Momentum
+      @param index [out] index of the closest element
+      @param deltaR [out] \Delta{R}
+      @return true if found
+  */
+  template <class COLL> bool matchR
+    (const INavigable4Momentum *t, COLL *coll, int &index, double &deltaR, const int pdg, 
+     double &deltaE) const;
+
+  template <class COLL> bool matchR
+    (const double eta, const double phi, const double e, COLL *coll, int &index, double &deltaR, 
+     const int pdg, double &deltaE) const;
+
+  bool matchR (const double eta, const double phi, const double e, const TruthParticleContainer *coll, 
+	       int &index, double &deltaR, const int pdg, double &deltaE, const bool genOnly=true) const
+    {
+      return AnalysisUtils::Match::R(eta, phi, e, coll, index, deltaR, pdg, deltaE, genOnly);
+    }
+
+  bool matchR (const INavigable4Momentum *t, const TruthParticleContainer *coll, 
+	       int &index, double &deltaR, const int pdg, double &deltaE, const bool genOnly=true) const
+    {
+      return AnalysisUtils::Match::R(t->eta(), t->phi(), t->e(), coll, index, deltaR, pdg, deltaE, genOnly);
+    }
+
+  /** find the closest (in R) element in a collection to an INavigable4Momentum
+      @param element [out] pointer to the closest element
+      @param deltaR [out] \Delta{R}
+      @return true if found
+  */
+  template <class COLL, class ELEMENT> bool matchR
+    (const INavigable4Momentum *t, COLL *coll, ELEMENT *&element, double &deltaR, const int pdg) const;
+
+  template <class COLL, class ELEMENT> bool matchR
+    (const double eta, const double phi, COLL *coll, ELEMENT *&element, double &deltaR, const int pdg) const;
+
+  bool matchR (const INavigable4Momentum *t, const TruthParticleContainer *coll, const TruthParticle *&element, 
+	       double &deltaR, const int pdg, const bool genOnly=true) const
+    {
+      int index;
+      bool ret = AnalysisUtils::Match::R(t,coll,index,deltaR,pdg,genOnly);
+      if (!ret) return false;
+      element = (*coll)[index];
+      return true;
+    }
+
+  bool matchR (const double eta, const double phi, TruthParticleContainer *coll, const TruthParticle *&element, 
+	       double &deltaR, const int pdg, const bool genOnly=true) const
+    {
+      int index;
+      bool ret = AnalysisUtils::Match::R(eta,phi,coll,index,deltaR,pdg,genOnly);
+      if (!ret) return false;
+      element = (*coll)[index];
+      return true;
+    }
+
+  /** find the closest (in R) element in a collection to an INavigable4Momentum
+      @param element [out] pointer to the closest element and a condition on E
+      @param deltaR [out] \Delta{R}
+      @return true if found
+  */
+  template <class COLL, class ELEMENT> bool matchR
+    (const INavigable4Momentum *t, COLL *coll, ELEMENT *&element, double &deltaR, const int pdg,
+     double &deltaE) const;
+
+  template <class COLL, class ELEMENT> bool matchR
+    (const double eta, const double phi, const double e, COLL *coll, ELEMENT *&element, 
+     double &deltaR, const int pdg, double &deltaE) const;
+
+  bool matchR(const INavigable4Momentum *t, const TruthParticleContainer *coll, const TruthParticle *&element, double &deltaR, 
+	      const int pdg,double &deltaE, const bool genOnly=true) const
+    {
+      int index;
+      bool ret = AnalysisUtils::Match::R(t,coll,index,deltaR,pdg,deltaE,genOnly);
+      if (!ret) return false;
+      element = (*coll)[index];
+      return true;
+    }
+
+  bool matchR (const double eta, const double phi, const double e, const TruthParticleContainer *coll, 
+	       const TruthParticle *&element, double &deltaR, const int pdg, double &deltaE, const bool genOnly=true) const
+    {
+      int index;
+      bool ret = AnalysisUtils::Match::R(eta,phi,e,coll,index,deltaR,pdg, deltaE,genOnly);
+      if (!ret) return false;
+      element = (*coll)[index];
+      return true;
+    }
+
+  /** sort by pT
+      @param coll [in] collection
+      @param out [out] sorted collection
+   */
+  template <class COLL> void sortPT (COLL *coll) const;
+
+  /** sort by energy
+      @param coll [in] collection
+      @param out [out] sorted collection
+   */
+  template <class COLL> void sortE (COLL *coll) const;
+
+  /** sort by eta
+      @param coll [in] collection
+      @param out [out] sorted collection
+   */
+  template <class COLL> void sortEta (COLL *coll) const;
+
+  /** sort by phi
+      @param coll [in] collection
+      @param out [out] sorted collection
+   */
+  template <class COLL> void sortPhi (COLL *coll) const;
+
+  /** classify by charge
+      @param COLL [in] type of collection
+      @param coll [in] pointer to collection
+      @param pos [out] collection of positives
+      @param neg [out] collection of nagatives
+  */
+  template <class COLL> void classifyCharge (const COLL *coll,
+					     std::vector<typename COLL::value_type> &pos,
+					     std::vector<typename COLL::value_type> &neg) const;
+
+  /** selection
+      @param CALLER   [in] type of caller. e.g., class XYZ
+      @param CRITERIA [in] function pointer. must be void XYZ::abc(COLL::value_type, XYZ*) 
+      @param COLL     [in] type of 
+      @param caller   [in] pointer to caller
+      @param criteria [in] pointer to criteria
+      @param coll     [in] pointer to collection
+      @param key      [in] key for selected collection in SG
+      @param lock     [in] lock the selected collection in SG. default=false
+  */
+  template <class CALLER, class CRITERIA, class COLL> StatusCode select
+     (CALLER *caller, CRITERIA criteria, COLL *coll, const std::string &key, const bool=false) const;
+};
+
+// implementation for templates
+#include "AnalysisTools/IAnalysisTools.icc"
+
+#endif
diff --git a/PhysicsAnalysis/AnalysisCommon/AnalysisTools/AnalysisTools/IAnalysisTools.icc b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/AnalysisTools/IAnalysisTools.icc
new file mode 100755
index 0000000000000000000000000000000000000000..c034d82e17cc89b542be1db41e18a04ac634d0c0
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/AnalysisTools/IAnalysisTools.icc
@@ -0,0 +1,220 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "AnalysisUtils/AnalysisMisc.h"
+
+#include "GaudiKernel/MsgStream.h"
+#include "StoreGate/StoreGate.h"
+#include "DataModel/OwnershipPolicy.h"
+
+inline double IAnalysisTools::deltaPhi (const INavigable4Momentum *p1, const INavigable4Momentum *p2) const
+{
+  return AnalysisUtils::Delta::phi(p1,p2);
+}
+
+inline double IAnalysisTools::deltaR (const INavigable4Momentum *p1, const INavigable4Momentum *p2) const
+{
+  return AnalysisUtils::Delta::R(p1,p2);
+}
+
+inline double IAnalysisTools::imass2 (const INavigable4Momentum *p1, const INavigable4Momentum *p2) const
+{
+  return AnalysisUtils::Imass::two(p1,p2);
+}
+
+inline double IAnalysisTools::imass4 (const INavigable4Momentum *p1, const INavigable4Momentum *p2,
+				      const INavigable4Momentum *p3, const INavigable4Momentum *p4) const
+{
+  return AnalysisUtils::Imass::four(p1,p2,p3,p4);
+}
+
+template <class COLL> inline bool IAnalysisTools::matchR
+(const INavigable4Momentum *t, COLL *coll, int &index, double &deltaR) const
+{
+  return AnalysisUtils::Match::R(t,coll,index,deltaR);
+}
+
+template <class COLL> inline bool IAnalysisTools::matchR
+(const INavigable4Momentum *t, COLL *coll, int &index, double &deltaR, double &deltaE) const
+{
+  return AnalysisUtils::Match::R(t,coll,index,deltaR, deltaE);
+}
+
+template <class COLL> inline bool IAnalysisTools::matchR
+(const double eta, const double phi, COLL *coll, int &index, double &deltaR) const
+{
+  return AnalysisUtils::Match::R(eta,phi,coll,index,deltaR);
+}
+
+template <class COLL> inline bool IAnalysisTools::matchR
+(const double eta, const double phi, const double e, COLL *coll, int &index, 
+ double &deltaR, double &deltaE) const
+{
+  return AnalysisUtils::Match::R(eta,phi,e,coll,index,deltaR,deltaE);
+}
+
+template <class COLL, class ELEMENT > inline bool IAnalysisTools::matchR
+(const INavigable4Momentum *t, COLL *coll, ELEMENT *&element, double &deltaR) const
+{
+  int index = 0;
+  bool ret = AnalysisUtils::Match::R(t,coll,index,deltaR);
+  if (!ret) return false;
+  element = (*coll)[index];
+  return true;
+}
+
+template <class COLL, class ELEMENT > inline bool IAnalysisTools::matchR
+(const INavigable4Momentum *t, COLL *coll, ELEMENT *&element, double &deltaR, double &deltaE) const
+{
+  int index = 0;
+  bool ret = AnalysisUtils::Match::R(t,coll,index,deltaR, deltaE);
+  if (!ret) return false;
+  element = (*coll)[index];
+  return true;
+}
+
+template <class COLL, class ELEMENT > inline bool IAnalysisTools::matchR
+(const double eta, const double phi, COLL *coll, ELEMENT *&element, double &deltaR) const
+{
+  int index = 0;
+  bool ret = AnalysisUtils::Match::R(eta,phi,coll,index,deltaR);
+  if (!ret) return false;
+  element = (*coll)[index];
+  return true;
+}
+
+template <class COLL, class ELEMENT > inline bool IAnalysisTools::matchR
+(const double eta, const double phi, const double e, COLL *coll, ELEMENT *&element, 
+ double &deltaR, double &deltaE) const
+{
+  int index = 0;
+  bool ret = AnalysisUtils::Match::R(eta,phi,e, coll,index,deltaR, deltaE);
+  if (!ret) return false;
+  element = (*coll)[index];
+  return true;
+}
+
+template <class COLL> inline bool IAnalysisTools::matchR
+(const INavigable4Momentum *t, COLL *coll, int &index, double &deltaR, int pdg) const
+{
+  return AnalysisUtils::Match::R(t,coll,index,deltaR,pdg);
+}
+
+template <class COLL> inline bool IAnalysisTools::matchR
+(const double eta, const double phi, COLL *coll, int &index, double &deltaR, int pdg) const
+{
+  return AnalysisUtils::Match::R(eta,phi,coll,index,deltaR,pdg);
+}
+
+template <class COLL> inline bool IAnalysisTools::matchR
+(const INavigable4Momentum *t, COLL *coll, int &index, double &deltaR, int pdg, double &deltaE) const
+{
+  return AnalysisUtils::Match::R(t,coll,index,deltaR,pdg,deltaE);
+}
+
+template <class COLL> inline bool IAnalysisTools::matchR
+(const double eta, const double phi, const double e, COLL *coll, int &index, double &deltaR, 
+ int pdg, double &deltaE) const
+{
+  return AnalysisUtils::Match::R(eta,phi,e,coll,index,deltaR,pdg,deltaE);
+}
+
+template <class COLL, class ELEMENT> inline bool IAnalysisTools::matchR
+(const INavigable4Momentum *t, COLL *coll, ELEMENT *&element, double &deltaR, int pdg) const
+{
+  int index = 0;
+  bool ret = AnalysisUtils::Match::R(t,coll,index,deltaR,pdg);
+  if (!ret) return false;
+  element = (*coll)[index];
+  return true;
+}
+
+template <class COLL, class ELEMENT> inline bool IAnalysisTools::matchR
+(const INavigable4Momentum *t, COLL *coll, ELEMENT *&element, double &deltaR, int pdg, double &deltaE) const
+{
+  int index = 0;
+  bool ret = AnalysisUtils::Match::R(t,coll,index,deltaR,pdg,deltaE);
+  if (!ret) return false;
+  element = (*coll)[index];
+  return true;
+}
+
+template <class COLL, class ELEMENT> inline bool IAnalysisTools::matchR
+(const double eta, const double phi, COLL *coll, ELEMENT *&element, double &deltaR, int pdg) const
+{
+  int index = 0;
+  bool ret = AnalysisUtils::Match::R(eta,phi,coll,index,deltaR,pdg);
+  if (!ret) return false;
+  element = (*coll)[index];
+  return true;
+}
+
+template <class COLL, class ELEMENT> inline bool IAnalysisTools::matchR
+(const double eta, const double phi, const double e, COLL *coll, ELEMENT *&element, double &deltaR, 
+ int pdg, double &deltaE) const
+{
+  int index = 0;
+  bool ret = AnalysisUtils::Match::R(eta,phi,e,coll,index,deltaR,pdg,deltaE);
+  if (!ret) return false;
+  element = (*coll)[index];
+  return true;
+}
+
+template <class COLL> inline void IAnalysisTools::sortPT (COLL *coll) const
+{
+  AnalysisUtils::Sort::pT<COLL>(coll);
+}
+
+template <class COLL> inline void IAnalysisTools::sortE (COLL *coll) const
+{
+  AnalysisUtils::Sort::e<COLL>(coll);
+}
+
+template <class COLL> inline void IAnalysisTools::sortEta (COLL *coll) const
+{
+  AnalysisUtils::Sort::eta<COLL>(coll);
+}
+
+template <class COLL> inline void IAnalysisTools::sortPhi (COLL *coll) const
+{
+  AnalysisUtils::Sort::phi<COLL>(coll);
+}
+
+template <class COLL> inline void IAnalysisTools::classifyCharge (const COLL *coll,
+								  std::vector<typename COLL::value_type> &pos,
+								  std::vector<typename COLL::value_type> &neg) const
+{
+  AnalysisUtils::Classify::charge<COLL>(coll,pos,neg);
+}
+
+template <class CALLER, class CRITERIA, class COLL> inline StatusCode IAnalysisTools::select
+(CALLER *caller, CRITERIA criteria, COLL *coll, const std::string &key, const bool lock) const
+{
+  MsgStream log(msgSvc(), name());
+
+  // create new container with the view mode
+  COLL * newColl = new COLL(SG::VIEW_ELEMENTS);
+
+  /// record the container in SG
+  StatusCode sc = evtStore()->record(newColl, key);
+  if (sc.isFailure())
+    {
+      log << MSG::ERROR << "Unable to record Container in SG with key=" << key << endreq; 
+      return sc;
+    }
+
+  // loop over all elements
+  typename COLL::const_iterator it  = coll->begin();
+  typename COLL::const_iterator itE = coll->end();
+  for (; it != itE; ++it)
+    // selection
+    if (criteria(*it,caller))
+      newColl->push_back(*it);
+  
+  // lock the container
+  if (lock)
+    evtStore()->setConst(newColl);
+
+  return StatusCode::SUCCESS;
+}
diff --git a/PhysicsAnalysis/AnalysisCommon/AnalysisTools/AnalysisTools/selection.xml b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/AnalysisTools/selection.xml
new file mode 100755
index 0000000000000000000000000000000000000000..d2cc171409900f34a0c47f813f3935baba1a062d
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/AnalysisTools/selection.xml
@@ -0,0 +1,7 @@
+<lcgdict>
+
+  <class name="AANTEventSelector" />
+  <class name="AANTTreeGate" />
+  <class name="IAnalysisTools" />
+
+</lcgdict>
diff --git a/PhysicsAnalysis/AnalysisCommon/AnalysisTools/cmt/requirements b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/cmt/requirements
new file mode 100755
index 0000000000000000000000000000000000000000..ecb03df8ee2f72604f804c25f0caed18d8c5f465
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/cmt/requirements
@@ -0,0 +1,48 @@
+package AnalysisTools
+
+author Tadashi Maeno       <Tadashi.Maeno@cern.ch>
+
+use AtlasPolicy         AtlasPolicy-*
+use GaudiInterface      GaudiInterface-* 		External
+
+use AtlasPython		AtlasPython-*		External
+
+
+use NavFourMom		NavFourMom-*	    		Event #KC adding this for the time being
+use McParticleEvent	McParticleEvent-*		PhysicsAnalysis/TruthParticleID
+
+use AthenaBaseComps	AthenaBaseComps-*		Control
+use StoreGate           StoreGate-*      		Control
+use DataModel           DataModel-*      		Control
+
+use AnalysisUtils       AnalysisUtils-*  		PhysicsAnalysis/AnalysisCommon
+
+
+
+private
+use AtlasROOT           AtlasROOT-*      		External
+use AtlasPOOL           AtlasPOOL-*      		External
+use AtlasCORAL		AtlasCORAL-*			External
+use SGTools		SGTools-*      		        Control
+use PersistentDataModel PersistentDataModel-*           Database
+use AthenaPoolUtilities AthenaPoolUtilities-* 	        Database/AthenaPOOL
+use EventInfo           EventInfo-*      		Event
+
+# Checkreq says we don't need this, but we really do
+# (as of AnalysisTools-00-05-06).
+use RootCollection      RootCollection-*                Database/APR
+end_private
+
+
+library AthAnalysisTools *.cxx components/*.cxx
+apply_pattern named_component_library library="AthAnalysisTools"
+
+apply_pattern declare_joboptions files="*.py"
+apply_pattern declare_python_modules files="*.py"
+
+private
+
+use AtlasReflex  AtlasReflex-*  External -no_auto_imports
+
+apply_pattern lcgdict dict=AnalysisTools selectionfile=selection.xml \
+        headerfiles="../AnalysisTools/AnalysisToolsDict.h"
diff --git a/PhysicsAnalysis/AnalysisCommon/AnalysisTools/doc/mainpage.h b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/doc/mainpage.h
new file mode 100755
index 0000000000000000000000000000000000000000..71149acfc2d9809bad5f8df05a9eb3ac06ef3509
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/doc/mainpage.h
@@ -0,0 +1,22 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+\mainpage AnalysisTools
+
+\section introductionAnalysisTools Introduction
+This package contains general Gaudi-Tools
+
+\section packagecontentAnalysisTools Package Contents
+AnalysisTools contains the following classes:
+
+- AnalysisTools : provides I/F to analysis tools
+
+\section used_packagesAnalysisTools Used packages
+@htmlinclude used_packages.html
+
+\section requirementsAnalysisTools Requirements
+@include requirements
+
+*/
diff --git a/PhysicsAnalysis/AnalysisCommon/AnalysisTools/python/AnalysisToolsConf.py b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/python/AnalysisToolsConf.py
new file mode 100644
index 0000000000000000000000000000000000000000..6afa1be99a0a9a9fc4da8e97beed8c522edf1c33
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/python/AnalysisToolsConf.py
@@ -0,0 +1,8 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+from AthAnalysisToolsConf import *
+
+from AthenaCommon.Logging import log as _msg
+_msg.warning ('    AnalysisTools.AnalysisToolsConf is DEPRECATED !')
+_msg.warning ('use AnalysisTools.AthAnalysisToolsConf instead')
+
diff --git a/PhysicsAnalysis/AnalysisCommon/AnalysisTools/python/__init__.py b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/python/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e9ee48cc427b186bf46781f51e9adddd87641e3f
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/python/__init__.py
@@ -0,0 +1,3 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# hook for the AnalysisTools py-module
diff --git a/PhysicsAnalysis/AnalysisCommon/AnalysisTools/share/AANTEventSelector_jobOptions.py b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/share/AANTEventSelector_jobOptions.py
new file mode 100755
index 0000000000000000000000000000000000000000..68c6e7b3136281a0b7e82a5342400bdbce9b0dba
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/share/AANTEventSelector_jobOptions.py
@@ -0,0 +1,14 @@
+theApp.Dlls += ["AnalysisTools"]
+theApp.ExtSvc += [ "AANTEventSelector/EventSelector"]
+theApp.EvtSel = "EventSelector"
+
+# set C++->Python converter for TTree
+import PyCintex
+PyCintex.loadDictionary("AnalysisToolsDict")
+aantGate = PyCintex.Namespace('').AANTTreeGate
+def aantConvFunc():
+    return aantGate.getTree()
+
+EventSelector = Service( "EventSelector" )
+EventSelector.Converter = "aantConvFunc"
+    
diff --git a/PhysicsAnalysis/AnalysisCommon/AnalysisTools/share/AANTEvtSelTest_jobOptions.py b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/share/AANTEvtSelTest_jobOptions.py
new file mode 100755
index 0000000000000000000000000000000000000000..54da147c8d748008739fc83d45e86df53d134b65
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/share/AANTEvtSelTest_jobOptions.py
@@ -0,0 +1,20 @@
+# read AANT
+include( "AnalysisTools/AANTEventSelector_jobOptions.py" )
+
+EventSelector = Service( "EventSelector" )
+EventSelector.InputCollections = [ "user.KyleCranmer.eleJetStudy.Wenu.cone7.etoe.AANT1._00003.root" ]
+
+# callback
+def selection(tree):
+    print "PyExecute begin"
+    print tree.All_E.size()
+    for i in range (tree.All_E.size()):
+        print tree.All_E[i]
+    if tree.All_E.size() > 2:
+        return True
+    return False
+
+EventSelector.Selection = "selection"
+
+# Number of Events to process
+theApp.EvtMax = 10
diff --git a/PhysicsAnalysis/AnalysisCommon/AnalysisTools/src/AANTEventContext.cxx b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/src/AANTEventContext.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..a1f25d6f09a72c244191825bbc6f9d10a99a3d6f
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/src/AANTEventContext.cxx
@@ -0,0 +1,36 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "AnalysisTools/AANTEventContext.h"
+
+//________________________________________________________________________________
+AANTEventContext::AANTEventContext(const IEvtSelector* selector)
+  : m_evtSelector(selector)
+{
+}
+
+//________________________________________________________________________________
+AANTEventContext& AANTEventContext::operator=(const AANTEventContext& ctxt)
+{
+  if (this != &ctxt)
+    m_evtSelector = ctxt.m_evtSelector;
+  return *this;
+}
+
+//________________________________________________________________________________
+AANTEventContext::AANTEventContext(const AANTEventContext& ctxt)
+  : IEvtSelector::Context(), m_evtSelector(ctxt.m_evtSelector)
+{
+}
+
+//________________________________________________________________________________
+AANTEventContext::~AANTEventContext()
+{
+}
+
+//________________________________________________________________________________
+void* AANTEventContext::identifier() const
+{
+  return ((void*)(m_evtSelector));
+}
diff --git a/PhysicsAnalysis/AnalysisCommon/AnalysisTools/src/AANTEventSelector.cxx b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/src/AANTEventSelector.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..008ac0d3e62856087846fcbeeef1ebc322c3e930
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/src/AANTEventSelector.cxx
@@ -0,0 +1,292 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//====================================================================
+//	AANTEventSelector.cxx
+//====================================================================
+// 
+// Include files.
+
+#include "AnalysisTools/AANTEventSelector.h"
+#include "AnalysisTools/AANTEventContext.h"
+
+#include "GaudiKernel/SvcFactory.h"
+#include "GaudiKernel/ISvcLocator.h"
+#include "GaudiKernel/StatusCode.h"
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/ClassID.h"
+
+#include "EventInfo/EventInfo.h"
+#include "EventInfo/EventType.h"
+#include "EventInfo/EventID.h"
+#include "StoreGate/StoreGate.h" 
+
+#include "TChain.h"
+
+TChain *AANTTreeGate::m_tree = 0;
+
+// Constructor.
+AANTEventSelector::AANTEventSelector(const std::string& name, ISvcLocator* svcloc)
+  : AthService(name, svcloc),
+    m_storeGate(0),
+    m_skipEvents(0), m_numEvents(0), m_totalNEvents(0),
+    m_tree(0),
+    m_runNumber(0),
+    m_eventNumber(0),
+    m_convFunc(0), m_selectionFunc(0)
+{
+  declareProperty("InputCollections",          m_inputCollectionsProp);
+  declareProperty("SkipEvents",                m_skipEvents = 0);
+  declareProperty("Converter",                 m_strConverter = "");
+  declareProperty("Selection",                 m_strSelection = "");
+}
+
+
+// Destructor.
+AANTEventSelector::~AANTEventSelector() 
+{
+  if (m_tree) 
+    delete m_tree;
+}
+
+
+// AANTEventSelector::initialize().
+StatusCode AANTEventSelector::initialize()
+{
+  // Initialize the Service base class.
+  StatusCode sc = Service::initialize();
+  
+  // Create a message stream.
+  MsgStream log(messageService(), name());
+
+  log << MSG::DEBUG << "initialize()" << endreq;
+
+  if (sc.isFailure())
+    {
+      log << MSG::ERROR << "Unable to initialize Service base class" << endreq;
+      return sc;
+    }
+
+  sc = service("StoreGateSvc", m_storeGate);
+  if (sc.isFailure())
+    {
+      log << MSG::ERROR << "Unable to retrieve pointer to StoreGateSvc" << endreq;
+      return sc;
+    }
+  
+
+  // parse jobO
+  if (m_inputCollectionsProp.value().size() == 0)
+    {
+      log << MSG::ERROR << "Use the property:"
+	  << " EventSelector.InputCollections = [ \"<collectionName>\" ] (list of collections)"
+	  << endreq;
+      return StatusCode::FAILURE;
+    }
+  // create TChain
+  m_tree = new TChain("CollectionTree");
+  std::vector<std::string> inputColl = m_inputCollectionsProp.value();
+  std::vector<std::string>::iterator it  = inputColl.begin();
+  std::vector<std::string>::iterator itE = inputColl.end();
+  for (; it!=itE; ++it)
+    {
+      log << MSG::DEBUG << "Add : " << *it << endreq;      
+      m_tree->Add(it->c_str());
+    }
+
+  // get total number of events
+  m_totalNEvents = m_tree->GetEntries();
+  
+  log << MSG::DEBUG << "Total Events : " << m_totalNEvents << endreq;      
+  
+  // RunNumber and EventNumber
+  m_tree->SetBranchAddress("EventNumber",&m_eventNumber);
+  m_tree->SetBranchAddress("RunNumber",  &m_runNumber);
+
+  // set TTree to AANTTreeGate
+  AANTTreeGate::setTree(m_tree);
+
+  // selection criteria
+  log << MSG::DEBUG << "Load Sel: " << m_strSelection << " from __main__" << endreq;      
+  char smain[] = "__main__";
+  m_selectionFunc = PyObject_GetAttr(PyImport_AddModule(smain),PyString_FromString(m_strSelection.c_str()));
+  if (m_selectionFunc == NULL)
+    {
+      log << MSG::ERROR << "Could not load sel : " << m_strSelection << endreq;
+      return StatusCode::FAILURE;
+    }
+
+  log << MSG::DEBUG << "Load Cnv: " << m_strConverter << " from __main__" << endreq;      
+  m_convFunc = PyObject_GetAttr(PyImport_AddModule(smain),PyString_FromString(m_strConverter.c_str()));
+  if (m_convFunc == NULL)
+    {
+      log << MSG::ERROR << "Could not load conv : " << m_strConverter << endreq;
+      return StatusCode::FAILURE;
+    }
+
+  return  StatusCode::SUCCESS;
+}
+
+
+// createContext
+StatusCode AANTEventSelector::createContext(IEvtSelector::Context*& it) const
+{
+  it = new AANTEventContext(this);
+  return StatusCode::SUCCESS;
+}
+
+
+// Implementation of IEvtSelector::next().
+StatusCode AANTEventSelector::next(IEvtSelector::Context& it)const 
+{
+  return this->next(it,0);
+}
+
+
+// jump
+StatusCode AANTEventSelector::next(IEvtSelector::Context& it, int jump) const
+{
+  MsgStream log(messageService(), name());
+  log << MSG::DEBUG << "next(" << jump << ") : iEvt " << m_numEvents << endreq;
+
+  // get EventContext
+  AANTEventContext* ct = dynamic_cast<AANTEventContext*>(&it);
+  if (ct == 0)
+    {
+      log << MSG::ERROR << "Could not dcast to AANTEventContext" << endreq;
+      return StatusCode::FAILURE;
+    }
+  // jump
+  if (((m_numEvents + jump) >= 0) and ((m_numEvents + jump) < m_totalNEvents))
+    {
+      // move pointer
+      m_numEvents += jump;
+      // get entry
+      m_tree->GetEntry(m_numEvents);
+      // increment pointer
+      ++m_numEvents;
+      // convert C++ obj to Python obj
+      PyObject *pyObj = PyObject_CallObject(m_convFunc,NULL); 
+      // execute Python code fragment
+      PyObject *tup = Py_BuildValue((char*)"(O)",pyObj);
+      PyObject *ret = PyObject_CallObject(m_selectionFunc,tup); 
+      // decrement reference counters
+      Py_DECREF(pyObj); 
+      Py_DECREF(tup); 
+      if (ret != NULL and PyObject_IsTrue(ret))
+	{
+	  // decrement reference counters
+	  Py_DECREF(ret); 
+	  // EventInfo
+	  EventType *peT = new EventType();
+	  EventInfo *evtInfo = new EventInfo( new EventID(m_runNumber,m_eventNumber,0),peT);
+	  StatusCode sc = m_storeGate->record(evtInfo, "AANTEventInfo");
+	  if (sc.isFailure())
+	    {
+	      log << MSG::ERROR << "Could not record AANTEventInfo" << endreq;
+	      return sc;
+	    }
+	  // return
+	  return StatusCode::SUCCESS;
+	}
+      else
+	{
+	  // decrement reference counters
+	  Py_XDECREF(ret); 
+	  // next
+	  return this->next(it,0);
+	}
+    }
+  else
+    {
+      // EOF
+      //ct = new AANTEventContext(0);
+      return StatusCode::FAILURE; 
+    }
+
+  // should not be here...
+  log << MSG::ERROR << "jumping out of evt-boundaries" << endreq;
+  return StatusCode::FAILURE;
+}
+
+
+// previous
+StatusCode AANTEventSelector::previous(IEvtSelector::Context& it) const
+{
+  return this->next(it,-1);
+}
+
+
+// previous jump
+StatusCode AANTEventSelector::previous(IEvtSelector::Context& it, int jump) const
+{
+  return this->next(it,-jump);
+}
+
+
+// last
+StatusCode AANTEventSelector::last(IEvtSelector::Context& /*it*/) const
+{
+  MsgStream log(messageService(), name());
+  log << MSG::ERROR << "AANTEventSelector::last() not implemented" << endreq;
+  return StatusCode::FAILURE;
+}
+
+
+// resetCriteria
+StatusCode AANTEventSelector::resetCriteria(const std::string& /*criteria*/, IEvtSelector::Context& /*ctxt*/) const
+{
+  MsgStream log(messageService(), name());
+  log << MSG::ERROR << "AANTEventSelector::resetCriteria() not implemented" << endreq;
+  return StatusCode::FAILURE;
+}
+
+
+// rewind
+StatusCode AANTEventSelector::rewind(IEvtSelector::Context& /*it*/) const
+{
+  MsgStream log(messageService(), name());
+  log << MSG::ERROR << "AANTEventSelector::rewind() not implemented" << endreq;
+  return StatusCode::FAILURE;
+}
+
+
+// createAddress
+StatusCode AANTEventSelector::createAddress(const IEvtSelector::Context& /*it*/,
+					    IOpaqueAddress*& /*iop*/) const
+{
+  return StatusCode::SUCCESS;
+}
+
+
+// releaseContext
+StatusCode AANTEventSelector::releaseContext(IEvtSelector::Context*& /*it*/) const
+{
+  MsgStream log(messageService(), name());
+  log << MSG::ERROR << "AANTEventSelector::releaseContext() not implemented" << endreq;
+  return StatusCode::FAILURE;
+}
+
+
+// Implementation of IInterface::queryInterface.
+StatusCode AANTEventSelector::queryInterface(const InterfaceID& riid, void** ppvInterface)
+{
+  if (riid == IEvtSelector::interfaceID())  
+     {
+       *ppvInterface = (IEvtSelector*)this;
+     }
+  else if (riid == IProperty::interfaceID())
+     {
+       *ppvInterface = (IProperty*)this;
+     }
+   else   
+     {
+       return Service::queryInterface(riid, ppvInterface);
+     }
+   
+   addRef();
+   
+   return StatusCode::SUCCESS; 
+}
+
diff --git a/PhysicsAnalysis/AnalysisCommon/AnalysisTools/src/AANTupleStream.cxx b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/src/AANTupleStream.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..fbc0c46c8594f9110da0efe0d07f87934045a91d
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/src/AANTupleStream.cxx
@@ -0,0 +1,789 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "AnalysisTools/AANTupleStream.h"
+#include "AnalysisTools/AANTupleParams.h"
+
+#include "AnalysisUtils/AANTTreeMap.h"
+
+#include "AthenaPoolUtilities/AthenaAttributeList.h"
+
+#include "GaudiKernel/Tokenizer.h"
+#include "GaudiKernel/AlgFactory.h"
+#include "GaudiKernel/IAlgManager.h"
+#include "GaudiKernel/ISvcLocator.h"
+#include "GaudiKernel/IAddressCreator.h"
+#include "GaudiKernel/IOpaqueAddress.h"
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/ITHistSvc.h"
+#include "GaudiKernel/IJobOptionsSvc.h"
+#include "GaudiKernel/ListItem.h"
+#include "GaudiKernel/ServiceHandle.h"
+
+#include "GaudiKernel/IIoComponentMgr.h"
+#include "StoreGate/StoreGateSvc.h"
+#include "SGTools/DataProxy.h"
+#include "PersistentDataModel/DataHeader.h"
+#include "StoreGate/DataHandle.h"
+
+#include "RootCollection/AttributeListLayout.h"
+#include "CoralBase/AttributeList.h"
+#include "CoralBase/AttributeListSpecification.h"
+
+#include "EventInfo/EventInfo.h"
+#include "EventInfo/EventID.h"
+#include "EventInfo/TriggerInfo.h"
+
+#include "TFile.h"
+#include "TTree.h"
+#include "TText.h"
+#include "TBranch.h"
+#include "TInterpreter.h"
+
+#include <map>
+#include <string>
+#include <algorithm>
+
+using namespace AANTupleParams;
+
+// Standard Constructor
+AANTupleStream::AANTupleStream(const std::string& name, ISvcLocator* pSvcLocator) 
+  : AthAlgorithm(name, pSvcLocator),
+    m_persSvc      ("EventPersistencySvc", name),
+    m_attribSpec(0),
+    m_schemaDone(false),
+    m_tree(0),
+    m_tokenBranch(0),
+    m_tHistSvc     ("THistSvc", name)
+{
+  declareProperty("OutputName",           m_fileName="AANTuple.root");
+  declareProperty("ExtraRefNames",        m_extraRefNames);
+  declareProperty("WriteInputDataHeader", m_writeInputDH=false);
+  declareProperty("ExistDataHeader",      m_existDH=true);
+  declareProperty("StreamName",           m_streamName=c_streamName);
+  declareProperty("LateSchemaWriting",    m_lateSchema=false);
+  declareProperty("TreeName",             m_treeName=c_treeName);
+  declareProperty("Macro",                m_macro="");
+  declareProperty("Members",              m_membersNames);
+  declareProperty("FilterAlgs",           m_acceptNames);
+
+  m_tokenCString[0] = '\0';
+}
+
+
+// Standard Destructor
+AANTupleStream::~AANTupleStream()  
+{
+}
+
+
+// initialize data writer
+StatusCode AANTupleStream::initialize() 
+{
+  ATH_MSG_DEBUG ("In initialize ");
+  // register with the I/O component manager
+  {
+    ServiceHandle<IIoComponentMgr> iomgr ("IoComponentMgr", this->name());
+    if ( !iomgr.retrieve().isSuccess() ) {
+      ATH_MSG_ERROR ("Could not retrieve IIoComponentMgr/IoComponentMgr !");
+      return StatusCode::FAILURE;
+    }
+    if ( !iomgr->io_register (this).isSuccess() ) {
+      ATH_MSG_ERROR ("Could not register with the I/O component mgr !");
+      return StatusCode::FAILURE;
+    }
+    if ( !iomgr->io_register (this,
+			      IIoComponentMgr::IoMode::WRITE,
+			      m_fileName).isSuccess() ) {
+      ATH_MSG_ERROR ("Could not register [" << this->name() << "]["
+		     << m_fileName << "] with the I/O component manager !");
+      return StatusCode::FAILURE;
+    }
+  }
+
+  // StoreGateSvc
+  StatusCode sc = evtStore().retrieve();
+  if ( !sc.isSuccess() )
+    {
+      ATH_MSG_ERROR ("Could not locate default store");
+      return sc;
+    }
+
+  // set up the persistency service:
+  sc = m_persSvc.retrieve();
+  if ( !sc.isSuccess() )
+    {
+      ATH_MSG_ERROR ("Could not locate persistency service");
+      return sc;
+    }
+
+  // instantiate AttrListSpec and add attributes for Run# and Event# 
+  m_attribSpec = new coral::AttributeListSpecification;
+  m_attribSpec->extend( name_RunNumber,   "unsigned int" );
+  m_attribSpec->extend( name_EventNumber, "unsigned int" );
+
+  // Add on specification for extra refs
+  std::vector<std::string> extraRefs = m_extraRefNames.value();
+  for (unsigned int i = 0; i < extraRefs.size(); ++i)
+    {
+      // Append _ref to name of attribute
+      std::string name = extraRefs[i] + "_ref";
+      m_attribSpec->extend(name, "string");
+    }
+
+  if (!m_lateSchema) {
+    sc = initSchema();
+    if (sc.isFailure())
+      return sc;
+  }
+
+  // initialize sub-algos
+  sc = initialize_subAlgos();
+  if ( sc.isFailure() )
+    {
+      ATH_MSG_ERROR ("Could not initialize sub-algos");
+      return sc;
+    }      
+
+  // get filters
+  sc = getFilters();
+  if ( sc.isFailure() )
+    {
+      ATH_MSG_ERROR ("Could not get filters");
+      return sc;
+    }      
+
+  ATH_MSG_DEBUG ("End initialize ");
+  
+  return StatusCode::SUCCESS;
+}
+
+
+// initialize output collection
+StatusCode AANTupleStream::initCollection() 
+{
+  // write schema
+  writeAttributeListSpecification();
+
+  // setup TTree
+  setupTree();
+
+  // setup Token
+  m_tokenBranch = m_tree->GetBranch(c_tokenBranchName);
+  m_tokenBranch->SetAddress(m_tokenCString);
+
+  return StatusCode::SUCCESS;
+}
+
+
+// terminate data writer
+StatusCode AANTupleStream::finalize() 
+{
+  ATH_MSG_INFO ("finalize");
+
+  // exec macro
+  if (m_macro != "")
+    {
+      // save current dir
+      std::string curDir = gDirectory->GetPath();
+      // go to the root dir of output file
+      gDirectory->cd((m_fileName+":/").c_str());
+      // exec
+      // G__exec_tempfile(m_macro.c_str());
+      // MN: that should be the equivalent new call:
+      gInterpreter->ExecuteMacro(m_macro.c_str());
+      // back to the current dir
+      gDirectory->cd(curDir.c_str());
+    }
+
+  return StatusCode::SUCCESS;
+}
+
+
+// Work entry point
+StatusCode AANTupleStream::execute() 
+{
+  StatusCode sc;
+
+  if (!m_schemaDone) {
+    sc = initSchema();
+    if (sc.isFailure())
+      return sc;
+  }
+
+  // execute sub-algos
+  sc = execute_subAlgos();
+  if ( sc.isFailure() )
+    {
+      ATH_MSG_ERROR ("Could not execute sub-algos");
+      return sc;
+    }      
+
+  std::map<std::string,std::string> inputRefs;
+  std::string ref;
+
+  // Get tokens specified by item list
+  if (m_existDH)
+    {
+      // get token
+      const DataHandle<DataHeader> beg; 
+      const DataHandle<DataHeader> ending; 
+      StatusCode status = evtStore()->retrieve(beg,ending);
+      if (status.isFailure() || beg==ending)
+	{
+	  ATH_MSG_WARNING ("No DataHeaders present in StoreGate");
+	  return  StatusCode::FAILURE;
+	}
+
+      // look for header
+      for (; beg != ending; ++beg)
+	if (m_writeInputDH == beg->isInput()) break;
+
+      if (beg==ending)
+	{
+	  ATH_MSG_WARNING ("No appropriate DataHeader present in StoreGate");
+	  return  StatusCode::FAILURE;
+	}
+
+      // get the ref
+      while (getRef(ClassID_traits<DataHeader>::ID(), beg.key(), ref) == StatusCode::FAILURE)
+	{
+	  ++beg;
+	  if (beg==ending)
+	    {
+	      ATH_MSG_ERROR ("No refs found");
+	      return StatusCode::FAILURE;
+	    }
+	}
+
+      ATH_MSG_DEBUG ("Found token: Key=" << beg.key() << ", Ref=" << ref);
+
+      // Get a single input header ref if requested
+      const DataHeader* hdr=0;
+      hdr = beg;
+      if (hdr->sizeProvenance())
+	{
+	  std::vector<DataHeaderElement>::const_iterator it =
+	    (const_cast<DataHeader*>(hdr)->beginProvenance());
+	  std::vector<DataHeaderElement>::const_iterator itE = 
+	    (const_cast<DataHeader*>(hdr)->endProvenance());
+	  // grab refs for those
+	  for (; it!=itE; ++it)
+	    {
+	      std::string tmpRef = (*it).getToken() != NULL
+		? (*it).getToken()->toString()
+		: "";
+	      inputRefs.insert(std::make_pair(it->getKey(),tmpRef));
+	      ATH_MSG_DEBUG ("Found ref for input header: Key=" << it->getKey()
+			     << ", Ref=" << tmpRef);
+	    }
+	}
+    }
+  
+  // create Attrlist, add attributes and if extra ref is requested, append to the end
+
+  ATH_MSG_DEBUG ("create AttributeList");
+  // AthenaAttributeList  newAttr(*m_attribSpec);
+  coral::AttributeList newAttr(*m_attribSpec);
+
+  // retrieve event info
+  const EventInfo* eventInfo;
+  sc = evtStore()->retrieve( eventInfo );
+  if (sc.isFailure())
+    {
+      ATH_MSG_ERROR ("Cannot get event info.");
+      return sc;
+    }
+
+  // add global event tag data
+  unsigned int runNumber   = eventInfo->event_ID()->run_number();
+  unsigned int eventNumber = eventInfo->event_ID()->event_number();
+  newAttr[ name_RunNumber   ].setValue( runNumber );
+  newAttr[ name_EventNumber ].setValue( eventNumber );
+
+  // add back nav ref's
+  ATH_MSG_DEBUG ("Append extra ref");
+  std::vector<std::string> extraRefs = m_extraRefNames.value();
+  std::map<std::string,std::string>::iterator itRef  = inputRefs.begin();
+  std::map<std::string,std::string>::iterator itRefE = inputRefs.end();
+  for (; itRef != itRefE; ++itRef)
+    {
+      std::string name = itRef->first + "_ref";
+      if (extraRefs.end() != std::find(extraRefs.begin(),extraRefs.end(),itRef->first))
+	{
+	  newAttr[name].setValue(std::string(itRef->second));
+	  ATH_MSG_DEBUG (" Added extra ref to new attribute list - name: " 
+			 << name << " " << itRef->second);
+	}
+    }
+
+  // write if filters passed
+  if (isEventAccepted())
+    {
+      ATH_MSG_DEBUG ("write attributes to collection");
+  
+      // write token plus attributes
+      try
+	{
+	  writeTokenAttrList(ref, newAttr);
+	} 
+      catch (std::exception &e)
+	{
+	  ATH_MSG_ERROR 
+	    ("Caught exception from collection add of Pool attributes. "
+	     "Message: " << e.what());
+	  return StatusCode::FAILURE;
+	}
+    }
+  
+  ATH_MSG_DEBUG ("done successfully");
+
+  return StatusCode::SUCCESS;
+}
+
+  
+void AANTupleStream::writeAttributeListSpecification()
+{
+  // go to the root dir of output file
+  TDirectory::TContext save (0);
+  gDirectory->cd((m_fileName+":/").c_str());
+
+  AttributeListLayout all;
+  // store schema in the schema object
+  for( coral::AttributeListSpecification::const_iterator iter = m_attribSpec->begin();
+       iter != m_attribSpec->end(); ++iter) {
+     all.m_layout.push_back( make_pair( iter->name(), iter->typeName() ) );
+  }
+  // write schema object
+  all.Write(c_attributeListLayoutName);
+}
+
+
+void AANTupleStream::setupTree()
+{
+  static std::map<std::string,char> typeDict;
+  if (!typeDict.size())
+    {
+      typeDict["double"] = 'D';   
+      typeDict["long double"] = 'D';    // only 64 bit doubles are supported 
+      typeDict["float"] = 'F';
+      typeDict["int"] = 'i';
+      typeDict["unsigned int"] = 'I';
+      typeDict["long"] = 'i';           // support for 64 bit integers introduced with ROOT 4.00/08 
+      typeDict["unsigned long"] = 'I';  // support for 64 bit integers introduced with ROOT 4.00/08 
+      typeDict["short"] = 's';
+      typeDict["unsigned short"] = 'S';
+      typeDict["char"] = 'b';           // AttributeLists's "get_root_type_char(...)" returned 'C' ??? 
+      typeDict["unsigned char"] = 'B';  // AttributeLists's "get_root_type_char(...)" returned 's' ???
+      typeDict["bool"] = 'B';           // AttributeLists's "get_root_type_char(...)" returned 'i' ???
+      typeDict["string"] = 'C';
+      typeDict["Token"] = 'C';
+    }
+
+  // go to the root dir of output file
+  TDirectory::TContext save (0);
+  gDirectory->cd((m_fileName+":/").c_str());
+  
+  // instantiate TTree
+  m_tree = new TTree(m_treeName.c_str(), m_treeName.c_str());
+
+  // add branches for attributes
+  for(coral::AttributeListSpecification::const_iterator iter=m_attribSpec->begin(); iter!=m_attribSpec->end(); ++iter)
+    {
+      std::string type = "/?";
+      type[1] = typeDict[iter->typeName()];
+      std::string leaflist = iter->name() + type;
+      m_tree->Branch(iter->name().c_str(),0,leaflist.c_str());
+    }
+
+  // add Token branch
+  std::string leaflist = c_tokenBranchName;
+  leaflist += "/C";
+  m_tree->Branch(c_tokenBranchName,0,leaflist.c_str());
+
+  // set TTree
+  AANTTreeMap::setTree(m_streamName,m_tree);
+}
+
+
+// Get the string form of a ref for a given clid and key
+StatusCode AANTupleStream::getRef(CLID id, const std::string& key, std::string& ref)
+{
+  // Must access the SG proxy to get the IOpaqueAddress
+  SG::DataProxy* itemProxy = 0;
+  ATH_MSG_DEBUG ("Retrieving proxy for " << id << " " << key);
+  itemProxy = evtStore()->proxy(id, key);
+  if (!itemProxy)
+    {
+      ATH_MSG_ERROR ("Could not get proxy ");
+      return(StatusCode::FAILURE);
+    }
+  else
+    {
+      ATH_MSG_DEBUG (" found proxy for ("<< id << ",\"" << key << "\") ");
+    }
+  
+  if (!itemProxy)
+    {
+      ATH_MSG_ERROR ("Empty proxy ");
+      return(StatusCode::FAILURE);
+    }
+  
+  // Get IOpaqueAddress from the proxy
+  IOpaqueAddress* addr = itemProxy->address();
+  if (!addr)
+    {
+      ATH_MSG_DEBUG ("Could not get address for clid "
+		     << itemProxy->clID() << " " << itemProxy->name());
+      return( StatusCode::FAILURE);
+    }
+
+  // Convert IOpaqueAddress to string via the persistency
+  // service. And then remove header to extract the token.
+  std::string saddr;
+
+  StatusCode sc = m_persSvc->convertAddress(addr, saddr);   
+  if (sc.isFailure()) 
+    {
+      ATH_MSG_ERROR 
+	("Could not get string from IOpaqueAddress for clid " << id
+	 << " " << key
+	 << " is BAD_STORAGE_TYPE: "<< (sc == IConverter::BAD_STORAGE_TYPE));
+      return( StatusCode::FAILURE);
+    }
+		    
+
+  // We assume here some knowledge of the form of the AthenaPool
+  // string address
+  std::string hdr;
+  sc = splitAddress(saddr, " /> ", hdr, ref);
+  if (sc.isFailure()) 
+    {
+      ATH_MSG_ERROR ("Could not get split off token. string address " << saddr);
+      return( StatusCode::FAILURE);
+    }
+  
+  ATH_MSG_DEBUG ("String address " << ref);
+
+  return StatusCode::SUCCESS;
+}
+
+
+// Extract the address header and data from an IOpaqueAddress in
+// string form
+StatusCode AANTupleStream::splitAddress( const std::string& address,
+					 const std::string& match,
+					 std::string&       address_header,
+					 std::string&       address_data ) const
+{
+  ATH_MSG_DEBUG ("splitAddress " << endreq
+		 << "   address :  " << address
+		 << "   match :  " << match);
+  
+  std::string::size_type p1;
+
+  p1 = address.find( match );
+  if (p1 != std::string::npos) 
+    {
+      address_header = address.substr( 0, p1+match.size());
+      
+      address_data = address.substr( p1+match.size() );
+    } 
+  else 
+    {
+      return StatusCode::FAILURE;
+    }
+
+  ATH_MSG_DEBUG ("   address_header :  " << address_header
+		 << endreq
+		 << "   address_data   :  " << address_data);
+
+  return StatusCode::SUCCESS;
+}
+
+
+// write Token and Attributes to the output collection
+bool AANTupleStream::writeTokenAttrList( const std::string& token, const coral::AttributeList& attributeList )
+{
+  // set addresses for attributes
+  coral::AttributeList::const_iterator attIter = attributeList.begin();
+  const TObjArray* branches = m_tree->GetListOfBranches();
+  std::vector<std::string> tokenStringDump;
+  // loop over all attributes
+  for (unsigned int i=0; i<attributeList.size(); ++i)
+    {
+      TBranch* branch = (TBranch*)branches->UncheckedAt(i);
+      // string attributes
+      if (attIter->specification().type() == typeid(std::string))
+	{
+	  const std::string& str = attIter->data<std::string>();
+	  if( str.length()+1 >= c_maxLengthOfStrings )
+	    {
+	      throw std::runtime_error("String is too long : RootCollection::pool2Root<std::string>"); 
+	    }
+	  branch->SetAddress( (void*)str.c_str() );
+	}
+      // Token
+      else if(attIter->specification().typeName() == "Token")
+	{
+	  tokenStringDump.push_back( attIter->data<std::string>() );
+	  branch->SetAddress( (void*) tokenStringDump.back().c_str() );
+	}
+      // else
+      else
+	{
+	  branch->SetAddress( (void*)attIter->addressOfData() );
+	}
+      ++attIter;  
+    }
+
+  // set address for Token
+  m_tokenBranch->SetAddress((void*)token.c_str());
+
+  // fill TTree
+  m_tree->Fill();
+
+  // releases Token
+  m_tokenBranch->SetAddress(m_tokenCString); 
+
+  return true;
+}
+
+
+// initialize sub-algos
+StatusCode AANTupleStream::initialize_subAlgos()
+{
+  StatusCode sc = StatusCode::SUCCESS;
+  
+  Algorithm* algo;
+  std::vector<std::string>::const_iterator it;
+  std::vector<std::string>::const_iterator itend = m_membersNames.end( );
+  for (it = m_membersNames.begin(); it != itend; ++it)
+    {
+      // Parse the name for a syntax of the form:
+      //
+      // <type>/<name>
+      //
+      // Where <name> is the algorithm instance name, and <type> is the
+      // algorithm class type (being a subclass of Algorithm).
+      ListItem foo(*it);
+      std::string theType = foo.type();
+      std::string theName = foo.name();
+
+      // create sub-algorithm
+      ATH_MSG_INFO (" -> creating sub-algorithm " << (*it));
+      sc =  createSubAlgorithm( theType,theName, algo );
+      if (sc.isFailure())
+	{
+	  ATH_MSG_FATAL (" ERROR creating sub-alg." << (*it));
+	  return StatusCode::FAILURE;
+	}
+
+      // force subAlgorithm to set his properties now (reading the jobOptions
+      sc = algo->setProperties();
+      if (sc.isFailure())
+	{
+	  ATH_MSG_FATAL (" ERROR setting properties for this sub-algorithm.");
+	  return StatusCode::FAILURE;
+	}
+    }
+
+  return sc;
+}
+
+
+// execute sub-algos
+StatusCode AANTupleStream::execute_subAlgos()
+{
+  StatusCode sc = StatusCode::SUCCESS;
+  
+  ATH_MSG_DEBUG ("in execute_subAlgos() ...");
+
+  // -- run subalgorithms
+  for ( unsigned int i=0; i < m_membersNames.size(); ++i )
+    {
+      ATH_MSG_DEBUG (" -> calling sub-algorithm " << m_membersNames[i]);
+      // skip disabled algo
+      if (! (*(this->subAlgorithms()))[i]->isEnabled()) continue ;
+      
+      sc = (*(this->subAlgorithms()))[i]->execute();
+      if ( sc.isFailure())
+	{
+	  ATH_MSG_ERROR
+	    (" ERROR executing sub-algorithm:" << m_membersNames[i]);
+	  return StatusCode::FAILURE;
+	}
+    }
+  return sc;
+}
+
+
+// get filters
+StatusCode AANTupleStream::getFilters()
+{
+  ATH_MSG_DEBUG ("in getFilters()");
+  
+  // no filter
+  if (m_acceptNames.empty())
+    return StatusCode::SUCCESS;
+
+
+
+  // old way to get ApplicationMgr crash with gaudi 21 (dynamic_cast fails)
+  //  IAlgManager* theAlgMgr;
+//   IInterface* ptmp;
+//   StatusCode sc = serviceLocator()->getService("ApplicationMgr",
+//                                                IAlgManager::interfaceID(),
+//                                                ptmp);
+
+//   if (sc.isFailure())
+//     {
+//       ATH_MSG_FATAL ("Can't locate ApplicationMgr!!!");
+//       return sc;
+//     }
+//   theAlgMgr = dynamic_cast<IAlgManager*> (ptmp);
+
+  // new safe way to get ApplicationMgr (gaudi 21 and backward compatible)
+  ServiceHandle<IAlgManager> theAlgMgr("ApplicationMgr", this->name());
+  if (theAlgMgr==0){
+    ATH_MSG_FATAL ("Can't locate    ApplicationMgr!!!");
+    return StatusCode::FAILURE;
+  }
+  
+
+  // loop over all alg names
+  std::vector<std::string>::const_iterator it;
+  std::vector<std::string>::const_iterator itend = m_acceptNames.end();
+  for (it = m_acceptNames.begin(); it != itend; ++it)
+    {
+      IAlgorithm* ialg;
+      // get Alg
+      StatusCode sc = theAlgMgr->getAlgorithm(*it, ialg);
+
+      if (sc.isFailure() )
+	{
+	  ATH_MSG_ERROR ("Can't get Filter Alg : " << *it);
+	  return StatusCode::FAILURE;
+	}
+      Algorithm *theAlg = dynamic_cast<Algorithm*>(ialg);
+      if (theAlg==0 )
+	{
+	  ATH_MSG_ERROR ("Can't cast Filter Alg : " << *it);
+	  return StatusCode::FAILURE;
+	}
+      ATH_MSG_DEBUG (" -> getting Filter Alg success " << *it);
+      // push back
+      m_acceptAlgs.push_back(theAlg);
+    }
+  return StatusCode::SUCCESS;
+}
+
+
+// Loop over all Algorithms in the accept list to see
+// whether any have been executed and have their filter
+// passed flag set. Any match causes the event to be
+// provisionally accepted.
+bool AANTupleStream::isEventAccepted() const
+{
+  // no filter
+  if (m_acceptAlgs.empty())
+    return true;
+    
+  // loop over all algs
+  std::vector<Algorithm*>::const_iterator it;
+  std::vector<Algorithm*>::const_iterator itend = m_acceptAlgs.end();
+  for (it = m_acceptAlgs.begin(); it != itend; ++it)
+    {
+      const Algorithm* theAlgorithm = (*it);
+      if ( theAlgorithm->isExecuted() && (! theAlgorithm->filterPassed()))
+	return false;
+    }
+
+  return true;
+}
+
+StatusCode
+AANTupleStream::initSchema()
+{
+  m_schemaDone = true;
+
+  StatusCode sc = m_tHistSvc.retrieve();
+  if (sc.isFailure())
+  {
+    ATH_MSG_ERROR ("Unable to retrieve pointer to THistSvc");
+    return sc;
+  }
+
+  // initialize output collection
+  sc = initCollection();
+  if ( sc.isFailure() )
+  {
+    ATH_MSG_ERROR ("Could not init collection");
+    return sc;
+  }
+
+  // register TTree to THistSvc
+  sc = m_tHistSvc->regTree("/"+m_streamName+"/"+m_treeName, m_tree);
+  if ( sc.isFailure() )
+  {
+    ATH_MSG_ERROR ("Could not register TTree");
+    return sc;
+  }
+
+  /// dump
+  m_tree->Print();
+
+  return sc;
+}
+
+StatusCode
+AANTupleStream::io_reinit()
+{
+  ServiceHandle<IIoComponentMgr> iomgr ("IoComponentMgr", this->name());
+  if ( !iomgr.retrieve().isSuccess() ) {
+    ATH_MSG_ERROR ("Could not retrieve IIoComponentMgr/IoComponentMgr !");
+    return StatusCode::FAILURE;
+  }
+
+  ServiceHandle<IJobOptionsSvc> josvc ("JobOptionsSvc", this->name());
+  if ( !josvc.retrieve().isSuccess() ) {
+    ATH_MSG_ERROR ("Could not retrieve IJobOptionsSvc/JobOptionsSvc !");
+    return StatusCode::FAILURE;
+  }
+
+  // check the I/O manager knows about me
+  if ( !iomgr->io_hasitem (this) ) {
+    ATH_MSG_ERROR ("I/O component mgr does not know about ourselves !");
+    return StatusCode::FAILURE;
+  }
+
+  // check there is actually something to do...
+  if ( !iomgr->io_contains (this, m_fileName) ) {
+    ATH_MSG_DEBUG 
+      ("I/O component mgr does not have any entry about ["<< m_fileName<<"]");
+    return StatusCode::SUCCESS;
+  }
+
+  if ( !iomgr->io_retrieve (this, m_fileName).isSuccess() ) {
+    ATH_MSG_ERROR ("Could not retrieve new name for [" << m_fileName << "] !");
+    return StatusCode::FAILURE;
+  }
+  
+  // recreate the proper property value...
+  std::vector<std::string> outvec(1);
+  outvec[0] = "AANT DATAFILE='" + m_fileName + "' OPT='RECREATE'";
+  StringArrayProperty prop ("Output", outvec);
+  if ( !josvc->addPropertyToCatalogue ("THistSvc", prop).isSuccess() ) {
+    ATH_MSG_ERROR ("Could not update THistSvc.Output property with new name !");
+  }
+
+  // handle schema...
+  if (!m_schemaDone) {
+    if ( !initSchema().isSuccess() ) {
+      ATH_MSG_ERROR ("Could not initialize schema !");
+    }
+  }
+
+  return StatusCode::SUCCESS;
+}
diff --git a/PhysicsAnalysis/AnalysisCommon/AnalysisTools/src/AnalysisTools.cxx b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/src/AnalysisTools.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..3cb8cf80bbf2bea2c22f0e8dde197662fe8ab010
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/src/AnalysisTools.cxx
@@ -0,0 +1,21 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "AnalysisTools/AnalysisTools.h"
+
+
+// constructor
+AnalysisTools::AnalysisTools( const std::string& type, const std::string& name,
+			      const IInterface* parent )
+  :  IAnalysisTools (type,name,parent)
+{
+  declareInterface<AnalysisTools>( this );
+}
+
+// initialize
+StatusCode AnalysisTools::initialize()
+{
+  MsgStream log(msgSvc(), name());
+  return StatusCode::SUCCESS;
+}
diff --git a/PhysicsAnalysis/AnalysisCommon/AnalysisTools/src/components/AnalysisTools_entries.cxx b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/src/components/AnalysisTools_entries.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..8dcd12aece3e528f4fa9afe0220037c312b37875
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/src/components/AnalysisTools_entries.cxx
@@ -0,0 +1,17 @@
+#include "Python.h"
+#include "AnalysisTools/AANTupleStream.h"
+#include "AnalysisTools/AANTEventSelector.h"
+#include "AnalysisTools/AnalysisTools.h"
+#include "GaudiKernel/DeclareFactoryEntries.h"
+ 
+DECLARE_TOOL_FACTORY( AnalysisTools )
+DECLARE_SERVICE_FACTORY( AANTEventSelector )
+DECLARE_ALGORITHM_FACTORY( AANTupleStream )
+
+ 
+DECLARE_FACTORY_ENTRIES( AnalysisTools )
+{
+  DECLARE_TOOL( AnalysisTools )
+  DECLARE_ALGORITHM( AANTupleStream )
+  DECLARE_SERVICE( AANTEventSelector )   
+}
diff --git a/PhysicsAnalysis/AnalysisCommon/AnalysisTools/src/components/AnalysisTools_load.cxx b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/src/components/AnalysisTools_load.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..dd6be4f037c136211349111f17762b330bbb8ec5
--- /dev/null
+++ b/PhysicsAnalysis/AnalysisCommon/AnalysisTools/src/components/AnalysisTools_load.cxx
@@ -0,0 +1,3 @@
+#include "GaudiKernel/LoadFactoryEntries.h"
+ 
+LOAD_FACTORY_ENTRIES ( AnalysisTools )