diff --git a/Trigger/TrigEvent/TrigNavigation/TrigNavigation/AccessProxy.h b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/AccessProxy.h
new file mode 100644
index 0000000000000000000000000000000000000000..54fc7bf5728c7e101dc0d1b531273d288f92a80a
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/AccessProxy.h
@@ -0,0 +1,18 @@
+//  -*- c++ -*- 
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#pragma once
+#include "StoreGate/StoreGateSvc.h"
+
+
+/**
+ * It used to be useful piece of code for replacing actual SG with other store of similar functionality 
+ * In fact it used to be more like interface adapter for ARA objects access, nevertheless since the ARA project is gone it is only an unnecessary extra layer.
+ * The polimorphic dispatch only created unnecessary overhead. 
+ */
+namespace HLT {
+  typedef StoreGateSvc AccessProxy;
+}
diff --git a/Trigger/TrigEvent/TrigNavigation/TrigNavigation/ComboIterator.h b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/ComboIterator.h
new file mode 100644
index 0000000000000000000000000000000000000000..a35ddd0f90c7cb74f790c8634595dafaf467e781
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/ComboIterator.h
@@ -0,0 +1,10 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TRIGNAVIGATION_ComboIterator_H
+#define TRIGNAVIGATION_ComboIterator_H
+
+#include "TrigNavStructure/ComboIterator.h"
+
+#endif //#ifndef
diff --git a/Trigger/TrigEvent/TrigNavigation/TrigNavigation/Holder.h b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/Holder.h
new file mode 100644
index 0000000000000000000000000000000000000000..4a212c83b834e2ff4f1a2c654be3d086a8181fb3
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/Holder.h
@@ -0,0 +1,349 @@
+// Emacs -*- c++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TRIGNAVIGATION_HOLDER_H
+#define TRIGNAVIGATION_HOLDER_H
+#include <string>
+#include <vector>
+
+#include "GaudiKernel/ClassID.h"
+
+
+#include "DataModel/OwnershipPolicy.h"
+#include "DataModel/DataVector.h"
+#include "DataModel/ElementLinkVector.h"
+#include "SGTools/StorableConversions.h"
+
+#include "TrigNavigation/AccessProxy.h"
+#include "TrigNavigation/TypeProxy.h"
+#include "TrigNavigation/TriggerElement.h"
+
+#include "TrigStorageDefinitions/TypeInformation.h"
+#include "TrigStorageDefinitions/EDM_TypeInfoMethods.h"
+
+
+class MsgStream;
+class ITrigSerializerToolBase;
+
+namespace HLTNavDetails {
+
+  /**
+   * @brief declaration of formatting function.
+   */
+  //note: needs to be up here to get template compiled.
+  std::string formatSGkey(const std::string& prefix, const std::string& containername, const std::string& label);
+  
+
+
+  /**
+   * @class used for features holding
+   * In fact this class is here in order to allow STL container for all features
+   * This class is showing a common denominator of all Holders for given type
+   * The necessary for class to be storable is to have CLID.
+   * In order to be serialized by Serializer at least the dictionary must be generated.
+   */
+
+  class IHolder {
+  public:
+    IHolder();
+    //    IHolder(const std::string& label, uint16_t idx );
+    virtual ~IHolder();
+
+
+    virtual IHolder* clone(const std::string& label,  uint16_t idx) = 0; // actual constructor
+
+    /**
+     * @brief prepares this holder
+     */
+    
+    virtual void prepare(MsgStream* log, HLT::AccessProxy* sg);
+    
+    
+    virtual bool syncWithSG(SG::OwnershipPolicy policy = SG::OWN_ELEMENTS) = 0;
+    virtual bool clearSG() = 0;
+
+    /**
+     * @brief returns the CLID of objects stores by this holder
+     */
+    virtual CLID typeClid() const  =0;
+    virtual CLID containerClid() const =0;
+    virtual CLID auxClidOrZero() const =0;
+
+    /**
+     * @brief returns the label of objects stores by this holder
+     */
+    inline const std::string& label() const { return  m_label; }
+
+
+    void setObjectsKeyPrefix(std::string& p) { m_prefix = p; }
+
+    /**
+     * @brief returns the containers StoreGate key
+     */
+
+    virtual const std::string key() const = 0;
+
+    /**
+     * @brief returns the object's name stored by this holder
+     */
+    virtual const std::string typeName() const = 0;
+
+    /**
+     * @brief returns the collection's name stored by this holder
+     */
+    virtual const std::string collectionName() const = 0;
+
+    /**
+     * @brief returns the index (short number used when linking object to the TE)
+     * of objects stores by this holder
+     */
+    inline uint16_t subTypeIndex() const { return  m_subTypeIndex; }
+
+    std::string generateAliasKey(CLID c, uint16_t sti, const std::string& label, unsigned size);
+
+    /**
+     * @brief serializes this Holder
+     */
+    virtual bool serialize(std::vector<uint32_t>& output)  const;
+
+    virtual void print(MsgStream& m) const;
+
+    /**
+     * @brief deserializes this Holder
+     */
+    virtual bool deserialize(const std::vector<uint32_t>& input)  = 0;
+
+    /**
+     * @brief this staic method is used to figure out what is actuall contained in the blob of ints
+     */
+    static bool enquireSerialized(const std::vector<uint32_t>& blob,
+				  std::vector<uint32_t>::const_iterator& fromHere,
+				  CLID& c, std::string& label,
+				  uint16_t& subtypeIndex );
+
+    // serialization helpers
+    virtual DataObject* getDataObject() = 0;
+    virtual DataObject* getAuxDataObject() = 0;
+
+    virtual bool setDataObject(DataObject* dobj) = 0;
+    virtual bool setAuxDataObject(DataObject* dobjaux) = 0;
+
+    /**
+     * Get the proxy for the container
+     */
+    virtual const ITypeProxy& containerTypeProxy() const = 0;
+
+  protected:
+    mutable std::vector<uint32_t>*  m_serialized;              //!< serialized vector of this type
+    // serialization helpers
+    MsgStream*                      m_log;
+    HLT::AccessProxy*               m_storeGate;               //!< pointer to SG
+    ITrigSerializerToolBase*        m_serializer;              //!< pointer to Serializer
+
+
+    //    CLID         m_CLID;           //!< class ID of objects holded
+    //    CLID         m_collectionCLID; //!< class ID of objects holded
+    std::string  m_label;          //!< label given to the objects in this holder (labels given at attachFeature)
+    std::string  m_prefix;         //!< prefix for key given to the objects
+    uint16_t     m_subTypeIndex;   //!< index to notify how many objects of given type we have (we need to record it in case of slimming will be done latter)
+    ITypeProxy * m_aux;
+  private:
+    mutable std::ostringstream m_ostream; //!< used internally for keys generation
+    int m_uniqueCounter; 
+
+  };
+
+
+  //////////////////////////////////////////////////////////////////////////////////////
+
+  /**
+   * @brief Helper struct to determine if persistable type is a DataLink<CONTAINER> (in case STORED and CONTAINER are the same)
+   * of rather an ElementLink<CONTAINER> in case STORED is the element type of CONTAINER
+   * 
+   *
+   *
+   */
+
+  template<class STORED, class CONTAINER, bool is_same> struct set_link;
+
+  template<class STORED, class CONTAINER>
+  struct set_link<STORED,CONTAINER,true>{
+    typedef DataLink<CONTAINER> type;
+    static type do_it(const STORED* el, const CONTAINER* src, HLT::TriggerElement::ObjectIndex idx){
+      (void)src;(void)idx; //not used here
+      type t(el);
+      return t;
+    }
+  };
+
+  template<class STORED, class CONTAINER>
+  struct set_link<STORED,CONTAINER,false>{
+    typedef ElementLink<CONTAINER> type;
+    static type do_it(const STORED* el,const CONTAINER* src, HLT::TriggerElement::ObjectIndex idx){
+      (void)el;//not used here
+      type t(*src,idx.objectsBegin());
+      return t;
+    }
+  };
+
+  //////////////////////////////////////////////////////////////////////////////////////
+  template<class T, class C> class HolderImp;
+  /**
+   * @class Specialized holder class for each object type
+   *******************************************************************
+   * This class in addition to the above IHolder implements 2 methods get & add.
+   */
+  template<class STORED>
+  class Holder : public IHolder {
+  public:
+    Holder();
+    Holder(const std::string& label, uint16_t idx);
+    virtual ~Holder();
+
+
+    virtual HLT::TriggerElement::ObjectIndex add( const STORED* f, bool inSG, const std::string& = "" ) = 0;          //!< saved object in this holder
+    virtual bool get(const STORED*& dest, HLT::TriggerElement::ObjectIndex idx) = 0;
+
+    template<class CONTAINER2> 
+    bool get(ElementLinkVector<CONTAINER2>& cont);
+
+    template<class CONTAINER2> 
+    bool get(ElementLinkVector<CONTAINER2>& cont, HLT::TriggerElement::ObjectIndex idx);
+
+    template<class CONTAINER2> 
+    bool getWithLink(typename set_link<STORED,CONTAINER2,boost::is_same<STORED,CONTAINER2>::value>::type& link,
+                     HLT::TriggerElement::ObjectIndex& idx) {
+      
+      bool result = static_cast<HolderImp<STORED,CONTAINER2>*>(this)->getWithLink(link,idx);
+      return result;
+    }       
+
+    virtual bool contains(const STORED* obj, HLT::TriggerElement::ObjectIndex& idx) const = 0;
+
+    virtual bool checkAndSetOwnership(SG::OwnershipPolicy policy) = 0;
+    virtual CLID typeClid() const { return ClassID_traits<STORED>::ID(); }
+
+    
+
+    virtual std::string getUniqueKey() = 0; // this is backward compatibility for TrigCaloRec and TrigTauRec, whould be removed
+    virtual std::string getNextKey() = 0; // this is backward compatibility for TrigCaloRec and TrigTauRec, whould be removed
+    virtual void print(MsgStream& m) const;
+
+  private:
+
+
+
+
+  };
+
+  //////////////////////////////////////////////////////////////////////////////////////
+
+  /**
+   * @brief This is an implementation class for all Holders
+   * It is templated with 2 arguments STORED which is type of stored objects
+   * Another type is CONTAINER for that type.
+   * Examples when it works are:
+   * HolderImp<A, DataVector<A> > --- typical
+   * HolderImp< A, Acontainer> >  --- as above, Acontainer is either typedef for DataVector<A> or inherits from it
+   * HolderImp< DataVector<A>, DataVector<A> > --- when both are of the same type
+   * HolderImp< Acontainer, Acontainer> >      --- as above
+   *
+   *
+   */
+  template<class STORED, class CONTAINER>
+  class HolderImp: public  Holder<STORED> {
+  public:
+    
+    typedef Holder<STORED> base_type;
+    typedef STORED stored_type;
+    typedef CONTAINER container_type;
+
+    HolderImp();
+    HolderImp(const std::string& label, uint16_t idx);
+    virtual ~HolderImp();
+
+    virtual IHolder* clone(const std::string& label, uint16_t idx );
+
+    /**
+     * @brief adds object(s) to be holded
+     */
+    virtual HLT::TriggerElement::ObjectIndex add( const STORED* f, bool inSG = false, const std::string& = "" );
+
+    /**
+     * @brief gets object(s) holded
+     */
+    virtual bool get(const STORED*& dest, HLT::TriggerElement::ObjectIndex idx);
+
+    /**
+     * @brief cehcks if object(s) in dest are holded by this holder
+     */
+    virtual bool contains(const STORED* obj, HLT::TriggerElement::ObjectIndex& idx) const;
+
+    bool getElementLinks(ElementLinkVector<CONTAINER>& cont,  HLT::TriggerElement::ObjectIndex idx);
+    bool getElementLinks(ElementLinkVector<CONTAINER>& cont);
+        
+    bool getWithLink(typename set_link<STORED,CONTAINER,boost::is_same<STORED,CONTAINER>::value>::type& link,
+                     HLT::TriggerElement::ObjectIndex& idx);
+        
+    virtual std::string getUniqueKey(); // this is backward compatibility for TrigCaloRec and TrigTauRec, whould be removed
+    virtual std::string getNextKey(); // this is backward compatibility for TrigCaloRec and TrigTauRec, whould be removed
+
+    virtual void prepare(MsgStream* log, HLT::AccessProxy* sg);
+    virtual bool syncWithSG(SG::OwnershipPolicy policy=SG::OWN_ELEMENTS);
+    virtual bool clearSG();
+    virtual bool checkAndSetOwnership(SG::OwnershipPolicy policy);
+
+    virtual bool serialize(std::vector<uint32_t>& output) const;
+    virtual bool deserialize(const std::vector<uint32_t>& input);
+    virtual const std::string key() const {
+      return formatSGkey(this->m_prefix,ClassID_traits<CONTAINER>::typeName(),this->m_label);
+    };
+    virtual const std::string typeName() const { return ClassID_traits<STORED>::typeName(); }
+    virtual const std::string collectionName() const { return ClassID_traits<CONTAINER>::typeName(); }
+    virtual void print(MsgStream& m) const;
+
+    virtual DataObject* getDataObject();
+    virtual DataObject* getAuxDataObject();
+    virtual bool setDataObject(DataObject* dobj);
+    virtual bool setAuxDataObject(DataObject* dobjaux);
+
+    virtual CLID containerClid() const { return ClassID_traits<CONTAINER>::ID(); }
+    virtual CLID auxClidOrZero() const;
+
+    //    virtual bool bindAux(IHolder* h);
+
+    typedef HLTNavDetails::TypeProxy<CONTAINER> ContainerProxy;
+    mutable ContainerProxy m_containerProxy;
+
+    virtual const ITypeProxy& containerTypeProxy() const { return m_containerProxy; }
+
+    typedef HLTNavDetails::TypeProxy<STORED> FeatureProxy;
+
+    //    mutable CONTAINER* m_objects;
+    //    STORED *m_return;
+    // for memory management
+    struct MemoryMgr {
+      MemoryMgr();
+      MemoryMgr(const FeatureProxy& st, bool inSG);
+      void clear();
+      FeatureProxy proxy;
+      bool inSG;
+    };
+    typedef std::multimap<HLT::TriggerElement::ObjectIndex, MemoryMgr> MemoryMgrMap;
+    MemoryMgrMap m_memMgr;
+  };
+
+  MsgStream& operator<< ( MsgStream& m, const HLTNavDetails::IHolder& nav ); //<! printing helper
+  template<class T>
+  MsgStream& operator<< ( MsgStream& m, const HLTNavDetails::Holder<T>& nav ); //<! printing helper
+  template<class T, class C>
+  MsgStream& operator<< ( MsgStream& m, const HLTNavDetails::HolderImp<T, C>& nav ); //<! printing helper
+} // end of namespace
+
+//#include "TrigNavigation/Holder.icc"
+
+//
+#endif
diff --git a/Trigger/TrigEvent/TrigNavigation/TrigNavigation/Holder.icc b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/Holder.icc
new file mode 100644
index 0000000000000000000000000000000000000000..c8a7a7e3107c05cc6bfdd9c10c6db30cc55d853c
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/Holder.icc
@@ -0,0 +1,973 @@
+// Emacs -*- c++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//#include "iostream"
+#include <iterator>
+#include <boost/type_traits/is_same.hpp>
+#include <boost/mpl/if.hpp>
+
+#include "GaudiKernel/MsgStream.h"
+//
+#include "TrigNavigation/TypeMaps.h"
+
+#ifndef TrigNavigation_Holder_icc
+#define TrigNavigation_Holder_icc
+
+#define HMLOG(x)   if (Holder<STORED>::m_log->level()<=MSG::x) *Holder<STORED>::m_log << MSG::x 
+#define MLOG(x)   if (m_log->level()<=MSG::x) *m_log << MSG::x 
+
+
+
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+// T is for objects, C for container for this objects
+template<class STORED>
+HLTNavDetails::Holder<STORED>::Holder() {
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED>
+HLTNavDetails::Holder<STORED>::Holder(const std::string& label, uint16_t idx) {
+  m_label = label;
+  m_subTypeIndex = idx;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED>
+HLTNavDetails::Holder<STORED>::~Holder() {
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED, bool> struct createTemporary;
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED> 
+struct createTemporary<STORED, true>
+{
+  static STORED* do_it() { 
+    //    std::cerr << " created temporary return cache" << std::endl; 
+    STORED *s = new STORED;
+    s->clear(SG::VIEW_ELEMENTS);
+    return s; 
+  }
+}; 
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED> 
+struct createTemporary<STORED, false>
+{
+  static STORED* do_it() { 
+    //    std::cerr << " Not created temporary return cache" << std::endl;   
+    return 0;
+  }
+}; 
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED> 
+template<class CONTAINER2> 
+bool HLTNavDetails::Holder<STORED>::get( ElementLinkVector<CONTAINER2>& el, HLT::TriggerElement::ObjectIndex idx) {
+  return static_cast<HolderImp<STORED, CONTAINER2>* >(this)->getElementLinks(el, idx);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED> 
+template<class CONTAINER2> 
+bool HLTNavDetails::Holder<STORED>::get( ElementLinkVector<CONTAINER2>& el ) {
+  return static_cast<HolderImp<STORED, CONTAINER2>* >(this)->getElementLinks(el);
+}
+
+
+
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Implementation
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED, class CONTAINER>
+HLTNavDetails::HolderImp<STORED, CONTAINER>::HolderImp() 
+  : Holder<STORED>()/*, m_return(0)*/ {
+
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED, class CONTAINER>
+HLTNavDetails::HolderImp<STORED, CONTAINER>::HolderImp(const std::string& label, uint16_t idx) 
+  : Holder<STORED>(label, idx)/*, m_return(0)*/ {
+
+  //  m_return = create<STORED, boost::is_same<STORED, CONTAINER>::value>::do_it();
+
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED, class CONTAINER>
+HLTNavDetails::HolderImp<STORED, CONTAINER>::~HolderImp() {  
+  typedef Holder<STORED> H;
+  if (H::m_log) HMLOG(VERBOSE) << "~HolderImp clearing memory manager" << endreq;
+  //  typename MemoryMgrMap::iterator it;
+  //  for ( it = m_memMgr.begin(); it != m_memMgr.end(); ++it ) {
+  //      if (H::m_log) HMLOG(VERBOSE) << "~HolderImp clearing MemoryMgrMap entry: " << it->first << " inSG: " << it->second.inSG  << endreq;
+      //it->second.proxy.clear(H::m_storeGate);
+  //  }
+  m_memMgr.clear();
+  //  if ( m_return ) delete m_return;
+  if (H::m_log) HMLOG(VERBOSE) << "~HolderImp Holder deleted" << endreq;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED, class CONTAINER>
+HLTNavDetails::IHolder* HLTNavDetails::HolderImp<STORED, CONTAINER>::clone(const std::string& label, uint16_t idx ) {
+  typedef Holder<STORED> H;
+  if ( not m_containerProxy.empty() ) {
+    return 0;
+  }
+  HolderImp<STORED, CONTAINER> *imp = new HolderImp<STORED, CONTAINER>(label, idx);
+  //  imp->m_return = create<STORED, boost::is_same<STORED, CONTAINER>::value>::do_it();
+  IHolder *h        = imp;
+  return h;
+}
+
+
+/*
+  //temporary debugging
+  if (Holder<STORED>::m_log->level()<=MSG::VERBOSE){
+    HMLOG(VERBOSE) << "looking up SG key: " << l << " of clid: " << cc << endreq;
+    HMLOG(VERBOSE) << "inbetween keys: " ;
+    std::vector<std::string> kk = H::m_storeGate->keys(cc); 
+    for (unsigned int ik=0; ik<kk.size(); ik++){
+      HMLOG(VERBOSE) << kk[ik] << " ";
+      if (kk[ik]==l)
+	HMLOG(VERBOSE) << kk[ik] << "<-matched ";
+    }
+    HMLOG(VERBOSE) << endreq;
+  }
+*/
+template<class AUX>
+struct auxCLIDOrZero {
+  static CLID get() {
+    return ClassID_traits<AUX>::ID();
+  }
+  static std::string getName() {
+    return ClassID_traits<AUX>::typeName();    
+  }
+};
+template<>
+struct auxCLIDOrZero<HLT::TypeInformation::no_aux> {
+  static CLID get() { 
+    return 0;
+  }
+  static std::string getName() {
+    return std::string("no_aux");    
+  }
+};
+ 
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED, class CONTAINER> 
+CLID  HLTNavDetails::HolderImp<STORED, CONTAINER>::auxClidOrZero() const {
+  return auxCLIDOrZero<typename Container2Aux<CONTAINER>::type>::get();
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED, class CONTAINER> 
+void  HLTNavDetails::HolderImp<STORED, CONTAINER>::prepare(MsgStream* log, HLT::AccessProxy* sg){
+  typedef Holder<STORED> H;
+  IHolder::prepare(log,sg);
+  CLID auxCLID = auxCLIDOrZero<typename Container2Aux<CONTAINER>::type>::get();
+  if ( auxCLID ) {
+    H::m_aux = HLT::TypeMaps::proxies()[auxCLID];
+    if ( H::m_aux == 0 ) {
+      HMLOG(ERROR) << "HolderImp::prepare can not find Aux store proxy " << *this << endreq;
+    }
+    
+    H::m_aux = H::m_aux->clone();
+    if ( H::m_aux == 0 ) {
+      HMLOG(ERROR) << "HolderImp::prepare can not clone Aux store proxy " << *this << endreq;
+    }
+    HMLOG(VERBOSE) << "HolderImp::prepare proxy toAux store ready decorating" << endreq;
+  }
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED, class CONTAINER> 
+bool  HLTNavDetails::HolderImp<STORED, CONTAINER>::syncWithSG(SG::OwnershipPolicy policy) {
+  typedef Holder<STORED> H;
+  if ( !H::m_storeGate ) {    
+    HMLOG(WARNING) << "HolderImp::syncWithSG no SG available " << *this << endreq;
+    return false;
+  }
+  HMLOG(VERBOSE) << "HolderImp::syncWithSG syncing holder with SG " << *this << endreq;
+  std::string l = key();
+
+  std::string auxkey = key()+"Aux.";
+  HMLOG(VERBOSE) << "HolderImp::syncWithSG looking in SG for key " << key() << " possible aux should have " << auxkey << endreq;
+
+  const bool transientInSG ( m_containerProxy.transientContains(H::m_storeGate, key() ) );
+  const bool persistentThroughSG ( m_containerProxy.contains(H::m_storeGate, key() ) );
+  if (  transientInSG or persistentThroughSG ) {
+    HMLOG(VERBOSE) << "HolderImp::syncWithSG objects " 
+		   << ( transientInSG ?  "already in" : "available through" ) 
+		   << " SG, syncing to them " << *this << endreq;
+    
+
+    if ( m_containerProxy.sync( H::m_storeGate, key()).isFailure() )  {
+      HMLOG(WARNING) << "HolderImp::syncWithSG objects already in SG, however failed syncing (SG::retrieve) to them " << *this << endreq;
+      return false;
+    }          
+    HMLOG(VERBOSE) << "HolderImp::syncWithSG got container from SG: " << m_containerProxy.data() << endreq; 
+    if ( this->m_aux )  {
+      const bool transientInSGAux ( this->m_aux->transientContains(H::m_storeGate, auxkey ) );
+      const bool persistentThroughSGAux ( this->m_aux->contains(H::m_storeGate, auxkey ) );
+      if(!transientInSGAux and !persistentThroughSGAux){
+	HMLOG(WARNING) << "HolderImp::syncWithSG syncing Aux holder and CONTAINER is SG but Aux Store not" << endreq;
+	return false;
+      }
+      if(this->m_aux->sync(H::m_storeGate,auxkey).isFailure()){
+	HMLOG(WARNING) << "HolderImp::syncWithSG objects already in SG, however failed syncing aux (SG::retrieve) to them " << *this << endreq;
+	return false;
+      }
+      typedef typename Container2Aux<CONTAINER>::type auxtype;
+      HLTNavDetails::TypeProxy<auxtype>* auxcasted = static_cast<HLTNavDetails::TypeProxy<auxtype>*>(this->m_aux);
+      HMLOG(VERBOSE) << "HolderImp::syncWithSG got aux container from SG: " << auxcasted->data() << endreq; 
+      HMLOG(VERBOSE) << "HolderImp::syncWithSG store is: " << m_containerProxy.data()->getStore() << endreq; 
+    }         
+  } else { // SG is empty, we need to put the obj ito it
+    HMLOG(VERBOSE) << "HolderImp::syncWithSG objects not in SG, adding them to SG " << *this << endreq;
+    if (  m_containerProxy.create().isFailure() )  {
+      HMLOG(WARNING) << "HolderImp::syncWithSG can not create container " << *this << endreq;
+      return false;
+    }
+
+    m_containerProxy.data()->clear(policy);
+    
+    CLID auxCLID = auxCLIDOrZero<typename Container2Aux<CONTAINER>::type>::get();
+    if ( auxCLID ) {
+      if ( H::m_aux == 0 ) {
+	HMLOG(ERROR) << "HolderImp::syncWithSG can not clone Aux store proxy " << *this << endreq;
+	return false;
+      }
+      
+      HMLOG(VERBOSE) << "HolderImp::syncWithSG proxy toAux store ready decorating" << endreq;
+
+      if( H::m_aux->create().isFailure() ) {
+	HMLOG(WARNING) << "HolderImp::syncWithSG can not create Aux store for container " << *this << endreq;
+	return false;
+      }
+      std::string auxkey = formatSGkey(this->m_prefix,
+				       ClassID_traits<CONTAINER>::typeName(),
+				       this->m_label+"Aux.");
+
+      if( H::m_aux->reg(H::m_storeGate,auxkey).isFailure() ) {
+	HMLOG(WARNING) << "HolderImp::syncWithSG can not register Aux store for container in SG " << *this << endreq;
+	return false;
+      }
+
+      SG::AuxVectorBase* container = m_containerProxy.castAuxVectorBase();
+      SG::IAuxStore* aux = H::m_aux->castIAuxStore();
+      if ( container and aux ) {
+	HMLOG(DEBUG) << "HolderImp::syncWithSG Aux sotore configured for " << *this << endreq;
+	container->setStore(aux);
+      } else {
+	HMLOG(WARNING) << "HolderImp::syncWithSG type configured to have Aux store but no appropriate Aux interaces are implemented AuxVectorBase for container: " 
+		       << container << " IAuxStore for Aux sotore: " << aux <<  " "<<  *this << endreq;
+	return false;	
+      }
+    } 
+    
+    if ( m_containerProxy.reg( H::m_storeGate, key()).isFailure() ) {
+       HMLOG(ERROR) << "HolderImp::syncWithSG recording collection failed " << *this << endreq;
+      return false;   
+    }
+  }  
+
+  return true;   
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED, class CONTAINER> 
+bool  HLTNavDetails::HolderImp<STORED, CONTAINER>::clearSG() {
+  if ( m_containerProxy.empty() ) return false;
+
+  //  typedef Holder<STORED> H;
+  //  if ( m_containerProxy.clear(H::m_storeGate).isFailure() )     
+  //    return false;  
+  return true;
+}
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED, class CONTAINER> 
+bool HLTNavDetails::HolderImp<STORED, CONTAINER>::checkAndSetOwnership(SG::OwnershipPolicy policy) {
+  if ( m_containerProxy.empty() ) 
+    return false;
+
+  if ( m_containerProxy.data()->empty() ) {
+    m_containerProxy.data()->clear(policy);
+    return true;
+  } 
+  
+  if ( m_containerProxy.data()->ownPolicy() == policy )
+    return true;
+
+  return false;
+}
+/////////////////////////////////////////////////////////////////////////////
+template<class CONTAINER, bool b> 
+struct transferBetweenContainers;
+
+
+// case when the containers can be transfered
+template <class CONTAINER> 
+struct transferBetweenContainers<CONTAINER, true> {
+  static void do_it(CONTAINER *source, CONTAINER* dest, MsgStream* m_log) {
+    const size_t orig_size = dest->size();
+    dest->resize( orig_size + source->size() );
+    std::swap_ranges( source->begin(), source->end(), dest->begin() + orig_size );
+    MLOG( VERBOSE ) << "insert::do_it objects moved, converting to a view container now"    << endreq;
+    source->setStore((SG::IAuxStore*)0);
+    source->clear(SG::VIEW_ELEMENTS);
+    MLOG( VERBOSE ) << "insert::do_it refilling the feature container"    << endreq;
+    source->insert(source->begin(), std::next(dest->begin(), orig_size), dest->end());
+
+  }
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// case when the containers CAN NOT be transfered
+template <class CONTAINER> 
+struct transferBetweenContainers<CONTAINER, false> {
+  static void do_it(CONTAINER *, CONTAINER* , MsgStream* ) {
+    throw std::runtime_error
+      ("TrigNavigation: Tried to attach an owning container of type " +
+       ClassName<CONTAINER>::name() +
+       "; only view containers of this type are supported.");    
+  }
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// code below checks if the transfer of elements between the two OWNING containers can happen
+// It is based on the check of the type returned by the iterator i.e. if the reference is const or not const (i.e. assignable)
+//
+template<class CONTAINER> 
+struct canTransfer {  
+  const static bool value = std::is_assignable<typename CONTAINER::iterator::reference,
+					       typename CONTAINER::iterator::value_type>::value;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED, class CONTAINER, bool b> struct insert;
+
+/////////////////////////////////////////////////////////////////////////////
+// implementation if stored and container are the same
+// this version is suggested by Attila, it has several advantages
+// 1) the source container is useable after the insertion (important for the monitoring)
+// 2) ownership of objects is greately simplified (i.e. the event-wise container always own objects,
+//    the roi-wise containers always view objects
+//
+template <class STORED, class CONTAINER> 
+struct insert<STORED, CONTAINER, true>{
+  static bool do_it(STORED *source, CONTAINER* dest, bool /*hasAux*/, MsgStream* m_log) {
+
+    MLOG( VERBOSE ) << "insert::do_it CONTAINER " << ClassID_traits<STORED>::typeName() << endreq;
+    MLOG( VERBOSE ) << "Destination is " << (dest->ownPolicy() == SG::VIEW_ELEMENTS ? "VIEW" : "OWN") 
+		    << " source is " << (source->ownPolicy() == SG::VIEW_ELEMENTS ? "VIEW" : "OWN")  << endreq;
+
+    
+    // From Scott
+    // - Input container is owning.  Output container should also be owning;
+    //   ownership should be transferred from input to output container.
+    
+    // - Input is a view container and doesn't track indices
+    //   (trackIndices() is false).  Output should be a view container.
+    //   Aux data are not transferred in this case.
+    
+    // - Input is a view container that does track indices
+    //   (trackIndices() is true).  Output should be a view container
+    //   with ALWAYS_TRACK_INDICES.  Aux data are transferred in this case.    
+    //   (I don't think trigger will see this case.)
+
+    
+    if ( dest->empty() ) { // epmty destination, we can do adaptations
+      if ( source->ownPolicy() == SG::OWN_ELEMENTS ) {
+	dest->clear( SG::OWN_ELEMENTS );
+      }
+
+      if ( source->ownPolicy() == SG::VIEW_ELEMENTS and source->trackIndices() == false ) {
+	MLOG( VERBOSE ) << "insert::do_it destination container made a VIEW"    << endreq;
+	dest->clear( SG::VIEW_ELEMENTS);
+      }
+      
+      if ( source->ownPolicy() == SG::VIEW_ELEMENTS and source->trackIndices() == true ) {
+	MLOG( VERBOSE ) << "insert::do_it destination container made a VIEW wiht indices tracking "    << endreq;
+	// it should be like this but I can not implemnt it like this because many container do not implement second arg dest->clear( SG::VIEW_ELEMENTS, SG::ALWAYS_TRACK_INDICES );
+	dest->clear( SG::VIEW_ELEMENTS );
+      }
+    }
+    if ( source->ownPolicy() != dest->ownPolicy() ) {  // a simple check if in case of nonempty container we are dooing consistent insertion
+      MLOG( WARNING ) << "insert::do_it objects can not be inserted because of ownership issues. "
+		      << "Destination container has already " << dest->size() << " objects " 
+		      <<  " and ownership policy "
+		      << (dest->ownPolicy() == SG::OWN_ELEMENTS ? "OWN" : "")  // this is dumb code but who knows what other policies will be implemented in the future
+		      << (dest->ownPolicy() == SG::VIEW_ELEMENTS ? "VIEW" : "") 
+		      << " no action is performed, potential memory leak"    << endreq;
+      return false;
+    }
+
+    
+    if ( source->ownPolicy() == SG::VIEW_ELEMENTS ) {
+      //      const size_t orig_size = dest->size();
+      //      dest->resize( orig_size + source->size() );
+      dest->insert(dest->end(), source->begin(), source->end());
+      MLOG( VERBOSE ) << "insert::do_it objects copied, conversion to view container not needed"    << endreq;
+    } else {
+      // We have an owning container.  Transfer the element ownership
+      // from SOURCE to DEST.  We can only do this if the container
+      // has modifiable iterators.  For containers with non-modifiable
+      // iterators (like CaloTowerContainer), we throw an exception.
+      // Such containers should be added only as view containers.
+      transferBetweenContainers<CONTAINER, canTransfer<CONTAINER>::value>
+	::do_it(source, dest, m_log);
+
+
+      // const size_t orig_size = dest->size();
+      // dest->resize( orig_size + source->size() );
+      // std::swap_ranges( source->begin(), source->end(), dest->begin() + orig_size );
+      // MLOG( VERBOSE ) << "insert::do_it objects moved, converting to a view container now"    << endreq;
+      // source->setStore((SG::IAuxStore*)0);
+      // source->clear(SG::VIEW_ELEMENTS);
+      // MLOG( VERBOSE ) << "insert::do_it refilling the feature container"    << endreq;
+      // source->insert(source->begin(), std::next(dest->begin(), orig_size), dest->end());
+    }
+    return true;    
+  }
+};
+
+
+/*
+template <class STORED, class CONTAINER> 
+struct insert<STORED, CONTAINER, true>{
+  static bool do_it(STORED *source, CONTAINER* dest, bool hasAux, MsgStream* m_log) {
+
+    if (hasAux) {      
+
+      MLOG( VERBOSE ) << "insert::do_it CONTAINER " << ClassID_traits<STORED>::typeName()
+			   << "  has defined Aux decorations, swap_ranges used"    << endreq;
+      
+      const size_t orig_size = dest->size();
+      dest->resize( orig_size + source->size() );
+      std::swap_ranges( source->begin(), source->end(), dest->begin() + orig_size );
+      return true;
+    } else {
+      
+      // we may to have little problem here because the either both source and destination own the memory or 
+      // or noone owns it
+      if ( source->ownPolicy() == dest->ownPolicy() ) { 
+	if (dest->empty() ) { // if the destination is still empty we can adapt it
+	  MLOG( VERBOSE ) << "insert::do_it CONTAINER " << ClassID_traits<STORED>::typeName() 
+			  << "  adapting the destination container SG::OwnPolicy for the first insert"    << endreq;
+	  
+	  if (  source->ownPolicy()  == SG::OWN_ELEMENTS) dest->clear( SG::VIEW_ELEMENTS );  
+	  if (  source->ownPolicy()  == SG::VIEW_ELEMENTS) dest->clear( SG::OWN_ELEMENTS );  
+	} else { // real issue
+	  MLOG( WARNING ) << "insert::do_it CONTAINER " << ClassID_traits<STORED>::typeName() 
+			  << " already has has objects and own policiec clash"  <<  source->ownPolicy() << " " << dest->ownPolicy()  << endreq;
+	  return false;
+	}
+      }       
+      MLOG ( VERBOSE ) << "insert::do_it CONTAINER " << ClassID_traits<STORED>::typeName() 
+		       << "  has no decorations, insert used"    << endreq;
+      dest->insert(dest->end(), source->begin(), source->end());
+    }
+  return true;
+  }
+};
+*/
+/////////////////////////////////////////////////////////////////////////////
+// implementation if stored and container are distinct
+template <class STORED, class CONTAINER> 
+struct insert <STORED, CONTAINER, false>{
+  static bool do_it(STORED *s, CONTAINER* dest, bool /*hasAux*/, MsgStream* /*msglog*/ ) {
+
+    //    if (dest->empty()) 
+    //      dest->clear(SG::VIEW_ELEMENTS); // this is the way to change ownership
+    dest->push_back(s);
+    return true;
+  }
+};
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED, class CONTAINER, bool b> struct remap;
+template<class STORED, class CONTAINER> 
+struct remap<STORED, CONTAINER, false> {
+  static void do_it(const std::string&, const std::string&, STORED *, CONTAINER*, HLT::AccessProxy*,  MsgStream* ) {
+    
+  }
+};
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED, class CONTAINER> 
+struct remap<STORED, CONTAINER, true> {
+  static void do_it(const std::string& storedkey , const std::string& contkey, STORED *s, CONTAINER* cont, HLT::AccessProxy *sg,  MsgStream* m_log ) {
+    std::string skey = storedkey;
+    if ( storedkey == "" ) {
+      // we can't do it 
+      if ( m_log->level() <= MSG::VERBOSE ) {
+	*m_log << MSG::VERBOSE << "HolderImp::remap trying to discover object key, this is potentially slow and should be avoided, type: "  << ClassID_traits<STORED>::typeName() << " from: " << s << " to: " << cont  << endreq;
+      }
+      SG::DataProxy* px = sg->proxy((void const* )s);
+      if ( !px ) {
+	*m_log << MSG::WARNING << "HolderImp::remap When remaping containers found no proxy for the object" << s << " of type " << ClassID_traits<STORED>::typeName()  << endreq;
+	return;
+      }
+      if ( !px->isValid() ) {
+	*m_log << MSG::WARNING << "HolderImp::remap When remaping containers found no valid proxy for the object" << s << " of type " << ClassID_traits<STORED>::typeName()  << endreq;
+	return;
+      }
+      skey = px->name();
+    }      
+    if ( m_log->level() <= MSG::VERBOSE ) 
+      *m_log << MSG::VERBOSE << "HolderImp::remap remapping collections of type: " << ClassID_traits<STORED>::typeName() 
+	     << " from: " << skey << " to: " << contkey << " while destination container size is: " <<  cont->size() << endreq;
+    sg->remap(ClassID_traits<CONTAINER>::ID(), skey, contkey, cont->size());
+
+  }
+};
+
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED, class CONTAINER>
+HLT::TriggerElement::ObjectIndex HLTNavDetails::HolderImp<STORED, CONTAINER>::add( const STORED* f, bool inSG, const std::string& sgKey ) {
+  typedef Holder<STORED> H;
+  if ( ! syncWithSG() )
+    return HLT::TriggerElement::ObjectIndex();
+
+  uint32_t bidx = m_containerProxy.data()->size();
+
+  std::string thiskey(sgKey);
+  if ( !inSG && boost::is_same<STORED, CONTAINER>::value ) { // conditions to place partial containers in SG 
+    thiskey  = this->getUniqueKey();
+    if ( H::m_storeGate->record(f, thiskey).isFailure()  ) {
+      HMLOG(WARNING) << "HolderImp::add object " <<  f << "and sgKey:" << thiskey << " intended for holder" << *this << " can't be placed directly in SG" << endreq;
+    } else {
+      inSG = true;
+      HMLOG(VERBOSE) << "HolderImp::add feature SG direct registration succesful with the key:" << thiskey << endreq;
+    }
+  }
+
+  if ( inSG ) { //conditions to add remapping
+    remap<STORED, CONTAINER,  
+      boost::is_same<STORED, CONTAINER>::value>::do_it (thiskey, key(), const_cast<STORED*>(f), m_containerProxy.data(), H::m_storeGate, H::m_log);
+  }
+
+  bool insertStatus = insert<STORED, CONTAINER, boost::is_same<STORED, CONTAINER>::value>
+    ::do_it (const_cast<STORED*>(f), m_containerProxy.data(), H::m_aux != 0, H::m_log);
+  if ( insertStatus == false ) {
+    HMLOG(WARNING) << "HolderImp::add  insert failed "  << endreq;
+    return  HLT::TriggerElement::ObjectIndex();
+  }
+
+  uint32_t eidx = m_containerProxy.data()->size();
+  HMLOG(VERBOSE) << "HolderImp::add added object(s) to the container, size increase from : " << bidx << " to: " << eidx << endreq;
+  HLT::TriggerElement::ObjectIndex objIdx (H::subTypeIndex(), bidx, eidx );
+
+  m_memMgr.insert(std::make_pair(objIdx, MemoryMgr(const_cast<STORED*>(f), inSG||m_containerProxy.data()->ownPolicy() == SG::OWN_ELEMENTS)));
+  
+  return objIdx;
+}
+
+
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED, class CONTAINER, bool b> struct retrieve;
+
+/////////////////////////////////////////////////////////////////////////////
+// implementation if stored and container are the same
+template <class STORED, class CONTAINER> 
+struct retrieve<STORED, CONTAINER, true>{
+  static bool do_it(STORED*& dest, CONTAINER* src, HLT::TriggerElement::ObjectIndex idx) {
+    // find 2 iterators
+    // assert(idx.objectsBegin());
+    if ( src->size() < idx.objectsBegin() || src->size() < idx.objectsEnd()) {
+      REPORT_MESSAGE_WITH_CONTEXT(MSG::VERBOSE,"Holder") << "either begin index or end index is larger than size";
+      REPORT_MESSAGE_WITH_CONTEXT(MSG::VERBOSE,"Holder") << "size: " << src->size() << " begin: " << idx.objectsBegin() << " end: " << idx.objectsEnd();
+      dest = 0;
+      return false;
+    }
+    dest = createTemporary<STORED, boost::is_same<STORED, CONTAINER>::value>::do_it(); 
+    typename CONTAINER::iterator beg = src->begin(); 
+    typename CONTAINER::iterator end = src->begin(); 
+    std::advance(beg, idx.objectsBegin());
+    std::advance(end, idx.objectsEnd());
+    dest->insert(dest->end(), beg, end);
+    return true;
+  }
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// implementation if stored and container are distinct
+template <class STORED, class CONTAINER> 
+struct retrieve <STORED, CONTAINER, false>{
+  static bool do_it(STORED*& dest, CONTAINER* src, HLT::TriggerElement::ObjectIndex idx) {
+
+    if (idx.objectsBegin() <  (*src).size()) {
+      dest = src->at(idx.objectsBegin());
+      return true;
+    } else {
+      /*
+      HMLOG(ERROR) << "idx.objectsBegin()=" << idx.objectsBegin()
+		  << " out of range in source container of size " <<  (*src).size() << endreq;
+      */
+      dest = 0;
+      return false;
+    }
+  }
+};
+
+template<class STORED, class CONTAINER>
+bool HLTNavDetails::HolderImp<STORED, CONTAINER>::getWithLink(typename set_link<STORED,CONTAINER,boost::is_same<STORED,CONTAINER>::value>::type& link,
+                 HLT::TriggerElement::ObjectIndex& idx) {
+
+   const STORED* dest = 0;
+   bool result = this->get(dest,idx);
+   if(!result) return false;
+
+   link = set_link<STORED,CONTAINER,boost::is_same<STORED,CONTAINER>::value>::do_it(dest,m_containerProxy.data(),idx);
+   return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED, class CONTAINER>
+bool HLTNavDetails::HolderImp<STORED, CONTAINER>::get(const STORED*& dest, HLT::TriggerElement::ObjectIndex idx) {
+  typedef Holder<STORED> H;
+  if ( !syncWithSG() )
+    return false;
+
+
+  HMLOG(VERBOSE) << "HolderImp::get getting object(s) from Holder" << *this << endreq;
+  typename MemoryMgrMap::const_iterator cache;
+  if ( (cache = m_memMgr.find(idx)) != m_memMgr.end() ) {
+    HMLOG(DEBUG) << "HolderImp::get object found in the cache with address " << idx << endreq;
+    dest = cache->second.proxy.data();
+    return true;
+  }
+  else{
+    HMLOG(VERBOSE) << "HolderImp::get getting object from primary collection " << idx << endreq;
+  }
+  
+  if ( ! retrieve<STORED, CONTAINER,  // short circuited .. retrieve will not run if in cache
+		  boost::is_same<STORED, CONTAINER>::value>::
+       do_it (const_cast<STORED*&>(dest), m_containerProxy.data(), idx) ) {
+    HMLOG(WARNING) << "HolderImp::get getting chunk of the container failed for Holder: " << *this  
+		   << " index: " << idx << endreq;
+    return false;
+  }
+      
+  if ( boost::is_same<STORED, CONTAINER>::value ) { // temporary view containers in SG and cache filling
+    FeatureProxy tempProxy( const_cast<STORED*>(dest) );
+    
+    m_memMgr.insert(std::make_pair(idx, MemoryMgr(tempProxy, true)));    // store it in the cache for futher uses
+    
+    std::string sgKey = this->generateAliasKey( H::typeClid(), H::subTypeIndex(), H::label(), 0xffffffff );
+
+    if ( tempProxy.reg(H::m_storeGate, sgKey).isFailure() ) {
+      HMLOG(WARNING) << "HolderImp::get for some reason object can't be placed in SG, key:" << sgKey << endreq;
+      return false;
+    }
+    remap<STORED, CONTAINER, 
+	  boost::is_same<STORED, CONTAINER>::value>::do_it (sgKey, key(), tempProxy.data(), m_containerProxy.data(), H::m_storeGate, H::m_log);
+    HMLOG(VERBOSE) << "Added view collection to SG with defined EL remapping to event-wide colection, key: " << sgKey << endreq;
+  }
+  return true;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// check if objects in obj are in the container 
+template<class STORED, class CONTAINER, bool b> struct isin;
+
+/////////////////////////////////////////////////////////////////////////////
+// check if the container obj is a subcontainer of cont 
+template <class STORED, class CONTAINER> 
+struct isin<STORED, CONTAINER, true> {
+  static bool do_it(const STORED* obj, const CONTAINER* cont, MsgStream* /*msg*/, uint32_t& begin, uint32_t& end) {
+    typename CONTAINER::const_iterator it =  std::search(cont->begin(), cont->end(), obj->begin(), obj->end());
+    if ( it == cont->end() ) {
+      return false;
+    }
+    begin = it - cont->begin();
+    end = begin + obj->size();
+    return true;
+  }
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// check if the obj is in a container cont
+template <class STORED, class CONTAINER> 
+struct isin<STORED, CONTAINER, false> {
+  static bool do_it(const STORED* obj, const CONTAINER* cont, MsgStream* /*msg*/, uint32_t& begin, uint32_t& end) {
+    typename CONTAINER::const_iterator it = std::find(cont->begin(), cont->end(), obj);
+    if ( it == cont->end() ) {
+      return false;
+    } 
+    //    std::cerr << "fubu " << obj << " " << *it << std::endl;
+    begin = it - cont->begin();
+    end = begin+1;
+    
+    return true;
+  }
+};
+
+template<class STORED, class CONTAINER>
+bool HLTNavDetails::HolderImp<STORED, CONTAINER>::contains(const STORED* obj, HLT::TriggerElement::ObjectIndex& idx) const {
+  typedef Holder<STORED> H;
+  if ( !const_cast<HolderImp<STORED, CONTAINER>* >(this)->syncWithSG() )
+    return false;
+
+  HMLOG(VERBOSE) << "HolderImp::contains" << endreq;
+  uint32_t begin=0;
+  uint32_t end=0;
+  bool ok = isin<STORED, CONTAINER, 
+		 boost::is_same<STORED, CONTAINER>::value>::do_it (obj, m_containerProxy.data(), H::m_log, begin, end);
+  if ( !ok ) {
+    HMLOG(VERBOSE) << "HolderImp::contains object " << obj << " not in the holder" << *this  << endreq;
+    return false;
+  }
+  idx = HLT::TriggerElement::ObjectIndex(H::subTypeIndex(),begin,end);
+  HMLOG(VERBOSE) << "HolderImp::contains object " << obj << " found by in holder" << *this << " " << idx << endreq;
+  return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED, class CONTAINER>
+bool HLTNavDetails::HolderImp<STORED, CONTAINER>::getElementLinks(ElementLinkVector<CONTAINER>& cont,  
+								  HLT::TriggerElement::ObjectIndex idx) {
+  typedef Holder<STORED> H;
+  if ( !syncWithSG() )
+    return false;
+
+  HMLOG(VERBOSE) << "HolderImp::getElementLinks(ELV, Index) getting objects" << endreq;
+  for (unsigned i = idx.objectsBegin(); i != idx.objectsEnd(); ++i ){
+    cont.push_back(ElementLink<CONTAINER>(*(m_containerProxy.data()), i));
+  }
+  return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED, class CONTAINER>
+bool HLTNavDetails::HolderImp<STORED, CONTAINER>::getElementLinks(ElementLinkVector<CONTAINER>& cont) {
+ 
+  typedef Holder<STORED> H;
+  if ( !syncWithSG() )
+    return false;
+  HMLOG(VERBOSE) << "HolderImp::getElementLinks (ELV) getting all objects" << endreq;
+  for (unsigned i = 0; i < m_containerProxy.data()->size(); ++i ){
+    cont.push_back(ElementLink<CONTAINER>(*(m_containerProxy.data()), i));
+  }
+  return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED, class CONTAINER>
+std::string HLTNavDetails::HolderImp<STORED, CONTAINER>::getUniqueKey() {
+  HMLOG(VERBOSE) << "HolderImp::getUniqueKey" << endreq;
+  if ( !syncWithSG() )
+    return "Bad_Key";
+  return IHolder::generateAliasKey( Holder<STORED>::typeClid(), 
+				    Holder<STORED>::subTypeIndex(),
+				    Holder<STORED>::label(),
+				    m_containerProxy.data()->size() );
+}
+
+template<class STORED, class CONTAINER>
+std::string HLTNavDetails::HolderImp<STORED, CONTAINER>::getNextKey() {
+  HMLOG(VERBOSE) << "HolderImp::getNextKey" << endreq;
+  return getUniqueKey();
+}
+
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED, class CONTAINER>
+bool HLTNavDetails::HolderImp<STORED, CONTAINER>::serialize(std::vector<uint32_t>& output) const {
+  typedef Holder<STORED> H; // this is to make things below shorter
+  
+  HMLOG(VERBOSE) << "HolderImp::serialize " << *this << endreq;
+  // if feature to be forgotten then indication of it is simply 0 size of serialized vector
+  H::serialize(output);
+  
+   
+  //  copy(output.begin(), output.end(), std::ostream_iterator<int>(std::cerr, " S "));
+  //  std::cerr << "\n";
+  return true;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED, class CONTAINER>
+bool HLTNavDetails::HolderImp<STORED, CONTAINER>::deserialize(const std::vector<uint32_t>& input) {
+  // first is recorded method of serialization used for this feature
+  typedef Holder<STORED> H; // this is to make things below shorter
+  //  copy(input.begin(), input.end(), std::ostream_iterator<int>(std::cerr, " D "));
+  //  std::cerr << "\n";
+  HMLOG(VERBOSE) << "HolderImp::deserialize " << *this << endreq;   
+  CLID c;
+  std::vector<uint32_t>::const_iterator it = input.begin();
+  if ( ! IHolder::enquireSerialized(input, it, 
+				    c, H::m_label, H::m_subTypeIndex ) ) {
+    HMLOG(WARNING) << "HolderImp::deserialize failed to enquire serialized blob of data" << endreq;
+    return false;
+  } 
+  HMLOG(DEBUG) << "HolderImp::deserialize success " << *this << endreq;
+  return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED>
+void HLTNavDetails::Holder<STORED>::print(MsgStream& m) const {
+  IHolder::print(m);
+  m << " Stored type name: " << ClassID_traits<STORED>::typeName();  
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED, class CONTAINER>
+void HLTNavDetails::HolderImp<STORED, CONTAINER>::print(MsgStream& m) const {
+  Holder<STORED>::print(m);
+  m << " Collection type name: " << ClassID_traits<CONTAINER>::typeName() << " CLID: " << ClassID_traits<CONTAINER>::ID();
+  if ( not m_containerProxy.empty() )
+    m << " size: " << m_containerProxy.data()->size() << " @"<<m_containerProxy.data();
+  else
+    m << " container not allocated yet";
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED, class CONTAINER>
+DataObject* HLTNavDetails::HolderImp<STORED, CONTAINER>::getDataObject() {
+  if(!m_containerProxy.data()) return 0;
+  return SG::asStorable(m_containerProxy.data());
+}
+
+#define _IS_AUXTYPE_ !boost::is_same<typename Container2Aux<T>::type,HLT::TypeInformation::no_aux>::value
+
+struct AuxDataObjectHelper{
+  template<typename T>
+  static typename std::enable_if<!_IS_AUXTYPE_,DataObject*>::type get(HLTNavDetails::ITypeProxy*/* aux*/){
+    return 0;
+  }
+  template<typename T>
+  static typename std::enable_if<_IS_AUXTYPE_,DataObject*>::type get(HLTNavDetails::ITypeProxy* aux){
+    typedef typename Container2Aux<T>::type auxtype;
+    HLTNavDetails::TypeProxy<auxtype>* auxcasted = static_cast<HLTNavDetails::TypeProxy<auxtype>*>(aux);
+    if(auxcasted){
+      if(!auxcasted->data()) return 0;
+      return SG::asStorable(auxcasted->data());
+    }
+    return 0;
+  }
+  template<typename T>
+  static typename std::enable_if<!_IS_AUXTYPE_,bool>::type set(HLTNavDetails::ITypeProxy*,DataObject*){
+    return true;//always success
+  }
+  template<typename T>
+  static typename std::enable_if<_IS_AUXTYPE_,bool>::type set(HLTNavDetails::ITypeProxy* aux, DataObject* dobjaux){
+    typedef typename Container2Aux<T>::type auxtype;
+    HLTNavDetails::TypeProxy<auxtype>* auxcasted = static_cast<HLTNavDetails::TypeProxy<auxtype>*>(aux);
+    if(auxcasted){      
+      bool success = SG::fromStorable(dobjaux,auxcasted->data_ref());
+      auxcasted->syncTypeless();
+      REPORT_MESSAGE_WITH_CONTEXT(MSG::VERBOSE,"Holder") << "set from storable " << success << " to address " << auxcasted->data() << std::endl;
+      return success;
+    }
+    return 0;
+  }
+};
+
+
+template<class STORED, class CONTAINER>
+DataObject* HLTNavDetails::HolderImp<STORED, CONTAINER>::getAuxDataObject() {
+  return AuxDataObjectHelper::get<CONTAINER>(this->m_aux);
+}
+
+template<class STORED, class CONTAINER>
+bool HLTNavDetails::HolderImp<STORED, CONTAINER>::setAuxDataObject(DataObject* dobjaux) {
+  bool status =  AuxDataObjectHelper::set<CONTAINER>(this->m_aux,dobjaux);
+  HMLOG(VERBOSE) << "container data is: " << m_containerProxy.data() << endreq;
+  SG::AuxVectorBase* container = m_containerProxy.castAuxVectorBase();
+  if(!this->m_aux or !container){
+    HMLOG(ERROR) << "in aux branch but aux type proxy or container proxy is null" << endreq;
+    HMLOG(ERROR) << "container is: " << container << endreq;
+    HMLOG(ERROR) << "aux is: " << this->m_aux << endreq;
+    return false;
+  }
+  SG::IAuxStore* aux = this->m_aux->castIAuxStore();
+  if(!aux){
+    HMLOG(ERROR) << "cast of auxstore failed " << endreq;    
+  }
+  if(container and aux and status){
+    HMLOG(VERBOSE) << "container is: " << container << endreq;
+    HMLOG(VERBOSE) << "aux is: " << this->m_aux << endreq;    
+    container->setStore(aux);
+    return true;
+  }
+  HMLOG(WARNING) << "something went wrong setting aux data object " <<  endreq;
+  return false;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED, class CONTAINER>
+bool HLTNavDetails::HolderImp<STORED, CONTAINER>::setDataObject(DataObject* dobj) {
+  bool success = SG::fromStorable(dobj, m_containerProxy.data_ref());
+  m_containerProxy.syncTypeless();
+  REPORT_MESSAGE_WITH_CONTEXT(MSG::VERBOSE,"Holder") << "set from storable " << success << " to address " << m_containerProxy.data();
+  return success;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED, class CONTAINER>
+HLTNavDetails::HolderImp<STORED, CONTAINER>::MemoryMgr::MemoryMgr(const FeatureProxy& st, bool sg)
+  : proxy(st), inSG(sg)
+{}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED, class CONTAINER>
+HLTNavDetails::HolderImp<STORED, CONTAINER>::MemoryMgr::MemoryMgr()
+  :  inSG(false)
+{}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED, class CONTAINER>
+void HLTNavDetails::HolderImp<STORED, CONTAINER>::MemoryMgr::clear() {
+  // if the thing is not in SG it shoudl not be cleared, if is the SG will take care of it if ( !inSG )   proxy.clear();
+}
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED>
+MsgStream& HLTNavDetails::operator<< ( MsgStream& m, const HLTNavDetails::Holder<STORED>& h ) {
+  h.print(m);
+  return m;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class STORED, class CONTAINER>
+MsgStream& HLTNavDetails::operator<< ( MsgStream& m, const HLTNavDetails::HolderImp<STORED, CONTAINER>& h ) {
+  h.print(m);
+  return m;
+}
+
+
+#undef HMLOG
+#undef MLOG
+#endif
diff --git a/Trigger/TrigEvent/TrigNavigation/TrigNavigation/Navigation.h b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/Navigation.h
new file mode 100644
index 0000000000000000000000000000000000000000..2340c314b8d4ded7a6fdaf8d78893c325ecc2e20
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/Navigation.h
@@ -0,0 +1,233 @@
+// Emacs -*- c++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+
+#ifndef TRIGNAVIGATION_HLTNAVIGATION_H
+#define TRIGNAVIGATION_HLTNAVIGATION_H
+
+#include <stdint.h>
+#include <set>
+#include <sstream>
+#include <iostream>
+
+//#include <boost/cstdint.hpp>
+//#include <stdint.h>
+
+#include "GaudiKernel/ClassID.h"
+#include "GaudiKernel/MsgStream.h"
+#include "AthenaBaseComps/AthAlgTool.h"
+#include "GaudiKernel/ToolHandle.h"
+#include "GaudiKernel/ServiceHandle.h"
+#include "GaudiKernel/IConversionSvc.h"
+
+#include "DataModel/OwnershipPolicy.h"
+#include "DataModel/DataVector.h"
+#include "DataModel/ElementLinkVector.h"
+
+// for 2 ways of performing serialization
+#include "StoreGate/StoreGateSvc.h"
+//#include "TrigSerializeResult/ITrigSerializerToolBase.h"
+//#include "TrigSerializeCnvSvc/TrigSerializeCnvSvc.h"
+//#include "TrigSerializeResult/StringSerializer.h"
+
+#include "TrigNavigation/NavigationCore.h"
+#include "TrigNavigation/TriggerElement.h"
+#include "TrigNavigation/Holder.h"
+
+class StringSerializer;
+
+static const InterfaceID IID_TrigNavigation("TrigNavigation", 1 , 0);
+
+
+namespace HLT {
+
+  
+
+  /**
+   * @brief The Navigation class, organizes TriggerElements into the tree structure.
+   *
+   * @author Tomasz Bold     <Tomasz.Bold@cern.ch>     - U. of California - Irvine
+   * @author Till Eifert     <Till.Eifert@cern.ch>     - U. of Geneva, Switzerland
+   * @author Nicolas Berger  <Nicolas.Berger@cern.ch>  - CERN
+   *
+   * The class is providing an interface to the whole navigation. The internal ingredients
+   * of the navigation which are TriggerElements are well hidden.
+   * All operations on the navigation structure are possible only via trick class.
+   * This operations are basically:
+   *
+   * -# creation of TriggerElements
+   *     - creation of the initial (root) node
+   *     - creation of RoI nodes (one per RoI, also for secondary RoIs)
+   *     - creation of normal nodes (seed by one TriggerElement)
+   *     - creation of normal nodes suitable for topological selection (being seed by 2 TriggerElements)
+   * .
+   * The created nodes are given to user with all the navigational links prepared
+   *
+   * -# features attaching and retrieval
+   *    - attaching feature to node
+   *    - attaching feature to RoI node ( therefore all TE originating from node can use it )
+   *    - attaching feature to initial (root) node for global (event wide) features
+   *    - retrieval of features attached to given node
+   *    - retrieval of features attached to given node or any predecessor (back to an initial node)
+   *    - retrieval of features attached to given node or any predecessor (traversing back to an initial node)
+   *    - retrieval of recent feature attached to given node or any predecessor (traversing back to an initial node)
+   *    - retrieval of features attached to RoI nodes of given TriggerElement
+   *    - retrieval of features attached to initial (root) node
+   * .
+   *
+   * -# queering methods
+   *    - simple queries (isInitial, isTerminal, isRoI)
+   *    - more complicated queries for 2 TriggerElements (if they share RoI etc)
+   *    - global comparison for 2 navigation structures (needed up to the moment only for validation of serialization)
+   *    - query for all TriggerElements of a given type
+   * Queries are designed to be usable with STL algorithms.
+   *
+   *
+   * Documentation of EDM related upgrade:
+   * -# objects storage
+   *    - all possible types are known at compile time (Scott's magic)
+   *    - some collections are placed in the SG always independently of the event content
+   *    - there can be more collection of given type (one for each user label i.e. number of tracks collections)
+   *    - if in navigation config this is given: TrigVertexCollection#HLTAutoKey_T2HistoPrmVtx  --> 
+   *      then DataVector<TrigVertexCollection> of label "HLTAutoKey_T2HistoPrmVtx" is placed in the SG in every event
+   *    - if in config only type is mentioned TrigVertexCollection#HLTAutoKey ---> 
+   *      then  DataVector<TrigVertexCollection> of label HLTAutoKey is placed in SG for each event
+   *    - if nothing is mentioned in config the DataVector<TrigVertexCollection> labeled at runtime depending on user labels will be placed in SG (one per label)
+   *
+   *    - the object of given type are then organized then as follows:
+   *      there is many collections of given type per event (each for one label) 
+   *      this collections are accessible by label or "SubTypeIndex"
+   *      second is to keep the TE -> feature link unchanged if we remove obe of collection during slimming or we simply not record it 
+   *
+   *     Is is like this
+   *     collection of type T |XXXXXXX|       label: ID    subTypeIndex: 0
+   *     collection of type T |XXXX|          label: MS    subTypeIndex: 1
+   *     collection of type T |XXXXXXXXXXXXX| label: Muons subTypeIndex: 2
+   *     collection of type T |XXXXXXXX|      label: Calo  subTypeIndex: 3
+   *
+   * -# the features <-> TE link
+   *    - Features are located in supercontainers DataVector<TrigVertexCollection>
+   *    - each label yields in one supercontainer (the unlabeled objects are in the container with HLTAutoKey_ label)
+   *    - The link to object in the TE is composed out of 2 numbers CLID, and index
+   *    - index (from above) is composed out of 2 parts collection coordinate and second is coordinate within collection
+   *    - this way we do not need to touch TE serialization/desetialization
+   *    - collection index and inter-collection index are uint16_t word which means we are limited to 65000 collections
+   *       of given type and same number of objects in each sub collection
+   */
+
+
+  class Navigation : public AthAlgTool, public NavigationCore {
+
+  public:
+
+    Navigation( const std::string& type,
+                const std::string& name,
+                const IInterface* parent );
+
+    virtual ~Navigation();
+    static const InterfaceID& interfaceID() {
+      return IID_TrigNavigation;
+    }
+
+    virtual StatusCode initialize();  //!< initialization, there JO are read,parsed
+    virtual StatusCode finalize();    //!< finalization, as reset()
+
+
+
+
+    /**
+     * @brief attaches feature to given TriggerElement
+     * @param te TriggerElement to which attach feature
+     * @param feature is feature ptr to attach
+     * @param key is filled up by the key used to put into SG (if not SG is involved then untouched)
+     * @param label for additional marking of this feature
+     * @return false if error enountered, true if no error encountered
+     *  if this feature is on the list of classes to be serialized by reference then
+     *  it is put into the SG (using SG->record)
+     */
+    template<class T> 
+    bool attachFeature( TriggerElement* te, const T* feature,
+			MemoryManagement, std::string& key,
+			const std::string& label="" );
+
+    //    template<class T>  bool attachFeature( TriggerElement* te, typename DataVector<T>::const_iterator begin,
+    //					   typename DataVector<T>::const_iterator end,
+    //					   MemoryManagement, std::string& key,
+    //					   const std::string& label="" );
+
+
+    /*
+     * brief attaches feature to given TriggerElement
+     * param te TriggerElement to which attach feature
+     * param feature is feature ptr to attach
+     * param label for additional marking of this feature
+     * warning WILL REMOVE IT, seems to be unusable, everyone can do the loop by him/herself
+     *
+     *   template<class T> bool attachFeatures( TriggerElement* te, const std::vector<T*>& features, const std::string& label="" );
+     */
+
+
+
+
+
+
+
+
+    /**
+     * @brief find all TriggerElements which have this object attached given feature
+     * @warning This search is costly since all TEs needs to be searched for. It can be significantly improved if
+     *           search is limited to TEs with given ID
+     * @param obj is a pointer to object of interest
+     * @param owners is a vector of TEs which will be filled by all owners of the feature
+     * @param id the id of TEs which should be inspected
+     * @return true if no error was encountered, this does not mean that object is found, false if data access error occured
+     **/
+    template<class T> bool findOwners(const T* obj, std::vector<const TriggerElement*>& owners, unsigned int id = 0);
+
+    /**
+     * @brief Get the next key for a given object
+     */
+    template<class T> const std::string getNextKey( const std::string& label = "" );
+
+    /**
+     * @brief Get a unique key (not in the usual series) for a given object
+     */
+    template<class T> const std::string getUniqueKey( const std::string& label = "" );
+
+    
+  protected:
+    Navigation(); //> not implemented
+    Navigation (const Navigation&); //> not implemented
+    Navigation& operator= (const Navigation&); //> not implemented
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////
+  private:
+    //////////////////////////////////////////////////////////////////////////////////////////////////////
+    // features holding classes
+    
+
+    // private stuff of Navigation class
+    
+
+    ServiceHandle<IConversionSvc>          m_serializerServiceHandle;
+    ServiceHandle<StoreGateSvc>            m_storeGateHandle;
+    StringSerializer                      *m_stringSerializer;
+    std::vector<std::string>               m_dlls;
+
+    
+    StatusCode classKey2CLIDKey(const std::vector<std::string> prop, std::vector<std::pair<CLID, std::string> >& decoded);
+
+
+
+  };
+
+  MsgStream& operator<< ( MsgStream& m, const Navigation& nav ); //<! printing helper
+
+} // eof namespace
+
+//#include "TrigNavigation/Navigation.icc"
+
+#endif //#ifndef HLTNAVIGATION_H
diff --git a/Trigger/TrigEvent/TrigNavigation/TrigNavigation/Navigation.icc b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/Navigation.icc
new file mode 100644
index 0000000000000000000000000000000000000000..f50ac24f2b1814752dc68ea0e12edf6d3a9c9b93
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/Navigation.icc
@@ -0,0 +1,267 @@
+// Emacs -*- c++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+
+#ifndef TRIGNAVIGATION_HLTNAVIGATION_ICC
+#define TRIGNAVIGATION_HLTNAVIGATION_ICC
+
+
+/*****************************************************************************
+ *
+ * COMPILE TYPE OBJECTS REGISTRATION
+ *
+ *****************************************************************************/
+
+#include <boost/type_traits.hpp>
+#include "TrigNavigation/Holder.h"
+#include "TrigNavigation/RoICacheHistory.h"
+
+#undef  MLOG
+#define MLOG(x)   if (m_log->level()<=MSG::x) *m_log << MSG::x
+
+
+
+/*****************************************************************************
+ *
+ * FEATURES OPERATIONS
+ *
+ *****************************************************************************/
+
+template<class T>
+__attribute__((__used__))
+bool HLT::Navigation::attachFeature( TriggerElement* te, const T* feature,
+				     MemoryManagement mmanagement, std::string& key,
+				     const std::string& label ) {
+  //typedef DataVector<T> C;
+  //  //  NavHook<T>::instan();
+
+  // Get clid
+  CLID clid = ClassID_traits<T>::ID();
+
+  MLOG(DEBUG) << "attachFeature: of clid: " << clid << "(" << ClassID_traits<T>::typeName() << ")"
+	      << " to TE: " << te->getId()
+	      << " label: \"" << label << "\""
+	      << " memory management: " << mmanagement <<  endreq;
+
+  // get a holder for this type --- if that's new it will be created
+
+  HLTNavDetails::Holder<T>* holder = getHolder<T>(label, nextSubTypeIndex(clid,label));
+
+  if ( ! holder ) {
+    MLOG(WARNING) << "attachFeature: Holder missing for CLID: " << clid << endreq;
+    return false;
+  }
+  // holder is keeping all objects of given class (indexes in this holder are used to get back to it)
+  //  unsigned int index = holder->getFeatures().size();
+
+
+  // do forced SG registration
+  /*  std::string key;
+      if ( ObjectToStoreGate == mmanagement ) {
+      key  = holder->getUniqueKey();
+      if ( m_storeGate->record(feature, key).isFailure()  ) {
+      MLOG(WARNING) << "attachFeature: feature of type: " << ClassID_traits<T>::typeName() 
+      << " and clid: " << clid << "  can't be placed directly in SG" << endreq;
+      } else {
+      MLOG(DEBUG) << "attachFeature: feature SG direct registration succesful with the key:" << key << endreq;
+      }
+      }
+  */
+
+  TriggerElement::ObjectIndex objectIndex = holder->add(feature, mmanagement == ObjectInStoreGate,  key);
+  if ( not objectIndex.valid() )
+      return false;
+  te->addFeature(clid, objectIndex, false);
+  RoICacheHistory::RememberAttachFeature(te, clid,  label,  this, objectIndex);
+  return true;
+}
+
+
+
+
+
+/*
+  //std::cerr << "Holder<" << m_typeName <<">::deserialize: unpacking labels, size of serialized:" << m_serialized << std::endl;
+  // first is recorded method of serialization used for this feature
+  SerializationMethod serializationMethod = (SerializationMethod)(input[0]);
+
+  // then comes size of serialized labels
+  uint32_t sizeOfLabels = input[1];
+
+
+
+  std::vector<uint32_t>::const_iterator begin  = input.begin();
+  std::advance(begin, 2); //
+
+  std::vector<uint32_t>::const_iterator end  = begin;
+  std::advance(end, sizeOfLabels);
+
+  // unpack labels
+  std::vector<std::string> labels;
+  std::vector<uint32_t> serializedLabels;
+  // copy out serialized lables
+
+  //std::cerr << "Holder<" << m_typeName <<">::deserialize: unpacking labels, size of serialized:" << sizeOfLabels << std::endl;
+  serializedLabels.insert(serializedLabels.end(), begin, end );
+  m_stringSerializer->deserialize(serializedLabels, labels);
+
+  //std::cerr << "Holder<" << m_typeName <<">::deserialize: unpacked labels" << std::endl;
+  //for ( unsigned int lab = 0 ; lab < labels.size() ; ++lab ) {
+  //    std::cerr << "Holder<" << m_typeName <<">::deserialize: label " << lab << " " << labels[lab] << std::endl;
+  //  }
+
+  // unpack object itself
+  begin = end;
+  end =  input.end();
+
+  std::vector<uint32_t> serializedObjects;
+  serializedObjects.insert(serializedObjects.end(), begin, end );
+
+  begin = serializedObjects.begin();
+  if ( SerializeByPayload == serializationMethod) {
+
+    std::vector<uint32_t> oneSerializedObject;
+    for ( unsigned int obj = 0; obj < labels.size() ; ++obj ) {
+      //      std::cerr << "Holder<" << m_typeName <<">::deserialize: starting with: " << labels[obj]  << std::endl;
+      uint32_t sizeOfObject = *begin;
+      //      std::cerr << "Holder<" << m_typeName <<">::deserialize: oneObjectSize: " << sizeOfObject  << std::endl;
+      advance(begin, 1);
+      end = begin;
+      advance(end, sizeOfObject);
+      oneSerializedObject.clear();
+      oneSerializedObject.insert(oneSerializedObject.end(), begin, end);
+      begin = end;
+
+      //      std::cerr << "Holder<" << m_typeName <<">::deserialize: oneObjectDeserialization size: " << oneSerializedObject.size() << std::endl;
+      m_serializer->reset();
+      T* ptr  = (T*)m_serializer->deserialize( m_typeName, oneSerializedObject);
+
+      std::string key;
+      addFeature(ptr, key, labels[obj], RecordInSG); // features not in SG and should be deleted
+    }
+  } else if ( SerializeByReference == serializationMethod) {
+
+    //std::cerr << "Holder<" << m_typeName <<">::deserialize: from StoreGate" << std::endl;
+    // retrieve this objects from SG
+    unsigned int size = labels.size();
+    if (size == 0)
+      return true;
+    //    std::cerr << "deserializing: " << m_typeName << " and the size is: " <<  size << std::endl;
+
+
+    // loop and regenerate the keys
+    for ( unsigned int i = 0 ; i < size; ++i ) {
+      const std::string& key = generateAliasKey(i, labels[i]);
+      const T* object;
+      //std::cerr << "deserializing: " << m_typeName << " and the key is: " <<  key << " sg ptr: " << m_storeGate << std::endl;
+      if ( m_storeGate->retrieve(object, key).isFailure() )
+	return false;
+
+      //      if ( m_storeGate->remove(object).isFailure() )
+      //	return false;
+      std::string newkey;
+      //std::cerr << "deserializing: " << m_typeName << "adding feature with key: "  << key << " " <<  labels[i] << std::endl;
+      addFeature(object, newkey, labels[i],  InSG); // features in SG and shouldn't be deleted
+    }
+  }
+  return true;
+}
+
+template<class T>
+const std::string HLT::Navigation::Holder<T>::getNextKey( const std::string& label ) const {
+  return generateAliasKey( m_pointers.size(), label);
+}
+
+template<class T>
+const std::string HLT::Navigation::Holder<T>::getUniqueKey( const std::string& label ) const {
+  static unsigned int counter = 0;
+  counter--;
+  return generateAliasKey(counter , label);
+}
+*/
+
+
+/////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+template<class T>
+__attribute__((__used__))
+bool HLT::Navigation::findOwners(const T* obj, std::vector<const TriggerElement*>& owners, unsigned int id) {
+  std::vector<TriggerElement*>::const_iterator it      = m_factory.listOfProduced().begin();
+  std::vector<TriggerElement*>::const_iterator itEnd   = m_factory.listOfProduced().end();
+  if ( id != 0 ) {
+    it      = m_factory.listOfProduced(id).begin();
+    itEnd   = m_factory.listOfProduced(id).end();
+    MLOG(VERBOSE) << "findOwners will scann TEs of ID : " << id << " #: " << itEnd-it << endreq;
+  } else {
+    MLOG(VERBOSE) << "findOwners will scann ALL TEs (slow):" << itEnd-it << endreq;
+  }
+
+  CLID clid = ClassID_traits<T>::ID();
+  std::map<CLID, std::map<uint16_t, HLTNavDetails::IHolder*> >::const_iterator hit = m_featuresByIndex.find(clid);
+  if (hit == m_featuresByIndex.end() ) {
+    return true;
+  }
+  MLOG(VERBOSE) << "findOwners features of this CLID present " << endreq;
+  bool holderFound = false;
+  HLT::TriggerElement::ObjectIndex idx;
+  std::map<uint16_t, HLTNavDetails::IHolder*>::const_iterator holderIt = hit->second.begin();
+  std::map<uint16_t, HLTNavDetails::IHolder*>::const_iterator holderEnd = hit->second.end();;
+  for ( ; holderIt != holderEnd; ++holderIt ) {
+    HLTNavDetails::Holder<T>* holder = (HLTNavDetails::Holder<T>*)holderIt->second; 
+    if ( holder->contains(obj, idx) ) {
+      holderFound = true;
+      MLOG(VERBOSE) << "findOwners found holder owning the object " << *holder << " and index: " << idx << endreq;
+      break;
+    }
+  }
+  if ( !holderFound ) 
+    return true;
+
+  // tmp vec
+  //  std::vector<const T*> tmp;
+  for (; it != itEnd; ++it ) {
+    //    tmp.clear();
+    std::vector< TriggerElement::FeatureAccessHelper >::const_iterator featureAccessIt = (*it)-> getFeatureAccessHelpers().begin();
+    std::vector< TriggerElement::FeatureAccessHelper >::const_iterator featureAccessEnd = (*it)-> getFeatureAccessHelpers().end();
+
+    for ( ; featureAccessIt != featureAccessEnd ; ++featureAccessIt ) {
+      if ( featureAccessIt->getCLID() == clid &&
+	   featureAccessIt->getIndex().isSameOrWithin(&idx) ) {
+	owners.push_back(*it);
+	MLOG(VERBOSE) << "findOwners while looking in TE(id): " << *it <<"(" << (*it)->getId() << ")" << " and access helper " << featureAccessIt->getIndex() << " found owner " << endreq;	
+	break;
+      }
+    }
+  }
+  return true;
+}
+
+template<class T>
+__attribute__((__used__))
+const std::string HLT::Navigation::getNextKey( const std::string& label ) {
+  CLID clid = ClassID_traits<T>::ID();
+  HLTNavDetails::Holder<T>* holder = getHolder<T>(label, nextSubTypeIndex(clid,label));
+  if (!holder) return ""; // should never happen, but who knows
+
+  return holder->getNextKey( );
+}
+
+template<class T>
+__attribute__((__used__))
+const std::string HLT::Navigation::getUniqueKey( const std::string& label ) {
+  CLID clid = ClassID_traits<T>::ID();
+  HLTNavDetails::Holder<T>* holder = getHolder<T>(label, nextSubTypeIndex(clid, label));
+  
+  if (!holder) return ""; // should never happen, but who knows
+
+  return holder->getUniqueKey( );
+}
+
+
+#undef MLOG
+//EOF
+#endif // TRIGNAVIGATION_HLTNAVIGATION_ICC
diff --git a/Trigger/TrigEvent/TrigNavigation/TrigNavigation/NavigationCore.h b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/NavigationCore.h
new file mode 100644
index 0000000000000000000000000000000000000000..8ecf0cf0e45d0c4a1fa092789e285c91e323d7a4
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/NavigationCore.h
@@ -0,0 +1,551 @@
+// Emacs -*- c++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+
+#ifndef TRIGNAVIGATION_HLTNAVIGATIONCORE_H
+#define TRIGNAVIGATION_HLTNAVIGATIONCORE_H
+
+#include <stdint.h>
+#include <set>
+#include <sstream>
+#include <iostream>
+
+//#include <boost/cstdint.hpp>
+//#include <stdint.h>
+
+#include "GaudiKernel/ClassID.h"
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/ServiceHandle.h"
+
+#include "DataModel/OwnershipPolicy.h"
+#include "DataModel/DataVector.h"
+
+// for 2 ways of performing serialization
+#include "StoreGate/StoreGateSvc.h"
+//#include "TrigSerializeResult/ITrigSerializerToolBase.h"
+//#include "TrigSerializeCnvSvc/TrigSerializeCnvSvc.h"
+
+#include "TrigNavStructure/TrigNavStructure.h"
+
+#include "TrigNavigation/Holder.h"
+#include "TrigNavigation/TypeProxy.h"
+#include "TrigNavigation/AccessProxy.h"
+#include "TrigNavigation/TypeMaps.h"
+#include "TrigNavigation/TrigFeatureLink.h"
+
+
+
+#include "TrigStorageDefinitions/EDM_TypeInfoMethods.h"
+
+class StringSerializer;
+
+//static const InterfaceID IID_TrigNavigation("TrigNavigation", 1 , 0);
+
+
+namespace HLTNavDetails { class TypeMapDeleter; }
+
+class TrigBStoxAODTool;
+
+namespace HLT {
+  class TrigNavigationSlimmingTool;
+  /**
+   * @brief The NavigationCore class, adds on top of the TrigNavStructure the EDM read-only handling
+   *
+   * @author Tomasz Bold     <Tomasz.Bold@cern.ch>     - U. of California - Irvine
+   * @author Till Eifert     <Till.Eifert@cern.ch>     - U. of Geneva, Switzerland
+   * @author Nicolas Berger  <Nicolas.Berger@cern.ch>  - CERN
+   *
+   *
+   * The created nodes are given to user with all the navigational links prepared
+   *
+   * -# features attaching and retrieval (the retrieval is implemented by this class whilc the attachement only needed in athena is in the HLTNavgation tool)
+   *    - attaching feature to node
+   *    - attaching feature to RoI node ( therefore all TE originating from node can use it )
+   *    - attaching feature to initial (root) node for global (event wide) features
+   *    - retrieval of features attached to given node
+   *    - retrieval of features attached to given node or any predecessor (back to an initial node)
+   *    - retrieval of features attached to given node or any predecessor (traversing back to an initial node)
+   *    - retrieval of recent feature attached to given node or any predecessor (traversing back to an initial node)
+   *    - retrieval of features attached to RoI nodes of given TriggerElement
+   *    - retrieval of features attached to initial (root) node
+   * .
+   *
+   *
+   * Documentation of EDM related upgrade:
+   * -# objects storage
+   *    - all possible types are known at compile time (Scott's magic)
+   *    - configured collections are placed in the SG always independently of the event content
+   *    - there can be more collection of given type (one for each user label i.e. there can be several of tracks collections depending on the reconstruction)
+   *
+   *    - the object of given type are then organized then as follows:
+   *      there is many collections of given type per event (each for one label)
+   *      this collections are accessible by label or "SubTypeIndex" uint16_t - it is used to save space in the creation of the link from TE to the feature
+   *      
+   *     Is is like this
+   *     collection of type T |XXXXXXX|       label: ID    subTypeIndex: 0
+   *     collection of type T |XXXX|          label: MS    subTypeIndex: 1
+   *     collection of type T |XXXXXXXXXXXXX| label: Muons subTypeIndex: 2
+   *     collection of type T |XXXXXXXX|      label: Calo  subTypeIndex: 3
+   *     (nothe that the association is not hardcoeded anywhere and can change from event to event. For that reason the association between the label and SubTypeIndex is recorded.)
+   *
+   * -# the features <-> TE link
+   *    - Features are located in supercontainers DataVector<TrigVertexCollection>
+   *    - each label yields in one supercontainer (the unlabeled objects are in the container with HLT_label)
+   *    - The link to object in the TE is composed out of 2 numbers CLID, and index
+   *    - index (from above) is composed out of 2 parts collection coordinate and second is coordinate within collection
+   *    - collection index and inter-collection index are uint16_t word which means we are limited to 65000 collections
+   *       of given type and same number of objects in each sub collection (this has been lifted up actually)
+   */
+
+
+  class NavigationCore : public HLT::TrigNavStructure {
+    friend class HLT::TrigNavigationSlimmingTool;
+    friend class HLTNavDetails::TypeMapDeleter;
+    friend class ::TrigBStoxAODTool;
+  public:
+    /**
+     * @brief constructor gets as an argument the TriggerElementFactory
+     *
+     * Will revise this Factory concept since it is probably better
+     * to have templated factory ... to instantiate RoIDescriptors this way as well
+     */
+
+    NavigationCore();
+    virtual ~NavigationCore();
+
+    /*
+    Navigation( const std::string& type,
+		const std::string& name,
+		const IInterface* parent );
+
+
+    static const InterfaceID& interfaceID() {
+      return IID_TrigNavigation;
+    }
+
+    virtual StatusCode initialize();  //!< initialization, there JO are read,parsed
+    virtual StatusCode finalize();    //!< finalization, as reset()
+    */
+
+
+    /**
+     * @brief prepapres the navigation for next event
+     */
+    virtual void prepare();
+    /**
+     * @brief resets all the navigation, goes to the factory and asks to withdraw all produced objects
+     */
+    virtual void reset();
+
+    /**
+     * @brief method serizlizes the navigation structure
+     * The structure is serrizlized in following order ...
+     * 1. TEs(together with links)
+     * 2. features in accordane to the lists given in property ClassesToPayload
+     *
+     * The truncation mechainsm. The parameter space should be given to the method.
+     * No more space than that will be ever taken. But since the actuall space limitation is not known
+     * at the time whrn this call happens additional list of safe to cut places is returned.
+     * One may ask why no tonly this cuts. ... Answer is follwing. If the event is huge then
+     * giving this rought limit would make procedure faster since not all features will
+     * be serialized. Otherwice they would be serialized and then thrown away, which is waste of CPU.
+     * For safe operation one can easilly make space huge (like 2MB) and not care. But for online such tuning
+     * can be considered. Space can be given as a property.
+     *
+     * @param output vector to place the result
+     * @param cuts are indexes where one can safely cut the navigation
+     *
+     * @return if true then OK
+     *         if false then truncated because of missing space - if output.size() != 0
+     *         if false and output.size() == 0 internal error
+     */
+    bool serialize( std::vector<uint32_t>& output, std::vector<unsigned int>& cuts ) const;
+    bool serialize( std::vector<uint32_t>& output, std::vector<unsigned int>& cuts, std::vector<std::pair<CLID, std::string> >& clid_name) const;
+    bool serialize_DSonly( std::vector<uint32_t>& output, std::vector<unsigned int>& cuts, std::vector<std::pair<CLID, std::string> >& clid_name) const;
+    bool deserialize( const std::vector<uint32_t>& input );
+
+    /**
+     * @brief reports on number of features which were unpacked frm BS but never accessed
+     * This mehtod is to report what objects are unnecesarilly put in BS or not extracted.
+     */
+    //int numberOfSerializedByPayload( std::vector<CLID>& listOfTypes );
+
+
+    /**
+     * @brief defines 3 possible origins of the objects which are attached to TEs
+     * This should be used like this:
+     * -# All the objects which are produced out of blue
+     *   using "new" operator should be attached with ObjectCreatedByNew switch.
+     *   This objects may also go to SG depending on configuration.
+     * -# All objects which needs to be registered in the StoreGate
+     *  should be registered using switch "ObjectToStoreGate" which tells
+     *  basically thet SG take control over the cleanup.
+     *  All objects registered like this will for sure go to SG.
+     * -# the switch "ObjectInStoreGate" should be used for objects
+     *  which are already in SG. (i.e. put there by offline reco. tools).
+     */
+    enum MemoryManagement { ObjectInStoreGate = 1, ObjectToStoreGate = 2, ObjectCreatedByNew = 3 };
+
+
+    /**
+     * @brief retrieve features attached to given TriggerElement
+     * @param te TriggerElement from retrieve
+     * @param features is collection to be feed
+     * @param label for additional marking of this feature
+     * @param labels list of all features of this type already in place and thier labels
+     * @return false if error enountered, true if no error encountered
+     * @warning No error (return true) does not mean that features were found,
+     * therefore what has to be checked is ... returned bool and
+     * size of features vector (if it has grew).
+     */
+    template<class T> 
+    bool getFeatures( const TriggerElement* te, std::vector< const T*>&  features, const std::string& label="", 
+		      std::map<const T*, std::string>* labels=0 );
+
+    template<class T> 
+    bool getFeature( const TriggerElement* te, const T*&  features, const std::string& label="", std::string& sourcelabel = m_unspecifiedLabel);
+
+    template<class T> 
+    const T* featureLink2Object( const TrigFeatureLink& );
+
+    template<class T> 
+    TrigFeatureLink object2FeatureLink(const TriggerElement* te, const std::string& label,
+				       const T* obj);
+
+
+    template<class C> 
+    TrigFeatureLink object2FeatureLink(const TriggerElement* te, const std::string& label,
+				       const typename Container2Object<C>::type * obj, 
+				       const C* container);
+
+    //const TriggerElement* te, const T*&  features, const std::string& label="", std::string& sourcelabel = m_unspecifiedLabel);
+
+
+    template<class C, class T> 
+    bool getFeaturesLinks( const TriggerElement* te, ElementLinkVector<C>& links, const std::string& label="");
+
+    
+
+    /**
+     * @brief retrieve features attached to given TriggerElement or its predecessors
+     * the algorithm will go recursively to all predecessors and once the feature is found attached to given TE
+     * returns all features (of this type and label) attached to this TE
+     * @param te TriggerElement from which to start
+     * @param features is vector to be filled up
+     * @param label for additional marking of this feature
+     * @param labels list of all features of this type already in place and thier labels (of not specified) faster query
+     * @return false if error enountered, true if no error encountered
+     * @warning No error (return true) does not mean that features were found,
+     * therefore what has to be checked is ... returned bool and
+     * feature ptr != 0;
+     */
+    template<class T> 
+    bool getRecentFeatures( const TriggerElement* te, 
+			    std::vector< const T*>&  features, const std::string& label="", 
+			    std::map<const T*, std::string>* labels=0 );
+
+    template<class T> 
+    bool getRecentFeature( const TriggerElement* te, 
+			   const T*&  feature, const std::string& label="", 
+			   const TriggerElement*& source = m_unspecifiedTE, 
+			   std::string& sourcelabel = m_unspecifiedLabel );
+
+    template<class LinkType> 
+    bool getRecentFeatureDataOrElementLink( const TriggerElement* te,
+			    LinkType& link, const std::string& label="",
+			    const TriggerElement*& source = m_unspecifiedTE, std::string& sourcelabel = m_unspecifiedLabel);
+
+    template<class C, class T> 
+    bool getRecentFeaturesLinks( const TriggerElement* te,
+			    ElementLinkVector<C>& links, const std::string& label="" );
+
+    template<class C, class T> 
+    bool getRecentFeatureLink( const TriggerElement* te,
+			       ElementLink<C>& link, const std::string& label="", 
+			       const TriggerElement*& source = m_unspecifiedTE, 
+			       std::string& sourcelabel = m_unspecifiedLabel );
+
+    
+
+    /**
+     * @brief retrieve features accessors according to the requrements
+     * This method is actually workhorse for all above. I.e. the TEs structure traversing happens inside it.
+     *
+     * @param te is TriggerElement at which searching starts
+     * @param clid is ClassID of type which is searched for
+     * @param label is object label (as used by attachFeature), empty lables (i.e. == "") means any label, 
+     *        nonempty label means exact matching, and noverlty label == "!" means we are specifically looking for empty label
+     * @param only_single_feature if true means we are looking for only one last object (i.e. imagine several object of the same type attached to TE)
+     * @param features vector of FeatureAccessHelper objects to fill up
+     * @param with_cache_recording record informations for caching 
+     * @param travel_backward_recursively if true will doe actual travering TriggerElement structure to find objects, if false search will stop at the TriggerElement te
+     * @param source TriggerElement where the object was found (or query stopped)
+     * @param sourcelabel is labels which the object had (useful when calling this routine with empty label)
+     **/
+     
+    bool getFeatureAccessors( const TriggerElement* te, CLID clid, const std::string& label, 
+			      bool only_single_feature,
+			      TriggerElement::FeatureVec& features, 
+			      bool with_cache_recording,
+			      bool travel_backward_recursively,
+			      const TriggerElement*& source = m_unspecifiedTE, 
+			      std::string& sourcelabel  = m_unspecifiedLabel);
+      
+
+    /**
+     * @brief retrieve features attached to the RoIs seeding this TriggerElement
+     * @param te TriggerElement from which start
+     * @param features is collection to be feed
+     * @param label for additional marking of this feature
+     * @return false if error enountered, true if no error encountered
+     * @param labels list of all features of this type already in place and thier labels (of not specified) faster query
+     * @warning No error (return true) does not mean that features were found,
+     * therefore what has to be checked is ... returned bool and
+     * size of features vector (if it has grew).
+     */
+    template<class T> bool getFeaturesInRoI( const TriggerElement* te,  std::vector<const T*>&  features, 
+					     const std::string& label="", std::map<const T*, std::string>* labels=0 );
+
+
+    /**
+     * @brief gets all features of type T atachedd to whichever TE
+     * @param features vector of pointers to features to which will be filled up
+     * @param label the label for a given feature
+     * @param labels list of all features of this type already in place and thier labels (of not specified) faster query
+     * @return true if no errors encountered
+     */
+    template<class C, class T> bool getAllFeatures( ElementLinkVector<C>&  features, const std::string& label="" ) ;
+
+
+
+    /**
+     * @brief Specialized by type and container for this type
+     */
+    template<class T, class C> static void registerFeatureContainer();
+
+
+
+    /**
+     * @brief attemtps to merge two trees
+     */
+
+    bool merge(const NavigationCore& l2);
+
+
+    void tweakMsgLvl(int newOffset);
+
+    void testMsgService() const; //!< test Message Svc
+
+    void testStaticMaps();
+
+    /**
+     * @brief convert strin g to hash.
+     * This is just making the function available, since there is no dict
+     * for TrigConf::HLTUtils
+     */
+    static uint32_t string2hash( const std::string&, const std::string& category="TE" );
+
+
+    /**
+     * @brief return trigger elements given the name of TEs
+     */
+    void getAllOfType ( const std::string& id, 
+			std::vector< HLT::TriggerElement* >& output,
+			const bool activeOnly=true) const;
+
+    using HLT::TrigNavStructure::getAllOfType;//( const HLT::te_id_type id, std::vector< TriggerElement* >& output,  const bool activeOnly = true ) const;
+
+    /** @brief return StoreGate label and position for each feature.
+     *
+     *  The format used here is: label::position, e.g. "HLT_initialRoi::1"
+     * @warning obsolete, will be removed
+     **/
+    /* maybe now
+    std::vector< std::string >
+    getFeatureSGLabelAndPosition( unsigned int clid, const TriggerElement* te,
+    				  const std::string& label="");
+
+    std::vector< std::string >
+    getFeatureSGLabelAndPosition( std::string featureClassName, const TriggerElement* te,
+				  const std::string& label="");
+
+    std::vector< std::string >
+    getRecentFeatureSGLabelAndPosition( unsigned int clid, const TriggerElement* te,
+    					const std::string& label="");
+
+    std::vector< std::string >
+    getRecentFeatureSGLabelAndPosition( std::string featureClassName, const TriggerElement* te,
+    					const std::string& label="");
+    */
+
+    /** @brief retrieve position of features inside the SG collections
+     *
+     * All data objects (features) attached to the TriggerElement te - with the given CLID + label -
+     * are retrieved and their positions are returned.
+     * @warning obsolete, will be removed
+     **/
+    /* maybe now
+    std::vector< unsigned int >
+    getFeatureContainerPosition( unsigned int clid, const TriggerElement* te,
+				 const std::string& label);
+
+
+    std::vector< unsigned int >
+    getFeatureContainerPosition( std::string typeName, const TriggerElement* te,
+    				 const std::string& label);
+    */
+    /** @brief retrieve position of features inside the SG collections
+     *
+     * All data objects (features) attached to the TriggerElement te - with the given CLID -
+     * are retrieved and their (label, position start - end) are returned.
+     *
+     * @warning obsolete, will be removed
+     */
+    // used in:  TrigOfflineVal.cxx (follow up)
+    /*
+    std::vector< HLT::FeatureDescriptor >
+    getFeatureContainerPosition( unsigned int clid, const TriggerElement* te);
+    
+
+    std::vector< HLT::FeatureDescriptor >
+    getFeatureContainerPosition( std::string typeName, const TriggerElement* te);
+
+
+    std::pair<std::string, std::string> getClassContainerNames(unsigned int clid) const;
+    */
+
+    /**
+     * @brief sets the object mediating communcation with SG
+     * We need this extra lightweight layer because in ARA we need to redirect SG::retrieve calls to ROOT TTree
+     **/    
+    void setAccessProxy(AccessProxy* ap);
+
+    /**
+     * @brief gets the access proxy
+     **/    
+    AccessProxy* getAccessProxy() const;
+    
+    /**
+     * @brief  changes the default collections prefix (HLT) to another
+     **/
+    void setObjKeyPrefix(const std::string& k);
+
+
+    template<class T> HLTNavDetails::Holder<T>* getHolder ( uint16_t subTypeIndex );                             //!< as above but does not create holder on demand (return 0 if not found)
+    ///////////////////////////////////////////////////////////////////////////////////////////////////////////
+  protected:
+    //////////////////////////////////////////////////////////////////////////////////////////////////////
+
+    // private stuff of Navigation class
+
+
+    bool createHolder ( HLTNavDetails::IHolder*& holder, CLID clid, const std::string& label, uint16_t idx );  //!< creates holder for type given by CLID
+    bool registerHolder ( HLTNavDetails::IHolder* holder );
+
+    template<class T> HLTNavDetails::Holder<T>* getHolder ( const std::string& label, uint16_t suggestedIndex ); //!< aware holder discovery, creates holder if needed
+
+    //    template<class T> HLTNavDetails::HolderCont<T>* getHolderCont ( const std::string& label );                          //!< type aware holder discovery, creates holder if needed
+    // template<class T> HLTNavDetails::HolderCont<T>* getHolderCont ( uint16_t subTypeIndex );                             //!< as above but does not create holder on demand (return 0 if not found)
+    HLTNavDetails::IHolder*                     getHolder ( CLID clid, uint16_t subTypeIndex ) const;            //!< as above but not type wise holder returned
+    HLTNavDetails::IHolder*                     getHolder ( CLID clid, const std::string& label ) const;         //!< as above
+
+    std::map< CLID, std::map< uint16_t, std::string> > m_lookupLabels;
+
+    typedef std::map<uint16_t, HLTNavDetails::IHolder*> IndexToHolderMap;
+    typedef std::map<std::string, HLTNavDetails::IHolder*> StringToHolderMap;
+    typedef std::map<CLID,  IndexToHolderMap>     FeaturesStructure;
+    typedef std::map<CLID,  StringToHolderMap>  FeaturesStructureLabelIndexed;
+
+    FeaturesStructure             m_featuresByIndex;     //!< all objects map (it can be addressed by m_features[clid][idx]
+
+    FeaturesStructureLabelIndexed m_featuresByLabel;     //!< all objects map (it can be addressed by m_features[clid][label]
+
+    std::map< CLID, std::vector<uint32_t>* > m_serializedFeatures; //!< map can be replaced by the same concept as in TriggerStore
+
+    /**
+     * @brief Helper method for "combine": add one "level" of multiplicity to the results.
+     */
+    bool addOneLevel(std::vector< std::vector<TriggerElement*> >& currentCombs,
+                     std::vector< std::vector<std::pair<unsigned int, unsigned int> > >& currentIdxs,
+                     unsigned int type,
+                     std::vector< std::vector<TriggerElement*> >& newCombs,
+                     std::vector< std::vector<std::pair<unsigned int, unsigned int> > >& newIdxs,
+                     unsigned int maxResults = 1000, bool onlyActive = 1);
+
+
+    //    ITrigSerializerToolBase* m_serializer;     //!< pointer to Serializer
+
+    MsgStream                             *m_log;                                //!< log stream
+    //    IConversionSvc                        *m_serializerSvc;
+    ServiceHandle<IConversionSvc>           m_serializerSvc;
+    StringSerializer                      *m_stringSerializer;
+    AccessProxy                           *m_storeGate;
+    //    StoreGateSvc                          *m_storeGate;
+    //    unsigned int                           m_serializeSpaceLimit;   //!< proprty to limit BS content to some reasonable size
+    std::string                            m_objectsKeyPrefix;      //!< property setting prefix which is to be given to all trigger EDM objects
+    unsigned                               m_objectsIndexOffset;    //!< small integer used to generate sub type index 
+
+    typedef std::pair<CLID, std::string> CSPair;
+
+    std::vector<std::string> m_classesToPayloadProperty;              //!< list of classes#keys to be put to BS payload
+    std::vector<CSPair>  m_classesToPayload;   //!< classess are put to payload according to that priority list (CLID + key)
+    
+    std::vector<std::string> m_classesToPayloadProperty_DSonly;              //!< list of classes#keys to be put to DS payload
+    std::vector<CSPair>  m_classesToPayload_DSonly;   //!< classess are put to payload according to that priority list (CLID + key)
+
+    std::vector<std::string> m_classesFromPayloadProperty;              //!< list of classes#keys to be extracted from BS payload
+
+
+    std::vector<std::string> m_classesToPreregisterProperty;             //!< as above but for preregistration
+    std::vector<CSPair> m_classesToPreregister;   //!< classes mentioned here will be put to SG irrespectively of thier presence in event
+
+
+
+    /**
+     * @brief initialization helper - turns the list of class#key into map of CLID:key
+     * As the same conversion (class name ==> CLID) needs to be done for classes to payload and classes to preregister this is outsourced to this function
+     */
+    StatusCode classKey2CLIDKey(const std::vector<std::string> prop, std::vector<CSPair>& decoded);
+
+
+
+    bool m_referenceAllClasses;
+    inline bool toBeReferenced(CLID /*c*/) { return m_referenceAllClasses; }
+    bool toBePutToPayload(const HLTNavDetails::IHolder*) const;
+
+
+
+    bool appendSerializedFeatureToPayload(CLID c, std::vector<uint32_t>& payload, const std::vector<uint32_t>& feature) const;
+
+
+    uint16_t nextSubTypeIndex(CLID clid, const std::string&label);
+
+    bool addBlob(std::vector<uint32_t>& output,
+		 const std::vector<uint32_t>& blob1,
+		 const std::vector<uint32_t>& blob2 ) const ;
+
+    bool extractBlob(const std::vector<uint32_t>& input,
+		     std::vector<uint32_t>::const_iterator& it,
+		     std::vector<uint32_t>& blob) const ;
+
+
+
+
+  private:
+    static const TriggerElement* m_unspecifiedTE;
+    static std::string m_unspecifiedLabel;
+    
+    HLTNavDetails::IHolder* prepareOneHolder(CLID clid, const std::string& label);
+
+  };
+
+  MsgStream& operator<< ( MsgStream& m, const NavigationCore& nav ); //<! printing helper
+
+} // eof namespace
+
+//#include "TrigNavigation/NavigationCore.icc"
+
+#endif //#ifndef HLTNAVIGATION_H
diff --git a/Trigger/TrigEvent/TrigNavigation/TrigNavigation/NavigationCore.icc b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/NavigationCore.icc
new file mode 100644
index 0000000000000000000000000000000000000000..88173e2e220078c069c2fc93c37e481eabb1a316
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/NavigationCore.icc
@@ -0,0 +1,623 @@
+// Emacs -*- c++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+
+#ifndef TRIGNAVIGATION_HLTNAVIGATIONCORE_ICC
+#define TRIGNAVIGATION_HLTNAVIGATIONCORE_ICC
+
+#include "TrigNavigation/Holder.h"
+#include "TrigNavigation/Holder.icc"
+#include "TrigNavigation/RoICacheHistory.h"
+
+
+
+#include <algorithm>
+//#include <assert.h>
+#include <boost/foreach.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/utility/enable_if.hpp>
+
+#include <iostream>
+
+/*****************************************************************************
+ *
+ * COMPILE TYPE OBJECTS REGISTRATION
+ *
+ *****************************************************************************/
+#include <boost/type_traits.hpp>
+#undef  MLOG
+#define MLOG(x)   if (m_log->level()<=MSG::x) *m_log << MSG::x
+
+
+/////////////////////////////////////////////////////////////////////////////
+template<class T>
+__attribute__((__used__))
+bool HLT::NavigationCore::getFeatures( const TriggerElement* te,
+				   std::vector<const T*>&  features, const std::string& label,
+				   std::map<const T*, std::string>* /*labels*/)  {
+
+
+  MLOG(DEBUG) << "getFeatures: of clid: " << ClassID_traits<T>::ID() << "(" << ClassID_traits<T>::typeName() << ")"
+	      <<" to TE: " << te->getId()
+	      << " label: \"" << label << "\"" << endreq;
+
+  TriggerElement::FeatureVec features_access_helpers;  
+  if ( getFeatureAccessors(te, ClassID_traits<T>::ID(), label, false, features_access_helpers, true, false ) == false ) {
+    return false;
+  }
+  
+  // type specific code
+  BOOST_FOREACH( const TriggerElement::FeatureAccessHelper& fea, features_access_helpers) {
+    TriggerElement::ObjectIndex objectIndex(fea.getIndex());
+    HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
+    const T* obj(0);
+    if ( holder->get(obj, objectIndex) == false ) {
+      MLOG(WARNING) << "getFeatures: problems while getting objects #" << objectIndex  
+			<< " from the holder: " << *holder <<  endreq;
+    } else {
+      features.push_back(obj);
+    }
+  }
+  return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class T> 
+__attribute__((__used__))
+bool HLT::NavigationCore::getFeature( const TriggerElement* te, const T*&  feature, const std::string& label, std::string& sourcelabel) {
+
+  feature = 0;
+  MLOG(DEBUG) << "getFeature: of clid: " << ClassID_traits<T>::ID() << "(" << ClassID_traits<T>::typeName() << ")"
+	      <<" to TE: " << te->getId()
+	      << " label: \"" << label << "\"" << endreq;
+  
+  TriggerElement::FeatureVec features_access_helpers;  
+  if ( getFeatureAccessors(te, ClassID_traits<T>::ID(), label, true, features_access_helpers, true, false, m_unspecifiedTE, sourcelabel ) == false ) {
+    return false;
+  }
+  // remove following after testing
+  if ( features_access_helpers.size() > 1 ) {
+    MLOG(WARNING) << "getFeature: logic error, got: " << features_access_helpers.size() <<  " features from: getFeatureAccessors"  << endreq;
+  }
+
+  
+  if ( features_access_helpers.empty() )
+    return true;
+
+  const TriggerElement::FeatureAccessHelper& fea = features_access_helpers.front();
+  TriggerElement::ObjectIndex objectIndex(fea.getIndex());
+  HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
+  
+  if ( holder->get(feature, objectIndex) == false ) {
+    MLOG(WARNING) << "getFeature: problems while getting objects #" << objectIndex
+		  << " from the holder: " << *holder <<  endreq;
+    feature = 0;    
+  }
+  
+  return true;  
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class C, class T> 
+__attribute__((__used__))
+bool HLT::NavigationCore::getFeaturesLinks( const TriggerElement* te, ElementLinkVector<C>& links, const std::string& label) {
+  
+  MLOG(DEBUG) << "getFeaturesLinks: of clid: " << ClassID_traits<T>::ID() << "(" << ClassID_traits<T>::typeName() << ")"
+	      << " to TE: " << te->getId()
+	      << " label: \"" << label << "\"" << endreq;
+
+  TriggerElement::FeatureVec features_access_helpers;  
+  if ( getFeatureAccessors(te, ClassID_traits<T>::ID(), label, false, features_access_helpers, true, false ) == false ) {
+    return false;
+  }
+
+  BOOST_FOREACH( const TriggerElement::FeatureAccessHelper& fea, features_access_helpers) {
+    TriggerElement::ObjectIndex objectIndex(fea.getIndex());
+    HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
+
+    if ( holder->get(links, objectIndex) == false ) {
+	  MLOG(WARNING) << "getFeaturesLinks: problems while getting objects #" << objectIndex  
+			<< " from the holder: " << *holder <<  endreq;
+    }
+  }
+  return true;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+template<class T>
+__attribute__((__used__))
+bool HLT::NavigationCore::getRecentFeatures( const TriggerElement* te,
+					     std::vector<const T*>&  features, const std::string& label,
+					     std::map<const T*, std::string>* /*labels*/) {
+
+  // start from itself
+  MLOG(DEBUG) << "getRecentFeatures: looking for CLID: " << ClassID_traits<T>::ID()  << "(" << ClassID_traits<T>::typeName() << ")"
+	      << " in TE: " << te->getId()  
+	      << " label: \"" << label << "\"" << endreq;
+
+  TriggerElement::FeatureVec features_access_helpers;  
+  if ( getFeatureAccessors(te, ClassID_traits<T>::ID(), label, false, features_access_helpers, true, true ) == false ) {
+    return false;
+  }
+
+  // type specific code
+  BOOST_FOREACH( const TriggerElement::FeatureAccessHelper& fea, features_access_helpers) {
+    TriggerElement::ObjectIndex objectIndex(fea.getIndex());
+    HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
+    const T* obj(0);
+    if ( holder->get(obj, objectIndex) == false ) {
+	  MLOG(WARNING) << "getRecentFeatures: problems while getting objects #" << objectIndex  
+			<< " from the holder: " << *holder <<  endreq;
+    } else {
+      features.push_back(obj);
+    }
+  }
+  return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class T> 
+__attribute__((__used__))
+bool HLT::NavigationCore::getRecentFeature( const TriggerElement* te, 
+					    const T*&  feature, const std::string& label, 
+					    const TriggerElement*& source, std::string& sourcelabel ) {
+
+  // important! set pointer to NULL to signify nothing was found, it will later be reset to sth else eventually
+  feature = 0;
+
+  MLOG(DEBUG) << "getRecentFeature: looking for CLID: " << ClassID_traits<T>::ID()  << "(" << ClassID_traits<T>::typeName() << ")"
+	      << " in TE: " << te->getId()  
+	      << " label: \"" << label << "\"" << endreq;
+
+  TriggerElement::FeatureVec features_access_helpers;  
+  if ( getFeatureAccessors(te, ClassID_traits<T>::ID(), label, true, features_access_helpers, true, true, source, sourcelabel ) == false ) {
+    return false;
+  }
+  // remove following after testing
+  if ( features_access_helpers.size() > 1 ) {
+    MLOG(WARNING) << "getRecentFeature: logic error, got: " << features_access_helpers.size() <<  " features from: getRecentFeaturesImpl"  << endreq;
+  }
+
+  if ( features_access_helpers.empty() )
+    return true;
+
+  const TriggerElement::FeatureAccessHelper& fea = features_access_helpers.front();
+  TriggerElement::ObjectIndex objectIndex(fea.getIndex());
+  HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
+  
+  if ( holder->get(feature, objectIndex) == false ) {
+    MLOG(WARNING) << "getRecentFeature: problems while getting objects #" << objectIndex
+		  << " from the holder: " << *holder <<  endreq;
+    feature = 0;    
+  }
+  
+  return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class C, class T> 
+__attribute__((__used__))
+bool HLT::NavigationCore::getRecentFeaturesLinks( const TriggerElement* te,
+						  ElementLinkVector<C>& links, const std::string& label ) {
+
+  MLOG(DEBUG) << "getRecentFeaturesLinks: looking for CLID: " << ClassID_traits<T>::ID()  << "(" << ClassID_traits<T>::typeName() << ")"
+	      << " in TE: " << te->getId()  
+	      << " label: \"" << label << "\"" << endreq;
+  
+  
+  TriggerElement::FeatureVec features_access_helpers;  
+  if ( getFeatureAccessors(te, ClassID_traits<T>::ID(), label, false, features_access_helpers, true, true ) == false ) {
+    return false;
+  }
+  
+  BOOST_FOREACH( const TriggerElement::FeatureAccessHelper& fea, features_access_helpers) {
+    TriggerElement::ObjectIndex objectIndex(fea.getIndex());
+    HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
+
+    if ( holder->get(links, objectIndex) == false ) {
+	  MLOG(WARNING) << "getRecentFeaturesLinks: problems while getting objects #" << objectIndex  
+			<< " from the holder: " << *holder <<  endreq;
+    }
+  }
+  return true;
+}
+
+//helper struct to get the container type if template argument is datalink or the element type if template arg is ElementLink
+
+template<class LinkType>
+struct link_to_type;
+
+template<class CONTAINERTYPE>
+struct link_to_type<DataLink<CONTAINERTYPE> >{
+  typedef CONTAINERTYPE container_type;
+  typedef typename DataLink<CONTAINERTYPE>::value_type type;
+};
+
+template<class CONTAINERTYPE>
+struct link_to_type<ElementLink<CONTAINERTYPE> >{
+  typedef CONTAINERTYPE container_type;
+  typedef typename ElementLink<CONTAINERTYPE>::ElementType ptr2constT_type;   // is a const T* if T is the feature type
+  typedef typename boost::remove_pointer<ptr2constT_type>::type constT_type;  // is a const T
+  typedef typename boost::remove_const<constT_type>::type type;               // is a       T
+};
+
+
+/////////////////////////////////////////////////////////////////////////////
+template<class LinkType> 
+__attribute__((__used__))
+bool HLT::NavigationCore::getRecentFeatureDataOrElementLink( const TriggerElement* te, LinkType& link, const std::string& label,
+                                                             const TriggerElement*& source, std::string& sourcelabel) {
+
+  typedef typename link_to_type<LinkType>::type T;
+  MLOG(DEBUG) << "getRecentFeatureDataOrElementLink: looking for CLID: " << ClassID_traits<T>::ID()  << "(" << ClassID_traits<T>::typeName() << ")"
+              << " in TE: " << te->getId()  
+              << " label: \"" << label << "\"" << endreq;
+  
+  TriggerElement::FeatureVec features_access_helpers;  
+  if ( getFeatureAccessors(te, ClassID_traits<T>::ID(), label, true, features_access_helpers, true, true, source, sourcelabel ) == false ) {
+    MLOG(WARNING) << "looking for FAs failed. Returning false! Details CLID: " << ClassID_traits<T>::ID()  << "(" << ClassID_traits<T>::typeName() << ")"
+	      << " in TE: " << te->getId()  
+	      << " label: \"" << label << "\"" << endreq;
+    return false;
+  }
+  // remove following after testing
+  if ( features_access_helpers.size() > 1 ) {
+    MLOG(WARNING) << "getRecentFeature: logic error, got: " << features_access_helpers.size() <<  " features from: getRecentFeaturesImpl"  << endreq;
+  }
+  
+  if ( features_access_helpers.empty() )
+    return true;
+    
+  const TriggerElement::FeatureAccessHelper& fea = features_access_helpers.front();
+  TriggerElement::ObjectIndex objectIndex(fea.getIndex());
+  HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
+  
+  //apparently must use function pointer to get all the types resolved properly
+  typedef typename link_to_type<LinkType>::container_type containertype;  
+  bool (HLTNavDetails::Holder<T>::*funcptr) (LinkType&, HLT::TriggerElement::ObjectIndex&) = 
+  &HLTNavDetails::Holder<T>::template getWithLink<containertype>;
+  
+  if ( (holder->*funcptr)(link, objectIndex) == false ) {
+      MLOG(WARNING) << "getRecentFeatureLink: problems while getting objects #" << objectIndex
+       << " from the holder: " << *holder <<  endreq;
+  }
+  return true;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class C, class T> 
+__attribute__((__used__))
+bool HLT::NavigationCore::getRecentFeatureLink( const TriggerElement* te,
+                                                ElementLink<C>& link, const std::string& label, 
+                                                const TriggerElement*& source, 
+                                                std::string& sourcelabel) {
+
+  MLOG(DEBUG) << "getRecentFeatureLink: looking for CLID: " << ClassID_traits<T>::ID()  << "(" << ClassID_traits<T>::typeName() << ")"
+              << " in TE: " << te->getId()  
+              << " label: \"" << label << "\"" << endreq;
+  
+  if( boost::is_same<C, T>::value ) 
+    return false;
+    
+
+  TriggerElement::FeatureVec features_access_helpers;  
+  if ( getFeatureAccessors(te, ClassID_traits<T>::ID(), label, true, features_access_helpers, true, true, source, sourcelabel ) == false ) {
+    return false;
+  }
+  // remove following after testing
+  if ( features_access_helpers.size() > 1 ) {
+    MLOG(WARNING) << "getRecentFeature: logic error, got: " << features_access_helpers.size() <<  " features from: getRecentFeaturesImpl"  << endreq;
+  }
+
+  if ( features_access_helpers.empty() )
+    return true;
+
+  const TriggerElement::FeatureAccessHelper& fea = features_access_helpers.front();
+  TriggerElement::ObjectIndex objectIndex(fea.getIndex());
+  HLTNavDetails::Holder<T>* holder = getHolder<T>(objectIndex.subTypeIndex());
+
+  ElementLinkVector<C> links;
+  if ( holder->get(links, objectIndex) == false ) {
+    MLOG(WARNING) << "getRecentFeatureLink: problems while getting objects #" << objectIndex
+                  << " from the holder: " << *holder <<  endreq;    
+  } else {
+    if ( links.size() != 1 ) {
+      MLOG(WARNING) << "getRecentFeatureLink: problems while getting objects #" << objectIndex
+		    << " from the holder: " << *holder << " links vector has size " << links.size() << " while shoudl have size == 1" << endreq;    
+      return false;
+    } else {
+      link = links.back();
+    }
+  }
+  return true;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+template<class T>
+__attribute__((__used__))
+bool HLT::NavigationCore::getFeaturesInRoI( const TriggerElement* te,
+                                            std::vector<const T*>&  features, const std::string& label,
+                                            std::map<const T*, std::string>* labels) {
+  // easy, jump to the RoI (if not RoI node) and loop over all TEs attached to it
+  const TriggerElement* roi(0);
+  if ( TrigNavStructure::isRoINode(te) )
+    roi = te;
+  else if ( te->getRelated(TriggerElement::sameRoIRelation).size() == 1 ) // means we do not support topological TEs here
+    roi = *(te->getRelated(TriggerElement::sameRoIRelation).begin());
+  else
+    return false;
+
+  bool oneRetStatus = false;
+  bool allRetStatus = false;
+  std::vector<TriggerElement*>::const_iterator it;
+  for ( it = roi->getRelated(TriggerElement::sameRoIRelation).begin();
+        it != roi->getRelated(TriggerElement::sameRoIRelation).end(); ++it ) {
+    oneRetStatus = getFeatures(*it, features, label, labels );  // the features will be paked to the end of the vector (see push_back in getFeatures)
+    allRetStatus = allRetStatus || oneRetStatus; // that's OK if at least one call returns some feature
+  }
+  return allRetStatus;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class C, class T> 
+__attribute__((__used__))
+bool HLT::NavigationCore::getAllFeatures( ElementLinkVector<C>&  features, const std::string& label ) {
+  CLID clid = ClassID_traits<T>::ID();
+  MLOG(DEBUG) << "getAllFeatures: of clid: " << clid << "(" << ClassID_traits<T>::typeName() << ")"
+              << " label: \"" << label << "\"" <<  endreq;
+  
+  FeaturesStructureLabelIndexed::const_iterator fit = m_featuresByLabel.find(clid);
+  if (fit == m_featuresByLabel.end() )
+    return true;
+  
+  const std::map<std::string, HLTNavDetails::IHolder*>& allOfThisType = fit->second;
+  std::map<std::string, HLTNavDetails::IHolder*>::const_iterator hit;
+  for ( hit = allOfThisType.begin(); hit != allOfThisType.end(); ++hit ) {
+    if ( label == hit->first || label == "" ) {
+      HLTNavDetails::Holder<T>* holder = getHolder<T>(hit->second->label(), nextSubTypeIndex(clid, label));
+      MLOG(VERBOSE)  << "getAllFeatures: getting from: " << *holder << endreq;
+      if ( holder->get(features) == false ) {
+        MLOG(WARNING) << "getAllFeatures: failed with the holder: " << *(hit->second) << endreq;
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+template<class T>
+__attribute__((__used__))
+HLTNavDetails::Holder<T>* HLT::NavigationCore::getHolder(const std::string& label, uint16_t suggestedIndex) {
+
+  // find object
+  CLID clid = ClassID_traits<T>::ID();
+  MLOG(DEBUG) << "Getting holder for type: " << clid << " label: " << label << endreq; 
+
+  HLTNavDetails::Holder<T>* holder = static_cast<HLTNavDetails::Holder<T>* >(getHolder(clid, label));
+  
+  if ( holder ) {
+    return holder; 
+  }
+  
+  // take an appropriate action if this is the first feature of that type#label to be attached/retrieved
+  HLTNavDetails::IHolder* baseholder;
+  if ( createHolder(baseholder, clid, label, suggestedIndex) ) {        // create fresh holder
+    MLOG(DEBUG) << "getHolder: predefined holder got" <<  endreq;
+    
+  } else {
+    MLOG(ERROR) << "getHolder: predefined holder does not exist, load EDM classes for: " 
+		  << ClassID_traits<T>::typeName() << " CLID " << ClassID_traits<T>::ID()  <<  endreq;
+    return 0;
+  }
+  holder = static_cast<HLTNavDetails::Holder<T>*>(baseholder);
+  registerHolder(holder);
+
+  return holder;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+template<class T>
+__attribute__((__used__))
+HLTNavDetails::Holder<T>* HLT::NavigationCore::getHolder(uint16_t subTypeIndex ) {
+  // find object
+  CLID clid = ClassID_traits<T>::ID();
+  MLOG(DEBUG) << "Getting holder for type: " << clid << endreq;
+  HLTNavDetails::Holder<T>* holder = static_cast<HLTNavDetails::Holder<T>* >(getHolder(clid, subTypeIndex));
+
+  return holder;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// 2012-09-14 new stuff for composite obejcts
+
+//#include "TrigNavigation/TypeInformation.h"
+
+
+#include "TrigNavigation/NavigationInit.h"
+
+/*
+template<class T> 
+const T* HLT::NavigationCore::featureLink2ObjectByObject( const TrigFeatureLink& fl) {
+
+  HLTNavDetails::Holder<Feature>* holder = getHolder<Feature>(fl.subTypeIndex());
+  const T* ptr(0);
+  holder->get(ptr, TriggerElement::ObjectIndex(fl.subTypeIndex(), fl.index(), fl.index()+1));
+  return ptr;
+}
+
+template<class T> 
+const T* HLT::NavigationCore::featureLink2ObjectByContainer( const TrigFeatureLink& fl) {
+
+  HLTNavDetails::Holder<Feature>* holder = getHolder<Feature>(fl.subTypeIndex());
+  const T* ptr(0);
+  holder->get(ptr, TriggerElement::ObjectIndex(fl.subTypeIndex(), fl.index(), fl.index()+1));
+  return ptr;
+}
+*/
+
+#include <stdlib.h>
+#include <cxxabi.h>
+
+namespace HLT{
+  /*
+  struct tool{
+    static std::string rtti_real_name(const char* name)
+    {
+      int status;
+      char *realname = abi::__cxa_demangle(name, 0, 0, &status);
+      std::string n(realname);
+      free(realname);
+    
+      return n;
+    }
+  };
+  */
+
+  template<class T, class C, bool get_by_contianer, bool get_by_object>
+  struct get{};
+
+  template<class T, class C>
+  struct get< T, C, false, false>{
+    static const T* do_it(const TrigFeatureLink&, HLT::NavigationCore* ){
+      return 0; // here compile time error shoudl be generated
+    }
+  };
+
+  template<class T, class C>
+  struct get< T,  C, false, true>{
+    static const T* do_it(const TrigFeatureLink&fl, HLT::NavigationCore* nav){
+      HLTNavDetails::Holder<T>* holder = nav->getHolder<T>(fl.subTypeIndex());
+      //std::cerr << " Holder acquired " << __LINE__ << std::endl;
+      const T* ptr(0);
+      holder->get(ptr, HLT::TriggerElement::ObjectIndex(fl.subTypeIndex(), fl.index(), fl.index()+1));
+      //      std::cerr << " object retrieved " << __LINE__ << std::endl;
+      return ptr;
+    }
+
+  };
+
+  template<class T, class C>
+  struct get< T, C, true, false>{
+    static const T* do_it(const TrigFeatureLink&fl, HLT::NavigationCore* nav){
+      HLTNavDetails::Holder<C>* holder = nav->getHolder<C>(fl.subTypeIndex());
+      //std::cerr << " Holder acquired " << __LINE__ <<  " " << fl.clid() << " " << fl.subTypeIndex() << " " << holder << "  " <<  ClassID_traits<C>::ID() << std::endl;
+      const C* ptr(0);
+      holder->get(ptr, HLT::TriggerElement::ObjectIndex(fl.subTypeIndex(), fl.index(), fl.index()+1));
+      //std::cerr << " object retrieved " << __LINE__ << std::endl;
+      if ( ptr and ptr->size() == 1) {
+	return ptr->at(0);
+      }
+      return 0;
+    }
+  };
+
+
+  template<class T, class C>
+  struct get< T, C, true, true> {
+    static const T* do_it(const TrigFeatureLink&fl, HLT::NavigationCore* nav){
+      if ( fl.clid() == ClassID_traits<C>::ID() ) {
+	return get<T,C, true, false>::do_it(fl, nav);
+      } else if ( fl.clid() == ClassID_traits<T>::ID() ) {
+	return get<T,C, false, true>::do_it(fl, nav);
+      }
+      return 0;
+    }
+  };
+}
+
+template<class T> 
+__attribute__((__used__))
+const T* HLT::NavigationCore::featureLink2Object( const TrigFeatureLink& fl) {
+  if (! fl.isValid())
+    return (const T*)0;
+
+  typedef typename Object2Features<T>::type list_of_possible_features;  
+  typedef typename Object2Container<T>::type container;  
+  
+  // std::cerr << " in the list "  << HLT::tool::rtti_real_name(typeid(list_of_possible_features).name()) << std::endl;
+  // std::cerr << " container "  << HLT::tool::rtti_real_name(typeid(container).name()) << std::endl;
+  // std::cerr << " has T "  << list_of_possible_features::template has<T>::result << std::endl;
+  // std::cerr << " has container "  << list_of_possible_features::template has<container>::result << std::endl;
+
+  const T* ptr = HLT::get<T, container, 
+    list_of_possible_features::template has<container>::result,
+    list_of_possible_features::template has<T>::result>::do_it(fl, this);
+
+  return ptr;
+
+}
+
+//not sure why i need to redef the macro here
+#define MLOG(x)   if (m_log->level()<=MSG::x) *m_log << MSG::x
+
+template<class T> 
+__attribute__((__used__))
+TrigFeatureLink HLT::NavigationCore::object2FeatureLink(const TriggerElement* te, const std::string& label,
+							const T* obj) {
+
+  typedef typename Features2Container<T>::type Container;
+  if ( obj == 0 ) 
+    return TrigFeatureLink();
+  TriggerElement::FeatureVec features_access_helpers;  
+  std::string sourcelabel;
+  if ( getFeatureAccessors(te, ClassID_traits<T>::ID(), label, true, features_access_helpers, false, true, m_unspecifiedTE, sourcelabel ) == false ) {
+    return TrigFeatureLink();
+  }
+
+  // remove following after testing
+  if ( features_access_helpers.size() > 1 ) {
+    MLOG(WARNING) << "getFeature: logic error, got: " << features_access_helpers.size() <<  " features from: getFeatureAccessors"  << endreq;
+  }
+
+  if ( features_access_helpers.empty() )
+    return TrigFeatureLink();
+
+  const TriggerElement::ObjectIndex& oindex = features_access_helpers.at(0).getIndex();
+  return TrigFeatureLink(ClassID_traits<T>::ID(), oindex.subTypeIndex(), oindex.objectsBegin());
+
+}
+
+template<class C> 
+__attribute__((__used__))
+TrigFeatureLink HLT::NavigationCore::object2FeatureLink(const TriggerElement* te, const std::string& label,
+							const typename Container2Object<C>::type* obj, 
+							const C* container) {
+
+  TriggerElement::FeatureVec features_access_helpers;  
+  std::string sourcelabel;
+  if ( getFeatureAccessors(te, ClassID_traits<C>::ID(), label, true, features_access_helpers, false, true, m_unspecifiedTE, sourcelabel ) == false ) {
+    return TrigFeatureLink();
+  }
+  // remove following after testing
+  if ( features_access_helpers.size() > 1 ) {
+    MLOG(WARNING) << "getFeature: logic error, got: " << features_access_helpers.size() <<  " features from: getFeatureAccessors"  << endreq;
+  }
+
+  if ( features_access_helpers.empty() )
+    return TrigFeatureLink();
+
+  const TriggerElement::ObjectIndex& oindex = features_access_helpers.at(0).getIndex();
+  typename C::const_iterator lookup = std::find(container->begin(), container->end(),obj);
+  if ( lookup == container->end() )
+    return TrigFeatureLink();
+
+  const unsigned offset =  lookup - container->begin();
+  return TrigFeatureLink(ClassID_traits<C>::ID(), oindex.subTypeIndex(), oindex.objectsBegin()+offset);
+
+}
+
+
+
+
+#undef MLOG
+
+//EOF
+#endif // #ifndef TRIGNAVIGATION_HLTNAVIGATIONCORE_ICC
diff --git a/Trigger/TrigEvent/TrigNavigation/TrigNavigation/NavigationInit.h b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/NavigationInit.h
new file mode 100644
index 0000000000000000000000000000000000000000..68af06d424928c692d58cb07516aab0687196693
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/NavigationInit.h
@@ -0,0 +1,60 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TrigNavigation_NavigationInit_h
+#define TrigNavigation_NavigationInit_h
+
+  /**
+   * @brief Classes used to provide static Trigger EDM list
+   *
+   * This code is from Scott Snyder
+   */
+//#include "TrigNavigation/NavigationCore.h"
+
+
+#include <boost/function_types/function_type.hpp>
+#include <boost/function_types/parameter_types.hpp>
+#include <boost/function_types/function_arity.hpp>
+#include <boost/typeof/std/utility.hpp>
+#include <boost/type_traits/remove_pointer.hpp>
+#include "DataModel/ElementLink.h"
+#include "DataModel/DataLink.h"
+
+#include "TrigNavigation/NavigationTraits.h"
+#include "TrigStorageDefinitions/EDM_TypeInfoMethods.h"
+
+namespace HLT{  
+  template <class FEATURE, class CONTAINER >
+  struct FeatureContainerInit {
+    FeatureContainerInit();
+    void null(){;}
+  };
+
+  template <class FEATURE, class CONTAINER > 
+  struct RegisterFeatureContainerTypes {    
+    static void instan(){s.null();}
+    static FeatureContainerInit<FEATURE, CONTAINER> s; 
+  };  
+  template <class FEATURE, class CONTAINER> FeatureContainerInit<FEATURE, CONTAINER> RegisterFeatureContainerTypes<FEATURE, CONTAINER>::s;
+
+
+  template <class TYPE >
+  struct AuxInit {
+    AuxInit();
+    void null(){;}
+  };
+
+  template <class TYPE > 
+  struct RegisterAuxType {    
+    static void instan(){s.null();}
+    static AuxInit<TYPE> s; 
+  };  
+  template <class TYPE> AuxInit<TYPE> RegisterAuxType<TYPE>::s;
+}
+
+
+
+#include "TrigNavigation/NavigationInit.icc"
+
+#endif
diff --git a/Trigger/TrigEvent/TrigNavigation/TrigNavigation/NavigationInit.icc b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/NavigationInit.icc
new file mode 100644
index 0000000000000000000000000000000000000000..3098ab18ff88dfede9c787ad03d8066328bc9225
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/NavigationInit.icc
@@ -0,0 +1,274 @@
+// dear emacs this is -*- c++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+
+#ifndef TrigNavigation_NavigationInit_icc
+#define TrigNavigation_NavigationInit_icc
+
+//#include "GaudiKernel/MsgStream.h"
+#include <boost/type_traits/is_same.hpp>
+
+#include "DataModel/ConstDataVector.h"
+#include "TrigNavigation/Holder.h"
+#include "TrigNavigation/Holder.icc"
+
+#include "TrigNavigation/Navigation.h"
+#include "TrigNavigation/Navigation.icc"
+
+#include "TrigNavigation/NavigationCore.h"
+#include "TrigNavigation/NavigationCore.icc"
+
+#include "TrigNavigation/TypeMaps.h"
+
+
+//#include "TrigNavigation/AccessProxy.h"
+
+#include "TrigNavigation/TrigFeatureLink.h"
+#include "TrigNavigation/NavigationTraits.h"
+
+namespace HLT {
+  class TriggerElement;
+}
+
+template<class T> 
+struct FeatureLinkMethods {
+  typedef const T* (HLT::NavigationCore::*fl2o)( const TrigFeatureLink& ); 
+  typedef TrigFeatureLink (HLT::NavigationCore::*o2fl_1)(const HLT::TriggerElement*, const std::string&, const T*);
+};
+
+template<class T> 
+struct FeatureLinkMethods2 {
+  typedef typename Container2Object<T>::type Contained;
+  typedef TrigFeatureLink (HLT::NavigationCore::*o2fl_2)(const HLT::TriggerElement*, const std::string&, const  Contained*, const T* );
+};
+
+
+
+  /////////////////////////////////////////////////////
+template<class T, bool> struct acquire_featureLinkToObject;
+template<class T> 
+struct acquire_featureLinkToObject<T, false> { 
+  //  typename FF<T>::type;
+  static typename FeatureLinkMethods<T>::fl2o do_it() {
+    return &HLT::NavigationCore::featureLink2Object<T>;}
+};
+
+template<class T> struct acquire_featureLinkToObject<T, true>{ 
+  static typename FeatureLinkMethods<T>::fl2o do_it() {
+    return 0;}
+};
+
+  /////////////////////////////////////////////////////
+template<class T, bool FeatureIsContainer> struct acquire_getRecentFeatureConstDV;
+template<class T> 
+struct acquire_getRecentFeatureConstDV<T, true> {
+  typedef  bool (HLT::NavigationCore::*type)( const HLT::TriggerElement*, 
+					      const ConstDataVector<T>*&, const std::string&, 
+					      const HLT::TriggerElement*&, std::string& );
+  static type do_it() { return &HLT::NavigationCore::getRecentFeature<ConstDataVector<T>>;  }
+};
+
+template<class T> 
+struct acquire_getRecentFeatureConstDV<T, false> {
+  typedef void* type;
+  static type do_it() { return 0; }
+  
+};
+  /////////////////////////////////////////////////////
+
+template<class T, bool FeatureIsContainer> struct acquire_attachFeatureConstDV;
+template<class T> 
+struct acquire_attachFeatureConstDV<T, true> {
+  typedef  bool (HLT::Navigation::*type)( HLT::TriggerElement*, const ConstDataVector<T>*,
+					  HLT::Navigation::MemoryManagement, std::string&, const std::string&  );
+  
+  static type do_it() { return &HLT::Navigation::attachFeature<ConstDataVector<T>>; }
+};
+
+template<class T> 
+struct acquire_attachFeatureConstDV<T, false> {
+  typedef void* type;
+  static type do_it() { return 0; }
+  
+};
+
+
+
+
+//template<class T> 
+//struct O2FLMethod_1 {
+//  typedef TrigFeatureLink (HLT::NavigationCore::*o2fl_1)(const HLT::TriggerElement*, const std::string&, const T*);
+//};
+
+template<class T, bool> struct acquire_object2FeatureLink1;
+template<class T> struct acquire_object2FeatureLink1<T, true> {
+  static typename FeatureLinkMethods<T>::o2fl_1 do_it() {
+    return &HLT::NavigationCore::object2FeatureLink<T>;
+  }
+};
+template<class T> struct acquire_object2FeatureLink1<T, false> {
+  static typename FeatureLinkMethods<T>::o2fl_1 do_it() {
+    return 0;
+  }
+};
+
+//
+template<class T, bool> struct acquire_object2FeatureLink2;
+template<class T> struct acquire_object2FeatureLink2<T, false> {
+  static typename FeatureLinkMethods2<T>::o2fl_2 do_it() {
+    return &HLT::NavigationCore::object2FeatureLink<T>;
+  }
+};
+template<class T> struct acquire_object2FeatureLink2<T, true> {
+  static typename FeatureLinkMethods2<T>::o2fl_2 do_it() {
+    return 0;
+  }
+};
+
+template<typename C, bool>
+struct instantiate_dataelementlink;
+
+template<typename C>
+struct instantiate_dataelementlink<C,true>{
+  static void do_it(){
+  __attribute__((__unused__))
+    bool (HLT::NavigationCore::*temp)(const HLT::TriggerElement*,DataLink<C>& link,
+				      const std::string&, const HLT::TriggerElement*&, std::string&);
+  temp = &HLT::NavigationCore::getRecentFeatureDataOrElementLink<DataLink<C> >;  
+  //std::cout << "DataLink version instantiated for " << ClassID_traits<C>::ID() << std::endl;
+  }
+};
+
+template<typename C>
+struct instantiate_dataelementlink<C,false>{
+  static void do_it(){
+    __attribute__((__unused__))
+    bool (HLT::NavigationCore::*temp)(const HLT::TriggerElement*,ElementLink<C>& link,
+				      const std::string&, const HLT::TriggerElement*&, std::string&);
+  temp = &HLT::NavigationCore::getRecentFeatureDataOrElementLink<ElementLink<C> >;
+  //std::cout << "ElementLink version instantiated for " << ClassID_traits<C>::typeName() << std::endl;
+  }
+};
+
+template <class T, class C>
+HLT::FeatureContainerInit<T, C>::FeatureContainerInit() {
+  HLT::TypeMaps::registerFeatureContainer<T, C>();
+
+  //  staements below force generation of the specializations for the methods
+  __attribute__((__unused__))
+  bool (HLT::Navigation::*temp_attachFeature)( TriggerElement*, const T*,
+					       Navigation::MemoryManagement, std::string&, const std::string&  );
+  temp_attachFeature = &HLT::Navigation::attachFeature<T>;
+
+
+  __attribute__((__unused__))
+  typename acquire_attachFeatureConstDV<T, boost::is_same<T,C>::value>::type temp_attachFeatureConstDV;
+  temp_attachFeatureConstDV = acquire_attachFeatureConstDV<T, boost::is_same<T,C>::value>::do_it();
+  
+  //  typename acquire_getRecentFeatureConstDV<T, boost::is_same<T,C>::value>::type temp_getRecentFeatureConstDV;
+  //  temp_getRecentFeatureConstDV = acquire_getRecentFeatureConstDV<T, boost::is_same<T,C>::value>::do_it();
+
+
+  //
+  __attribute__((__unused__))
+  bool (HLT::NavigationCore::*temp_getFeatures)( const TriggerElement*, std::vector< const T*>&, 
+					     const std::string&, std::map<const T*, std::string>* );
+  temp_getFeatures = &HLT::NavigationCore::getFeatures<T>;
+
+
+  //
+  __attribute__((__unused__))
+  bool (HLT::NavigationCore::*temp_getFeature)( const TriggerElement*, const T*&, const std::string&, std::string&);
+  temp_getFeature = &HLT::NavigationCore::getFeature<T>;
+
+
+  //const T* (HLT::NavigationCore::*temp_featureLink2Object)( const TrigFeatureLink& ); 
+  __attribute__((__unused__))
+  typename FeatureLinkMethods<T>::fl2o temp_featureLink2Object;
+  temp_featureLink2Object = acquire_featureLinkToObject<T, boost::is_same<T, C>::value>::do_it();//&HLT::NavigationCore::featureLink2Object<T>;
+    
+  //
+  __attribute__((__unused__))
+  typename FeatureLinkMethods<T>::o2fl_1 temp_object2FeatureLink;
+  temp_object2FeatureLink = acquire_object2FeatureLink1<T, boost::is_same<T, C>::value>::do_it();
+
+  //
+  __attribute__((__unused__))
+  typename FeatureLinkMethods2<C>::o2fl_2 temp_object2FeatureLink2;
+  temp_object2FeatureLink2 = acquire_object2FeatureLink2<C, boost::is_same<T, C>::value>::do_it();
+
+  //
+  __attribute__((__unused__))
+  bool (HLT::NavigationCore::*temp_getRecentFeatures)( const TriggerElement*, 
+			  std::vector< const T*>&, const std::string&, 
+			  std::map<const T*, std::string>*  );
+  temp_getRecentFeatures = &HLT::NavigationCore::getRecentFeatures<T>;
+
+  //
+  __attribute__((__unused__))
+  bool (HLT::NavigationCore::*temp_getRecentFeature)( const TriggerElement*, 
+						  const T*&, const std::string&, const TriggerElement*&, std::string& );
+  temp_getRecentFeature = &HLT::NavigationCore::getRecentFeature<T>;
+
+
+  __attribute__((__unused__))
+    typename acquire_getRecentFeatureConstDV<T, boost::is_same<T,C>::value and canTransfer<C>::value >::type temp_getRecentFeatureConstDV;
+  temp_getRecentFeatureConstDV = acquire_getRecentFeatureConstDV<T, boost::is_same<T,C>::value and canTransfer<C>::value>::do_it();
+  
+
+  //
+  __attribute__((__unused__))
+  bool (HLT::NavigationCore::*temp_getRecentFeaturesLinks)( const TriggerElement*,
+							ElementLinkVector<C>&, const std::string&  );  
+  temp_getRecentFeaturesLinks = &HLT::NavigationCore::getRecentFeaturesLinks<C,T>;
+
+
+  //
+  __attribute__((__unused__))
+  bool (HLT::NavigationCore::*temp_getRecentFeatureLink)( const TriggerElement*,
+						      ElementLink<C>&, const std::string&, const TriggerElement*&, std::string& );
+  temp_getRecentFeatureLink = &HLT::NavigationCore::getRecentFeatureLink<C,T>;
+
+  //getRecentFeatureDataOrElementLink depends on what kind of feature we have
+  //therefore we need to outsource to helper
+  instantiate_dataelementlink<C,boost::is_same<T,C>::value >::do_it();
+
+  //
+  __attribute__((__unused__))
+  bool (HLT::NavigationCore::*temp_getFeaturesInRoI)( const TriggerElement*,  std::vector<const T*>&, 
+						      const std::string&, std::map<const T*, std::string>* );
+  temp_getFeaturesInRoI = &HLT::NavigationCore::getFeaturesInRoI<T>;
+
+  //
+  __attribute__((__unused__))
+  bool (HLT::NavigationCore::*temp_getAllFeatures)(ElementLinkVector<C>&, const std::string& );
+  temp_getAllFeatures = &HLT::NavigationCore::getAllFeatures<C,T>; 
+
+  //
+  __attribute__((__unused__))
+  bool (HLT::Navigation::*temp_findOwners)(const T*, std::vector<const TriggerElement*>&, unsigned int);
+  temp_findOwners = &HLT::Navigation::findOwners<T>;
+
+  //
+  typedef const std::string const_string;
+  __attribute__((__unused__))
+  const_string (HLT::Navigation::*temp_getNextKey)( const std::string& );
+  temp_getNextKey = &HLT::Navigation::getNextKey<T>;
+
+
+  //
+  __attribute__((__unused__))
+  const_string (HLT::Navigation::*temp_getUniqueKey)( const std::string&);
+  temp_getUniqueKey = &HLT::Navigation::getUniqueKey<T>;
+
+}
+
+template <class T>
+HLT::AuxInit<T>::AuxInit() {
+  HLT::TypeMaps::registerType<T>();
+}
+
+#endif
diff --git a/Trigger/TrigEvent/TrigNavigation/TrigNavigation/NavigationTraits.h b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/NavigationTraits.h
new file mode 100644
index 0000000000000000000000000000000000000000..427c690b1d29e3c356a1f1849401ffb369da397a
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/NavigationTraits.h
@@ -0,0 +1,17 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TrigNavigation_NavigationTraits_h
+#define TrigNavigation_NavigationTraits_h
+
+// template <class T> struct Feature2Container; 
+// template <class T> struct Feature2Object; 
+// template <class T> struct Container2Object; 
+// template <class T> struct Object2Feature; 
+// template <class T> struct Object2Container; 
+// template <class T> struct Link2Object;
+
+
+
+#endif // TrigNavigation_NavigationTraits_h
diff --git a/Trigger/TrigEvent/TrigNavigation/TrigNavigation/RoICacheHelper.h b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/RoICacheHelper.h
new file mode 100644
index 0000000000000000000000000000000000000000..97a20e0444e213869fb8b5f7627c0f9001d6d9f7
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/RoICacheHelper.h
@@ -0,0 +1,155 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TRIGNAVIGATION_ROICACHEHELPER_H
+#define TRIGNAVIGATION_ROICACHEHELPER_H
+
+#include <iostream>
+#include <vector>
+#include <set>
+
+#include "TrigNavigation/RoICacheHistory.h"
+#include "TrigNavigation/TriggerElement.h"
+
+namespace HLT {
+    /**
+     * \brief class to support in RoI caching
+     * If algo wants to profit from caching it should create private objects
+     * of HLT::TriggerElement::CacheHelper or inherit from it.
+     *
+     * Each time when the algo wants to run on TE given as an argument it should
+     * check if needsExecution() returns true. If so, then the algorithms needs to be executed.
+     * The execution needs to be wrapped by calls to start/stop caching
+     * startCaching(TE)
+     * ... algo execution
+     * stopCaching(TE)
+     *
+     * If false is returned then caching has heppened. Nothing else needs to be done.
+     *
+     * After event processing the cahce needs to be reset.
+     *
+     *
+     */
+
+
+  class RoICacheHelper {
+  public:
+
+    /**
+     * \brief adds objects from cache to this TE as if the algorithm would have run on this TE
+     * \param te is trigger element, non-const since eventually it will be updated from cache
+     * \return true if all worked correctly, false if failed, this should never ahppen, if it does it shoudl be severe error
+     */
+    bool cache ( TriggerElement* te );
+    
+
+
+
+    /**
+     * \brief checks if there was an execution on RoI already
+     * \param te is trigger element
+     * \return true if running is needed, false if not
+     */    
+    bool needsExecution ( const TriggerElement* te );
+
+
+
+    /**
+     * \brief checks if there was an execution on RoI already
+     * \param te is trigger element
+     * \return true if running is needed, false if not
+     */        
+    bool isInputAccepted ( const TriggerElement* te );
+    
+
+    /**
+     * \brief starts collecting cache
+     * \param te the same te as for needsExecution
+     * \warning For optimization reasons this calls assume that is done only after needsExecution returned true. If that is not the case it will make mess.
+     * \return true if all went OK, false if there is logica failure, (this method can only be called after needsExecution(te) == true)
+     */
+    bool startCaching( const TriggerElement* te );
+
+    /**
+     * \brief stop collecting cache
+     * \see startCaching(const TriggerElement*)
+     */
+    bool stopCaching( const TriggerElement* te );
+
+    /**
+     * \brief reset caches for this event
+     */
+    void reset();
+
+    enum CachingMode { None=0, RoIOnly=1, AllObjects=2, HistoryBased=3 };
+    static enum CachingMode s_cachingMode;
+   
+  private:
+    /**
+     * \brief Helper class for caching.
+     * This class keeps cache for all RoIs.
+     * That means it remembers if the algo was run on this RoIs and whcih objects reated for the first time.
+     **/
+
+    class CacheEntry {
+    public:
+
+      typedef std::vector<HLT::RoICacheHistory::FeatureCall> FeatureCallVec;
+      typedef HLT::RoICacheHistory::FeatureCall FeatureCall;
+
+      typedef std::vector<HLT::TriggerElement::FeatureAccessHelper> FeatureVec;
+      typedef HLT::TriggerElement::FeatureAccessHelper Feature;
+
+      bool operator== (const std::vector<TriggerElement*>& roite) const;
+      bool operator== (const TriggerElement* te) const;
+
+      CacheEntry(const TriggerElement* cacheHolder ) 
+	:  m_rois(TrigNavStructure::getRoINodes(cacheHolder).begin(), TrigNavStructure::getRoINodes(cacheHolder).end()), 
+	m_cacheHolder(cacheHolder), 
+	m_begin(0),
+	m_end(0) {
+      }
+
+      /*
+	CacheEntry(const std::vector<TriggerElement*>& rois, const TriggerElement* cacheHolder=0 ) 
+	:  m_rois(rois.begin(), rois.end()), 
+	m_cacheHolder(cacheHolder), 
+	m_begin(0),
+	m_end(0) {
+	
+	//	std::cout << "setsize" << m_rois.size() << "\n";
+	//	std::set<const TriggerElement*>(m_rois.begin(), m_rois.end());
+	//	for ( std::set<const TriggerElement*>::const_iterator is = m_rois.begin(); is != m_rois.end(); ++is)
+	//	  std::cout << *is << " creset \n";
+	}
+      */
+
+      
+      void start(unsigned int begin) { m_begin = m_end = begin; } //!< record moment just before execution when no feature was yet attached
+      void finish(unsigned int end) { m_end = end; }              //!< record moment just after execution when no more featuresd are attached
+
+      void add(const FeatureCallVec &qvec) { m_questions = qvec; }
+
+      unsigned int begin() const { return m_begin; }              //!< 
+      unsigned int end() const { return m_end; }
+
+      const TriggerElement* holder() { return m_cacheHolder; }  
+      void holder(const TriggerElement* te) { m_cacheHolder = te; }
+      unsigned int size() const { return m_end - m_begin; } //!< gets number of objects attaced by algo
+
+    private:
+
+      std::set<const TriggerElement*> m_rois;  //!< handy varaible to keep all RoIs of given TE
+      const TriggerElement* m_cacheHolder;     //!< the first TE processed in given RoI (from it the objects will be copied to all cached TEs)
+      FeatureCallVec m_questions;
+
+      unsigned int m_begin;
+      unsigned int m_end;
+    };
+
+    std::vector<struct CacheEntry> m_caches;   //!< caches for all RoIs
+  };
+}
+
+#endif //#ifndef TRIGNAVIGATION_ROICACHEHELPER_H
diff --git a/Trigger/TrigEvent/TrigNavigation/TrigNavigation/RoICacheHistory.h b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/RoICacheHistory.h
new file mode 100644
index 0000000000000000000000000000000000000000..e3f3a7497b9061cbd2bdd45f63b19ebb72aae3f3
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/RoICacheHistory.h
@@ -0,0 +1,114 @@
+// -*- c++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TRIGNAVIGATION_ROICACHEHISTORY_H
+#define TRIGNAVIGATION_ROICACHEHISTORY_H
+
+#include <vector>
+#include <string>
+
+#include "CLIDSvc/CLASS_DEF.h"
+#include "TrigNavigation/TriggerElement.h"
+
+namespace HLT {
+
+  class NavigationCore;
+
+  class RoICacheHistory {
+  public:
+    class FeatureCall {
+    public:
+      FeatureCall(const TriggerElement* work,
+		  const TriggerElement* te, CLID clid, const std::string& label, 
+		  bool issingle, bool isget);
+      FeatureCall();
+      
+      void addAnswer( const TriggerElement* te, const TriggerElement::FeatureAccessHelper&);
+
+      const TriggerElement::FeatureVec& getAnswers() const { return m_answers; }
+
+
+      const TriggerElement* getInitTE() const { return m_init; }
+      const TriggerElement* getWorkTE() const { return m_work; }
+
+      bool isValid() const;
+      void reset();
+      const std::string& label() const { return m_label; }
+      CLID clid() const {return m_clid; }
+      bool issingle() const {return m_issingle; }
+      bool isget() const {return m_isget; }
+
+      
+    private:
+
+      const TriggerElement* m_init; // place where the first query starts from
+      const TriggerElement* m_work; // current TE on which algorithm is working
+      CLID m_clid;
+      std::string m_label;
+      TriggerElement::FeatureVec m_answers;
+      bool m_issingle;
+      bool m_isget;
+    };
+    
+
+    class QuestionScope {
+    public:
+      QuestionScope(const TriggerElement *te, CLID clid, const std::string& label, NavigationCore *navig, bool issingle=false);  
+      QuestionScope();
+      ~QuestionScope();
+    private:      
+      const TriggerElement *m_start;
+    };
+
+    class RememberAttachFeature {
+    public:
+      RememberAttachFeature(const TriggerElement* te, CLID clid, const std::string& label,
+			    NavigationCore* navig, TriggerElement::ObjectIndex& idx);
+    };
+
+
+
+    static RoICacheHistory& instance();
+
+
+    void startHistory(const TriggerElement* te) { m_collect = true; m_questions.clear(); m_work = te; }
+    void stopHistory() { m_collect = false; m_questions.clear(); }
+
+    bool collectHistory() const { return m_collect; }
+
+    void setCurrentFeatureCall(const FeatureCall &curr, NavigationCore *navig);
+    const FeatureCall& getCurrentFeatureCall() const { return m_current; }
+
+    void addAnswer(const TriggerElement* te, const TriggerElement::FeatureAccessHelper&);
+
+
+    void stopCurrentFeatureCall();
+
+    NavigationCore* getNavigation() const { return m_navigation; }
+    const TriggerElement* getWorkTE() const { return m_work; }
+    const std::vector<FeatureCall>& getFeatureCalls() const { return m_questions; }       
+
+  private:
+    
+    RoICacheHistory()
+    : m_collect(false), m_navigation(0), m_work(0) {}
+    ~RoICacheHistory(){}
+
+    RoICacheHistory(const RoICacheHistory&);
+    RoICacheHistory& operator=(const RoICacheHistory&);
+
+  private:
+
+    FeatureCall                m_current;
+    std::vector<FeatureCall>   m_questions;
+    bool                    m_collect;
+
+    NavigationCore         *m_navigation;
+    const TriggerElement   *m_work;
+  };
+}
+
+#endif
diff --git a/Trigger/TrigEvent/TrigNavigation/TrigNavigation/TrigEDMSizes.h b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/TrigEDMSizes.h
new file mode 100644
index 0000000000000000000000000000000000000000..ba6578b54f088f40ab37b86de3da7d667416e169
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/TrigEDMSizes.h
@@ -0,0 +1,46 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TRIGNAVIGATION_TRIGEDMSIZES_H
+#define TRIGNAVIGATION_TRIGEDMSIZES_H
+#include <string>
+#include <vector>
+#include "GaudiKernel/ClassID.h"
+#include "CLIDSvc/CLASS_DEF.h"
+namespace HLT {
+    /**
+     * Class used to pass around information about the sizes of the EDM obejcts.
+     *
+     **/
+
+  class TrigEDMSizes {
+  public:
+    TrigEDMSizes();    
+
+    struct EDMObjectInfo {
+      EDMObjectInfo(const std::string& c, const std::string& l, unsigned w, unsigned cut);
+      bool isTruncated(unsigned size_after_serialization) const;
+      std::string  collection;
+      std::string  label;
+      unsigned int words;
+      unsigned int cutsize;
+    };
+    
+    typedef std::vector<EDMObjectInfo> EDMEventInfo;
+    const EDMEventInfo& info() const;
+
+    void addObject(const std::string& c, const std::string& label, unsigned words, unsigned cutsize);
+    const EDMObjectInfo& lastNotTruncated(unsigned size_after_truncation) const;
+
+
+  private:    
+    EDMEventInfo m_objects;
+  };
+
+
+}
+
+CLASS_DEF( HLT::TrigEDMSizes , 190211077 , 1 )
+
+#endif 
diff --git a/Trigger/TrigEvent/TrigNavigation/TrigNavigation/TrigFeatureLink.h b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/TrigFeatureLink.h
new file mode 100644
index 0000000000000000000000000000000000000000..6b70b67dbe2e91ca68faf848f02a9fe9b1d11a59
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/TrigFeatureLink.h
@@ -0,0 +1,34 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TrigNavigation_TrigFeatureLink
+#define TrigNavigation_TrigFeatureLink
+#include <stdint.h>
+
+#include "GaudiKernel/ClassID.h"
+
+
+class TrigFeatureLink {
+
+ public:
+  TrigFeatureLink(CLID clid, uint16_t subtype, uint32_t index);  
+  TrigFeatureLink();  
+  bool isValid() const { return m_clid != 0; }
+  
+  CLID clid() const { return m_clid; }
+  uint16_t subTypeIndex() const { return m_subTypeIndex; }
+  uint32_t index() const { return m_index; }
+  
+ private:
+
+  CLID m_clid;
+  uint16_t m_subTypeIndex;
+  uint32_t m_index;
+};
+
+//TrigFeatureLink getFeatureLink( const TriggerElement* te, const std::string& label, const T* object, const C* container)
+//const T* getFeature(TrigFeatureLink*)
+
+
+#endif
diff --git a/Trigger/TrigEvent/TrigNavigation/TrigNavigation/TrigNavigationDict.h b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/TrigNavigationDict.h
new file mode 100644
index 0000000000000000000000000000000000000000..e12a82f1ef812aa1b7eb1db07d6cff3d524005e6
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/TrigNavigationDict.h
@@ -0,0 +1,19 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+
+#include "GaudiKernel/IConversionSvc.h"
+#include "TrigNavigation/NavigationCore.h"
+#include "TrigNavigation/NavigationCore.icc"
+
+#include "TrigNavigation/TriggerElement.h" 
+#include "TrigNavigation/AccessProxy.h" 
+//#include "TrigNavigation/Holder.h"
+
+struct dummy {
+  std::vector<HLT::TriggerElement*> te_vec;
+  std::vector<const HLT::TriggerElement*> te_const_vec;
+  // HLT::NavigationCore nc;
+};
+
diff --git a/Trigger/TrigEvent/TrigNavigation/TrigNavigation/TriggerElement.h b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/TriggerElement.h
new file mode 100644
index 0000000000000000000000000000000000000000..1807040b49fe09ad074a2340d449c4b2a967d7cd
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/TriggerElement.h
@@ -0,0 +1,18 @@
+// -*- c++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TRIGNAVIGATION_TRIGGERELEMENT_H
+#define TRIGNAVIGATION_TRIGGERELEMENT_H
+
+
+#include "TrigNavStructure/TriggerElement.h"
+
+#include "GaudiKernel/MsgStream.h"
+
+
+MsgStream& operator<< ( MsgStream& m, const HLT::TriggerElement& te );
+MsgStream& operator<< ( MsgStream& m, const HLT::TriggerElement::ObjectIndex& i );
+#endif //TRIGGERELEMENT_H
diff --git a/Trigger/TrigEvent/TrigNavigation/TrigNavigation/TriggerElement.icc b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/TriggerElement.icc
new file mode 100644
index 0000000000000000000000000000000000000000..0264758a6542a6a139c7e4a914087c433b1cb3e7
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/TriggerElement.icc
@@ -0,0 +1,18 @@
+// Dear Emacs this is -*- c++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+ * IMPROVEMENT TO BE DONE:
+ * find firs having the same CLID
+ * after that go ahead until different CLID and copy to objects
+ * that would be an optimization step
+ * for that the features should be inserted in stable manner
+ */
+/*
+  The features manegement was moved to Navigation.icc. No templated code in TriggerElement now. 
+  Will delete this file as soon as the idea behind current development will get validated. 
+*/
+// EOF
diff --git a/Trigger/TrigEvent/TrigNavigation/TrigNavigation/TypeMaps.h b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/TypeMaps.h
new file mode 100644
index 0000000000000000000000000000000000000000..39fcc756cb2b97d2436916e670c00e654a72aa27
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/TypeMaps.h
@@ -0,0 +1,41 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#pragma once
+#include <map>
+#include <string>
+
+#include "GaudiKernel/ClassID.h"
+
+#include "TrigNavigation/Holder.h"
+#include "TrigNavigation/TypeProxy.h"
+
+namespace HLT {
+  class TypeMaps {
+  public:
+  typedef std::map<CLID,  HLTNavDetails::ITypeProxy*> CLIDtoTypeProxyMap;
+    static CLIDtoTypeProxyMap& proxies();
+    
+    typedef std::map<CLID,  HLTNavDetails::IHolder*> CLIDtoHolderMap;
+    static CLIDtoHolderMap& holders();
+    
+    typedef std::map<std::string, CLID> NametoCLIDMap;
+    static NametoCLIDMap& type2clid();   //!< translate class name to CLID
+    
+    template<class T> 
+    static void registerType() {
+      HLT::TypeMaps::proxies()[ClassID_traits<T>::ID()] = new HLTNavDetails::TypeProxy<T>();
+      HLT::TypeMaps::type2clid()[ ClassID_traits<T>::typeName() ] = ClassID_traits<T>::ID();        
+    }
+
+
+    template<class T, class C>
+    static void registerFeatureContainer() {
+      HLT::TypeMaps::holders()[ClassID_traits<T>::ID()] = new HLTNavDetails::HolderImp<T, C>();
+      HLT::TypeMaps::registerType<T>();
+      HLT::TypeMaps::registerType<C>();
+    }
+    
+  };
+}
diff --git a/Trigger/TrigEvent/TrigNavigation/TrigNavigation/TypeProxy.h b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/TypeProxy.h
new file mode 100644
index 0000000000000000000000000000000000000000..08adf27cd1ea3a9a6ceae5d697bb06d3f17d6f97
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/TypeProxy.h
@@ -0,0 +1,261 @@
+// Dear emacs, this is -*- c++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: TypeProxy.h 610936 2014-08-08 14:17:56Z tbold $
+#ifndef TRIGNAVIGATION_TYPEPROXY_H
+#define TRIGNAVIGATION_TYPEPROXY_H
+
+// Boost include(s):
+#include <boost/type_traits/is_base_of.hpp>
+
+// Gaudi/Athena include(s):
+#include "GaudiKernel/ClassID.h"
+#include "GaudiKernel/StatusCode.h"
+#include "SGTools/DataProxy.h"
+#include "SGTools/ClassID_traits.h"
+#include "StoreGate/StoreGateSvc.h"
+#include "AthenaKernel/errorcheck.h"
+#include "AthContainers/AuxVectorBase.h"
+
+// Forward declaration(s):
+namespace SG {
+   class IAuxStore;
+}
+
+namespace HLTNavDetails {
+
+   /**
+    *  @short Interface to the TypeProxy<...> objects created at runtime
+    *
+    *         It's not really a pure interface, but to simplify the class
+    *         structure, let's keep this naming...
+    *
+    * @author Tomasz Bold <Tomasz.Bold@cern.ch>
+    * @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch>
+    *
+    * $Revision: 610936 $
+    * $Date: 2014-08-08 16:17:56 +0200 (Fri, 08 Aug 2014) $
+    */
+   class ITypeProxy {
+
+   public:
+      /// Default constructor
+      ITypeProxy();
+      /// Virtual destructor, to make vtable happy...
+      virtual ~ITypeProxy() {}
+
+      /// Make a new object
+      virtual StatusCode create() = 0;
+      /// Save proxied object in DG (record)
+      virtual StatusCode reg( StoreGateSvc* sg, const std::string& key ) = 0;
+      /// SG retrieve, and fill the proxy
+      virtual StatusCode sync( StoreGateSvc* sg, const std::string& key );
+      /// Remove the object from SG and make the pointer null
+      virtual StatusCode clear( StoreGateSvc* sg ) = 0;
+
+      /// @name Cast operations for xAOD decorations
+      /// Actual implementation rely in boost::is_base_of to avoid dynamic_cast
+      /// @{
+
+      /// Return a pointer to the SG::AuxVectorBase base class of the object if
+      /// possible
+      SG::AuxVectorBase* castAuxVectorBase();
+      /// Return a pointer to the SG::IAuxStore base class of the object if
+      /// possible
+      SG::IAuxStore* castIAuxStore();
+
+      virtual void syncTypeless() = 0;
+
+      /// @}
+
+      /// Check whether StoreGate contains an object of this type and with
+      /// the specified key
+      bool contains( StoreGateSvc* sg, const std::string& key ) const;
+
+      /// Check whether StoreGate contains a modifyable object of this type
+      /// and with the specified key
+      bool transientContains( StoreGateSvc* sg, const std::string& key ) const;
+
+      /// True if proxy has not yet made object or not synced to any yet
+      /// (0 pointer)
+      bool empty() const;
+
+      /// This is how typed proxy is obtained
+      virtual ITypeProxy* clone() const = 0;
+
+      /// The CLID of the object being proxied
+      CLID clid() const;
+
+      /// The type name of the object being proxied
+      const std::string& typeName() const;
+
+     const void* cptr() const { return m_pointer; }
+
+   protected:
+      CLID m_clid; ///< The CLID of the type being proxied
+      std::string m_typeName; ///< The type name of the object being proxied
+      std::string m_key; ///< StoreGate key of the proxied object
+      SG::DataProxy* m_proxy; ///< StoreGate proxy for the object
+      void* m_ncPointer; ///< Non-const pointer to the proxied object
+      const void* m_pointer; ///< Const pointer to the proxied object
+      /// Does the proxied type inherit from SG::AuxVectorBase?
+      bool m_isAuxVectorBase;
+
+   }; // class ITypeProxy
+
+
+   /**
+    *  @short Type specific implementation of ITypeProxy
+    *
+    * @author Tomasz Bold <Tomasz.Bold@cern.ch>
+    * @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch>
+    *
+    * $Revision: 610936 $
+    * $Date: 2014-08-08 16:17:56 +0200 (Fri, 08 Aug 2014) $
+    */
+   template< class T >
+   class TypeProxy : public ITypeProxy {
+
+   public:
+      /// Convenience type declaration
+      typedef T value_type;
+      /// Convenience type declaration
+      typedef T* pointer_type;
+
+      /// Default constructor
+      TypeProxy();
+      /// Constructor pointing to an existing object
+      TypeProxy( pointer_type t );
+
+      /// Make a new object
+      virtual StatusCode create();
+      /// Save proxied object in DG (record)
+      virtual StatusCode reg( StoreGateSvc* sg, const std::string& key );
+      /// SG retrieve, and fill the proxy
+      virtual StatusCode sync( StoreGateSvc* sg, const std::string& key );
+      /// Remove the object from SG and make the pointer null
+      virtual StatusCode clear( StoreGateSvc* sg );
+
+      virtual void syncTypeless(){
+	m_ncPointer = m_data;
+	m_pointer = m_data;
+      }
+
+      /// This is how typed proxy is obtained
+      virtual ITypeProxy*  clone() const { return new TypeProxy<T>(); }
+
+      /// Pointer to the exact object type
+      pointer_type data() { return m_data; }
+      /// Constant pointer to the exact object type
+      const pointer_type& data() const { return m_data; }
+      /// Reference to the exact object type pointer
+      pointer_type& data_ref() { return m_data; }
+
+   private:
+      pointer_type m_data; ///< Non-const pointer to the proxied object
+
+   }; // class TypeProxy
+
+   /// Default constructor
+   template< class T >
+   TypeProxy< T >::TypeProxy()
+      : ITypeProxy(), m_data( 0 ) {
+
+      // Set the properties of the base class:
+      m_clid = ClassID_traits< T >::ID();
+      m_typeName = ClassID_traits< T >::typeName();
+      m_isAuxVectorBase = boost::is_base_of< SG::AuxVectorBase, T >::value;
+   }
+
+   /// Constructor pointing to an existing object
+   ///
+   /// Notice that this constructor delegates much of the work to the default
+   /// constructor. (C++11 magic...)
+   ///
+   template< class T >
+   TypeProxy< T >::TypeProxy( pointer_type t )
+      : TypeProxy() {
+
+      // Set the properties of this class:
+      m_data = t;
+
+      // Set the properties of the base class:
+      m_ncPointer = m_data;
+      m_pointer = m_data;
+   }
+
+   template< class T >
+   StatusCode TypeProxy< T >::create() {
+
+      // Check if we already proxy some object. Then this should not be called
+      // again...
+      if( m_data ) {
+         REPORT_MESSAGE( MSG::ERROR )
+            << "Object is already being proxied";
+         return StatusCode::FAILURE;
+      }
+
+      // Create the new object:
+      m_data = new T();
+
+      // Fill the base class's variables:
+      m_ncPointer = m_data;
+      m_pointer = m_data;
+
+      // Return gracefully:
+      return StatusCode::SUCCESS;
+   }
+
+   template< class T >
+   StatusCode TypeProxy< T >::reg( StoreGateSvc* sg, const std::string& key ) {
+
+      // Record the object:
+      CHECK( sg->record( m_data, key ) );
+
+      // Fill some variables in the base class:
+      m_key = key;
+      m_proxy = sg->proxy( m_clid, m_key );
+
+      return StatusCode::SUCCESS;
+   }
+
+   /**
+    * Unfortunately the typeless removeProxy functions of StoreGateSvc are all
+    * private. Although I would've loved to implement this function in a
+    * non-template way as well... :-/
+    */
+   template< class T >
+   StatusCode TypeProxy< T >::clear( StoreGateSvc* sg ) {
+
+      // Do the deed:
+      CHECK( sg->remove( m_data ) );
+
+      // Clear the object:
+      m_data = 0;
+      m_proxy = 0;
+      m_ncPointer = 0;
+      m_pointer = 0;
+
+      // Return gracefully:
+      return StatusCode::SUCCESS;
+   }
+
+   template< class T >
+   StatusCode TypeProxy< T >::sync( StoreGateSvc* sg, const std::string& key ) {
+
+      // First let the base class do its own thing:
+      CHECK( ITypeProxy::sync( sg, key ) );
+
+      // Get the object out of the proxy:
+      m_data = SG::DataProxy_cast< T >( m_proxy );
+
+      // Return gracefully:
+      return StatusCode::SUCCESS;
+   }
+
+} // namespace HLTNavDetails
+
+#endif // not TRIGNAVIGATION_TYPEPROXY_H
diff --git a/Trigger/TrigEvent/TrigNavigation/TrigNavigation/TypeRegistration.h b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/TypeRegistration.h
new file mode 100644
index 0000000000000000000000000000000000000000..e77353418c43d97ce1efad13d01cf11122021ab9
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/TypeRegistration.h
@@ -0,0 +1,80 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "TrigNavigation/NavigationInit.h"
+#include "TrigStorageDefinitions/EDM_TypeInfo.h"
+
+#include <iostream>
+
+template<typename CONTAINER>
+struct register_feature{
+  template<class FEATURE>
+  void do_it() const {
+    //std::cout << "\t\t registering feature: " << typeid(FEATURE).name() <<  " -> ";
+    //std::cout << "container: " << typeid(CONTAINER).name() << std::endl;
+    
+    HLT::RegisterFeatureContainerTypes<FEATURE,CONTAINER>::instan();
+  }
+};
+
+
+template<class AUX>
+struct register_aux{
+  static void do_it() {
+    HLT::RegisterAuxType<AUX>::instan();
+  }
+};
+
+
+template<>
+struct register_aux<HLT::TypeInformation::no_aux>{
+  static void do_it() {}
+};
+
+
+
+
+struct registertype{
+  template<class typeinfo_element>
+  void do_it() const {
+    typedef typename typeinfo_element::list_of_features FEATURES;
+    typedef typename typeinfo_element::container CONTAINER;
+    typedef typename typeinfo_element::aux AUX;
+
+    //std::cout << "list of features for contaier " <<  typeid(CONTAINER).name() << " ";
+    //HLT::TypeInformation::for_each_type<FEATURES,HLT::TypeInformation::simple_printer >::do_it();
+    //std::cout<< std::endl;
+
+    HLT::TypeInformation::for_each_type<FEATURES,register_feature<CONTAINER> >::do_it();
+    register_aux<AUX>::do_it();
+  }
+};
+
+//we want to exectute a function upon loading of a library (i.e. 'static'). since this is not possible
+//per se, we take a detour via a default constructor. we declare a class with a static data member
+//and initizalize that static member. This will call the default ctor of this member type during 
+//which we can register all kinds of types to the navigation. This also uses the looping functionality
+//of the typemap
+
+
+template <typename TYPELIST>
+struct a_default_ctor{
+  a_default_ctor(){
+    //std::cout << "registering package with navi, packae typelist has size: " << TYPELIST::last_index + 1 << std::endl;
+    //we need to do this by hand unfortunately because we hit the template instantiaton depth of 99
+    HLT::TypeInformation::for_each_type<typename TYPELIST::template range< 0, 9>::type,registertype>::do_it();
+    HLT::TypeInformation::for_each_type<typename TYPELIST::template range<10,19>::type,registertype>::do_it();
+    HLT::TypeInformation::for_each_type<typename TYPELIST::template range<20,29>::type,registertype>::do_it();
+   }
+};
+
+template <typename TYPELIST>
+struct a_class_that_calls_default_ctor{
+  static a_default_ctor<TYPELIST> member;
+};
+
+#define REGISTER_PACKAGE_WITH_NAVI(name)\
+template<> a_default_ctor<class_##name::map>\
+a_class_that_calls_default_ctor<class_##name::map>::member = \
+a_default_ctor<class_##name::map>();
diff --git a/Trigger/TrigEvent/TrigNavigation/TrigNavigation/selection.xml b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/selection.xml
new file mode 100644
index 0000000000000000000000000000000000000000..66e6f34cf4a10841cd030bc26ea0c8f077c62315
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/TrigNavigation/selection.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<lcgdict>
+<!--  <class name="HLT::Navigation" /> -->
+  <!-- <class name="HLT::NavigationCore" /> -->
+
+  <exclusion>
+    <class pattern="HLT::TypeInformation::*"/>
+    <class pattern="TypeInfo_*">
+      <field name="*" />
+      <method name="*"/>
+   </class>
+  </exclusion>
+
+  <class name="HLT::TriggerElement">
+   <field name="m_relations" transient="true"/>
+  </class>
+  <class name="std::vector<HLT::TriggerElement*>" />
+  <class name="std::vector<const HLT::TriggerElement*>" />
+  <!-- <exclusion>
+   <class name="HLT::TriggerElement">
+    <method name="activeState"/>
+    <method name="addFeature"/>
+    <method pattern="*serialize"/>
+    <method name="getFeatureAccessHelpers"/>
+    <method name="getRelated"/>
+    <method name="inquireId"/>
+    <method name="nofwdState"/>
+    <method name="relate"/>
+    <method name="reset"/>
+    <method pattern="*Relation"/>
+    <method pattern="set*"/>
+   </class>
+  </exclusion> -->
+  <!-- <class name="HLT::FeatureDescriptor" />
+  <class name="std::vector< HLT::FeatureDescriptor >" /> -->
+
+  <class name="HLT::TriggerElement::FeatureAccessHelper" />  
+
+</lcgdict>
diff --git a/Trigger/TrigEvent/TrigNavigation/cmt/requirements b/Trigger/TrigEvent/TrigNavigation/cmt/requirements
new file mode 100644
index 0000000000000000000000000000000000000000..35a06248021d1aaf9ce796a21b5df910296dd883
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/cmt/requirements
@@ -0,0 +1,58 @@
+package TrigNavigation
+author Tomasz.Bold@cern.ch
+
+use  AtlasPolicy                AtlasPolicy-*
+
+use  AtlasBoost                 AtlasBoost-*                    External
+use  AtlasROOT                  AtlasROOT-*                     External
+use  GaudiInterface             GaudiInterface-*                External
+use  CLIDSvc                    CLIDSvc-*                       Control
+use  StoreGate                  StoreGate-*                     Control
+use  SGTools                    SGTools-*                       Control
+use  DataModel                  DataModel-*                     Control
+use  AthContainers              AthContainers-*                 Control
+use  AthenaKernel               AthenaKernel-*                  Control
+use  AthenaBaseComps            AthenaBaseComps-*               Control
+use  TrigStorageDefinitions     TrigStorageDefinitions-*        Trigger/TrigEvent
+use  TrigNavStructure           TrigNavStructure-*              Trigger/TrigEvent
+
+private
+use  TrigSerializeResult        TrigSerializeResult-*           Trigger/TrigDataAccess
+use  AthContainersInterfaces    AthContainersInterfaces-*       Control
+
+
+public
+apply_pattern dual_use_library files=*.cxx
+#library TrigNavigation *.cxx
+#apply_pattern installed_library
+#apply_pattern declare_non_standard_include name=doc
+apply_pattern declare_python_modules files="*.py"
+
+
+private
+use     TrigConfHLTData     TrigConfHLTData-*       Trigger/TrigConfiguration
+use     xAODCore                  xAODCore-*        Event/xAOD # for tests only
+use     TrigSerializeCnvSvc TrigSerializeCnvSvc-*   Trigger/TrigDataAccess
+use     AtlasReflex               AtlasReflex-*          External -no_auto_import
+
+
+
+
+# UnitTest programs
+apply_pattern declare_joboptions files="test.txt navigation2dot.py"
+
+use TestTools      TestTools-*         AtlasTest
+apply_pattern UnitTest_run unit_test=TriggerElement extrapatterns=".*"
+apply_pattern UnitTest_run unit_test=Holder extrapatterns=".*"
+apply_pattern UnitTest_run unit_test=Registration extrapatterns=".*"
+
+apply_pattern UnitTest_run unit_test=Ownership extrapatterns=".*"
+
+apply_pattern UnitTest_run unit_test=HLTNavigation extrapatterns=".*"
+apply_pattern UnitTest_run unit_test=RoICache extrapatterns=".*"
+
+
+
+
+apply_pattern lcgdict dict=TrigNavigation selectionfile=selection.xml headerfiles="../TrigNavigation/TrigNavigationDict.h"
+end_private
diff --git a/Trigger/TrigEvent/TrigNavigation/doc/mainpage.h b/Trigger/TrigEvent/TrigNavigation/doc/mainpage.h
new file mode 100644
index 0000000000000000000000000000000000000000..b01797bfe5cbcf31f93027fa4ce63ec80c3d887b
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/doc/mainpage.h
@@ -0,0 +1,23 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+
+
+@mainpage TrigNavigation Package
+
+@section TrigSteeringEventIntro Introduction
+
+This package contains the new(rel 13) Trigger Navigation structure:
+ - HLT::TriggerElement: which is node of navigation structure graph
+ - HLT::Navigation: is collection of accessor methods for the whole navigation structure 
+ - HLT::RoICacheHelper: which is helper class used in FEX algorithms to do so called "caching".  
+
+
+
+Notice little dependency. It is a core package.
+@htmlinclude used_packages.html 
+
+
+*/
diff --git a/Trigger/TrigEvent/TrigNavigation/python/TrigNavigationConfig.py b/Trigger/TrigEvent/TrigNavigation/python/TrigNavigationConfig.py
new file mode 100644
index 0000000000000000000000000000000000000000..1b6d7e0ce52de5fb9099a1b3b28d6dd5210b41c0
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/python/TrigNavigationConfig.py
@@ -0,0 +1,58 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+from TrigNavigation.TrigNavigationConf import HLT__Navigation
+
+
+
+class HLTNavigation ( HLT__Navigation ):
+    __slots__ = []
+    
+    def __init__(self, name = 'Navigation' ):# , offline=None):
+        super( HLTNavigation, self ).__init__( name )  #
+        #        self.Serializer = Serializer()
+        from TrigSerializeResult.TrigSerializeResultConf import TrigTSerializer
+        from AthenaCommon.AppMgr import ToolSvc
+        ToolSvc += TrigTSerializer()
+
+    def appendToPayload(self, classname ):
+        if classname not in  self.ClassesToPayload:
+            self.ClassesToPayload += [ classname ]
+
+    def removeFromPayload(self, classname ):
+        self.ClassesToPayload.remove ( classname )
+
+
+
+class HLTNavigationOffline ( HLTNavigation ):
+    __slots__ = []
+    def __init__(self, name = 'Navigation' ):
+        super( HLTNavigationOffline, self ).__init__( name )
+
+    def setDefaults(self, handle):
+        handle.ReferenceAllClasses = True
+        handle.ClassesToPayload = []
+
+
+
+
+class HLTNavigationOnline ( HLTNavigation ):
+    __slots__ = []
+    def __init__(self, name = 'Navigation' ):
+        super( HLTNavigationOnline, self ).__init__( name )
+
+    def setDefaults(self, handle):
+        handle.ReferenceAllClasses = False
+        handle.ClassesToPayload = []
+
+
+
+class TestingHLTNavigationOffline ( HLTNavigation ):
+    __slots__ = []
+    def __init__(self, name = 'Navigation' ):
+        super( TestingHLTNavigationOffline, self ).__init__( name )
+
+    def setDefaults(self, handle):
+        handle.ReferenceAllClasses = True
+        handle.ClassesToPayload = []
+        from AthenaCommon.Constants import VERBOSE
+        handle.OutputLevel = VERBOSE
diff --git a/Trigger/TrigEvent/TrigNavigation/python/__init__.py b/Trigger/TrigEvent/TrigNavigation/python/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..c87c7b03a3cfa86ac617897ff933ff867e5f75a1
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/python/__init__.py
@@ -0,0 +1,8 @@
+# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+
+# File: TrigNavigation/__init__.py
+# Author: Tomasz.Bold@cern.ch
+  
+__version__ = '1.0.0'
+__author__  = 'Tomasz.Bold@cern.ch'
+__all__ = [ 'TrigNavigationConfig' ]
diff --git a/Trigger/TrigEvent/TrigNavigation/share/HLTNavigation_test.ref b/Trigger/TrigEvent/TrigNavigation/share/HLTNavigation_test.ref
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/Trigger/TrigEvent/TrigNavigation/share/Holder_test.ref b/Trigger/TrigEvent/TrigNavigation/share/Holder_test.ref
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/Trigger/TrigEvent/TrigNavigation/share/Registration_test.ref b/Trigger/TrigEvent/TrigNavigation/share/Registration_test.ref
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/Trigger/TrigEvent/TrigNavigation/share/RoICache_test.ref b/Trigger/TrigEvent/TrigNavigation/share/RoICache_test.ref
new file mode 100644
index 0000000000000000000000000000000000000000..93e06b516dcbdf13f38eb5c956238574761985d0
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/share/RoICache_test.ref
@@ -0,0 +1,191 @@
+Athena::getMessageSvc: WARNING MessageSvc not found, will use std::cout
+RoICache_test        INFO LINE:77 Start of the test: RoIcaching test
+
+
+Initializing Gaudi ApplicationMgr using job opts ../share/test.txt
+JobOptionsSvc        INFO # =======> /afs/cern.ch/user/t/tbold/workarea/devval/Trigger/TrigEvent/TrigNavigation/run/../share/test.txt
+JobOptionsSvc        INFO # (2,1): ApplicationMgr.DLLs += ["StoreGate", "TrigNavigation", "TrigSerializeCnvSvc"]
+JobOptionsSvc        INFO # (3,1): ApplicationMgr.ExtSvc += ["ClassIDSvc"]
+JobOptionsSvc        INFO # (4,1): ApplicationMgr.ExtSvc += ["TrigSerializeCnvSvc"]
+JobOptionsSvc        INFO # (5,1): ApplicationMgr.ExtSvc += ["StoreGateSvc", "StoreGateSvc/DetectorStore", "StoreGateSvc/HistoryStore"]
+JobOptionsSvc        INFO # (6,1): ApplicationMgr.ExtSvc += ["ActiveStoreSvc"]
+JobOptionsSvc        INFO # (7,1): ApplicationMgr.ExtSvc += ["ToolSvc"]
+JobOptionsSvc        INFO # (8,1): AuditorSvc.Auditors += ["AlgContextAuditor"]
+JobOptionsSvc        INFO # (9,1): StoreGateSvc.OutputLevel = 1
+JobOptionsSvc        INFO # (10,1): StoreGateSvc.ActivateHistory = 0
+JobOptionsSvc        INFO # (11,1): CLIDSvc.OutputLevel = 1
+JobOptionsSvc        INFO # (12,1): ClassIDSvc.OutputLevel = 1
+JobOptionsSvc        INFO # (13,1): MessageSvc.OutputLevel = 1
+JobOptionsSvc        INFO # (14,1): MessageSvc.useColors = 0
+JobOptionsSvc        INFO # (35,1): Holder_test.OutputLevel = 1
+JobOptionsSvc        INFO # (36,1): RoICache_test.OutputLevel = 3
+JobOptionsSvc        INFO Job options successfully read in from ../share/test.txt
+ApplicationMgr      DEBUG Getting my own properties
+ApplicationMgr       INFO Application Manager Configured successfully
+ServiceManager      DEBUG Initializing service IncidentSvc
+ServiceManager      DEBUG Initializing service ClassIDSvc
+ClassIDSvc          DEBUG Service base class initialized successfully
+ClassIDSvc        VERBOSE ServiceLocatorHelper::service: found service IncidentSvc
+ServiceManager      DEBUG Initializing service TrigSerializeCnvSvc
+TrigSerializeCn...   INFO initialize()
+ServiceManager      DEBUG Initializing service StoreGateSvc
+StoreGateSvc        DEBUG Service base class initialized successfully
+StoreGateSvc      VERBOSE ServiceLocatorHelper::service: found service IncidentSvc
+EventPersistenc...  DEBUG Service base class initialized successfully
+StoreGateSvc      VERBOSE ServiceLocatorHelper::service: found service EventPersistencySvc
+StoreGateSvc      VERBOSE ServiceLocatorHelper::service: found service ClassIDSvc
+ProxyProviderSvc  VERBOSE ServiceLocatorHelper::service: found service EventPersistencySvc
+ProxyProviderSvc    DEBUG Service base class initialized successfully
+StoreGateSvc      VERBOSE ServiceLocatorHelper::service: found service ProxyProviderSvc
+ServiceManager      DEBUG Initializing service DetectorStore
+DetectorStore       DEBUG Service base class initialized successfully
+DetectorStore     VERBOSE ServiceLocatorHelper::service: found service IncidentSvc
+DetectorStore     VERBOSE ServiceLocatorHelper::service: found service EventPersistencySvc
+DetectorStore     VERBOSE ServiceLocatorHelper::service: found service ClassIDSvc
+DetectorStore     VERBOSE ServiceLocatorHelper::service: found service ProxyProviderSvc
+ServiceManager      DEBUG Initializing service HistoryStore
+HistoryStore        DEBUG Service base class initialized successfully
+HistoryStore      VERBOSE ServiceLocatorHelper::service: found service IncidentSvc
+HistoryStore      VERBOSE ServiceLocatorHelper::service: found service EventPersistencySvc
+HistoryStore      VERBOSE ServiceLocatorHelper::service: found service ClassIDSvc
+HistoryStore      VERBOSE ServiceLocatorHelper::service: found service ProxyProviderSvc
+ServiceManager      DEBUG Initializing service ActiveStoreSvc
+ActiveStoreSvc      DEBUG Service base class initialized successfully
+ActiveStoreSvc    VERBOSE ServiceLocatorHelper::service: found service StoreGateSvc
+ServiceManager      DEBUG Initializing service ToolSvc
+ToolSvc             DEBUG Service base class initialized successfully
+ServiceManager      DEBUG Initializing service AppMgrRunable
+AppMgrRunable       DEBUG Service base class initialized successfully
+ServiceManager      DEBUG Initializing service EventLoopMgr
+EventLoopMgr        DEBUG Service base class initialized successfully
+EventDataSvc        DEBUG Service base class initialized successfully
+EventDataSvc      VERBOSE ServiceLocatorHelper::service: found service IncidentSvc
+EventLoopMgr      WARNING Unable to locate service "EventSelector" 
+EventLoopMgr      WARNING No events will be processed from external input.
+HistogramDataSvc    DEBUG Service base class initialized successfully
+HistogramDataSvc  VERBOSE ServiceLocatorHelper::service: found service IncidentSvc
+HistogramPersis...  DEBUG  'CnvServices':[ 'RootHistSvc' ]
+HistogramPersis...  DEBUG Service base class initialized successfully
+HistogramPersis...WARNING Histograms saving not required.
+HistogramDataSvc  VERBOSE ServiceLocatorHelper::service: found service HistogramPersistencySvc
+ApplicationMgr       INFO Application Manager Initialized successfully
+ApplicationMgr Ready
+ToolSvc.Navigat...VERBOSE ServiceLocatorHelper::service: found service StoreGateSvc
+NavigationCore....VERBOSE ServiceLocatorHelper::service: found service TrigSerializeCnvSvc
+RoICache_test        INFO LINE:106 Test progress fine:  OK navigation tool retrieved
+RoICache_test        INFO LINE:109 Test progress fine:  OK navigation casted
+RoICache_test        INFO LINE:153 Test progress fine:  Navigation structure built
+RoICache_test:calo   INFO LINE:34 Start of the test: One algorithm test calo
+RoICache_test:calo   INFO REGTEST executing on 11
+RoICache_test:calo   INFO REGTEST REAL execution needed on 11
+RoICache_test:calo   INFO LINE:56 End of the test: One algorithm test calo
+RoICache_test:calo   INFO LINE:34 Start of the test: One algorithm test calo
+RoICache_test:calo   INFO REGTEST executing on 12
+RoICache_test:calo   INFO REGTEST CACHED execution needed on 12
+RoICache_test:calo   INFO LINE:56 End of the test: One algorithm test calo
+RoICache_test:calo   INFO LINE:34 Start of the test: One algorithm test calo
+RoICache_test:calo   INFO REGTEST executing on 13
+RoICache_test:calo   INFO REGTEST CACHED execution needed on 13
+RoICache_test:calo   INFO LINE:56 End of the test: One algorithm test calo
+RoICache_test:calo   INFO LINE:34 Start of the test: One algorithm test calo
+RoICache_test:calo   INFO REGTEST executing on 14
+RoICache_test:calo   INFO REGTEST CACHED execution needed on 14
+RoICache_test:calo   INFO LINE:56 End of the test: One algorithm test calo
+RoICache_test:calo   INFO LINE:34 Start of the test: One algorithm test calo
+RoICache_test:calo   INFO REGTEST executing on 1200
+RoICache_test:calo   INFO REGTEST REAL execution needed on 1200
+RoICache_test:calo   INFO LINE:56 End of the test: One algorithm test calo
+RoICache_test        INFO LINE:178 Test progress fine:  Executed calo on clusters
+RoICache_test:caux   INFO LINE:34 Start of the test: One algorithm test caux
+RoICache_test:caux   INFO REGTEST executing on 13
+RoICache_test:caux   INFO REGTEST REAL execution needed on 13
+RoICache_test:caux   INFO LINE:56 End of the test: One algorithm test caux
+RoICache_test:caux   INFO LINE:34 Start of the test: One algorithm test caux
+RoICache_test:caux   INFO REGTEST executing on 14
+RoICache_test:caux   INFO REGTEST CACHED execution needed on 14
+RoICache_test:caux   INFO LINE:56 End of the test: One algorithm test caux
+RoICache_test:c...   INFO LINE:34 Start of the test: One algorithm test calo2
+RoICache_test:c...   INFO REGTEST executing on 14
+RoICache_test:c...   INFO REGTEST REAL execution needed on 14
+RoICache_test        INFO LINE:210 Test progress fine:  got back object -38
+RoICache_test:c...   INFO LINE:56 End of the test: One algorithm test calo2
+RoICache_test:c...   INFO LINE:34 Start of the test: One algorithm test calo2
+RoICache_test:c...   INFO REGTEST executing on 13
+RoICache_test:c...   INFO REGTEST CACHED execution needed on 13
+RoICache_test:c...   INFO LINE:56 End of the test: One algorithm test calo2
+RoICache_test:c...   INFO LINE:34 Start of the test: One algorithm test calo2
+RoICache_test:c...   INFO REGTEST executing on 12
+RoICache_test:c...   INFO REGTEST REAL execution needed on 12
+RoICache_test        INFO LINE:210 Test progress fine:  got back object -34
+RoICache_test:c...   INFO LINE:56 End of the test: One algorithm test calo2
+RoICache_test:c...   INFO LINE:34 Start of the test: One algorithm test calo2
+RoICache_test:c...   INFO REGTEST executing on 11
+RoICache_test:c...   INFO REGTEST CACHED execution needed on 11
+RoICache_test:c...   INFO LINE:56 End of the test: One algorithm test calo2
+RoICache_test:c...   INFO LINE:34 Start of the test: One algorithm test calo2
+RoICache_test:c...   INFO REGTEST executing on 1200
+RoICache_test:c...   INFO REGTEST REAL execution needed on 1200
+RoICache_test        INFO LINE:210 Test progress fine:  got back object -34
+RoICache_test:c...   INFO LINE:56 End of the test: One algorithm test calo2
+RoICache_test        INFO LINE:228 Test progress fine:  Executed c2 on clusters
+RoICache_test:trk    INFO LINE:34 Start of the test: One algorithm test trk
+RoICache_test:trk    INFO REGTEST executing on 102
+RoICache_test:trk    INFO REGTEST REAL execution needed on 102
+RoICache_test        INFO LINE:251 Test progress fine:  got back object -34
+RoICache_test:trk    INFO LINE:56 End of the test: One algorithm test trk
+RoICache_test:trk    INFO LINE:34 Start of the test: One algorithm test trk
+RoICache_test:trk    INFO REGTEST executing on 104
+RoICache_test:trk    INFO REGTEST CACHED execution needed on 104
+RoICache_test:trk    INFO LINE:56 End of the test: One algorithm test trk
+RoICache_test:trk    INFO LINE:34 Start of the test: One algorithm test trk
+RoICache_test:trk    INFO REGTEST executing on 103
+RoICache_test:trk    INFO REGTEST CACHED execution needed on 103
+RoICache_test:trk    INFO LINE:56 End of the test: One algorithm test trk
+RoICache_test:trk    INFO LINE:34 Start of the test: One algorithm test trk
+RoICache_test:trk    INFO REGTEST executing on 101
+RoICache_test:trk    INFO REGTEST CACHED execution needed on 101
+RoICache_test:trk    INFO LINE:56 End of the test: One algorithm test trk
+RoICache_test:trk    INFO LINE:34 Start of the test: One algorithm test trk
+RoICache_test:trk    INFO REGTEST executing on 10100
+RoICache_test:trk    INFO REGTEST REAL execution needed on 10100
+RoICache_test        INFO LINE:251 Test progress fine:  got back object -34
+RoICache_test:trk    INFO LINE:56 End of the test: One algorithm test trk
+RoICache_test        INFO LINE:268 Test progress fine:  Executed trk
+RoICache_test:m...   INFO LINE:34 Start of the test: One algorithm test matcher
+RoICache_test:m...   INFO REGTEST executing on 1001
+RoICache_test:m...   INFO REGTEST REAL execution needed on 1001
+RoICache_test        INFO LINE:295 Test progress fine:  got back object 55
+RoICache_test:m...   INFO LINE:56 End of the test: One algorithm test matcher
+RoICache_test:m...   INFO LINE:34 Start of the test: One algorithm test matcher
+RoICache_test:m...   INFO REGTEST executing on 1002
+RoICache_test:m...   INFO REGTEST REAL execution needed on 1002
+RoICache_test        INFO LINE:295 Test progress fine:  got back object 77
+RoICache_test:m...   INFO LINE:56 End of the test: One algorithm test matcher
+RoICache_test:m...   INFO LINE:34 Start of the test: One algorithm test matcher
+RoICache_test:m...   INFO REGTEST executing on 1003
+RoICache_test:m...   INFO REGTEST CACHED execution needed on 1003
+RoICache_test:m...   INFO LINE:56 End of the test: One algorithm test matcher
+RoICache_test:m...   INFO LINE:34 Start of the test: One algorithm test matcher
+RoICache_test:m...   INFO REGTEST executing on 1004
+RoICache_test:m...   INFO REGTEST CACHED execution needed on 1004
+RoICache_test:m...   INFO LINE:56 End of the test: One algorithm test matcher
+RoICache_test:m...   INFO LINE:34 Start of the test: One algorithm test matcher
+RoICache_test:m...   INFO REGTEST executing on 100100
+RoICache_test:m...   INFO REGTEST REAL execution needed on 100100
+RoICache_test        INFO LINE:295 Test progress fine:  got back object 77
+RoICache_test:m...   INFO LINE:56 End of the test: One algorithm test matcher
+RoICache_test        INFO LINE:313 Test progress fine:  Executed ma on electron TEs
+RoICache_test:o...   INFO LINE:34 Start of the test: One algorithm test overlap
+RoICache_test:o...   INFO REGTEST executing on 222
+RoICache_test:o...   INFO REGTEST REAL execution needed on 222
+RoICache_test:o...   INFO LINE:56 End of the test: One algorithm test overlap
+RoICache_test:o...   INFO LINE:34 Start of the test: One algorithm test overlap
+RoICache_test:o...   INFO REGTEST executing on 223
+RoICache_test:o...   INFO REGTEST CACHED execution needed on 223
+RoICache_test:o...   INFO LINE:56 End of the test: One algorithm test overlap
+RoICache_test:o...   INFO LINE:34 Start of the test: One algorithm test overlap
+RoICache_test:o...   INFO REGTEST executing on 224
+RoICache_test:o...   INFO REGTEST REAL execution needed on 224
+RoICache_test:o...   INFO LINE:56 End of the test: One algorithm test overlap
+RoICache_test        INFO LINE:353 Test progress fine:  Executed on topo TEs
+RoICache_test        INFO LINE:354 Test progress fine:  ALLOK
diff --git a/Trigger/TrigEvent/TrigNavigation/share/TriggerElement_test.ref b/Trigger/TrigEvent/TrigNavigation/share/TriggerElement_test.ref
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/Trigger/TrigEvent/TrigNavigation/share/navigation2dot.py b/Trigger/TrigEvent/TrigNavigation/share/navigation2dot.py
new file mode 100755
index 0000000000000000000000000000000000000000..44cbb51987ba43f1e12e2b8beb24a2a3192e3dd7
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/share/navigation2dot.py
@@ -0,0 +1,339 @@
+#! /usr/bin/python
+# Q? Send mail to Tomasz dot Bold at cern dot ch
+
+import string
+from string import rstrip,atoi,replace
+import sys
+import commands
+import os
+import re
+
+teIdtoName = {'0':'0'}
+featureCLIDtoName = {}
+
+
+
+    
+
+if 'CMTROOT' not in os.environ.keys():
+    print 'Can not find out graphviz binaries: ',GraphivizBinPath
+    print 'Have you setup CMT environmet? CMTROOT not set'
+    raise SystemExit
+
+else:
+    # setup lib
+    GraphivizPath = os.environ['CMTROOT']+'/../Grafviz/2.2'
+    GraphivizBinPath = GraphivizPath+'/bin/'
+    GraphivizLibPath = GraphivizPath+'/lib/graphviz'
+
+    if 'LD_LIBRARY_PATH' not in os.environ.keys():
+        os.environ['LD_LIBRARY_PATH'] = ''
+    os.environ['LD_LIBRARY_PATH'] = os.environ['LD_LIBRARY_PATH']+':'+GraphivizLibPath
+
+    print "Graphviz programs from there: ", GraphivizBinPath
+
+    
+# global options driving grph drawing (switched by command line parser)
+options =  {'drawFeatures': False,
+            'clid': True,
+            'convert': False,
+            'program': 'dot',
+            'event': None,
+            'raw': False,
+            'regex': re.compile('.*')}
+
+
+def featureClassName(clid):
+    """ converts the CLID to ClassName in C++. If falied then CLID instead.
+        The CLIDS to name is taken from CLID Svc dump."""
+    if clid in featureCLIDtoName.keys():
+        return featureCLIDtoName[clid]
+    else:
+        if options['clid'] is False:
+            return str(clid)
+        else: # use CLID DB clid command to get it)
+            name = commands.getoutput( 'clid '+clid).split(' ')[1]
+            featureCLIDtoName[clid] = name
+            return name
+
+def teName(teid):
+    if teid in teIdtoName.keys():
+        return teIdtoName[teid]
+    else:
+        print "TE id: ", teid, " unknown"
+        return teid
+    
+class TE:
+    def __init__(self, s):
+        # print s
+        # this si typical line it has to deal with: id:0;active:1;error:0;ptr:0x9606b98;#seeds:4,0x9606ce0 0x9607338 0x96075b0 0x96077e8 #seededBy:0;#RoI:0;#features:1 CLID:242645981 idx:0:0:1 label:"OPI_L2";
+        tok = s.split(';')
+        #print tok
+        self.tename = teName(tok[0].split(':')[1])
+        self.active = bool(int(tok[1].split(':')[1]))
+        self.error  = bool(int(tok[2].split(':')[1]))
+        self.ptr    = tok[3].split(':')[1]
+        self.roi    = tok[5].split(':')[1]
+        # find out relations
+        self.relations = []
+        self.terminal = False
+        seeds = tok[4].split(',')[0].split(':')[1]
+        if seeds is '0':
+            self.terminal = True
+        else:
+            self.relations = tok[4].split(',')[1].split(' ')[0:-1]
+        
+        # find out features attached
+        #print tok
+        self.features = []
+        global options
+        passed=False
+        if options['drawFeatures']:
+            for part in tok:
+                if 'keyprints' in part:
+                    passed=True
+                clid = 0
+                label = ''
+                idx=''
+                for field in  part.split(" "):
+                    if field.find("CLID") is not -1:
+                        clid = field.split(":")[1].lstrip(' ').lstrip(' ')
+                    elif field.find("label") is not -1:
+                        label = field.split(":")[1].rstrip("\"").lstrip("\"")
+                    elif field.find("idx") is not -1:
+                        idx=field
+                if clid is not 0:
+                    #print (featureClassName(clid), label, idx, passed)
+                    self.features.append( (featureClassName(clid), label, idx, ('','*')[passed]) )
+                    
+        # print self.features
+        
+        # print self.tename, self.active, self.ptr, self.relations
+
+    def node(self):
+        """ Draws node of the graph. """
+        global options
+        
+        if options['regex'].search(self.tename) == None and self.tename != '0':
+            #            print "rejecting TE which of name ", self.tename, ' due to regex'
+            return None
+        
+        nodename = 'X'+ str(self.ptr)
+        line =  nodename +' [  label="{TE: ' + self.tename
+        
+        line += reduce(lambda x,y: x + "|"+y[0]+ "(" +y[1] + ' '+ y[2]+str(y[3])+")", self.features, "")
+        line += '}", style=filled, '
+
+        # special nodes 
+        if self.tename is '0':
+            line += 'fillcolor=pink, '            
+        else:
+            if self.active:
+                line += 'color=green, '
+            else:
+                line += 'color=plum, '
+            
+            # error color scheme
+            if self.error:
+                line += 'fillcolor=red, '
+            else:
+                line += 'fillcolor=palegreen, '
+
+
+
+
+        line += 'shape=record'
+        line += ']\n'
+        return line
+    
+    def edges (self):
+        """ Draws node and edges. """
+        line = ''
+        for rel in self.relations:
+            line += 'X'+self.ptr + ' -> X' + rel + '\n'
+        return line
+
+    def __str__(self):
+        r = self.node()
+        if r:
+            return r + self.edges()
+        else:
+            return ""
+    
+
+def nav2dot(nav, eventId, level):
+    """ converts"""
+    global options
+    inputTEs = nav.split('\n')
+    stringTEs = []
+    for te in inputTEs:
+        if te is not '':
+            stringTEs.append(te.lstrip(' |\_'))
+        
+    # unique
+    uniqueTEs = []
+    for ste in stringTEs:
+        if ste not in uniqueTEs:
+            uniqueTEs.append(ste)
+    # print "LEN :" + str(len(stringTEs)) + "-->" + str(len(uniqueTEs))
+    
+    objectTEs = map( lambda x: TE(x), uniqueTEs)
+    dot = 'digraph Menu  {\n'\
+          +'\n'\
+          +'graph [ rankdir = "TR"];'\
+          +'node [ shape=polygon, fontname=Helvetica ]\n'\
+          +'edge [ fontname=Helvetica ]\n'
+    dot += reduce(lambda x,y: x+str(y), objectTEs, '')
+    dot += '\n}'
+
+    fname = 'navigationEvent-'+level+'-'+str(eventId)
+    if options['event'] is None or str(options['event']) == str(eventId):
+        print 'writing file: '+fname+'.dot'
+        f = file('temp.dot','w')
+        f.write(dot)
+        f.close()
+        #print commands.getoutput(GraphivizBinPath+'unflatten -l4 -f -c2 -o '+ fname+ '.dot temp.dot')
+        print commands.getoutput('mv -f temp.dot '+fname+'.dot')
+        print commands.getoutput('/bin/rm -f temp.dot')
+        if options['convert']:
+            print 'converting file: '+fname+'.dot to graphics'
+            global GraphivizBinPath
+            print commands.getoutput(GraphivizBinPath+options['program']+' ' + fname +'.dot -Tpng -o '+fname+'.png')
+            # delete dot file
+            print commands.getoutput('rm -f '+fname+'.dot')
+# nav2dot(navex)
+
+def parseLog(file):
+    eventNumber = -1
+    navigationStarted=False
+    nav = ""
+    step = 0
+    stepToLevel =   ["L2", "EFunpacking", "EF"]     
+
+    for line in file:
+        if line.find("- --") is not -1:
+            # print line
+            if line.find("inputTEs") is not -1: # we spoted input TE in sequence printout
+                try:
+                    teId = line.split(" ")[5]
+                    teId = string.strip(teId, "(), \"\n")
+                    teId = rstrip(teId, ",")
+                    teName = line.split(" ")[4]
+                    teName = string.strip(teName, "(), \"\n")
+                    teIdtoName[teId] = teName
+                except:
+                    pass
+            if line.find(" outputTE   : (") is not -1:
+                teId = line.split(" ")[7]
+                teId = string.strip(teId, "() \n")
+                teName = line.split(" ")[6]
+                teName = string.strip(teName, "()\",\n")
+                teIdtoName[teId] = teName
+
+        # catch the navigation printout
+        if line.find("start processing event #") is not -1:
+            eventId = line.split("#")[1].split(",")[0]
+            step=0
+            print "scanning event: ",eventId
+
+
+        if line.find("Start of HLT Processing in L2") is not -1:
+            step = 0
+
+        if line.find("Start of HLT Processing in EF") is not -1:
+            step = 1
+
+        if line.find("TrigSteer_EF.ResultBuilder") is not -1:
+            step = 2
+            
+        # catch navigation block
+        if line.find("\\_") is not -1:
+            if navigationStarted is False:
+                navigationStarted=True
+            nav += line
+        else:
+            if navigationStarted is True:
+              navigationStarted=False
+              nav2dot(nav, eventId, stepToLevel[step] )
+
+              nav = ""
+
+
+def parseCLIDs():
+
+    if options['clid'] is False:
+        clids = file("CLIDDBout.txt")
+        for line in clids:
+            clid = line.split(" ")[0]
+            name = line.split(" ")[1].rstrip("\n")
+            featureCLIDtoName[clid] = name
+    # print featureCLIDtoName
+
+
+
+def parseOpt():
+    global options
+    stat = True
+        
+    if '-f' in sys.argv:
+        options['drawFeatures'] = True
+        print "OPTION: will draw features"
+
+    if '-d' in sys.argv:
+        options['clid'] = True
+        print "OPTION: will use clid command to get class names (slower)"
+    if '-x' in sys.argv:
+        options['regex'] = re.compile(sys.argv[sys.argv.index('-x')+1])
+        print "OPTION: will use only TEs accepted by regex", sys.argv[sys.argv.index('-x')+1]
+    if '-e' in sys.argv:
+        import string
+        options['event'] = string.atoi(sys.argv[sys.argv.index('-e')+1])
+        print "OPTION: will only draw event: ", options["event"]
+
+    if '-c' in sys.argv:
+        options['convert'] = True;
+        print "OPTION: will convert to graphics on the fly"
+
+    if '-p' in sys.argv:
+        options['program'] = sys.argv[sys.argv.index('-p')+1]
+        print "OPTION: will convert to graphics on the fly using ", options['program']
+
+    if '-r' in sys.argv:
+        options['raw'] = True
+        options['configdump'] = sys.argv[sys.argv.index('-r')+2]
+        options['navigationdump'] = sys.argv[sys.argv.index('-r')+1]
+        
+                
+    if '-h' in sys.argv:
+        print "OPTION: Help needed? Here it is:"
+        print """
+        Files generated by this utility can be viewed by programs like 'dotty'.
+        Thay can be converted to graphics using probram 'dot':
+        dot nav_event_123.dot -o nav123.png -Tpng
+        
+        -h               -- this help
+        -f               -- draw freatures atteched to TE (with lables)
+        -d               -- use clid command instead of CLIDDBout.txt to get human class names rather than CLIDs
+        -e X             -- writeout only event (X)
+        -x regex         -- use the regex to select only wanted TEs
+        -c               -- convert graphs to png on the fly using dot program
+        -p prog          -- use other program(neato, twopi, circo, fdp)
+        -r navigationfile configfile              -- take files  with the navigation dump and the configuration dump (rather than plain log)
+        """
+        stat = False
+    return stat
+# main script
+
+if parseOpt():
+    if not options['raw']:
+        logname = sys.argv[-1]
+        log = file(logname)
+        parseCLIDs()
+        parseLog(log)
+    else:
+        conflog = file(options['configdump'])
+        parseLog(conflog)
+        navlog = file(options['navigationdump'])
+        parseLog(navlog)
+        
+    #print teIdtoName
diff --git a/Trigger/TrigEvent/TrigNavigation/share/test.txt b/Trigger/TrigEvent/TrigNavigation/share/test.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1824074540c594b678203e897c36f734b221bbc9
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/share/test.txt
@@ -0,0 +1,36 @@
+//ApplicationMgr.DLLs += { "StoreGate", "CLIDSvc", "TrigNavigation" };
+ApplicationMgr.DLLs += { "StoreGate", "TrigNavigation", "TrigSerializeCnvSvc" };
+ApplicationMgr.ExtSvc += { "ClassIDSvc" };
+ApplicationMgr.ExtSvc += { "TrigSerializeCnvSvc" };
+ApplicationMgr.ExtSvc += { "StoreGateSvc", "StoreGateSvc/DetectorStore", "StoreGateSvc/HistoryStore" };
+ApplicationMgr.ExtSvc += { "ActiveStoreSvc" };
+ApplicationMgr.ExtSvc += { "ToolSvc" };
+AuditorSvc.Auditors  += { "AlgContextAuditor"};
+StoreGateSvc.OutputLevel = 1;
+StoreGateSvc.ActivateHistory = false;
+CLIDSvc.OutputLevel = 1;
+ClassIDSvc.OutputLevel = 1;
+MessageSvc.OutputLevel = 1;
+MessageSvc.useColors        = false;
+
+//StoreGateSvc.FolderNameList = { "MyFolder", "YourFolder" };
+//MyFolder.ItemList = {"Foo#Bla", "Bar#*"};
+//YourFolder.ItemList = {"8101", "8107#", "Baricco#*"};
+
+//#include "IOVSvc/IOVSvc.txt"
+//ApplicationMgr.DLLs += { "IOVSvc" };
+
+//ApplicationMgr.ExtSvc += { "IOVSvc" };
+
+//EventPersistencySvc.CnvServices += { "TrigSerializeCnvSvc" }
+
+// 
+//Navigation.ReferenceAllClasses = 1
+//ApplicationMgr.DLLs += { "TrigCaloEvent" };
+ToolSvc.Navigation.ReferenceAllClasses = 1;
+ToolSvc.Navigation.ClassesToPreregister = {"TestA#EverEmptyButPresent", "TestA#AgainPresentButEmpty", "TestA#","TestBContainer#BContainer1", "TestBContainer#BContainer2", "TestDContainer#DContainer1"};
+//ToolSvc.Navigation.AuxClasses = {"TestAuxA#EverEmptyButPresent", "TestAuxB#BContainer2"};
+
+ToolSvc.Navigation.OutputLevel=4;
+Holder_test.OutputLevel=1;
+RoICache_test.OutputLevel=3;
diff --git a/Trigger/TrigEvent/TrigNavigation/src/Holder.cxx b/Trigger/TrigEvent/TrigNavigation/src/Holder.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..e1be3adad899ad469df70a311ca195981b5dde4c
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/src/Holder.cxx
@@ -0,0 +1,110 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include <sstream>
+#include <boost/regex.hpp>
+
+#include "TrigNavigation/Holder.h"
+#include "TrigSerializeResult/StringSerializer.h"
+#include "TrigSerializeResult/ITrigSerializerToolBase.h"
+
+using namespace HLTNavDetails;
+
+/*****************************************************************************
+ *
+ * INNER CLASS (fatures handling)
+ *
+ *****************************************************************************/
+IHolder::IHolder()
+  : m_serialized(0),
+    m_log(0),
+    m_storeGate(0),
+    m_serializer(0),
+    m_label(""),
+    m_subTypeIndex(0),
+    m_aux(0),
+    m_uniqueCounter(0)
+{}
+
+IHolder::~IHolder() {
+  if ( m_aux ) { delete m_aux; }
+}
+
+void IHolder::prepare(MsgStream* log, HLT::AccessProxy* sg) {
+  m_storeGate = sg;
+  m_log = log;
+}
+
+bool IHolder::serialize(std::vector<uint32_t>& output)  const {
+  if ( m_log->level()<=MSG::DEBUG )
+    *m_log << MSG::DEBUG << "Holder<T> serialize, " << *this  << endreq;
+  // if feature to be forgotten then indication of it is simply 0 size of serialized vector
+
+  output.push_back( typeClid() );
+  output.push_back( m_subTypeIndex );
+
+  // label
+  std::vector<uint32_t> serializedLabel;
+  StringSerializer ss;
+  ss.serialize( m_label, serializedLabel );
+  output.push_back( serializedLabel.size() );
+  output.insert(output.end(), serializedLabel.begin(), serializedLabel.end());
+  return true;
+}
+
+bool IHolder::enquireSerialized(const std::vector<uint32_t>& blob,
+                                std::vector<uint32_t>::const_iterator& it,
+                                CLID& c, std::string& label, uint16_t& subtypeIndex ) {
+
+  if ( it == blob.end() )  return false;
+
+  c = *it++;
+  if ( it == blob.end() )  return false;
+
+  subtypeIndex = *it++;
+  if ( it == blob.end() ) return false;
+
+  unsigned labelSize = *it++;
+  if ( it == blob.end() ) return false;
+  if ( it+labelSize > blob.end() ) return false;
+
+  std::vector<uint32_t> tmp(it, it+labelSize);
+  it += labelSize;
+
+  StringSerializer s;
+  s.deserialize(tmp, label);
+  return true;
+}
+
+
+
+std::string IHolder::generateAliasKey(CLID c, uint16_t sti, const std::string& label, unsigned size) {
+  std::ostringstream ss;
+  ss <<  "HLTAutoKey_" << label << "_" << c << "_" << sti << "_" << (size == 0xffffffff ? "back" : "to")  << "_" << m_uniqueCounter;
+  std::string st = ss.str();
+  if ( m_log->level()<=MSG::DEBUG )
+    *m_log << MSG::DEBUG << "IHolder::generateAliasKey generated key: " << st << endreq;
+  m_uniqueCounter++;
+  return st;
+}
+
+void IHolder::print(MsgStream& m) const {
+  m << "CLID: " << typeClid() << " label: \"" << label() << "\" subTypeIndex: " << subTypeIndex();
+}
+
+MsgStream& HLTNavDetails::operator<< ( MsgStream& m, const HLTNavDetails::IHolder& h ) {
+  h.print (m);
+  return m;
+}
+
+std::string HLTNavDetails::formatSGkey(const std::string& prefix, const std::string& containername, const std::string& label){
+  std::string cleaned = containername;
+  boost::regex rx1("_v[0-9]+$");
+  cleaned = boost::regex_replace(cleaned,rx1,std::string(""));
+  boost::regex rx2("::");
+  cleaned = boost::regex_replace(cleaned,rx2,std::string("__"));
+  return prefix+"_"+cleaned+(label.size() ? "_"+label : "");
+}
+
+
diff --git a/Trigger/TrigEvent/TrigNavigation/src/Navigation.cxx b/Trigger/TrigEvent/TrigNavigation/src/Navigation.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..a465506065b1157ed2ae2059ba6cc52e036b76f5
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/src/Navigation.cxx
@@ -0,0 +1,250 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include <sstream>
+#include <iostream>
+#include <algorithm>
+#include <iterator> // remove it (it is here to help with debugging)
+
+
+
+//#include <boost/cstdint.hpp>
+//#include <stdint.h>
+#include <boost/lexical_cast.hpp>
+
+#include "AthenaKernel/getMessageSvc.h"
+#include "GaudiKernel/System.h"
+//#include "GaudiKernel/IClassManager.h"
+//#include "GaudiKernel/SmartIF.h"
+
+#include "TrigNavigation/Navigation.h"
+using namespace HLT;
+using namespace HLTNavDetails;
+
+
+//std::map<CLID, IHolder* > Navigation::m_types;
+
+
+
+//Navigation::Navigation( TriggerElementFactory& factory )
+Navigation::Navigation(  const std::string& type, const std::string& name,
+                         const IInterface* parent )
+  : AthAlgTool(type, name, parent),
+    m_serializerServiceHandle("TrigSerializeCnvSvc", name),
+    m_storeGateHandle("StoreGateSvc", name)
+{
+
+  declareProperty("ReferenceAllClasses", m_referenceAllClasses=false,
+                  "Flag anabling all features referenceing.");
+
+  declareProperty("ClassesToPayload", m_classesToPayloadProperty,
+                  "List of classes which need to be serialized together with the Navigation.");
+
+  declareProperty("ClassesFromPayload", m_classesFromPayloadProperty,
+                  "List of classes which need to be de-serialized together with the Navigation.");
+  
+  declareProperty("ClassesToPayload_DSonly", m_classesToPayloadProperty_DSonly,
+                  "List of classes which need to be serialized together with the Navigation (Only in DataScouting collection).");
+  
+  declareProperty("ClassesToPreregister", m_classesToPreregisterProperty,
+                  "List of classes which need to be put in SG independently if they appear in event.");
+
+  //  declareProperty("SerializeSpaceLimit",  m_serializeSpaceLimit=8000000,
+  //                  "Limit of the size which navigation can use once serialized.");
+
+  declareProperty("Dlls",  m_dlls, "Libraries to load (with trigger EDM)");
+  declareProperty("ObjectsKeyPrefix", m_objectsKeyPrefix="HLT", "The prefix which all Trigger EDM objects will get, by default it is HLT");
+  declareProperty("ObjectsIndexOffset", m_objectsIndexOffset=0, "The offset with which the objects idx is be shifted.");
+  declareProperty("EvtStore", m_storeGateHandle);
+
+  declareInterface<Navigation>(this);
+}
+
+Navigation::~Navigation() {}
+
+
+/*****************************************************************************
+ *
+ * INITIALIZATION and FINALIZATION
+ *
+ *****************************************************************************/
+StatusCode Navigation::initialize() {
+  // message log
+  delete m_log;
+  m_log = new MsgStream(msgSvc(), name() );
+
+  // factor of TEs
+  /* in CORE m_factory = new TriggerElementFactory;
+  if ( m_factory->listOfProduced().size() != 0 ) {
+    *m_log << MSG::FATAL << "Navigation::Navigation(), factory size not 0 but: " 
+	   << m_factory->listOfProduced().size() << endreq;
+    return StatusCode::FAILURE;
+  }
+
+  */
+ // get StoreGate
+  StatusCode sc = m_storeGateHandle.retrieve();
+  if(sc.isFailure()) {
+    (*m_log) << MSG::FATAL << "Unable to get pointer to StoreGate Service: "
+             << m_storeGateHandle << endreq;
+    return StatusCode::FAILURE;
+  }
+  //  m_storeGate = m_storeGateHandle.operator->();
+  //  AccessProxy* ap = new AccessProxy(0, m_storeGateHandle.operator->());
+  setAccessProxy(m_storeGateHandle.operator->());
+
+  // create the Serializer
+  //  m_serializer = NULL;
+  /*
+    if ( m_serializerToolHandle.retrieve().isFailure() ) {
+    (*m_log) << MSG::FATAL << "failed to retrieve serializer tool: "
+    << m_serializerToolHandle<< endreq;
+    return  StatusCode::FAILURE;
+    } else {
+    (*m_log) << MSG::DEBUG << "successfully retrieved serializer tool: "
+    << m_serializerTool << endreq;
+    //    m_serializer = m_serializerTool.operator->();
+    }
+    m_serializerTool = m_serializerToolHandle.operator->();
+  */
+
+  StatusCode scnv = m_serializerSvc.retrieve();
+  if (scnv.isFailure()){
+    *m_log << MSG::FATAL << "Navigation::initialize() cannot get TrigSerializeCnvSvc"
+           << endreq;
+  } else {
+    if (m_log->level() <= MSG::DEBUG )
+      *m_log << MSG::DEBUG << "Navigation::initialize() got TrigSerializeCnvSvc"
+             << endreq;
+  }
+
+  // payload def
+  if ( classKey2CLIDKey(m_classesToPayloadProperty,  m_classesToPayload).isFailure() ) {
+    (*m_log) << MSG::FATAL << "failed to decode property ClassesToPayload: "
+             << m_classesToPayloadProperty << endreq;
+    return  StatusCode::FAILURE;
+  }
+
+  if ( classKey2CLIDKey(m_classesToPayloadProperty_DSonly,  m_classesToPayload_DSonly).isFailure() ) {
+    (*m_log) << MSG::FATAL << "failed to decode property ClassesToPayload: " 
+	     << m_classesToPayloadProperty_DSonly << endreq;
+    
+    return  StatusCode::FAILURE;
+  }
+  
+  // initialize converters
+  for (size_t icl=0; icl<m_classesToPayload.size(); icl++){
+    CLID cl = m_classesToPayload.at(icl).first;
+    StatusCode stmp = m_serializerSvc->addConverter(cl);
+    if (stmp.isFailure())
+      *m_log << MSG::WARNING << "Initialization of a converter for CLID=" << cl << " failed" << endreq;
+  }
+
+
+  // preregistration def
+  if ( classKey2CLIDKey(m_classesToPreregisterProperty,  m_classesToPreregister).isFailure() ) {
+    (*m_log) << MSG::FATAL << "failed to decode property ClassesToPreregister: "
+             << m_classesToPreregisterProperty << endreq;
+    return  StatusCode::FAILURE;
+  }
+
+
+  // create string specific serializer
+  //in CORE m_stringSerializer = new StringSerializer();
+
+  // print out registered holders
+  HLT::TypeMaps::CLIDtoHolderMap::const_iterator holderIt;
+  if (m_log->level() <= MSG::VERBOSE ) {
+    for ( holderIt = HLT::TypeMaps::holders().begin(); holderIt != HLT::TypeMaps::holders().end(); ++holderIt ) {
+      if(!holderIt->second){
+	(*m_log) << MSG::FATAL << "static type information not intialized. Holder is null pointer" << endreq;
+      }
+      (*m_log) << MSG::VERBOSE << *(holderIt->second) << endreq;
+    }
+  }
+
+  // load libraries
+  std::vector<std::string>::const_iterator dlIt;
+  for ( dlIt = m_dlls.begin(); dlIt != m_dlls.end(); ++dlIt ) {
+    System::ImageHandle handle = 0;
+    if ( System::loadDynamicLib( *dlIt, &handle)  != 1 ) {
+      (*m_log) << MSG::WARNING << "failed to load " << *dlIt << endreq;
+    } else {
+      if (m_log->level() <= MSG::DEBUG )
+        (*m_log) << MSG::DEBUG << "forcibly loaded library " << *dlIt << endreq;
+    }
+  }
+
+  // translate Class names into CLID numbers
+  if (m_log->level() <= MSG::DEBUG )
+    (*m_log) << MSG::DEBUG << " successfully initialized Navigation "
+             << endreq;
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode
+Navigation::classKey2CLIDKey(const std::vector<std::string> property,
+                             std::vector<std::pair<CLID,
+                             std::string> >& decoded ) {
+  // translate Class names into CLID numbers
+  IClassIDSvc* clidSvc;
+  if( service("ClassIDSvc", clidSvc).isFailure() ) {
+    (*m_log) << MSG::FATAL << "Unable to get pointer to CLIDSvc Service" << endreq;
+    return StatusCode::FAILURE;
+  }
+
+  std::vector<std::string>::const_iterator it;
+  for ( it = property.begin(); it != property.end(); ++it ) {
+    CLID clid;
+    std::string key;
+    std::string type;
+
+    if ( it->find("#") != std::string::npos ) {
+      type = it->substr(0, it->find("#") );
+      key  = it->substr(it->find("#")+1 );
+    } else {
+      type = *it;
+      key = "";
+    }
+
+    if ( clidSvc->getIDOfTypeName(type, clid).isFailure() ) {
+      (*m_log) << MSG::FATAL << "Unable to get CLID for class: " << *it
+               << " check property" << endreq;
+      return StatusCode::FAILURE;
+    }
+
+    if (m_log->level() <= MSG::DEBUG )
+      (*m_log) << MSG::DEBUG << "Recognized CLID : " << type << " and key: " << key
+               << endreq;
+
+    decoded.push_back(std::make_pair(clid, key));
+  }
+  return StatusCode::SUCCESS;
+}
+
+StatusCode Navigation::finalize() {
+  if (m_log->level() <= MSG::DEBUG )
+    *m_log << MSG::DEBUG << "Navigation finalize" << endreq;
+  //  reset();
+
+  /* in CORE elete m_stringSerializer;
+  delete m_factory;
+  delete m_log;
+  */
+  /*
+    for (std::map< CLID, std::vector<uint32_t>* > ::iterator it = m_serializedFeatures.begin();
+    it != m_serializedFeatures.end(); ++it) {
+    delete it->second;
+    }
+  */
+  return StatusCode::SUCCESS;
+}
+
+
+
+MsgStream& HLT::operator<< ( MsgStream& m, const Navigation& nav ) {
+  m << (NavigationCore&)nav;
+  return m;
+}
diff --git a/Trigger/TrigEvent/TrigNavigation/src/NavigationCore.cxx b/Trigger/TrigEvent/TrigNavigation/src/NavigationCore.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..9f95c652171e70bc47b57039917750b9183dbc1f
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/src/NavigationCore.cxx
@@ -0,0 +1,1201 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include <sstream>
+#include <iostream>
+#include <algorithm>
+#include <iterator> // remove it (it is here to help with debugging)
+
+
+
+//#include <boost/cstdint.hpp>
+//#include <stdint.h>
+#include <boost/lexical_cast.hpp>
+#include "GaudiKernel/IConversionSvc.h"
+#include "AthenaKernel/getMessageSvc.h"
+#include "SGTools/DataBucketBase.h"
+
+
+#include "TrigNavigation/TriggerElement.h"
+
+#include "TrigConfHLTData/HLTUtils.h"
+
+#include "TrigNavigation/TrigEDMSizes.h"
+#include "TrigNavigation/RoICacheHistory.h"
+
+#include "TrigSerializeCnvSvc/TrigStreamAddress.h"
+#include "TrigSerializeResult/StringSerializer.h"
+
+
+#include "TrigNavigation/NavigationCore.h"
+
+
+//#define MLOG(x)   if (m_log->level()<=MSG::x+m_msgLvlOffset) *m_log << (m_msgLvlOffset+MSG::x)
+#define MLOG(x)   if (m_log->level()<=MSG::x) *m_log << MSG::x
+
+using namespace HLT;
+using namespace HLTNavDetails;
+
+
+template<typename T>
+std::ostream& operator<<( std::ostream& s, const std::vector<T>& v)
+{
+  s<< "[";for(auto i:v){s << i << ", ";} s << "]";
+  return s;
+}
+
+
+
+
+std::string NavigationCore::m_unspecifiedLabel = "";
+const TriggerElement* NavigationCore::m_unspecifiedTE = 0;
+
+
+
+NavigationCore::NavigationCore()
+  : TrigNavStructure(), m_log(0), m_serializerSvc("TrigSerializeCnvSvc","NavigationCore"),
+    m_storeGate(0),
+    //m_serializeSpaceLimit(8000000),
+    m_objectsKeyPrefix("HLT"),
+    m_objectsIndexOffset(0),
+    m_referenceAllClasses(true) {
+
+  m_log = new MsgStream(Athena::getMessageSvc(), "NavigationCore");
+
+  m_stringSerializer = new StringSerializer();
+}
+
+NavigationCore::~NavigationCore() {
+
+
+  MLOG(VERBOSE) << "~NavigationCore: cleaning static type information" << endreq;
+  {
+    HLT::TypeMaps::CLIDtoTypeProxyMap::iterator it;
+    for ( it = HLT::TypeMaps::proxies().begin(); it != HLT::TypeMaps::proxies().end(); ++it ) {
+      delete it->second; it->second = 0;
+    }
+    HLT::TypeMaps::proxies().clear();
+  }
+  {
+    HLT::TypeMaps::CLIDtoHolderMap::iterator it;
+    for ( it = HLT::TypeMaps::holders().begin(); it != HLT::TypeMaps::holders().end(); ++it ) {
+      delete it->second; it->second = 0;
+    }
+    HLT::TypeMaps::holders().clear();
+  }
+
+  delete m_stringSerializer;
+  delete m_log;
+}
+
+
+
+
+
+
+/*****************************************************************************
+ *
+ * PREATY PRINTING
+ *
+ *****************************************************************************/
+
+MsgStream& HLT::operator<< ( MsgStream& m, const NavigationCore& nav ) {
+  std::string str;
+  nav.printASCIIArt(str);
+  
+  m << str;
+  return m;
+}
+
+
+bool NavigationCore::addBlob(std::vector<uint32_t>& output,
+			     const std::vector<uint32_t>& blob1,
+			     const std::vector<uint32_t>& blob2) const {
+  output.push_back(blob1.size()+blob2.size());
+  output.insert(output.end(), blob1.begin(), blob1.end());
+  output.insert(output.end(), blob2.begin(), blob2.end());
+  //  copy(blob.begin(), blob.end(), std::ostream_iterator<int>(std::cerr, " A "));
+  //  std::cerr << std::endl;
+  return true;
+}
+
+
+bool NavigationCore::extractBlob(const std::vector<uint32_t>& input, std::vector<uint32_t>::const_iterator& it, std::vector<uint32_t>& blob) const {
+  blob.clear();
+  if ( it == input.end() )
+    return false;
+
+  unsigned sizeOfBlob = *it;
+  //  MLOG(DEBUG) << "blob size is: " << sizeOfBlob << endreq;
+  std::vector<uint32_t>::const_iterator begin = it;
+  ++begin;
+  std::vector<uint32_t>::const_iterator end   = it;
+  ++end;
+  advance(end, sizeOfBlob);
+
+  if ( end <= input.end()) {
+    blob.reserve(end-begin);
+    blob.insert(blob.end(), begin, end);
+    //    copy(blob.begin(), blob.end(), std::ostream_iterator<int>(std::cerr, " X "));
+    //    std::cerr << std::endl;
+    it = end; // update iterator
+    return true;
+  }
+  return false; // failed to get blob
+}
+
+bool doSingleHolderSerialization(std::vector<uint32_t>& headerBlob, std::vector<uint32_t>& dataBlob, HLTNavDetails::IHolder* holder, const ServiceHandle<IConversionSvc>& serializerSvc, bool dataSerialization ) {
+  holder->serialize( headerBlob );
+  
+  if (dataSerialization) {
+    DataObject* dobj = holder->getDataObject();
+    TrigStreamAddress* addr(0);
+    if ( serializerSvc->createRep(dobj, *pp_cast<IOpaqueAddress>(&addr) ).isSuccess() ) {
+      REPORT_MESSAGE_WITH_CONTEXT(MSG::VERBOSE,"NavigationCore") << "serialization of feature (object) successful, blob size: "  << addr->get().size();
+      dataBlob.push_back(addr->get().size());
+      dataBlob.insert(dataBlob.end(), addr->get().begin(), addr->get().end());
+      // above should be optimized (need to know if in case of failed serialization addr->get() contains empty data vector)
+    }
+    else{
+      REPORT_MESSAGE_WITH_CONTEXT(MSG::ERROR,"NavigationCore") << "Container serialization Failure" << endreq;
+      return false;
+    }
+    //dobj->addRef();
+    DataBucketBase* dobjBase = static_cast<DataBucketBase*>(dobj);
+    if ( dobjBase ) {
+      dobjBase->relinquish();
+      REPORT_MESSAGE_WITH_CONTEXT(MSG::VERBOSE,"NavigationCore") << "serialization giving up the ownership";
+    }
+    delete dobj;
+    delete addr;
+    
+    DataObject* dobjaux = holder->getAuxDataObject();
+    TrigStreamAddress* auxaddr(0);
+    if(dobjaux){
+      REPORT_MESSAGE_WITH_CONTEXT(MSG::VERBOSE,"NavigationCore") << "AuxStore serialization" << endreq;
+      if(serializerSvc->createRep(dobjaux,*pp_cast<IOpaqueAddress>(&auxaddr) ).isSuccess() ){
+	REPORT_MESSAGE_WITH_CONTEXT(MSG::VERBOSE,"NavigationCore") << "aux conversion success! aux blob has size: " << auxaddr->get().size();
+	dataBlob.push_back(auxaddr->get().size());
+	dataBlob.insert(dataBlob.end(), auxaddr->get().begin(), auxaddr->get().end());
+      }
+      else{
+	REPORT_MESSAGE_WITH_CONTEXT(MSG::ERROR,"NavigationCore") << "AuxStore serialization Failure" << endreq;
+	return false;
+      }
+      DataBucketBase* dobjBaseAux = static_cast<DataBucketBase*>(dobjaux);
+      if ( dobjBaseAux ) {
+	dobjBaseAux->relinquish();
+	REPORT_MESSAGE_WITH_CONTEXT(MSG::VERBOSE,"NavigationCore") << "serialization giving up the ownership of Aux";
+      }
+      delete dobjaux;
+      delete auxaddr;
+    }
+  }
+
+  REPORT_MESSAGE_WITH_CONTEXT(MSG::VERBOSE,"NavigationCore") << "finished serializing dumping blobs. header size: " 
+							     << headerBlob.size() << " data size: " << dataBlob.size();
+  // std::cout << "[";for(auto i:headerBlob){std::cout << i << ", ";} std::cout << "]" << std::endl;
+  // std::cout << "[";for(auto i:dataBlob){std::cout << i << ", ";} std::cout << "]" << std::endl;
+
+  return true;
+}
+
+bool doSingleHolderDeserialization(const std::vector<uint32_t>& dataBlob, HLTNavDetails::IHolder* holder, const ServiceHandle<IConversionSvc>& serializerSvc, StoreGateSvc* /*storegate*/, const std::string& sgkey, CLID clid, int version){
+  REPORT_MESSAGE_WITH_CONTEXT(MSG::VERBOSE,"NavigationCore") << "deserializing a data blob of size " << dataBlob.size() << " navi version is " << version;
+  
+  typedef std::vector<uint32_t>::const_iterator it_type;
+  it_type it = std::begin(dataBlob);
+  
+  if(!dataBlob.size()) return false;
+
+
+  std::vector<uint32_t> first;
+  std::vector<uint32_t> second;
+
+  if(version == 4){
+    auto firstsize = *(it++);
+    REPORT_MESSAGE_WITH_CONTEXT(MSG::VERBOSE,"NavigationCore") << "first part has size: " << firstsize;
+
+    first = std::vector<uint32_t>(it,it+firstsize);
+  
+    std::advance(it,firstsize);  
+  
+    if(!(it!=dataBlob.end())){
+      REPORT_MESSAGE_WITH_CONTEXT(MSG::VERBOSE,"NavigationCore") << "this datablob only has a first part (non xAOD case)";
+    }
+    else{
+      auto secondsize = *(it++);
+      REPORT_MESSAGE_WITH_CONTEXT(MSG::VERBOSE,"NavigationCore") << "second part has size: " << secondsize;
+      second = std::vector<uint32_t>(it,it+secondsize);
+    }
+  }
+  else{
+    first = std::vector<uint32_t>(dataBlob.begin(),dataBlob.end());
+  }
+
+  TrigStreamAddress addr(clid, sgkey, "", 0, 0);
+  addr.add(first);
+  DataObject* dobj(0);
+
+  if (serializerSvc->createObj((IOpaqueAddress*)&addr, dobj).isFailure() ){
+    REPORT_MESSAGE_WITH_CONTEXT(MSG::WARNING,"NavigationCore") << "deserialize main: failed" << std::endl;
+    return false;
+  }
+
+  bool setcontainer = holder->setDataObject(dobj);
+  if(!setcontainer) return false;
+
+  DataObject* dobjaux(0);
+  if(!second.empty()){
+    std::string sgkeyaux = sgkey+"Aux.";
+    REPORT_MESSAGE_WITH_CONTEXT(MSG::VERBOSE,"NavigationCore") << "aux clid was deduced to be: " << holder->auxClidOrZero();
+    TrigStreamAddress auxaddr(holder->auxClidOrZero(), sgkeyaux, "", 0, 0);
+    auxaddr.add(second);
+
+    if (serializerSvc->createObj((IOpaqueAddress*)&auxaddr, dobjaux).isFailure() ){
+      REPORT_MESSAGE_WITH_CONTEXT(MSG::WARNING,"NavigationCore") << "Aux Store deserialization failed";
+      return false;
+    }
+    bool setaux = holder->setAuxDataObject(dobjaux);
+    if(!setaux) return false;
+  }
+
+
+
+  return true;  
+}
+
+
+bool NavigationCore::serialize( std::vector<uint32_t>& output, std::vector<unsigned int>& cuts ) const {
+  std::vector<std::pair<CLID, std::string> > clid_name;
+  clid_name.clear();
+  return serialize(output, cuts, clid_name);
+}
+
+bool NavigationCore::serialize( std::vector<uint32_t>& output, std::vector<unsigned int>& cuts, std::vector<std::pair<CLID, std::string> >& clid_name ) const {
+
+  const std::vector<TriggerElement*>& fullList =  m_factory.listOfProduced();
+  std::vector<TriggerElement*> all;
+  for(std::vector<TriggerElement*>::const_iterator iter = fullList.begin(); iter != fullList.end(); ++iter) {
+    if(! (*iter)->transient() ) {
+      all.push_back( *iter );
+    }
+  }
+
+  cuts.clear();
+  clid_name.clear();
+
+  // version
+  unsigned int version=4;
+  output.push_back(version);
+
+  MLOG(DEBUG) << "NavigationCore::serialize: serializing with version " << version << endreq;
+
+  unsigned int totalSizeIndex = output.size();
+  output.push_back(0); // reserve one word (accessible under the index totalSize), it is 0 if there was truncation here
+                       // and != output.size() if truncation using cuts
+
+  cuts.push_back(output.size()); // mark a cut place
+
+  unsigned int endSizeIndex = output.size();
+  output.push_back(0); // reserve one word (accessible under the index startSize)
+
+
+  // reserve space (in order to be efficient it should not be resized any more, this can be studied probably later to find optimum)
+  output.reserve(10*all.size());
+
+  // SERIALZE NAVIGATION STRUCTURE
+  // size (measured in elements)
+  output.push_back(all.size());
+
+  // helper keys
+  std::map<TriggerElement*, uint16_t> keys;
+
+  const TriggerElement* previous = 0;
+  std::vector<TriggerElement*>::const_iterator it;
+  uint16_t indexForTe = 0;
+  for ( it = all.begin(); it != all.end(); ++it ) {
+    // first we stream pointer as it (this is already an unique key for this TE)
+    //    output.push_back((unsigned int)(*it));
+    (*it)->serialize(output, keys, previous);
+    previous = *it;
+    keys[*it] =  indexForTe;
+    indexForTe++;
+  }
+  unsigned int endSize = output.size();
+
+  MLOG(DEBUG) << "serialize: Sizes start: " << endSizeIndex << " end: " << endSize <<
+    " TEs: " << m_factory.listOfProduced().size() << endreq;
+  output[endSizeIndex] = endSize; // one can use it for cutting out all features
+
+  cuts.push_back(output.size()); // mark a cut place
+
+
+  // SERIALIZE FEATURES
+  std::vector<uint32_t> headerBlob;
+  std::vector<uint32_t> dataBlob;
+
+
+  if ( m_classesToPayload.empty() ) { // this is offline case
+    FeaturesStructureLabelIndexed::const_iterator clidIt;
+    for ( clidIt = m_featuresByLabel.begin(); clidIt != m_featuresByLabel.end(); ++clidIt ) {
+      std::map<std::string, IHolder*>::const_iterator holderIt;
+      for ( holderIt = clidIt->second.begin(); holderIt != clidIt->second.end(); ++holderIt ) {
+
+        MLOG(DEBUG) << "serialization of featue attempting : " << clidIt->first << " " << holderIt->first << endreq;
+
+        IHolder *holder = holderIt->second;
+        if ( ! holder ) {
+          MLOG(DEBUG) << "serialization of feature skipped, nothing know on this objects"  << endreq;
+          continue;
+        }
+        MLOG(DEBUG) << "serialization of feature: " << holder->typeClid() << " label: " << holder->label()
+                    << " size of payload: " << output.size() << endreq;
+
+        headerBlob.clear();
+        dataBlob.clear();
+        bool status = doSingleHolderSerialization(headerBlob, dataBlob, holder, m_serializerSvc, false );
+        addBlob( output, headerBlob, dataBlob );
+	clid_name.push_back(std::pair < CLID, std::string> (holder->typeClid(), holder->label()));
+        cuts.push_back(output.size()); // mark truncation point
+        MLOG(DEBUG) << "serialization of feature: " << holder->typeClid() << " label: " << holder->label()
+                    << " size of blob: " << headerBlob.size()+dataBlob.size() << " done with status: " << status  << endreq;
+      }
+    }
+  } else { // this is online case when list of classes to payload is not empty
+    // prepare sizes object
+    //
+    std::string name_TrigEDMSizes("TrigEDMSizes");
+
+    // check if SG contains a previously registered TrigEDMSizes object
+    // reuse it and update it
+    // this is an issue when running L2 and EF together in athena
+    TrigEDMSizes* sizes(0);
+    if ( m_storeGate->transientContains(ClassID_traits<HLT::TrigEDMSizes>::ID(), name_TrigEDMSizes) ) {
+      MLOG(DEBUG) << "A previously registered object of type = (HLT::TrigEDMSizes) and name = " << name_TrigEDMSizes << " was found in SG." << endreq;
+      const TrigEDMSizes* sizesSG(0) ;
+      if ( m_storeGate->retrieve(sizesSG, name_TrigEDMSizes).isFailure() ) {
+        MLOG(WARNING) << "There was an error when retrieving the old object of type = (HLT::TrigEDMSizes) and name = " << name_TrigEDMSizes << " from SG." << endreq;
+      } else {
+        sizes = const_cast<TrigEDMSizes*>(sizesSG);
+      }
+    } else {
+      if ( m_storeGate->contains(ClassID_traits<HLT::TrigEDMSizes>::ID(), name_TrigEDMSizes) ) {
+        MLOG(DEBUG) << "An object of type = (HLT::TrigEDMSizes) and name = " << name_TrigEDMSizes << " accessible through SG was found." << endreq;
+        const TrigEDMSizes* sizesSG(0) ;
+        if ( m_storeGate->retrieve(sizesSG, name_TrigEDMSizes).isFailure() ) {
+          MLOG(WARNING) << "There was an error when retrieving the object contained in SG of type = (HLT::TrigEDMSizes) and name = " << name_TrigEDMSizes << "." << endreq;
+        } else {
+          sizes = const_cast<TrigEDMSizes*>(sizesSG);
+        }
+      } else {
+        sizes = new TrigEDMSizes();
+        m_storeGate->record(sizes, name_TrigEDMSizes).setChecked(); //
+        MLOG(DEBUG) << "A new object of type = (HLT::TrigEDMSizes) and name = " << name_TrigEDMSizes << " was registered in SG." << endreq;
+      }
+    }
+    
+    MLOG(DEBUG) << "serialization: number of classes to payload: " << m_classesToPayload.size() << endreq;
+
+    std::vector<std::pair<CLID, std::string> >::const_iterator cl;
+    for ( cl =  m_classesToPayload.begin();  cl != m_classesToPayload.end(); ++cl ) {
+      CLID clid = cl->first;
+      std::string key = cl->second;
+      MLOG(DEBUG) << "serialization (ordered) of featue attempting : " << clid << " " << key << endreq;
+      FeaturesStructureLabelIndexed::const_iterator clidIt = m_featuresByLabel.find(clid);
+      if ( clidIt != m_featuresByLabel.end() ) {
+        std::map<std::string, IHolder*>::const_iterator holderIt = clidIt->second.find(key);
+        if ( holderIt != clidIt->second.end() ) {
+          IHolder *holder = holderIt->second;
+          if ( ! holder ) {
+            MLOG(DEBUG) << "serialization (ordered) of feature skipped, nothing know on this objects"  << endreq;
+            continue;
+          }
+          MLOG(DEBUG) << "serialization (ordered) of feature: " << holder->typeClid() << " label: " << holder->label()
+                      << " size of payload: " << output.size() << endreq;
+          headerBlob.clear();
+          dataBlob.clear();
+          bool status = doSingleHolderSerialization(headerBlob, dataBlob, holder, m_serializerSvc, true );
+          addBlob( output, headerBlob, dataBlob );
+	  clid_name.push_back(std::pair < CLID, std::string> (holder->typeClid(), holder->label()));
+          cuts.push_back(output.size()); // mark truncation point
+          MLOG(DEBUG) << "serialization of feature: " << holder->typeClid() << " label: " << holder->label()
+                      << " size of blob: " << headerBlob.size()+dataBlob.size() << " done with status: " << status << endreq;
+          if (sizes) sizes->addObject(holder->collectionName(), holder->label(), dataBlob.size(), output.size() );
+        }
+      }
+    }
+  }
+
+  MLOG(DEBUG) << "serialization done" << endreq;
+
+  output[totalSizeIndex] = output.size();
+  return true;
+}
+
+bool NavigationCore::serialize_DSonly( std::vector<uint32_t>& output, std::vector<unsigned int>& cuts, std::vector<std::pair<CLID, std::string> >& clid_name ) const {
+  
+  cuts.clear();
+  clid_name.clear();
+  
+  cuts.push_back(output.size()); // mark a cut place
+  
+  std::vector<uint32_t> headerBlob;
+  std::vector<uint32_t> dataBlob;
+
+  std::vector<std::pair<CLID, std::string> >::const_iterator cl_DS;
+  for ( cl_DS =  m_classesToPayload_DSonly.begin();  cl_DS != m_classesToPayload_DSonly.end(); ++cl_DS ) {
+    CLID clid = cl_DS->first;
+    std::string key = cl_DS->second;
+    MLOG(DEBUG) << "serialization (ordered) of feature attempting : " << clid << " " << key << endreq;
+    FeaturesStructureLabelIndexed::const_iterator clidIt = m_featuresByLabel.find(clid);
+    if ( clidIt != m_featuresByLabel.end() ) {
+      std::map<std::string, IHolder*>::const_iterator holderIt = clidIt->second.find(key);
+      if ( holderIt != clidIt->second.end() ) {
+	IHolder *holder = holderIt->second;
+	if ( ! holder ) {
+	  MLOG(DEBUG) << "serialization (ordered) of feature skipped, nothing know on this objects"  << endreq;
+	  continue;
+	}
+	MLOG(DEBUG) << "serialization (ordered) of feature: " << holder->typeClid() << " label: " << holder->label()
+		    << " size of payload: " << output.size() << endreq;
+	headerBlob.clear();
+	dataBlob.clear();
+	bool status = doSingleHolderSerialization(headerBlob, dataBlob, holder, m_serializerSvc, true );
+	addBlob( output, headerBlob, dataBlob );
+	clid_name.push_back(std::pair < CLID, std::string> (holder->typeClid(), holder->label()));
+	cuts.push_back(output.size()); // mark truncation point
+	MLOG(DEBUG) << "serialization of feature: " << holder->typeClid() << " label: " << holder->label()
+		    << " size of blob: " << headerBlob.size()+dataBlob.size() << " done with status: " << status << endreq;
+	//if (sizes) sizes->addObject(holder->collectionName(), holder->label(), dataBlob.size(), output.size() );
+      }
+    }
+  }
+  return true;
+}
+
+
+/*****************************************************************************
+ *
+ * DESERIALIZATION
+ *
+ *****************************************************************************/
+
+bool NavigationCore::deserialize( const std::vector<uint32_t>& input ) {
+  using namespace std;
+  std::vector<uint32_t>::const_iterator inputIt = input.begin();
+
+  if (input.size()==0) {
+    MLOG(WARNING) << "Cannot work on empty payload" << endreq;
+    return false;
+  }
+  unsigned int  version = *inputIt++; // ignore version
+
+  MLOG(DEBUG) << "deserialize: the serialized input has versions " << version << endreq;
+
+
+  if ( version != 3 and version !=4  ) {
+    MLOG(WARNING) << "No backward compatibility beyond version 3 possible; data was serialized with V: " << version
+                << " while we are in version 4" << endreq;
+    return true;
+  }
+  //  version += 0; // this is to shut up gcc
+  MLOG(DEBUG) << "deserialize: deserialization of Navigation version: " << version << endreq;
+
+  unsigned int totalSize =  *inputIt++; // total size
+  if ( totalSize != input.size() )
+    MLOG(WARNING) << "deserialize: the navigation is truncated: " << input.size()
+                  << " while should be: " << totalSize  << endreq;
+
+  if ( input.size() == 2 ) { // there was only space for version and size
+    MLOG(WARNING) << "deserialize: the navigation is truncated badly, no recovery possible "  << endreq;
+    return false;
+  }
+
+  unsigned int endOfChunk  = *inputIt++; // size of the chunk
+  //  std::cerr << "Deserialization ot the chunk: " << endOfChunk  << std::endl;
+
+  unsigned int size = *inputIt++;
+  MLOG(DEBUG) << "deserialize: Number of TEs: " << size  << endreq;
+  TriggerElement* previous = 0;
+  std::map<uint16_t, TriggerElement* > keys;
+
+  for ( unsigned int i = 0; i < size; ++i ) {
+
+    // create new TE
+
+    TriggerElement* te = m_factory.produce(TriggerElement::enquireId(inputIt)); //
+    te->deserialize(inputIt, keys, previous);
+    previous = te;
+    // keys table for deserialization of other TEs
+    keys[i] = te;
+
+  }
+
+  if ( not m_factory.empty() ) {
+
+    // rebuild  sameRoI relations (this can't be done by TEs deserialization)
+    TriggerElement* initialNode = getInitialNode();
+    std::vector<TriggerElement*>::const_iterator roiTEit;
+    for ( roiTEit = getDirectSuccessors(initialNode).begin(); 
+	  roiTEit != getDirectSuccessors(initialNode).end(); ++roiTEit ) {
+      fillSameRoIRelation((*roiTEit), (*roiTEit));
+    }
+  } else {
+    MLOG(INFO) << "deserialize: the navigation TEs structure is empty, initial Node is missing" << endreq;
+    return false;
+  }
+  
+
+  // EOF TEs deserialization
+  // deserialize Features
+  std::vector<uint32_t>::const_iterator it=input.begin();
+  advance(it, endOfChunk );
+  std::vector<uint32_t> blob;
+  while ( extractBlob(input, it, blob) ) {
+
+    CLID        clid;
+    uint16_t    idx;
+    std::string label;
+    //    IHolder::SerializationMethod sm;
+    std::vector<uint32_t>::const_iterator blobIt= blob.begin();
+
+    IHolder::enquireSerialized(blob, blobIt, clid, label, idx);
+    MLOG(VERBOSE) << "deserialize: extracted blob CLID: " << clid << " of size: " << blob.size()
+                  << " SubTypeIndex: " << idx << " Label: " << label << endreq;
+
+    
+    IHolder *holder(0);
+    if (! createHolder(holder, clid, label, idx) ) {
+      MLOG(ERROR) << "deserialize: Could not create holder for CLID " << clid
+                  << " this probably means that the package holding the class for this CLID was not compiled against the TrigNavigation package in use!"
+                  << endreq;
+      continue;
+      //return false;
+    }
+    
+    registerHolder(holder); // ??? check status
+
+    // now we have the blobIt pointing to the place where objects may start
+    // if so we ought to do deserialization
+    if ( blob.end() != blobIt ) {
+      if ( m_storeGate->transientContains(holder->containerClid(), holder->key()) ) {
+	
+        MLOG(DEBUG) << "deserialize: while working on: " << holder->collectionName()
+                    << " and key: " << holder->key()
+                    << " from serialized form found it in SG already, OK if running transient BS job, SG has priority" << endreq;
+
+        // remove obj from SG
+        holder->syncWithSG();
+        holder->clearSG();
+      }
+ 
+      {
+        std::vector<uint32_t>::const_iterator constEnd = blob.end();
+        std::vector<uint32_t> blobpart2(blobIt, constEnd);
+        //      std::vector<uint32_t>::const_iterator bit;
+
+        //      for ( bit = blobIt; bit != blob.end(); ++it ) {
+        //	blobpart2.push_back(*bit);
+        //      }
+        MLOG(DEBUG) << "deserialize: going to deserialize clid: " << clid << " from its collection: "
+                    << holder->containerClid() << endreq;
+
+        if (holder->containerClid()<1)
+          MLOG(WARNING) << "deserialize: cannot map to a collection type by holder->containerClid()" << endreq;
+
+	doSingleHolderDeserialization(blobpart2,holder,m_serializerSvc,m_storeGate,holder->key(),holder->containerClid(),version);
+      }
+      if ( !holder->syncWithSG() ) {
+        MLOG(WARNING) << "deserialize: after deserialization obejct not accessible though SG"  << endreq;
+      }
+    }
+
+
+  }
+  return true;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+bool NavigationCore::merge(const NavigationCore& l2) {
+  // we need to pick the holders which are at L2 and move them to EF
+  FeaturesStructureLabelIndexed::const_iterator clidIt;
+
+  for ( clidIt = l2.m_featuresByLabel.begin(); clidIt != l2.m_featuresByLabel.end(); ++clidIt ) {
+    CLID c = clidIt->first;
+    std::map<std::string, IHolder*>::const_iterator labelIt;
+    for ( labelIt = clidIt->second.begin(); labelIt != clidIt->second.end(); ++labelIt ) {
+      IHolder *l2holder = labelIt->second;
+      if ( m_log->level()<=MSG::DEBUG )
+        *m_log << MSG::DEBUG << "will add holder " << *l2holder << endreq;
+      std::string label(l2holder->label());
+      IHolder* efholder = getHolder(c, label);
+      if ( efholder != 0 ) {
+        if ( (efholder->label() != l2holder->label())
+             || (efholder->subTypeIndex() != l2holder->subTypeIndex()) ) {
+
+          if ( m_log->level()<=MSG::DEBUG )
+            *m_log << MSG::DEBUG << "fixing bug for " << *efholder <<    endreq;
+          // bug which we need to fix (some week of data in autumn 2008)
+          // we have to delete current holder
+          // and replace it by L2 one
+          //
+          // efholder->setSubTypeIndex(l2holder->subTypeIndex());
+
+          if ( m_log->level()<=MSG::DEBUG )
+            *m_log << MSG::DEBUG << "after fixing   " << *efholder <<    endreq;
+        }
+      } else {
+        if ( m_log->level()<=MSG::DEBUG )
+          *m_log << MSG::DEBUG << "cloning the holder from L2 " << *l2holder << endreq;
+        efholder = HLT::TypeMaps::holders()[c]->clone(l2holder->label(), l2holder->subTypeIndex());
+        efholder->prepare(m_log, m_storeGate);
+        registerHolder(efholder);
+      }
+    } // over labels
+  } // over CLIDS
+  return true;
+}
+
+
+
+
+
+
+
+
+
+/*****************************************************************************
+ *
+ * very important RESET
+ *
+ *****************************************************************************/
+void NavigationCore::reset() {
+  TrigNavStructure::reset();
+
+  // clear structure after previous event
+  FeaturesStructure::iterator featuresIt;
+  for ( featuresIt = m_featuresByIndex.begin(); featuresIt != m_featuresByIndex.end(); ++featuresIt ) {
+
+    std::map<uint16_t, IHolder*>::iterator subTypeIt;
+    for ( subTypeIt = featuresIt->second.begin(); subTypeIt != featuresIt->second.end(); ++subTypeIt ) {
+      if ( m_log->level()<=MSG::DEBUG )
+        *m_log << MSG::DEBUG << "Deleting holder for clid:" << featuresIt->first << " and sub type idx " << subTypeIt->first << endreq;
+      //	m_log*(subTypeIt->second) << endreq;
+      delete subTypeIt->second;
+      subTypeIt->second = 0;
+    }
+    //    featuresIt->second.clear();
+  }
+  m_featuresByIndex.clear();
+  m_featuresByLabel.clear();
+  if ( m_log->level()<=MSG::DEBUG )
+    *m_log << MSG::DEBUG << "Navigation reset done" << endreq;
+}
+
+uint16_t NavigationCore::nextSubTypeIndex(CLID clid, const std::string& /*label*/) {
+  // this is tricky (we need to find next free slot (subTypeIndex)
+  // For that we look at the last registered holder in the map indexed by type
+
+  // label actually does not matter here
+  //
+  if ( m_featuresByIndex[clid].size() == 0 )
+    return m_objectsIndexOffset;
+  return (--m_featuresByIndex[clid].end())->first+1;
+}
+
+
+
+HLTNavDetails::IHolder* NavigationCore::prepareOneHolder(CLID clid, const std::string& label) {
+
+  MLOG( VERBOSE ) << "NavigationCore::prepare preregistering objects of clid: " << clid << " label: " << label << endreq;
+  IHolder *holder = getHolder(clid, label);
+  if ( holder ) {    
+    MLOG( VERBOSE ) << "NavigationCore::prepare preregistering objects  not executed as it already exists " << *holder << endreq;
+    return holder;
+  }
+  
+  uint16_t index =  nextSubTypeIndex(clid, label);
+  if ( m_log->level() <= MSG::DEBUG )
+    MLOG( VERBOSE ) << "NavigationCore::prepare creating handler for type (CLID): " << clid
+			 << " label: " << label << " index: " << index << endreq;
+  
+  if ( !createHolder(holder, clid, label, index) ) {
+    MLOG( INFO ) << "NavigationCore::prepare Can't create storage for objects of CLID: " << clid << " as it is requested by configuration" << endreq;
+      return 0;
+  }
+
+  MLOG( VERBOSE ) << "Holder created, registering " << holder << " " << *holder << endreq;
+
+  if ( !registerHolder(holder) ) {
+    MLOG( WARNING ) << "Holder registration failed " << holder << " " << *holder << endreq;
+    return 0;
+  }
+  if ( !holder->syncWithSG() ) {
+    MLOG( WARNING ) << "Holder SG sync failed" << holder << " " << *holder << endreq;
+    return 0;
+  }
+  
+  return holder;
+}
+
+void NavigationCore::prepare() {
+
+  if ( m_log->level()<=MSG::DEBUG ) {
+    HLT::TypeMaps::CLIDtoHolderMap::const_iterator hIt;
+    for ( hIt = HLT::TypeMaps::holders().begin(); hIt != HLT::TypeMaps::holders().end(); ++hIt ) {
+      MLOG( VERBOSE ) << "NavigationCore::prepare Compile time known types : " << *(hIt->second) << endreq;
+    }
+  }
+  
+  MLOG( VERBOSE ) << "NavigationCore::prepare Preregistering objects #:" <<  m_classesToPreregister.size()<< endreq;
+  // populate structure with "must have" features
+
+  std::vector<std::pair<CLID, std::string> >::const_iterator confIt;
+  for ( confIt = m_classesToPreregister.begin(); confIt != m_classesToPreregister.end() ; ++confIt ) {
+    CLID clid = confIt->first;
+    std::string label  = confIt->second;
+    if ( prepareOneHolder(clid, label) == 0 ) {
+      MLOG( WARNING  )<< "NavigationCore::prepare failed preparing the holder for CLID: " << clid << " and label " << label << endreq;
+    }
+  }
+
+  MLOG( DEBUG  )<< "NavigationCore::prepare Navigation structure prepared for next event" << endreq;
+}
+
+bool NavigationCore::registerHolder(IHolder* holder) {
+  /*  if ( syncWithSG )
+      if (  ! holder->syncWithSG() ) {
+      *m_log << MSG::WARNING << "createHolder: super-container can't be recorded to SG for CLID:" << holder->typeClid()  << " and label: " << holder->label() << " sub type index: " << holder->subTypeIndex() << endreq;
+      // return false;
+      }
+  */
+  if ( m_featuresByLabel.count(holder->typeClid()) != 0 || m_featuresByIndex.count(holder->typeClid()) != 0 ) {
+    if (m_featuresByIndex[holder->typeClid()].count(holder->subTypeIndex()) != 0
+        || m_featuresByLabel[holder->typeClid()].count(holder->label()) != 0 ) {
+      *m_log << MSG::WARNING << "registerHolder registration failing, there are already registered ones (in byIndex map): "
+             << m_featuresByIndex[holder->typeClid()].count(holder->subTypeIndex())
+             << " OR (byLabel map): " << m_featuresByLabel[holder->typeClid()].count(holder->label()) << endreq;
+      return false;
+    }
+  }
+
+  m_featuresByIndex[holder->typeClid()][holder->subTypeIndex()] = holder;
+  m_featuresByLabel[holder->typeClid()][holder->label()] = holder;
+  m_lookupLabels[holder->typeClid()][holder->subTypeIndex()] = holder->label();
+  *m_log << MSG::DEBUG <<  "registerHolder for OK " << *holder << endreq;
+  return true;
+}
+
+
+
+bool NavigationCore::createHolder( IHolder*& holder,  CLID clid, const std::string& label, uint16_t index) {
+  if ( HLT::TypeMaps::holders().count(clid) == 0 ) {
+    if (m_log->level()<=MSG::ERROR)
+      *m_log << MSG::ERROR << "createHolder: holder can't be done, no predefined storage found for CLID: " << clid << endreq;
+    //    throw std::runtime_error("Can not find predefined storage of clid: " + boost::lexical_cast<std::string>(clid) +" and label: " + label );
+    return false;
+  }
+
+  holder = HLT::TypeMaps::holders()[clid]->clone(label, index);
+  //  holder->prepare(m_log, m_storeGate, getAux(label));
+  holder->prepare(m_log, m_storeGate);
+  holder->setObjectsKeyPrefix(m_objectsKeyPrefix);
+
+  if (m_log->level()<=MSG::DEBUG)
+    *m_log << MSG::DEBUG << "createHolder: holder prepared " << *holder << endreq;
+
+
+  return true;
+}
+
+
+
+
+IHolder* NavigationCore::getHolder(CLID clid, uint16_t subTypeIndex) const {
+  FeaturesStructure::const_iterator clidIt = m_featuresByIndex.find(clid);
+  if ( clidIt ==  m_featuresByIndex.end() )
+    return 0;
+  std::map<uint16_t, IHolder*>::const_iterator indexIt = clidIt->second.find(subTypeIndex);
+  if ( indexIt == clidIt->second.end() ) {
+    return 0;
+  }
+  return indexIt->second;
+}
+
+IHolder* NavigationCore::getHolder(CLID clid, const std::string& label) const {
+  FeaturesStructureLabelIndexed::const_iterator clidIt = m_featuresByLabel.find(clid);
+  if ( clidIt ==  m_featuresByLabel.end() )
+    return 0;
+  std::map<std::string, IHolder*>::const_iterator labelIt = clidIt->second.find(label);
+  if ( labelIt == clidIt->second.end() ) {
+    return 0;
+  }
+  return labelIt->second;
+}
+
+bool NavigationCore::toBePutToPayload(const HLTNavDetails::IHolder* holder) const {
+  std::string option = holder->typeName()+"#"+holder->key();
+  //std::string option = holder->typeName();
+  std::vector<std::string>::const_iterator it;
+  it = find(m_classesToPayloadProperty.begin(), m_classesToPayloadProperty.end(), option);
+  if (it != m_classesToPayloadProperty.end() )
+    return true;
+  return false;
+}
+
+void NavigationCore::tweakMsgLvl(int newOffset) {
+  //  m_msgLvlOffset = newOffset;
+  m_log->setLevel(newOffset);
+}
+
+void NavigationCore::testMsgService() const {
+  if (m_log) {
+    MLOG(DEBUG) << "MLOG printout" << endreq;
+    *m_log << MSG::FATAL << "MSG::FATAL" << MSG::FATAL << endreq;
+    *m_log << MSG::ERROR << "MSG::ERROR " << MSG::ERROR << endreq;
+    *m_log << MSG::WARNING << "MSG::WARNING " << MSG::WARNING << endreq;
+    *m_log << MSG::INFO << "MSG::INFO " << MSG::INFO << endreq;
+    *m_log << MSG::DEBUG << "MSG::DEBUG " << MSG::DEBUG << endreq;
+    *m_log << MSG::VERBOSE << "MSG::VERBOSE " << MSG::VERBOSE <<endreq;
+    *m_log << MSG::INFO << "MSG level()=" << m_log->level() << endreq;
+  } else {
+    std::cerr << "ERROR -> No MessageSvc available !" << std::endl;
+  }
+}
+
+
+
+uint32_t  NavigationCore::string2hash( const std::string& s, const std::string& category) {
+  return TrigConf::HLTUtils::string2hash(s, category);
+}
+
+void NavigationCore::getAllOfType ( const std::string& id, std::vector< HLT::TriggerElement* >& output,
+                                    const bool activeOnly) const {
+  if ( id == "" )
+    return getAll(output, activeOnly);
+  
+  return TrigNavStructure::getAllOfType( string2hash(id, "TE"), output, activeOnly);
+}
+
+
+/*
+std::vector< std::string >
+NavigationCore::getFeatureSGLabelAndPosition( std::string featureClassName, const TriggerElement* te,
+                                              const std::string& label)
+{
+  return getFeatureSGLabelAndPosition( HLT::TypeMaps::type2clid()[featureClassName], te, label);
+}
+
+std::vector< std::string >
+NavigationCore::getFeatureSGLabelAndPosition( unsigned int clid, const TriggerElement* te,
+                                              const std::string& label)
+{
+  std::vector< std::string > result;
+
+  MLOG(DEBUG) << "got CLID: " << clid << endreq;
+  // now look into the TriggerElement to get from it AccessHelpers (look only at features reated to this TE)
+  // bool found = false;
+  std::vector< TriggerElement::FeatureAccessHelper >::const_iterator it;
+  for ( it = te->getFeatureAccessHelpers().begin(); it != te->getFeatureAccessHelpers().end(); ++it ) {
+    MLOG(DEBUG) << "got Feature ObjectIndex " << *it << endreq;
+
+    if ( it->getCLID() == clid ) { // CLID is matching
+      // remember an index (in holder vector)
+      //uint16_t subTypeIndex = TriggerElement::ObjectIndex(it->getIndex()).subTypeIndex();
+
+      uint16_t   subIndex = it->getIndex().subTypeIndex();
+
+      MLOG(DEBUG) << "found label = " << m_lookupLabels[clid][subIndex] << endreq;
+
+      if ( label == m_lookupLabels[clid][subIndex] or label =="") {
+        // insert all entries:
+        for (unsigned int i = it->getIndex().objectsBegin();
+             i < it->getIndex().objectsEnd(); ++i ) {
+          std::ostringstream ss;
+          ss << "HLT_" << m_lookupLabels[clid][subIndex] << "::" << i;
+          result.push_back( ss.str() );
+        }
+        // found = true;
+      }
+
+    }
+  }
+  return result;
+}
+
+std::vector< std::string >
+NavigationCore::getRecentFeatureSGLabelAndPosition( unsigned int clid, const TriggerElement* te,
+                                                    const std::string& label)
+{
+  // start from given TriggerElement
+  std::vector< std::string > result = getFeatureSGLabelAndPosition(clid, te, label);
+
+  if ( !result.empty() ) {
+    MLOG(DEBUG) << "getRecentFeatureSGLabelAndPosition: found one in: " << te->getId()  << endreq;
+    return result; // end of our search
+  }
+  if ( isRoINode(te) ) {
+    return result;    // do not search deeper
+  } else { // here the logic needed if the feature was not found attached to the current TE
+    std::vector<TriggerElement*>::const_iterator it;
+    for ( it = getDirectPredecessors(te).begin(); it != getDirectPredecessors(te).end(); ++it ) {
+      MLOG(DEBUG) << "getRecentFeatureSGLabelAndPosition: searching deeper in TE: " << (*it)->getId()  << endreq;
+
+      std::vector< std::string > result2 = getRecentFeatureSGLabelAndPosition(clid, *it, label );
+
+      if ( !result2.empty() )
+        return result2; // found feature in subtree of one of the predecessors
+    }
+  }
+  return result;
+}
+
+std::vector< std::string >
+NavigationCore::getRecentFeatureSGLabelAndPosition( std::string featureClassName, const TriggerElement* te,
+						    const std::string& label)
+{
+  return getRecentFeatureSGLabelAndPosition( type2clid()[featureClassName], te, label);
+}
+
+
+
+std::vector< unsigned int >
+NavigationCore::getFeatureContainerPosition( unsigned int clid, const TriggerElement* te,
+                                             const std::string& label)
+{
+  std::vector<unsigned int > result;
+
+  MLOG(DEBUG) << "got CLID: " << clid << endreq;
+  // now look into the TriggerElement to get from it AccessHelpers (look only at features reated to this TE)
+  // bool found = false;
+  std::vector< TriggerElement::FeatureAccessHelper >::const_iterator it;
+  for ( it = te->getFeatureAccessHelpers().begin(); it != te->getFeatureAccessHelpers().end(); ++it ) {
+    MLOG(DEBUG) << "got Feature ObjectIndex " << *it << endreq;
+
+    if ( it->getCLID() == clid ) { // CLID is matching
+      // remember an index (in holder vector)
+      //uint16_t subTypeIndex = TriggerElement::ObjectIndex(it->getIndex()).subTypeIndex();
+
+      uint16_t   subIndex = it->getIndex().subTypeIndex();
+
+      MLOG(DEBUG) << "found label = " << m_lookupLabels[clid][subIndex] << endreq;
+
+      if ( label == m_lookupLabels[clid][subIndex] ) {
+        // insert all entries:
+        for (unsigned int i = it->getIndex().objectsBegin();
+             i < it->getIndex().objectsEnd(); ++i )
+          result.push_back( i );
+        // found = true;
+      }
+
+    }
+  }
+  return result;
+}
+
+std::vector< unsigned int >
+NavigationCore::getFeatureContainerPosition( std::string typeName, const TriggerElement* te,
+                                             const std::string& label)
+{
+  return getFeatureContainerPosition(type2clid()[typeName], te, label);
+}
+
+
+std::vector< HLT::FeatureDescriptor >
+NavigationCore::getFeatureContainerPosition( unsigned int clid, const TriggerElement* te)
+{
+  std::vector< HLT::FeatureDescriptor > result;
+
+  MLOG(DEBUG) << "got CLID: " << clid << endreq;
+  // now look into the TriggerElement to get from it AccessHelpers (look only at features reated to this TE)
+  // bool found = false;
+  std::vector< TriggerElement::FeatureAccessHelper >::const_iterator it;
+  for ( it = te->getFeatureAccessHelpers().begin(); it != te->getFeatureAccessHelpers().end(); ++it ) {
+    MLOG(DEBUG) << "got Feature ObjectIndex " << *it << endreq;
+
+    if ( it->getCLID() == clid ) { // CLID is matching
+      // remember an index (in holder vector)
+      //uint16_t subTypeIndex = TriggerElement::ObjectIndex(it->getIndex()).subTypeIndex();
+      //      unsigned int index = it->getIndex();
+      uint16_t   subIndex = it->getIndex().subTypeIndex( );
+      std::string label( m_lookupLabels[clid][subIndex] );
+
+      MLOG(DEBUG) << "found label = " << label << endreq;
+
+      result.push_back( FeatureDescriptor(label, it->getIndex().objectsBegin(),
+                                          it->getIndex().objectsEnd()) );
+      // found = true;
+
+    }
+  }
+  return result;
+}
+
+
+std::vector< HLT::FeatureDescriptor >
+NavigationCore::getFeatureContainerPosition( std::string typeName, const TriggerElement* te)
+{
+  return getFeatureContainerPosition(type2clid()[typeName], te);
+}
+
+
+std::pair<std::string, std::string> NavigationCore::getClassContainerNames(unsigned int clid) const
+{
+  IHolder* h = getHolder(clid, 0); 
+  if (h) {
+    return std::make_pair( h->typeName(), h->collectionName() );
+  } else {
+    return std::make_pair( "", "" );
+  }
+}
+*/
+
+void NavigationCore::testStaticMaps()
+{
+  *m_log << MSG::INFO << "print statis map: CLID -> class name "  << endreq;
+  for ( static HLT::TypeMaps::NametoCLIDMap::const_iterator it = HLT::TypeMaps::type2clid().begin();
+	it != HLT::TypeMaps::type2clid().end(); ++it) {
+    *m_log << MSG::INFO << "entry: " << (*it).first << " -> " << (*it).second << endreq;
+  }
+
+  *m_log << MSG::INFO << "print statis map: CLID -> holder "  << endreq;
+  for ( static HLT::TypeMaps::CLIDtoHolderMap::const_iterator it = HLT::TypeMaps::holders().begin();
+	it != HLT::TypeMaps::holders().end(); ++it) {
+    *m_log << MSG::INFO << "entry: " << (*it).first << " -> " << (* (*it).second) << endreq;
+  }
+
+}
+
+void NavigationCore::setAccessProxy(AccessProxy* ap) {
+  m_storeGate = ap;
+}
+
+AccessProxy* NavigationCore::getAccessProxy() const {
+  return m_storeGate;
+}
+
+void NavigationCore::setObjKeyPrefix(const std::string& k) {
+  m_objectsKeyPrefix = k;
+}
+
+bool NavigationCore::getFeatureAccessors( const TriggerElement* te, CLID clid, const std::string& label,
+                                          bool only_single_feature,
+                                          TriggerElement::FeatureVec& features,
+                                          bool with_cache_recording,
+                                          bool travel_backward_recursively,
+                                          const TriggerElement*& source,
+                                          std::string& sourcelabel ) {
+
+  MLOG(VERBOSE) << "getFeatureAccessors: looking for:" << (only_single_feature ? "one object" : "many objects" ) << " of CLID: " << clid
+                << " label: \"" << label << "\""
+                << " starting from TE: " << te->getId() << (with_cache_recording ? " with cache recording" : " without cache recording")<< endreq;
+  // start cache
+
+  //std::auto_ptr<HLT::RoICacheHistory::QuestionScope> qscope( with_cache_recording ? new  : 0);
+  HLT::RoICacheHistory::QuestionScope qscope( with_cache_recording
+                                              ? HLT::RoICacheHistory::QuestionScope(te, clid, label, this, only_single_feature)
+                                              : HLT::RoICacheHistory::QuestionScope() );
+
+  // record ending point (not this method is called recursivelly)
+
+  int size = te->getFeatureAccessHelpers().size(), it;
+
+  // loop the feature access helper in order depending of type of request (i.e. if single featyure needed then loop from back, if all then loop from the front)
+  for ( it = ( only_single_feature ? size-1 : 0 ); it != (only_single_feature ? -1 : size ); only_single_feature ? it--: it++ ) {
+    //for ( it = 0; it < size; ++it ) {
+    const TriggerElement::FeatureAccessHelper& fea = te->getFeatureAccessHelpers().at(it);
+    MLOG(VERBOSE) << "getFeatureAccessors: in a loop over FeatureAccessHelpers got ObjectIndex " << fea << endreq;
+
+
+    if ( fea.getCLID() == clid ) { // CLID is matching
+      // remember an index (in holder vector)
+      TriggerElement::ObjectIndex objectIndex(fea.getIndex());
+      HLTNavDetails::IHolder *holder = getHolder(clid, objectIndex.subTypeIndex());
+      if  (! holder ) {
+        MLOG(WARNING) << "getFeatureAccessors: feature of clid: " << clid <<  " and index: " << objectIndex.subTypeIndex()
+                      << " not available. Probably not recorded. Navigation structure inconsistent. " << endreq;
+        continue;
+      }
+
+      // now do labels matching
+      // "" (empty) label means all match
+      // "!" in the label means the collection having exactly empty label
+      // otherwise if label is provided it needs to match exactly
+      if (label.empty() || (label == "!" &&  holder->label().empty()) || label == holder->label() ) {
+        sourcelabel = holder->label();       
+        source = te;
+        features.push_back(fea);
+        if ( with_cache_recording )  HLT::RoICacheHistory::instance().addAnswer(te, fea);
+	
+        MLOG(DEBUG) << "getFeatureAccessors: matching feature found in te: " << *te << " index: " << fea << endreq;
+        // now the ending (depends on the "single" flag)
+        if ( only_single_feature )
+          break;
+      }
+    }
+  } // end of loop over feature access helpers of this TE
+
+  if ( ! travel_backward_recursively ) {
+    return true;
+  }
+
+  // stop digging deeper if this is an RoI node already
+  if ( isRoINode(te) ) {
+    return true;
+  }
+
+  // return if a feature(s) is/are found
+  if ( ! features.empty() ) {
+    return true;
+  }
+
+
+  // recurse deeper
+
+
+  // but recurse only when unambiguous
+  //if ( (label.empty() || only_single_feature ) &&  getDirectPredecessors(te).size() > 1  ) {
+  bool recursion_status = true;
+  for( TriggerElement* predecessor: getDirectPredecessors(te) ) {
+     
+    TriggerElement::FeatureVec features_in_branch;
+    recursion_status = recursion_status && getFeatureAccessors( predecessor, clid, label, only_single_feature, features_in_branch,
+                                                                with_cache_recording, travel_backward_recursively, source, sourcelabel);
+    features.insert(features.end(),  features_in_branch.begin(), features_in_branch.end());
+  }
+    
+  if ( only_single_feature &&  ( features.size() > 1 || recursion_status == false) ) {
+    MLOG(DEBUG) << "getFeatureAccessors: looking for object of CLID: " << clid
+                << " label: \"" << label << "\"" << " found several objects matching criteria while can only return back one, this is ambiguous" << endreq;
+      
+    if ( getDirectPredecessors(te).size() > 1 ) // mark bifurcation point as to where one can start again
+      source = te;
+
+    return false;
+  }
+  return true;
+}
+
+#undef MLOG
diff --git a/Trigger/TrigEvent/TrigNavigation/src/RoICacheHelper.cxx b/Trigger/TrigEvent/TrigNavigation/src/RoICacheHelper.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..a7dd989f0c9bb92b5a6245fa489f7c08f3872742
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/src/RoICacheHelper.cxx
@@ -0,0 +1,295 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "TrigConfHLTData/HLTTriggerElement.h"
+#include "TrigNavigation/Navigation.h"
+#include "AthenaKernel/getMessageSvc.h"
+
+#include "TrigNavigation/RoICacheHelper.h"
+
+/*****************************************************************************
+ *
+ * CACHING
+ *
+ *****************************************************************************/
+
+
+using namespace HLT;
+enum RoICacheHelper::CachingMode RoICacheHelper::s_cachingMode=RoICacheHelper::HistoryBased;
+
+bool RoICacheHelper::cache ( TriggerElement* te ) {
+  std::vector<struct CacheEntry>::iterator it;
+
+  // look into cache entries for cache holding same RoI
+  it = find(m_caches.begin(), m_caches.end(), te); // we have overloaded operator==
+
+  // nothing found, we run on this RoI for the first time (while we shouldn't)
+  if ( m_caches.end() == it ) { // we need to start up new cache but we can't do so here
+    return false;
+  } else {
+    if ( it->holder() == 0 ) {
+      return false;
+    }
+    // do caching
+    // real caching happens here
+    //std::vector< TriggerElement::FeatureAccessHelper >::const_iterator b = it->holder()->getFeatureAccessHelpers().begin();
+    //    advance(b, it->begin());
+    
+    //    std::vector< TriggerElement::FeatureAccessHelper >::const_iterator e = it->holder()->getFeatureAccessHelpers().begin();
+    //    advance(e, it->end());
+    
+    //    std::cerr << "caching now: " << it->begin() << " " << it->end() << std::endl;
+    const TriggerElement::FeatureVec& fvec = it->holder()->getFeatureAccessHelpers();
+
+    if ( fvec.size() < it->end()  || it->begin() > it->end()  ) {
+      return false;
+    }
+    
+    for ( unsigned int i = it->begin() ; i < it->end(); i++ ) {
+      te->addFeature(it->holder()->getFeatureAccessHelpers()[i]);
+    }
+    //    te->getFeatureAccessHelpers().insert(te->getFeatureAccessHelpers().end(), b, e);
+    //    te->featuresKeyPrint().insert(te->featuresKeyPrint().end(), b, e);
+    //    std::cerr << "after caching size: " << te->getFeatureAccessHelpers().size() << std::endl;
+  }
+
+  return true;
+}
+
+
+bool RoICacheHelper::isInputAccepted ( const TriggerElement* te ) {
+  std::vector<struct CacheEntry>::iterator it;
+  it = find(m_caches.begin(), m_caches.end(), te);
+  if ( m_caches.end() != it ) {
+    if (it->holder())
+      return true;
+    return false;
+  }
+  return false;
+}
+
+bool RoICacheHelper::needsExecution ( const TriggerElement* te ) {
+  std::vector<struct CacheEntry>::iterator it;
+  it = find(m_caches.begin(), m_caches.end(), te);
+  if ( m_caches.end() == it ) {
+    m_caches.push_back( CacheEntry(te) );
+    return true;
+  }
+  return false;
+}
+
+
+bool RoICacheHelper::startCaching( const TriggerElement* te ) {
+  //  we have to start caching, last entry (back()) in m_caches is the right place to do that
+  if ( te != m_caches.back().holder() )
+    return false;
+
+  RoICacheHistory::instance().startHistory(te);
+
+  m_caches.back().start( te->getFeatureAccessHelpers().size() );
+  return true;
+}
+
+bool RoICacheHelper::stopCaching( const TriggerElement* te ) {
+  // we have to save cache, last entry (back()) in m_caches is the started cache
+  CacheEntry &cache = m_caches.back();
+
+  if ( te != cache.holder() )
+    return false;
+
+  cache.add(RoICacheHistory::instance().getFeatureCalls());
+  /*
+  // print the history
+  std::vector<RoICacheHistory::Question>::const_iterator histIt;
+  for ( histIt = RoICacheHistory::instance().getQuestions().begin(); histIt != RoICacheHistory::instance().getQuestions().end(); ++histIt ) {
+  std::cout << "Objects access HISTORY: label: " << histIt->label() 
+  << " work: "  << histIt->getWorkTE() << std::endl;
+  if (histIt->getAnswers().empty()) 
+  std::cout << "Objects access HISTORY: got back nothing for clid: " << histIt->clid() << " and label " << histIt->label() << std::endl;
+  TriggerElement::FeatureVec::const_iterator feaIt;
+  for ( feaIt = histIt->getAnswers().begin(); feaIt != histIt->getAnswers().end(); ++feaIt ) {
+  const TriggerElement::FeatureAccessHelper& fea = *feaIt;
+  std::cout << "Objects access HISTORY: got back: " << fea << std::endl;
+  }
+  }
+  */
+  RoICacheHistory::instance().stopHistory();
+
+  cache.finish( te->getFeatureAccessHelpers().size() );
+  return true;
+}
+
+void RoICacheHelper::reset() {
+  m_caches.clear();
+}
+
+/*
+void printObjects(MsgStream* mlog, const TriggerElement* cache, const TriggerElement* te) {
+  if (mlog && mlog->level( ) <= MSG::DEBUG) {    
+    std::string l1; 
+    TrigConf::HLTTriggerElement::getLabel(te->getId(), l1);
+    std::string l2; 
+    TrigConf::HLTTriggerElement::getLabel(cache->getId(), l2);
+
+    (*mlog) << MSG::DEBUG << "found objects in querried TE: " << l1 << " in already executed (cache): " << l2 << endreq;
+    (*mlog) << MSG::DEBUG << "cache had : " <<cache->getPreviousFeatures().size() 
+	    << " while TE has: " << te->getPreviousFeatures().size() << endreq;
+    unsigned int i;
+    for ( i = 0 ; i < te->getPreviousFeatures().size(); ++i ) {
+      (*mlog) << MSG::DEBUG 
+	      << (te->getPreviousFeatures()[i] == cache->getPreviousFeatures()[i] ? "==": "!!")
+	      << "this TE " << te->getPreviousFeatures()[i] << " in cache: "  << cache->getPreviousFeatures()[i] 
+	      << endreq;
+    }  
+  }
+}
+*/
+// cache entry methods
+
+bool RoICacheHelper::CacheEntry::operator== (const std::vector<TriggerElement*>& roite) const {
+  return m_rois == std::set<const TriggerElement*>(roite.begin(), roite.end());
+}
+/*
+void xx_print( MsgStream& log, const TriggerElement::FeatureVec& fe, const std::string& prefix) {
+  
+  TriggerElement::FeatureVec::const_iterator i;
+  for ( i = fe.begin(); i != fe.end(); ++i ) {
+    log << MSG::DEBUG << prefix << " " << *i << endreq;
+  }
+}
+*/
+
+bool RoICacheHelper::CacheEntry::operator== (const TriggerElement* curr) const {
+  if (s_cachingMode == None)
+    return false;
+  
+
+  // check if set of RoIs is identical
+  const std::vector<TriggerElement*> &tvec = TrigNavStructure::getRoINodes(curr);
+  if ( m_rois != std::set<const TriggerElement*>(tvec.begin(), tvec.end()) ) {
+    return false;
+  }
+  if ( s_cachingMode == RoIOnly )
+    return true;
+
+  // Strict check: use all features in previous TEs
+  if ( s_cachingMode == AllObjects ) {
+    if (curr->getPreviousFeatures().size() != m_cacheHolder->getPreviousFeatures().size() - (m_cacheHolder->getFeatureAccessHelpers().size() - begin()) ) {
+      return false;
+    }
+    
+    if ( std::equal(curr->getPreviousFeatures().begin(), curr->getPreviousFeatures().end(),
+                    m_cacheHolder->getPreviousFeatures().begin()) ) {
+      return true;
+    }
+
+    return false;
+  }
+  
+  // History based check
+  if ( s_cachingMode != HistoryBased )
+    return false;
+  
+  // No history... no future
+  if(m_questions.empty()) {
+    //    MsgStream log(Athena::getMessageSvc(), "RoICacheHelper");
+    //    log << MSG::DEBUG << "No history available in this RoI, algorithms did not request any objecrs, safer not to cache" << endreq;
+    return false;
+  }
+
+  // The big loop below is repeating the same querries (getFeture(s) calls)
+  //   as on RoI as were done originaly by the running algorithm.
+  // This querries were recorded together with answers.
+  // When repeated now, any divergence in answering the same questions is good reason to run algorithm again.
+  // When the loop goes to the end it means all the answers were identical as when we run for the first time.
+  // Then thre is no reason to run algorithm again and only objects should be reattached.
+
+
+  // Need navigation to answer questions
+  NavigationCore *navig = RoICacheHistory::instance().getNavigation();
+  if(!navig) return false;
+
+  const std::vector<TriggerElement*> &pvec = TrigNavStructure::getDirectPredecessors(curr);
+
+  // Start of the loop over previoisly asked quiestions.
+  for(FeatureCallVec::const_iterator it = m_questions.begin(); it != m_questions.end(); ++it) {
+    if ( !it->isget() )
+      continue;
+
+    FeatureVec fvec;
+
+
+    if(it->getInitTE() == it->getWorkTE()) {
+      // History starts at the same TE (i.e. getFeature was called on outputTE in Fex)
+      // We ask again the same question (giving the same clid and label)
+      navig->getFeatureAccessors(curr, it->clid(), it->label(), it->issingle(), fvec, false, true);
+    } else if(pvec.size() == 1) {
+      // Check relationship at cached TE
+      const std::vector<TriggerElement*> &iwvec = TrigNavStructure::getDirectPredecessors(it->getWorkTE());
+      if(iwvec.size() != 1 || iwvec[0] != it->getInitTE()) {
+        // Should never happen - answers always come from single pred.
+        return false;
+      }
+      
+      // History starts at the previous TE (i.e. getFeature was called on inputTE in Fex)
+      navig->getFeatureAccessors(pvec[0], it->clid(), it->label(), it->issingle(), fvec, false, true);
+    } else {
+      // Previous history not unique (i.e. the navigaiton tree was traversed in some custom way in Fex)
+      return false;
+    }
+
+    // check if getFeature was called rather than getFeature*s*
+    if ( it->issingle()) {
+      
+      if(  it->getAnswers().empty()  ) {
+        // the answer in first case was empty - it means no feature was found
+        // It is fine if the answer was also empty this time.
+        if ( fvec.empty() ) {
+          continue;
+        } else {
+          // Else we need running. In first pass Fex could not get this object while now can. Clearly it would do different thing now.
+          return false;
+        }
+      } else {
+        if (fvec.empty())
+          return false; // This is inverted situation, frist time we got answer, but not this case, again we need to to run.
+	
+        // Now we need to do fancy check
+        // In first pass and now we got some answers (features found) we need to check if they would be the same ...
+        // but not compleetly, i.e. only as many objects as were of interest first time (i.e. one)
+        if ( !std::equal(it->getAnswers().begin(), it->getAnswers().end(), fvec.begin()) ) {
+          return false;
+          //	  MsgStream log(Athena::getMessageSvc(), "RoICacheHelper");
+          //	  	  log << MSG::DEBUG << "single history differs: " << fvec.size() << " " <<  it->getAnswers().size() << endreq;
+          //	  	  xx_print(log, fvec,             "questions");
+          //	  	  xx_print(log, it->getAnswers(), "in cache ");
+        }
+      }
+    } else {
+      // This is case for getFeature*s* (many features requested)
+      // First of all need to check if the number of objects is the same.
+      if( fvec.size() !=  it->getAnswers().size() ) {
+        //		MsgStream log(Athena::getMessageSvc(), "RoICacheHelper");
+        //		log << MSG::DEBUG << "history sizes incompatible this time: " << fvec.size() << " " <<  it->getAnswers().size() << endreq;
+        //		xx_print(log, fvec,             "questions");
+        //		xx_print(log, it->getAnswers(), "in cache ");
+        return false;
+      }
+      
+      // if number of objects is the same we need to check if the answers (features) we obtain now woudl be the same as in first pass
+      if ( fvec !=  it->getAnswers() ) {
+        //		MsgStream log(Athena::getMessageSvc(), "RoICacheHelper");
+        //		log << MSG::DEBUG << "history differs" << endreq;
+        //		xx_print(log, fvec,             "questions");
+        //		xx_print(log, it->getAnswers(), "in cache ");
+        return false;
+      }
+    }
+    
+  }
+  //    MsgStream log(Athena::getMessageSvc(), "RoICacheHelper");
+  //    log << MSG::DEBUG << "history the same, yesss" << endreq;
+
+  return true;
+}
diff --git a/Trigger/TrigEvent/TrigNavigation/src/RoICacheHistory.cxx b/Trigger/TrigEvent/TrigNavigation/src/RoICacheHistory.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..0c6d20c2da87bbfa3d4ab15057f6635a97dc2aab
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/src/RoICacheHistory.cxx
@@ -0,0 +1,168 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include <stdexcept>
+#include <boost/lexical_cast.hpp>
+
+#include "TrigNavigation/RoICacheHistory.h"
+
+//-----------------------------------------------------------------------------
+HLT::RoICacheHistory& HLT::RoICacheHistory::instance() {
+  static RoICacheHistory instance;
+  return instance;
+}
+
+//-----------------------------------------------------------------------------
+void HLT::RoICacheHistory::addAnswer(const TriggerElement* te, const TriggerElement::FeatureAccessHelper &f)
+{
+  if ( m_collect ) {
+    if (  m_current.isValid() ) {
+      m_current.addAnswer(te, f);
+    } else {
+      throw std::runtime_error("HLT caching problem: " + boost::lexical_cast<std::string>(te->getId()) );
+    }
+  }
+}
+
+//-----------------------------------------------------------------------------
+void HLT::RoICacheHistory::stopCurrentFeatureCall()
+{
+  if ( m_collect ) {
+    if (  ! m_current.isValid() ) {     
+      throw std::runtime_error("HLT caching problem: invalid current question" );
+    } else {
+      //      std::cout << "RoICacheHistory stopping feature call: " << m_current.isget() << std::endl;
+      if ( !m_current.isget() ) {
+	m_questions.push_back(m_current);
+      } else {
+	// traverse back the questions
+	bool local = false;
+	for ( unsigned i = 0, j = m_questions.size(); i < j ; i++ ) {
+	  //	  std::cout << "RoICacheHistory traversing back local history isget: " <<m_questions[i].isget() << std::endl;
+	  if ( !m_questions[i].isget()) {
+	    //	    std::cout << "RoICacheHistory encountered algo dooing attach before get" << std::endl;
+	    if ( m_current.getAnswers() == m_questions[i].getAnswers()){
+	      local = true;
+	      //	      std::cout << "RoICacheHistory algorithm asking for object which is creating itself, ignoring" << std::endl;
+	      break;
+	    }
+	  }
+	}
+	if (!local)
+	  m_questions.push_back(m_current);
+      }
+      m_current.reset();
+    }
+  } else {
+    throw std::runtime_error("HLT caching problem: question not collected" );
+  }
+}
+
+//-----------------------------------------------------------------------------
+void HLT::RoICacheHistory::setCurrentFeatureCall(const FeatureCall &curr, NavigationCore *navig)
+{  
+  if(m_current.isValid()) {
+    throw std::runtime_error("HLT caching problem: current question is valid" );
+  } else {
+    m_current = curr;
+    m_navigation = navig;
+  }
+}
+
+//-----------------------------------------------------------------------------
+HLT::RoICacheHistory::FeatureCall::FeatureCall(const TriggerElement* work, const TriggerElement* te, CLID clid, const std::string& label, bool issingle, bool isget) 
+  :m_init(te),
+   m_work(work),
+   m_clid(clid),
+   m_label(label),
+   m_issingle(issingle),
+   m_isget(isget) {
+}
+
+//-----------------------------------------------------------------------------
+HLT::RoICacheHistory::FeatureCall::FeatureCall() 
+  :m_init(0),
+   m_clid(0),
+   m_issingle(false),
+   m_isget(false) {
+}
+
+//-----------------------------------------------------------------------------
+void HLT::RoICacheHistory::FeatureCall::addAnswer(const TriggerElement* /*te*/, const TriggerElement::FeatureAccessHelper&f)
+{
+  m_answers.push_back(f);
+}
+
+//-----------------------------------------------------------------------------
+void HLT::RoICacheHistory::FeatureCall::reset() 
+{
+  // Complete reset
+  m_init = 0;
+  m_label.clear();
+  m_answers.clear();
+}
+
+//-----------------------------------------------------------------------------
+bool HLT::RoICacheHistory::FeatureCall::isValid() const {
+  return m_init;
+}
+
+HLT::RoICacheHistory::RememberAttachFeature::RememberAttachFeature(const TriggerElement* te, CLID clid, const std::string& label,
+								   NavigationCore* navig, TriggerElement::ObjectIndex& idx) {
+  HLT::RoICacheHistory& roih = HLT::RoICacheHistory::instance();
+  if(!roih.collectHistory()) return;
+  //  std::cout << "RoICacheHistory recording also attach feature" << std::endl;
+  roih.setCurrentFeatureCall(HLT::RoICacheHistory::FeatureCall(roih.getWorkTE(), te, clid, label, true, false), navig);
+  roih.m_current.addAnswer(te, TriggerElement::FeatureAccessHelper(clid, idx));
+  roih.stopCurrentFeatureCall();
+}
+
+
+//-----------------------------------------------------------------------------
+HLT::RoICacheHistory::QuestionScope::QuestionScope(const TriggerElement* te,
+						   CLID clid,
+						   const std::string& label,
+						   NavigationCore *navig, bool issingle)
+  : m_start(te)
+{
+  HLT::RoICacheHistory& roih = HLT::RoICacheHistory::instance();
+  
+  // Are we event collecting history?
+  if(!roih.collectHistory()) return;
+
+  if(roih.getCurrentFeatureCall().isValid()) {
+    return;
+  } else { 
+    // Create current question
+    roih.setCurrentFeatureCall(HLT::RoICacheHistory::FeatureCall(roih.getWorkTE(), te, clid, label, issingle, true), navig);
+  }
+}
+
+HLT::RoICacheHistory::QuestionScope::QuestionScope() 
+  : m_start(0)
+{}
+
+
+//-----------------------------------------------------------------------------
+HLT::RoICacheHistory::QuestionScope::~QuestionScope()
+{
+  if ( !m_start ) 
+    return;
+
+  HLT::RoICacheHistory& roih = HLT::RoICacheHistory::instance();
+  
+  // Are we event collecting history?
+  if(!roih.collectHistory()) return;
+
+  // Alway see valid question
+  if(!roih.getCurrentFeatureCall().isValid()) {
+    throw std::runtime_error("HLT caching problem: logic error in history");
+  }
+
+  // Return out of scope for first call
+  if(roih.getCurrentFeatureCall().getInitTE() == m_start) {
+    roih.stopCurrentFeatureCall();
+  }
+}
+
diff --git a/Trigger/TrigEvent/TrigNavigation/src/TrigEDMSizes.cxx b/Trigger/TrigEvent/TrigNavigation/src/TrigEDMSizes.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..681237cab62215fc4020e0dcd7e3bed5aeb6967f
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/src/TrigEDMSizes.cxx
@@ -0,0 +1,46 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "TrigNavigation/TrigEDMSizes.h"
+
+#include <boost/foreach.hpp>
+
+using namespace HLT;
+TrigEDMSizes::TrigEDMSizes(){}
+
+
+TrigEDMSizes::EDMObjectInfo::EDMObjectInfo(const std::string& coll, const std::string& l, unsigned w, unsigned cut) 
+  : collection(coll), label(l), words(w), cutsize(cut)
+{}
+
+bool TrigEDMSizes::EDMObjectInfo::isTruncated(unsigned size_after_serialization) const {
+  if (cutsize >  size_after_serialization)
+    return true;
+  return false;
+}
+
+void TrigEDMSizes::addObject(const std::string& coll, const std::string& label, unsigned words, unsigned cutsize) {
+  m_objects.push_back(TrigEDMSizes::EDMObjectInfo(coll, label, words, cutsize));
+}
+
+const TrigEDMSizes::EDMEventInfo& TrigEDMSizes::info() const {
+  return m_objects;
+}
+
+const TrigEDMSizes::EDMObjectInfo& TrigEDMSizes::lastNotTruncated(unsigned size_after_truncation) const {
+  bool foundTruncated = false;
+  bool foundNotTruncated = false;
+  
+  BOOST_REVERSE_FOREACH( const TrigEDMSizes::EDMObjectInfo& oi, m_objects) {    
+    if ( foundTruncated && foundNotTruncated )
+      return oi; 
+
+    if (  oi.isTruncated(size_after_truncation) ) {
+      foundTruncated = true;
+    } else {
+      foundNotTruncated = true;
+    }
+  }
+  return m_objects.front();
+}
diff --git a/Trigger/TrigEvent/TrigNavigation/src/TrigFeatureLink.cxx b/Trigger/TrigEvent/TrigNavigation/src/TrigFeatureLink.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..0db0bff2eb49cccfddc0f0334a169569aec8360b
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/src/TrigFeatureLink.cxx
@@ -0,0 +1,19 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "TrigNavigation/TrigFeatureLink.h"
+
+TrigFeatureLink::TrigFeatureLink(CLID clid, uint16_t subtype, uint32_t index) 
+  : m_clid(clid),
+    m_subTypeIndex(subtype),
+    m_index(index) 
+{}
+
+TrigFeatureLink::TrigFeatureLink() 
+  : m_clid(0),
+    m_subTypeIndex(0),
+    m_index(0) 
+{}
+
+
diff --git a/Trigger/TrigEvent/TrigNavigation/src/TriggerElement.cxx b/Trigger/TrigEvent/TrigNavigation/src/TriggerElement.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..bfe86ee344abe3b2e8cf098dac7395cf5975da6a
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/src/TriggerElement.cxx
@@ -0,0 +1,15 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "TrigNavigation/TriggerElement.h"
+
+MsgStream& operator<< ( MsgStream& m, const HLT::TriggerElement::ObjectIndex& i ) {
+  m << "SubTypeIdx: " << i.subTypeIndex() << " begin: " << i.objectsBegin() << " end: " << i.objectsEnd();
+  return m;    
+}
+
+MsgStream& operator<< ( MsgStream& m, const HLT::TriggerElement& te ) {
+  m << "TE id: " << te.getId() << " ac: " << te.getActiveState() << " err: " << te.getErrorState();
+  return m;
+}
diff --git a/Trigger/TrigEvent/TrigNavigation/src/TypeMaps.cxx b/Trigger/TrigEvent/TrigNavigation/src/TypeMaps.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..0da8fee433dabd31ff8bc417a000adcb3baa6853
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/src/TypeMaps.cxx
@@ -0,0 +1,52 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "TrigNavigation/TypeMaps.h"
+namespace HLT {
+  TypeMaps::CLIDtoTypeProxyMap& TypeMaps::proxies()
+  {
+    static CLIDtoTypeProxyMap map;
+    return map;
+  }
+  
+  TypeMaps::CLIDtoHolderMap& TypeMaps::holders()
+  {
+    static CLIDtoHolderMap map;  
+    return map;
+  }
+  
+  
+  TypeMaps::NametoCLIDMap& TypeMaps::type2clid()
+  {
+    static NametoCLIDMap type2clid;
+    return type2clid;
+  }
+}
+
+
+namespace HLTNavDetails {
+  class TypeMapDeleter {
+  public:
+    ~TypeMapDeleter() {
+      /*
+      {
+	HLT::TypeMaps::CLIDtoTypeProxyMap::iterator i;
+	for ( i = HLT::TypeMaps::proxies().begin(); i != HLT::TypeMaps::proxies().end(); ++i) {
+	  delete i->second; i->second = 0;
+	}
+	HLT::TypeMaps::proxies().clear();
+      }
+      {	
+	HLT::TypeMaps::CLIDtoHolderMap::iterator i;
+	for ( i = HLT::TypeMaps::holders().begin(); i != HLT::TypeMaps::holders().end(); ++i) {
+	  delete i->second; i->second = 0;
+	}	
+	HLT::TypeMaps::holders().clear();
+      }
+      */
+    }
+  };
+  TypeMapDeleter typeMapDeleter; // this objects is created in the file scope so at the deletion it can clean up the static types map
+}
+
diff --git a/Trigger/TrigEvent/TrigNavigation/src/TypeProxy.cxx b/Trigger/TrigEvent/TrigNavigation/src/TypeProxy.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..6ac935e0ca7eb5a0daec096c63747be069b815d7
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/src/TypeProxy.cxx
@@ -0,0 +1,85 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: TypeProxy.cxx 610817 2014-08-07 18:30:36Z lheinric $
+
+// EDM include(s):
+#include "AthContainersInterfaces/IAuxStore.h"
+
+// Local include(s):
+#include "TrigNavigation/TypeProxy.h"
+
+namespace HLTNavDetails {
+
+   ITypeProxy::ITypeProxy()
+      : m_clid( 0 ), m_typeName( "" ), m_key( "" ), m_proxy( 0 ),
+        m_ncPointer( 0 ), m_pointer( 0 ), m_isAuxVectorBase( false ) {
+
+   }
+
+   StatusCode ITypeProxy::sync( StoreGateSvc* sg, const std::string& key ) {
+
+      // Get a proxy for this object:
+      m_proxy = sg->proxy( m_clid, key );
+      if( ! m_proxy ) {
+         REPORT_MESSAGE_WITH_CONTEXT( MSG::ERROR, "HLTNavDetails::ITypeProxy::sync" )
+            << "Couldn't get SG::DataProxy to the managed object";
+         return StatusCode::FAILURE;
+      }
+
+      // Get the pointers:
+      m_ncPointer = SG::DataProxy_cast( m_proxy, m_clid );
+      m_pointer = m_ncPointer;
+
+      // Remember this key:
+      m_key = key;
+
+      // The rest is up to the code in the template class:
+      return StatusCode::SUCCESS;
+   }
+
+   SG::AuxVectorBase* ITypeProxy::castAuxVectorBase() {
+
+      if( m_isAuxVectorBase ) {
+         return static_cast< SG::AuxVectorBase* >( m_ncPointer );
+      } else {
+         return 0;
+      }
+   }
+
+   /// This cast can be done based on StoreGate, since SG::IAuxStore
+   /// has a CLID, as should the type that we're proxying
+   ///
+   SG::IAuxStore* ITypeProxy::castIAuxStore() {
+
+      return static_cast< SG::IAuxStore* >( m_ncPointer );
+   }
+
+   bool ITypeProxy::contains( StoreGateSvc* sg, const std::string& key ) const {
+
+      return sg->contains( m_clid, key );
+   }
+
+   bool ITypeProxy::transientContains( StoreGateSvc* sg,
+                                       const std::string& key ) const {
+
+      return sg->transientContains( m_clid, key );
+   }
+
+   bool ITypeProxy::empty() const {
+
+      return ( ( m_proxy == 0 ) && ( m_ncPointer == 0 ) );
+   }
+
+   CLID ITypeProxy::clid() const {
+
+      return m_clid;
+   }
+
+   const std::string& ITypeProxy::typeName() const {
+
+      return m_typeName;
+   }
+
+} // namespace HLTNavDetails
diff --git a/Trigger/TrigEvent/TrigNavigation/src/components/TrigNavigation_entries.cxx b/Trigger/TrigEvent/TrigNavigation/src/components/TrigNavigation_entries.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..c1070f612731d1dc4c1f74df3104deba2a3b8df7
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/src/components/TrigNavigation_entries.cxx
@@ -0,0 +1,10 @@
+#include "GaudiKernel/DeclareFactoryEntries.h"
+#include "TrigNavigation/Navigation.h"
+
+
+DECLARE_NAMESPACE_TOOL_FACTORY( HLT, Navigation )
+
+
+DECLARE_FACTORY_ENTRIES(TrigNavigation) {
+  DECLARE_NAMESPACE_ALGTOOL(HLT, Navigation)
+}
diff --git a/Trigger/TrigEvent/TrigNavigation/src/components/TrigNavigation_load.cxx b/Trigger/TrigEvent/TrigNavigation/src/components/TrigNavigation_load.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..a310ec257dea861e85162cb051885ecefd63e3d5
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/src/components/TrigNavigation_load.cxx
@@ -0,0 +1,12 @@
+#include "GaudiKernel/LoadFactoryEntries.h"
+
+LOAD_FACTORY_ENTRIES(TrigNavigation)
+
+  //Notes:
+  //
+  //1. The argument to the LOAD_FACTORY_ENTRIES() is the name of the
+  //   component library (libXXX.so).
+  //
+  // See Athena User Guide for more information
+
+
diff --git a/Trigger/TrigEvent/TrigNavigation/test/HLTNavigation_test.cxx b/Trigger/TrigEvent/TrigNavigation/test/HLTNavigation_test.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..4a9ede39c72da58123036536d93740cefa8f552e
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/test/HLTNavigation_test.cxx
@@ -0,0 +1,874 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include <sys/time.h>
+#include <iostream>
+#include <iterator>
+#include "GaudiKernel/ClassID.h"
+#include "GaudiKernel/MsgStream.h"
+#include "StoreGate/StoreGate.h"
+#include "StoreGate/StoreGateSvc.h"
+#include "AthenaKernel/getMessageSvc.h"
+#include "DataModel/ElementLinkVector.h"
+#include "DataModel/ConstDataVector.h"
+
+#include "TestTools/initGaudi.h"
+
+#include "TrigNavigation/TriggerElement.h"
+
+#include "TrigNavigation/Navigation.h"
+#include "TrigNavigation/Navigation.icc"
+#include "TrigNavigation/RoICacheHelper.h"
+
+#include <boost/type_traits/is_same.hpp>
+#include  <boost/type_traits/remove_const.hpp>
+#include "TrigSerializeCnvSvc/TrigSerializeConverter.h"
+
+#include "TestTypes.h"
+#include "TestUtils.h"
+
+double interval( struct timeval& begin, struct timeval& end) {
+  return (end.tv_sec - begin.tv_sec)*1000. + (end.tv_usec - begin.tv_usec)/1000.;
+}
+using namespace HLT;
+/*
+void blah( DataVector<B>::const_iterator ) {}
+
+void blah2() {
+  BContainer bb;
+  blah(bb.begin());
+}
+*/
+/////////////////////////////////////////////////////////////////////////////
+//  
+//  features retrieval test
+//  
+//  
+/////////////////////////////////////////////////////////////////////////////
+template<class T, class C>
+int testGetFeaturesOnDistinctTypes(MsgStream& log, Navigation* nav, TriggerElement* te, const std::string& label ) {
+  
+
+  const T* singleFromGet = 0;
+  const T* singleFromGetRecent = 0;
+  std::vector<const T*> multipleFromGet;
+  std::vector<const T*> multipleFromGetRecent;
+  const T* singleRecentThroughEL(0);
+  std::vector<const T*> multipleRecentThroughELV;
+
+  log << MSG::DEBUG << "testGetFeatures test for TE: " << te->getId() 
+      << " and features of type " << ClassID_traits<T>::typeName() 
+      << " with label " << label
+      << endreq;
+
+  if ( nav->getFeature(te, singleFromGet, label) == false ) {
+    log << MSG::ERROR << "falied to get: singleFromGetFeature" << endreq; return -1;
+  }
+
+  const TriggerElement* tsource(0);
+  std::string lsource;
+  if ( nav->getRecentFeature(te, singleFromGetRecent, label, tsource, lsource) ) {
+    if ( tsource == 0 && singleFromGetRecent != 0 ) {
+      log << MSG::ERROR << "falied to get: singleFromGetFeature no source found " << singleFromGetRecent << " " << tsource  << endreq; 
+      return -1;
+    } 
+    if ( tsource ) {
+      log << MSG::INFO << "worked to get: endreq " << tsource->getId() << " label >" << label << "< back label >" << lsource << "< ptr: " <<  singleFromGetRecent << endreq; 
+      
+    }
+    log << MSG::INFO << "falied to get: singleFromGetFeature" << endreq;    
+  } else {
+    if ( !tsource ) {
+      log << MSG::ERROR << "in falied to get: singleFromGetFeature no source found " << tsource  << endreq; 
+      return -1;
+    }
+  }
+  
+  
+
+  if ( nav->getFeatures(te, multipleFromGet, label) == false ) {
+    log << MSG::ERROR << "falied to get: multipleFromGet" << endreq;  return -1;
+  } 
+  if ( nav->getRecentFeatures(te, multipleFromGetRecent, label) == false ) {
+    if ( label != "" ) {
+      log << MSG::ERROR << "falied to get: multipleFromGetRecent" << endreq; return -1;
+    } else 
+      log << MSG::INFO << "falied to get: multipleFromGetRecent but OK, label is empty string" << endreq;
+  } 
+
+  typedef ElementLink<C> CEL;
+  CEL el;
+
+  if ( nav->getRecentFeatureLink<C, T>(te, el, label) == false ) {
+    log << MSG::INFO << "falied to get: singleRecentThroughEL" << endreq;
+  } 
+  if (el.isValid())
+    singleRecentThroughEL = *el;
+
+    
+  typedef ElementLinkVector<C> CELV;
+  CELV elv;  
+  typename CELV::iterator elvIt;
+
+  if ( nav->getRecentFeaturesLinks<C, T>(te, elv, label) == false ) {    
+    if ( label != "" ) {
+      log << MSG::ERROR << "falied to get: multipleRecentThroughELV" << endreq; return -1;
+    } else {
+      log << MSG::INFO << "falied to get: multipleRecentThroughELV" << endreq;
+    }
+  } 
+  
+  for ( elvIt = elv.begin(); elvIt != elv.end(); ++elvIt ) {
+    el = *elvIt;
+    const T* t = *el;
+    multipleRecentThroughELV.push_back(const_cast<typename C::base_value_type *>(t));
+  }
+   
+  log << MSG::DEBUG << "testGetFeatures passed features retrieval ... checking thier relations" << endreq; 
+
+   
+   // cross check ordering
+   if ( singleFromGet != 0 ) {
+     if ( multipleFromGet.size() < 1 ) {
+       log << MSG::ERROR << "singleFromGet & multipleFromGet give give inconsistent sizes " << multipleFromGet.size() << endreq;
+       return -1 ; 
+     }
+     if ( singleFromGet != multipleFromGet.back() ) {
+       log << MSG::ERROR << "singleFromGet & multipleFromGet give wrong ordering" << endreq;
+       return -1 ;
+     }
+   }
+
+  if ( singleFromGetRecent != 0 ) {
+     if ( singleFromGetRecent != multipleFromGetRecent.back() ) {
+       log << MSG::ERROR << "singleFromGetRecent & multipleFromGetRecent give wrong ordering" << endreq;
+       return -1 ;
+     }
+   }
+  
+  //cross check if EL based methog give the same
+  if ( singleFromGetRecent != singleRecentThroughEL ) {
+    log << MSG::ERROR << "singleFromGetRecent != singleRecentThroughEL" << endreq;
+    return -1 ;
+  }
+
+
+  if ( multipleRecentThroughELV.size() != multipleFromGetRecent.size() ) {
+    log << MSG::ERROR << "multipleRecentThroughELV.size() " << multipleRecentThroughELV.size() << " != multipleFromGetRecent.size() " <<multipleFromGetRecent.size() << endreq;
+    return -1 ;
+  }
+
+  for ( unsigned i = 0; i < multipleRecentThroughELV.size() ; i++ ) {
+    if ( multipleRecentThroughELV[i] != multipleFromGetRecent[i] ) {
+      log << MSG::ERROR << "multipleRecentThroughELV[i] != multipleFromGetRecent[i] for i: " << i  << endreq;
+      return -1; 
+    }
+  }
+
+  log << MSG::DEBUG << "testGetFeaturesOnDistinctTypes passed for TE: " << te->getId() 
+      << " and features of type " << ClassID_traits<T>::typeName() 
+      << " with label " << label
+      << " singleGet gave " << ( (singleFromGet) ? 1 : 0 )
+      << " multipleGet gave " << multipleFromGet.size()
+      << endreq;
+
+  return 0;
+}
+
+
+
+
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+// the same as above but when collections are involved
+
+
+
+template<class T>
+int testGetFeaturesOnSameTypes(MsgStream& log, Navigation* nav, TriggerElement* te, const std::string& label ) {
+
+  const T* singleFromGet(0);
+  const T* singleFromGetRecent(0);
+  std::vector<const T*> multipleFromGet;
+  std::vector<const T*> multipleFromGetRecent;
+  T multipleRecentThroughELV;
+  multipleRecentThroughELV.clear(SG::VIEW_ELEMENTS);
+  T multipleRecentThroughPlain;
+  multipleRecentThroughPlain.clear(SG::VIEW_ELEMENTS);
+
+  log << MSG::DEBUG << "testGetFeaturesOnSameTypes test for TE: " << te->getId() 
+      << " and features of type " << ClassID_traits<T>::typeName() 
+      << " with label " << label
+      << endreq;
+
+  if ( nav->getFeature(te, singleFromGet, label) == false ) {
+    log << MSG::ERROR << "falied to get: singleFromGetFeature" << endreq; return -1;
+  }
+  if ( nav->getRecentFeature(te, singleFromGetRecent, label) == false ) {
+    log << MSG::INFO << "falied to get: singleFromGetRecentFeature" << endreq; 
+  } 
+  if ( nav->getFeatures(te, multipleFromGet, label) == false ) {
+    log << MSG::ERROR << "falied to get: multipleFromGet" << endreq;  return -1;
+  } 
+  if ( nav->getRecentFeatures(te, multipleFromGetRecent, label) == false ) {
+     log << MSG::INFO << "falied to get: multipleFromGetRecent" << endreq;
+  } 
+
+  typename std::vector<const T*>::const_iterator pIt;
+  for ( pIt = multipleFromGetRecent.begin(); pIt != multipleFromGetRecent.end(); ++pIt) {
+    multipleRecentThroughPlain.insert(    multipleRecentThroughPlain.end(), (*pIt)->begin(), (*pIt)->end() ); 
+  }
+
+  typedef ElementLink<T> CEL;
+  CEL el;
+
+  if ( nav->getRecentFeatureLink<T, T>(te, el, label) == true ) {
+    log << MSG::ERROR << "managed to get: singleRecentThroughEL this method for same types should return false" << endreq; return -1;
+  } 
+    
+  typedef ElementLinkVector<T> CELV;
+  CELV elv;  
+  typename CELV::iterator elvIt;
+
+  if ( nav->getRecentFeaturesLinks<T, T>(te, elv, label) == false ) {
+     log << MSG::INFO << "falied to get: multipleRecentThroughELV" << endreq;
+  } 
+  
+  for ( elvIt = elv.begin(); elvIt != elv.end(); ++elvIt ) {
+    el = *elvIt;
+    typedef typename T::base_value_type S;
+    const S* t = *el;
+    multipleRecentThroughELV.push_back((S*)t);
+  }
+
+  log << MSG::DEBUG << "testGetFeatures passed features retrieval ... checking thier relations" << endreq; 
+
+   
+   // cross check ordering
+   if ( singleFromGet != 0 ) {
+     if ( multipleFromGet.size() < 1 ) {
+       log << MSG::ERROR << "singleFromGet & multipleFromGet give give inconsistent sizes " << multipleFromGet.size() << endreq;
+       return -1 ; 
+     }
+     if ( singleFromGet != multipleFromGet.back() ) {
+       log << MSG::ERROR << "singleFromGet & multipleFromGet give wrong ordering" << endreq;
+       return -1 ;
+     }
+   }
+
+  if ( singleFromGetRecent != 0 ) {
+     if ( singleFromGetRecent != multipleFromGetRecent.back() ) {
+       log << MSG::ERROR << "singleFromGetRecent & multipleFromGetRecent give wrong ordering" << endreq;
+       return -1 ;
+     }
+   }
+  
+  //cross check if EL based methog give the same
+  
+
+  if ( multipleRecentThroughELV.size() != multipleRecentThroughPlain.size() ) {
+    log << MSG::ERROR << "multipleRecentThroughELV.size() != multipleRecentThroughPlain.size()" << endreq;
+    return -1 ;
+  }
+
+  for ( unsigned i = 0; i < multipleRecentThroughELV.size() ; i++ ) {
+    if ( multipleRecentThroughELV[i] != multipleRecentThroughPlain[i] ) {
+      log << MSG::ERROR << "multipleRecentThroughELV[i] != multipleRecentThroughPlain[i] for i: " << i  << endreq;
+      return -1; 
+    }
+  } 
+
+  log << MSG::DEBUG << "testGetFeaturesOnSameTypes passed for TE: " << te->getId() 
+      << " and features of type " << ClassID_traits<T>::typeName() 
+      << " with label " << label
+      << " singleGet gave " << ( (singleFromGet) ? 1 : 0 )
+      << " multipleGet gave " << multipleFromGet.size()
+      << endreq;
+
+  return 0;
+}
+
+
+template<class T>
+int testFindOwners(MsgStream& log, Navigation* nav, T* t, bool isRealyAttached=true) {
+  std::vector<const TriggerElement*> tes;
+  if (nav->findOwners(t, tes)  == false) {
+    log << MSG::ERROR << "find owners failed for : " << t << " of type " << ClassID_traits<T>::typeName()  << endreq;
+      return -1; 
+    }
+  if ( isRealyAttached && tes.size() == 0 ) {
+    log << MSG::ERROR << "find owners found 0 TEs for : " << t << " of type " << ClassID_traits<T>::typeName()  << endreq;
+    return -1; 
+  }
+
+  if ( (!isRealyAttached) && tes.size() != 0 ) {      
+    log << MSG::ERROR << "find owners worked for : " << t << " of type " << ClassID_traits<T>::typeName()  << endreq;    
+    return -1; 
+  }
+  return 0;
+}
+
+
+
+
+template<class T, class C>
+int checkGetFeaturesOnAllTEsOnDistinctTypes(MsgStream& log, Navigation* nav, TriggerElement* te, const std::string& label) {
+
+
+  if ( testGetFeaturesOnDistinctTypes<T,C>(log, nav, te, label) != 0 )
+    return -1;
+
+  std::vector<TriggerElement*> succ = nav->getDirectSuccessors(te);
+  std::vector<TriggerElement*>::iterator i;
+  
+  log << MSG::DEBUG << "looping over successors " << succ.size() << endreq;
+  for ( i = succ.begin(); i != succ.end(); ++i ) {
+
+    if ( checkGetFeaturesOnAllTEsOnDistinctTypes <T,C>(log, nav, *i, label) != 0 )
+      return -1;
+  }
+  return 0;
+}
+
+
+template<class T>
+int checkGetFeaturesOnAllTEsOnSameTypes(MsgStream& log, Navigation* nav, TriggerElement* te, const std::string& label) {
+
+
+  if ( testGetFeaturesOnSameTypes<T>(log, nav, te, label) != 0 )
+    return -1;
+
+  std::vector<TriggerElement*> succ = nav->getDirectSuccessors(te);
+  std::vector<TriggerElement*>::iterator i;
+  
+  log << MSG::DEBUG << "looping over successors " << succ.size() << endreq;
+  for ( i = succ.begin(); i != succ.end(); ++i ) {
+
+    if ( checkGetFeaturesOnAllTEsOnSameTypes <T>(log, nav, *i, label) != 0 )
+      return -1;
+  }
+  return 0;
+}
+//****************************************************************************************
+StatusCode construction_test(HLT::Navigation* hns) {
+  BEGIN_TEST("Construction");
+  TriggerElement* initial =  hns->getInitialNode();
+  if ( not initial ) REPORT_AND_STOP("Can not get initial node");
+  if ( not HLT::Navigation::isInitialNode(initial) ) REPORT_AND_STOP("Initial node not initial");
+
+
+  TriggerElement* roi1    =  hns->addRoINode(initial); //roi1->setId(1); // id are for the test only
+  TriggerElement* roi2    =  hns->addRoINode(initial); //roi2->setId(2);
+  TriggerElement* roi3    =  hns->addRoINode(initial); //roi3->setId(3);
+  if ( HLT::Navigation::isInitialNode(roi3) ) REPORT_AND_STOP("The RoI node considered as initial");
+  
+    
+  TriggerElement* roi1eltr1 = hns->addNode(roi1, 11);
+  TriggerElement* roi1eltr2 = hns->addNode(roi1, 12);
+  TriggerElement* roi1eltr3 = hns->addNode(roi1, 13);
+  TriggerElement* roi1eltr4 = hns->addNode(roi1, 14);
+
+
+  TriggerElement* clu1 = hns->addNode(roi1eltr1, 111); 
+  TriggerElement* track1 = hns->addNode(clu1, 1111);   
+  TriggerElement* el1 = hns->addNode(track1, 11111); 
+  //  el1->attachFeature(new A);
+
+  // another roi
+  TriggerElement* roi2mutr1 = hns->addNode(roi2, 21); 
+  TriggerElement* roi2mutr2 = hns->addNode(roi2, 22); roi2mutr2->getId();
+
+  REPORT_AND_CONTINUE( "after adding inital nodes" );
+
+  // build big structure
+  std::vector<TriggerElement*> telist;
+  telist.push_back(roi2mutr1);
+  telist.push_back(track1);
+  TriggerElement* zz = hns->addNode(telist,   33301);
+  zz->setErrorState(true);
+  TriggerElement* zz2 = hns->addNode(telist,  33311);  zz2->getId();
+  TriggerElement* zz1 = hns->addNode(zz,      33321); 
+  TriggerElement* zz1prim = hns->addNode(zz1, 33323); 
+  TriggerElement* zz1prim2 = hns->addNode(telist, 33324, false, true); 
+
+  REPORT_AND_CONTINUE("RoIs made");
+
+  if ( ! HLT::Navigation::haveCommonRoI(roi1eltr1, roi1eltr2) ) 
+    REPORT_AND_STOP( "this TEs (2 direct successors) should have indicate that they have common RoI"  );
+
+  
+  if ( ! HLT::Navigation::haveCommonRoI(roi1, roi1eltr4) ) 
+    REPORT_AND_STOP( "this TEs (RoI and direct successor) should have indicate that they have common RoI"  );
+
+  
+  if ( ! HLT::Navigation::haveCommonRoI(roi1, clu1) ) 
+    REPORT_AND_STOP( "this TEs (RoI and indirect successor) should have indicate that they have common RoI"  );
+  
+  
+  if ( ! HLT::Navigation::haveCommonRoI(roi1eltr3, el1) ) 
+    REPORT_AND_STOP( "this TEs (2 indirect successors) should have indicate that they have common RoI"  );
+  
+  
+  if ( HLT::Navigation::haveCommonRoI(roi2mutr1, el1) ) 
+    REPORT_AND_STOP( "this simple TEs (direct successor and indeirect successor) should have indicate that they have distinct RoI"  );
+
+
+  if ( HLT::Navigation::haveCommonRoI(roi2mutr1, roi1) ) 
+    REPORT_AND_STOP( "this simple TEs (direct successor and RoI) should have indicate that they have distinct RoI"  );
+
+
+  if ( ! HLT::Navigation::haveDistinctRoI(roi3, zz) ) 
+    REPORT_AND_STOP( "this simple TEs (RoI and Topo) should have indicate that they have distinct RoI"  );
+
+
+  if ( ! HLT::Navigation::haveDistinctRoI(roi1, roi2) ) 
+    REPORT_AND_STOP( "this simple TEs (RoI and Topo) should have indicate that they have distinct RoI"  );
+  
+
+  REPORT_AND_CONTINUE("RoIs Common/Distinct check made");
+
+
+  // add ghost TES
+  TriggerElement* ghost;
+  ghost = hns->addNode(telist, 33399, true); ghost->setActiveState(false);
+  ghost = hns->addNode(telist, 33399, true); 
+  ghost = hns->addNode(telist, 33399, true); 
+  ghost = hns->addNode(telist, 33399, true); 
+  ghost = hns->addNode(telist, 33399, true); 
+  ghost = hns->addNode(telist, 33399, true); 
+  ghost = hns->addNode(telist, 33399, true); 
+
+  // build one long branch
+  TriggerElement* te1 = roi1eltr1;
+  TriggerElement* te2;
+  int i;
+  for ( i = 0; i < 25; i++ ) { 
+    te2 = hns->addNode(te1, 5000+i); 
+    te1 = te2;
+  }
+  
+  // add many leafs to one of the RoI
+  for ( i = 0; i < 24; i++ ) { 
+    te1 = hns->addNode(roi1, 50); 
+    // bunch of inactive TEes
+    TriggerElement* te3 = hns->addNode(roi1, 60); 
+    te3->setActiveState(false);
+
+    // every of it has 5 leafs
+    telist.clear();
+    for ( int j = 0; j < 5; j++ ) {
+      te2 = hns->addNode(te1, te1->getId()+100); 
+      telist.push_back(te2);
+    }
+    // a big join
+    te1 = hns->addNode(telist, te1->getId()+1000); 
+  }
+
+  std::vector<TriggerElement*> typeVec;
+  hns->getAllOfType(50, typeVec);
+  if (! HLT::Navigation::haveCommonRoI( typeVec[0], typeVec[1] ) ) 
+    REPORT_AND_STOP( "this simple TEs (2 sibling successors) should have indicate that they have distinct RoI"  );
+  
+
+  END_TEST;
+}
+
+//****************************************************************************************
+StatusCode counting_test(HLT::Navigation* hns) {
+  BEGIN_TEST("counting");
+  
+
+  
+  // test queries by type
+  std::vector<TriggerElement*> typeVec;
+  hns->getAllOfType(50, typeVec);
+
+  if ( typeVec.size() != 24 ) 
+    REPORT_AND_STOP( "Query by type incorrect, should have returned 25 TE: " << typeVec.size() );
+
+
+  typeVec.clear();
+  hns->getAllOfType(60, typeVec);
+  if ( typeVec.size() != 0 ) 
+    REPORT_AND_STOP( "Query by type incorrect, should have returned 0 TE (all are inactive): " << typeVec.size() )
+
+  
+  hns->getAllOfType(60, typeVec, false);
+  if ( typeVec.size() != 24 ) 
+    REPORT_AND_STOP( "Query by type incorrect, should have returned 0 TE (all are inactive, but shouldnot look at the status): " << typeVec.size() );
+
+  REPORT_AND_CONTINUE( "SUCCESS TEST of getAllOfType method" );
+  
+  if ( hns->countAllOfType(33399) != 6 ) 
+    REPORT_AND_STOP( "Count by type incorrect, got active only: " << hns->countAllOfType(33399) << " inestead of " << 6 );
+
+
+  if ( hns->countAllOfType(33399, false) != 7 ) 
+    REPORT_AND_STOP( "Count by type incorrect, got active and inactive: " << hns->countAllOfType(33399) << " inestead of " << 7 );
+
+  
+  END_TEST;
+
+}
+//****************************************************************************************
+StatusCode seeding_test(HLT::Navigation* hns) {
+  BEGIN_TEST("seeding");
+  
+
+
+  
+  END_TEST;
+
+}
+
+TriggerElement* getTE(Navigation* hns, int id) {
+  std::vector<TriggerElement*> tes;
+  hns->getAllOfType(id, tes);
+  if ( tes.size() == 1 ) 
+    return tes[0];
+  return 0;  
+}
+bool all_not_null(const std::initializer_list<TriggerElement*>& all) {
+  for ( TriggerElement* te: all )
+    if (te == 0) return false;
+  return true;
+}
+
+//****************************************************************************************
+StatusCode topo_test(HLT::Navigation* hns) {
+  BEGIN_TEST("topo");
+  TriggerElement* clu1      = getTE(hns, 111);
+  TriggerElement* zz        = getTE(hns, 33301);
+  TriggerElement* roi1eltr1 = getTE(hns, 11);
+  TriggerElement* roi1eltr2 = getTE(hns, 12);
+  TriggerElement* roi2 = getTE(hns, 21);
+  TriggerElement* roi2mutr2 = getTE(hns, 22);
+  
+  if ( not all_not_null({clu1, zz, roi1eltr1, roi1eltr2, roi2}) )
+    REPORT_AND_STOP("Some TEs are 0");
+
+    if ( HLT::Navigation::isTopological(clu1) != false ) 
+      REPORT_AND_STOP ( "clu1 TE is recognized as topological while it is not" );
+  
+  if ( HLT::Navigation::isTopological(zz) != true ) 
+    REPORT_AND_STOP( "zz TE is not recognized as topological while it is " );
+  
+  REPORT_AND_CONTINUE(  "SUCCESS tests of isTopological method" );
+  if ( ! HLT::Navigation::haveCommonSeed(roi1eltr1, roi1eltr2) ) 
+    REPORT_AND_STOP( "this TEs (2 direct successors) should have indicate that they have common seed"  );
+
+
+
+  if ( ! HLT::Navigation::haveDistinctSeed(roi1eltr1, roi2) ) 
+    REPORT_AND_STOP( "this TEs (normal and RoI) should have indicate that they have distinct seed"  );
+
+
+  if ( HLT::Navigation::getSuccessor(clu1, 33301) != zz ) 
+    REPORT_AND_STOP( "getSuccessor is failing to find right TE"  );
+
+
+  if ( HLT::Navigation::getSuccessor(roi2mutr2, 33301) != 0 ) 
+    REPORT_AND_STOP ("getSuccessor fond TE which is wrong"  );
+
+
+
+  REPORT_AND_CONTINUE( " of haveCommonSeed method" );
+
+  
+
+
+  END_TEST;
+
+}
+
+//****************************************************************************************
+StatusCode single_feature_test(HLT::Navigation* hns) {
+  BEGIN_TEST("single feature operations test");
+  TriggerElement* clu1        = getTE(hns, 111);
+  TriggerElement* track1      = getTE(hns, 1111);
+  TriggerElement* el1      = getTE(hns, 11111);
+
+  TestA* a1 = new TestA(1);
+  TestA* a2 = new TestA(2);
+  TestA* a3 = new TestA(3);
+  TestA* a4 = new TestA(4);
+  TestA* a5 = new TestA(5);
+  std::string key;
+  if ( hns->attachFeature(clu1, a1, Navigation::ObjectCreatedByNew, key, "Single") == false ) 
+    REPORT_AND_STOP( "Attach feature returned false " );
+
+  if ( hns->attachFeature(clu1, a2, Navigation::ObjectCreatedByNew, key, "Single") == false ) 
+    REPORT_AND_STOP( "Attach second feature failed" );
+
+
+  std::vector<const TestA*> avec;
+
+  hns->getFeatures(clu1, avec);
+  if ( avec.size() != 2 ) 
+    REPORT_AND_STOP( "No. of attached features wrong (2): " << avec.size()  );
+
+  
+  hns->getFeatures(track1, avec);
+  if ( avec.empty() ) 
+    REPORT_AND_STOP( "attached features visible in other TEs"  );
+
+
+
+  avec.clear();
+  hns->attachFeature(clu1, a3, Navigation::ObjectCreatedByNew, key, "ToolTestA");
+  hns->attachFeature(clu1, a4, Navigation::ObjectCreatedByNew, key, "ToolB");
+ 
+ 
+  hns->getFeatures(clu1, avec);
+  if ( avec.size() != 4 ) 
+    REPORT_AND_STOP ( "No. of attached features wrong, problem with labeled features (4): " << avec.size()  );
+
+
+  avec.clear();
+  hns->getFeatures(clu1, avec, "ToolTestA" );
+  if ( avec.size() != 1 )
+    REPORT_AND_STOP( "No. of attached features wrong, does not regard labels (1): " << avec.size() );
+  
+  avec.clear();
+  hns->attachFeature(track1, a5, Navigation::ObjectCreatedByNew, key, "ToolB");
+  hns->getFeaturesInRoI(el1, avec);
+  if ( avec.size() != 5 ) 
+    REPORT_AND_STOP( "No. of attached features wrong, does not see all RoI: " << avec.size() );
+  
+  std::vector<const TestA*> lastA; 
+  hns->getRecentFeatures(el1, lastA );
+  if ( lastA.empty() ) 
+    REPORT_AND_STOP( "getLastFeature retrieves null" );
+
+  if ( lastA.back()->a != 5 ) 
+    REPORT_AND_STOP( "getLastFeature retrieves wrong feature"  );
+
+  lastA.clear();
+  hns->getRecentFeatures(el1, lastA, "ToolTestA" );
+  if ( lastA.empty() ) 
+    REPORT_AND_STOP( "getLastFeature retrieves null" );
+  if ( lastA.back()->a != 3 ) 
+    REPORT_AND_STOP ( "getLastFeature retrieves wrong feature" );
+
+  REPORT_AND_CONTINUE("Get features worked fine");
+
+  END_TEST;
+}
+
+//****************************************************************************************
+TestBContainer* makeTestB(int value, size_t size=3) {
+  TestBContainer * tb = new TestBContainer;
+  TestAuxB* aux = new TestAuxB; // this will leak memory but it is more convenient for testing
+  tb->setStore(aux);
+  for ( size_t i = 0; i < size; ++i )
+    tb->push_back(new TestB(value));  
+
+  return tb;
+}
+
+
+StatusCode container_feature_test(HLT::Navigation* hns) {
+  BEGIN_TEST("container feature operations test");
+  TriggerElement* clu1        = getTE(hns, 111);
+  TriggerElement* track1      = getTE(hns, 1111);
+  TriggerElement* el1      = getTE(hns, 11111);
+
+  TestBContainer *tb1 = makeTestB(1);
+  std::string key;
+  hns->attachFeature(clu1, tb1, HLT::NavigationCore::ObjectCreatedByNew, key, "Test1");
+
+  TestBContainer * tb2 = makeTestB(2, 2);
+  hns->attachFeature(clu1, tb2, HLT::NavigationCore::ObjectCreatedByNew, key, "BContainer2"); // this one has Aux
+  
+  // get from the derived TE
+  const TestBContainer *bret(0);
+  hns->getRecentFeature(el1, bret);
+  if ( bret == 0 )
+    REPORT_AND_STOP( "Failed to get back last container container feature" );
+
+  if ( bret->size() != 2 )
+    REPORT_AND_STOP( "Failed to get back correct last container container feature" );
+  
+  //  if ( bret->getStore() == 0 ) 
+  //    REPORT_AND_STOP( "What we got back for the decorated has no decoration" );
+
+  bret = 0;
+  hns->getRecentFeature(el1, bret, "Test1");
+  if ( bret == 0)
+    REPORT_AND_STOP( "getRecentFeature does not respect labels" );
+
+  
+  END_TEST;
+}
+
+
+
+
+//****************************************************************************************
+StatusCode serialize_test(HLT::Navigation* hns, HLT::Navigation* newhns) {
+  BEGIN_TEST("serialize test");
+  std::vector<uint32_t> serialized;
+  std::vector<unsigned> breaks;
+  hns->serialize(serialized, breaks);
+  
+
+  newhns->deserialize(serialized);
+  REPORT_AND_CONTINUE( "serialize/deserialze sequence worked" );
+
+
+  if ( not HLT::Navigation::isCompatibleTree(newhns->getInitialNode(), hns->getInitialNode() ) ) 
+    REPORT_AND_STOP( "serialization/deserialization does not rebuild the the same structure" );
+
+
+  END_TEST;
+}
+
+StatusCode const_attach_test(HLT::Navigation* hns) {
+  BEGIN_TEST("const attach test");
+  typedef ConstDataVector<TestBContainer> ConstTestBContainer; // this is container of consts
+  ConstTestBContainer* cb = new ConstTestBContainer;
+  cb->push_back(new TestB(68));
+  cb->push_back(new TestB(78));
+  std::string key;
+  TriggerElement* el1      = getTE(hns, 11111);
+ 
+  if ( hns->attachFeature(el1, cb, HLT::NavigationCore::ObjectCreatedByNew, key, "ConstBContainer") == false )
+    REPORT_AND_STOP("attach of ConsTestBContainer failed");
+
+  const ConstTestBContainer* rcb{nullptr};
+  if ( hns->getFeature(el1, rcb) == false ) 
+    REPORT_AND_STOP("Retrieve of the ConstTestBContainer failed");
+
+  if ( rcb == nullptr ) 
+    REPORT_AND_STOP("Retrieve of the ConstTestBContainer failed, the pointer is 0");
+  if ( rcb->at(0)->value() != 68 ) 
+    REPORT_AND_STOP("Got incorrect container");
+
+
+  // now try to reuse some TestB obect stored in another non-const container
+  const TestBContainer* tb2{nullptr};
+  TriggerElement* clu1        = getTE(hns, 111);
+  const bool stat =  hns->getFeature(clu1, tb2, "BContainer2"); 
+  if ( stat == false ) 
+    REPORT_AND_STOP("Can not get the non-const TestBContainer object, error");
+  if ( tb2 == nullptr ) 
+    REPORT_AND_STOP("Can not get the non-const TestBContainer object, pointer is null");
+
+  REPORT_AND_CONTINUE("Got the already attached container "<< tb2->size());
+
+  if ( tb2->size() != 2 )
+    REPORT_AND_STOP("Can not get the non-const TestBContainer object, size is to small");
+  ConstTestBContainer* cb2 = new ConstTestBContainer;
+  cb2->push_back(tb2->at(1));
+  if ( cb2->size() != 1 ) 
+    REPORT_AND_STOP("Can not push_back into the ConstTestBContainer");
+
+  REPORT_AND_CONTINUE("Prepared ConstTestBContainer wiht contnt already present in another non-cont container" );
+
+  if ( hns->attachFeature(el1, cb2, HLT::NavigationCore::ObjectCreatedByNew, key, "ConstBContainer2") == false )
+    REPORT_AND_STOP("Can not attach ConstTestBContainer");
+  
+
+  END_TEST;
+}
+
+
+//****************************************************************************************
+int main () {
+  using std::cerr;
+  using std::endl;
+  using std::hex;
+  using std::dec;
+  //  blah2();
+
+  //  using namespace Athena_test;
+
+
+  ISvcLocator* pSvcLoc;
+  if (!Athena_test::initGaudi("test.txt",  pSvcLoc)) {
+    cerr << "ERROR This test can not be run" << endl;
+    return 0;
+  }
+  assert(pSvcLoc);
+
+
+  MsgStream log(Athena::getMessageSvc(), "HLTNavigation_test");
+  msglog = &log;
+
+
+  StoreGateSvc* pStore(0);
+
+
+  if( pSvcLoc->service("StoreGateSvc", pStore, true).isSuccess() ) {
+    log << MSG::DEBUG << "SG pointer: " << pStore << endreq;
+  } else REPORT_AND_STOP( "no SG available" );
+
+
+  IToolSvc* toolSvc;
+
+  if( pSvcLoc->service("ToolSvc", toolSvc, true).isSuccess()  ) {
+    log << MSG::DEBUG << "ToolSvc pointer: " << toolSvc << endreq;
+  } else 
+    ABORT ( "no ToolSvc available" );
+
+
+  HLT::Navigation* hns;
+  IAlgTool* algTool;
+  if ( toolSvc->retrieveTool("HLT::Navigation/Navigation", algTool).isSuccess() ) {
+    log << MSG::DEBUG << "OK navigation tool retrieved" << endreq;
+    hns = dynamic_cast< HLT::Navigation*>(algTool);
+    if ( hns ) {
+      log << MSG::DEBUG << "OK navigation casted" << endreq;    
+    } else 
+      ABORT( "navigation cast failed" );    
+
+  } else ABORT ("navigation tool NOT retrieved" );
+
+
+  hns->reset();
+  
+  if ( construction_test(hns).isFailure() ) 
+    ABORT("TEs construction test failed");
+
+
+  if ( counting_test(hns).isFailure() ) 
+    ABORT("Counting test failed");
+
+
+  if ( topo_test(hns).isFailure() ) 
+    ABORT("Topo test failed");
+
+
+  if ( single_feature_test(hns).isFailure() ) 
+    ABORT("Single feature manipulation");
+
+  if ( container_feature_test(hns).isFailure() ) 
+    ABORT("Container feature manipulation");
+
+  if ( const_attach_test(hns).isFailure() ) {
+    ABORT("ConstDV attaching test failed");
+  }
+  //  log << MSG::DEBUG << pStore->dump() << endreq;
+  
+
+  HLT::Navigation* newhns;
+  if ( toolSvc->retrieveTool("HLT::Navigation/Navigation2", algTool).isSuccess() ) {
+    REPORT_AND_CONTINUE( "OK navigation tool retrieved" );
+    newhns = dynamic_cast< HLT::Navigation*>(algTool);
+  }
+  if ( serialize_test(hns, newhns).isFailure() )
+    ABORT( "Serialization test failed" );
+
+
+  
+  
+  REPORT_AND_CONTINUE( "SUCCESS test passed OK " );
+
+  
+  return 0;
+
+}
+
diff --git a/Trigger/TrigEvent/TrigNavigation/test/Holder_test.cxx b/Trigger/TrigEvent/TrigNavigation/test/Holder_test.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..7d53e2ad710587b85fab56a79503f57279613348
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/test/Holder_test.cxx
@@ -0,0 +1,273 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "iostream"
+#include "vector"
+
+#include "TestTools/initGaudi.h"
+#include "AthenaKernel/getMessageSvc.h"
+#include "GaudiKernel/MsgStream.h"
+#include "StoreGate/StoreGate.h"
+#include "StoreGate/StoreGateSvc.h"
+#include "TrigNavigation/Holder.h"
+#include "TrigNavigation/Holder.icc"
+
+#include "TrigNavigation/TriggerElement.h"
+
+#include "TestTypes.h"
+#include "TestUtils.h"
+
+using namespace std;
+using namespace HLTNavDetails;
+// Hi-lock: (("REPORT_AND_STOP" (0 (quote hi-yellow) t)))
+
+//const int OK=1;
+//const int FAILED=0;
+
+StoreGateSvc* pStore(0);
+
+
+
+
+
+template<class HTYPE> 
+StatusCode reg( HTYPE* full, const char* name, int idx, ITypeProxy* /*aux*/, typename HTYPE::base_type*& base_holder ) {
+  BEGIN_TEST("Registration");
+  IHolder* iholder = full->clone(name, idx);
+  if ( ! iholder ) REPORT_AND_STOP ("Holder can't create IHolder" );
+
+  base_holder = dynamic_cast<typename HTYPE::base_type*>(iholder); // we do nto intend to do it but here it is to see if types realy fit
+  if ( ! base_holder ) REPORT_AND_STOP ("Holder can't create base holder" );
+  
+
+  iholder->prepare(msglog, pStore);
+  if ( iholder->syncWithSG() == false ) REPORT_AND_STOP( "can not sync wiht holder" );
+  
+  END_TEST;
+}
+
+//*****************************************************************************
+StatusCode creation() {
+  BEGIN_TEST( "Creation of the holders Container <-> Container" );
+  Holder<TestBContainer >* cc(0);
+
+  if (  reg(new HolderImp<TestBContainer, TestBContainer >() , "creation0", 0, 0, cc).isFailure() ) REPORT_AND_STOP( "reg creation0" );
+
+  REPORT_AND_CONTINUE( "Creation of the holders Object <-> Container" );
+  Holder<TestA>* oc(0); 
+  if ( reg(new HolderImp<TestA, TestAContainer >(), "creation1", 1, 0, oc).isFailure() ) REPORT_AND_STOP("reg creation1") ;
+  
+
+  //////////////////////////////////////////////////////////////////
+  REPORT_AND_CONTINUE( "Creation of the holders Container <-> Container with details" );
+  ITypeProxy* deco = HLT::TypeMaps::proxies()[ClassID_traits<TestAuxB>::ID()]->clone();
+  Holder<TestBContainer >* cc_dec(0) ; 
+  if ( reg(new HolderImp<TestBContainer, TestBContainer >(), "creation2", 2, deco, cc_dec).isFailure() ) REPORT_AND_STOP("reg creation2") ;
+
+
+  REPORT_AND_CONTINUE( "Creation of the holders Object <-> Container" );
+  Holder<TestA>* oc_dec(0); 
+  if ( reg(new HolderImp<TestA, TestAContainer >(), "creation3", 3, deco, oc_dec).isFailure() ) REPORT_AND_STOP("reg creation3") ;
+
+  END_TEST;
+}
+
+//*****************************************************************************
+StatusCode add_operation(bool wihtAux) {
+  BEGIN_TEST ( "Simple test of Container <-> Container holder (add)" );
+  ITypeProxy* deco(0);
+  if (wihtAux)
+    deco = HLT::TypeMaps::proxies()[ClassID_traits<TestAuxB>::ID()]->clone();
+
+  Holder<TestBContainer>* cch(0);
+  if ( reg( new HolderImp<TestBContainer, TestBContainer>(), "TestB", 11, deco, cch).isFailure() ) REPORT_AND_STOP("It should have failed before");
+
+  TestBContainer* dav0 = new TestBContainer;;
+  dav0->push_back(new TestB(6));
+  REPORT_AND_CONTINUE( "adding simple vec" );
+  HLT::TriggerElement::ObjectIndex single = cch->add(dav0, false);
+
+  //  BContainer dav(SG::OWN_ELEMENTS);
+  TestBContainer* dav = new TestBContainer;
+  dav->push_back(new TestB(1));
+  dav->push_back(new TestB(2));
+
+  REPORT_AND_CONTINUE( "Added another ownership" );
+  pStore->record(dav, "dav1").ignore();
+  HLT::TriggerElement::ObjectIndex two =  cch->add(dav, true);
+
+  TestBContainer* dav2 = new TestBContainer;
+  dav2->push_back(new TestB(3));
+  dav2->push_back(new TestB(4));  
+
+  REPORT_AND_CONTINUE( "Added another ownership -with the hint" );
+  pStore->record(dav2, "dav2").ignore();
+  HLT::TriggerElement::ObjectIndex three =  cch->add(dav2, true, "dav2");
+
+  REPORT_AND_CONTINUE( "Adding a VIEW container" );
+  TestBContainer* dav3 = new TestBContainer;
+  dav3->clear(SG::VIEW_ELEMENTS);
+  dav3->push_back(new TestB(7));
+  dav3->push_back(new TestB(7));
+
+  HLT::TriggerElement::ObjectIndex four =  cch->add(dav3, false, "dav3");
+
+  // retieve back the information
+  {
+    const TestBContainer* getv(0);
+    cch->get(getv, single);
+    if ( (*getv)[0]->value() != 6 ) 
+      REPORT_AND_STOP( "Content missing or reordered -single feature in the container)");
+  }
+  {
+    const TestBContainer* getv(0);
+    cch->get(getv, two);
+    if ( getv->size() != 2 or (*getv)[0]->value() != 1 or (*getv)[1]->value() != 2 ) 
+      REPORT_AND_STOP( "Content missing or reordered -single feature in the container)");
+  }
+
+  {
+    const TestBContainer* getv(0);
+    cch->get(getv, three);
+    if ( getv->size() != 2 or (*getv)[0]->value() != 3 or (*getv)[1]->value() != 4 ) 
+      REPORT_AND_STOP( "Content missing or reordered - single feature in the container)");
+  }
+  REPORT_AND_CONTINUE( "END Simple test of Container <-> Container holder -add-" );
+  ///////////////////////////////////////////////////////////////////////////// 
+
+  REPORT_AND_CONTINUE( "END Simple test of Object <-> Container holder -add-" );
+  Holder<TestA>* och(0); 
+  if ( reg(new HolderImp<TestA, TestAContainer >(), "TestA", 12, deco, och).isFailure() ) REPORT_AND_STOP("reg TestA") ;
+
+  TestA* an = new TestA(235);
+  HLT::TriggerElement::ObjectIndex coord = och->add(an, true); 
+  //  HLT::TriggerElement::ObjectIndex ancoord = coord;
+  const TestA* aback(0);
+  if ( och->get(aback, coord) == false ) 
+    REPORT_AND_STOP ("Content missing of single feature" );
+  
+  if ( aback == 0 ) REPORT_AND_STOP ("Content is none" );
+
+  if ( aback->value() != 235 ) REPORT_AND_STOP ( "Content is different" );
+
+  END_TEST;
+}
+
+//*****************************************************************************
+StatusCode contains_operations() {
+  BEGIN_TEST("Operations");
+  Holder<TestBContainer>* cch(0);
+  if ( reg( new HolderImp<TestBContainer, TestBContainer>(), "TestB", 11, 0, cch).isFailure() ) REPORT_AND_STOP("It should have failed before");
+  TestB* b0 = new TestB(67);
+  TestBContainer * t = new TestBContainer();
+  t->push_back( new TestB(9) );
+  t->push_back(b0);
+  t->push_back( new TestB(8) );
+  if ( not cch->add(t, false, "whatever").valid() )
+    REPORT_AND_STOP("adding failed");
+  HLT::TriggerElement::ObjectIndex testidx;
+  if ( not cch->contains(t, testidx) ) 
+    REPORT_AND_STOP("Holder should have this pointer");
+
+  TestBContainer * t2 = new TestBContainer();
+  t2->push_back( new TestB());
+  if ( cch->contains(t2, testidx) ) 
+    REPORT_AND_STOP("Holder should not have this pointer");
+
+  END_TEST;
+}
+
+//*****************************************************************************
+StatusCode serialization() {
+  BEGIN_TEST("serialization");
+  Holder<TestBContainer>* cch(0);
+  if ( reg( new HolderImp<TestBContainer, TestBContainer>(), "blu", 2, 0, cch).isFailure() ) REPORT_AND_STOP("It should have failed before");
+  IHolder * realH = cch;
+  std::vector<uint32_t>  blob;
+  
+  CLID c;
+  uint16_t idx;
+  string label;
+
+  realH->serialize(blob);
+
+  REPORT_AND_CONTINUE( "blob size " << blob.size() );
+  std::vector<uint32_t>::const_iterator it = blob.begin();
+
+
+  IHolder::enquireSerialized(blob, it, c, label, idx);
+  *msglog << MSG::DEBUG  << "INFO clid  : " << c << endreq;  
+  *msglog << MSG::DEBUG  << "INFO STidx : " << idx << endreq;  
+  *msglog << MSG::DEBUG  << "INFO label : " << label << endreq;  
+  if ( label != "blu" || idx != 2 || c != ClassID_traits<TestBContainer>::ID() ) 
+    REPORT_AND_STOP ( "serialization or inquire failed" );
+  
+  END_TEST;
+}
+//*****************************************************************************
+int main() {
+
+
+   ISvcLocator* pSvcLoc;
+   if (!Athena_test::initGaudi("test.txt",  pSvcLoc)) {
+     cerr << "ERROR This test can not be run" << endl;
+     return 0;
+   }
+   assert(pSvcLoc);
+   MsgStream log(Athena::getMessageSvc(), "Holder_test");
+   msglog = &log;
+
+  if( pSvcLoc->service("StoreGateSvc", pStore, true).isSuccess() ) {
+    *msglog << MSG::DEBUG << "SG pointer: " << pStore << endreq;
+  } else {
+    ABORT( "ERROR no SG available" );
+  }
+
+  if ( creation().isFailure() ) 
+    ABORT("Holders creation failed");
+
+  *msglog << MSG::DEBUG << pStore->dump();
+  *msglog << endreq;
+
+  pStore->clearStore();
+  if ( add_operation(false).isFailure() )
+    ABORT("Failed add_operation w/o Aux");
+
+  pStore->clearStore();
+  *msglog << MSG::DEBUG << "Holders with decorations "  << endreq;
+  if ( add_operation(true).isFailure() )
+    ABORT("Failed add_operation with Aux");
+
+  pStore->clearStore();
+  *msglog << MSG::DEBUG << "Contains and co. methods "  << endreq;
+  if ( contains_operations().isFailure() )
+    ABORT("Failed contains_operations");
+
+
+  *msglog << MSG::DEBUG << "Serialization "  << endreq;
+  if ( serialization().isFailure() )
+    ABORT("Failed serialization");
+
+
+  REPORT_AND_CONTINUE( "END all went fine" );
+  return 0;
+
+
+  /*
+
+
+
+
+
+  //////////////////////////////////////////////////////////////////
+  *msglog << MSG::DEBUG << "Serialization test" << endreq;
+  std::vector<uint32_t>
+  
+  //  pStore->clearStore();
+  */
+  *msglog << MSG::INFO << "SUCCESS " << endreq;
+  *msglog << MSG::DEBUG << "deleting messages below are related to scope exit " << endreq;
+  
+  return 0;
+}
diff --git a/Trigger/TrigEvent/TrigNavigation/test/Ownership_test.cxx b/Trigger/TrigEvent/TrigNavigation/test/Ownership_test.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..6f2f4e183dc53c85779aaaf61890bbeff65a0514
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/test/Ownership_test.cxx
@@ -0,0 +1,187 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "iostream"
+#include "vector"
+
+#include "TestTools/initGaudi.h"
+#include "AthenaKernel/getMessageSvc.h"
+#include "GaudiKernel/MsgStream.h"
+#include "StoreGate/StoreGate.h"
+#include "StoreGate/StoreGateSvc.h"
+#include "TrigNavigation/Holder.h"
+#include "TrigNavigation/Holder.icc"
+
+#include "TrigNavigation/TriggerElement.h"
+
+#include "TestTypes.h"
+#include "TestUtils.h"
+
+using namespace std;
+using namespace HLTNavDetails;
+using namespace HLT;
+// Hi-lock: (("REPORT_AND_STOP" (0 (quote hi-yellow) t)))
+
+//const int OK=1;
+//const int FAILED=0;
+
+StoreGateSvc* pStore(0);
+HLT::Navigation* hns;
+
+
+template <class T> 
+std::string view_or_own (T* c) {
+  return ((c->ownPolicy() == SG::VIEW_ELEMENTS) ? "VIEW" : "OWN");
+}
+
+TriggerElement * makeTE(HLT::Navigation* hns) {
+  TriggerElement* initial =  hns->getInitialNode();
+  TriggerElement* roi =  hns->addRoINode(initial);
+  TriggerElement* te =  hns->addNode(roi, 23);
+  return te;
+}
+
+
+TestBContainer* makeContainer(SG::OwnershipPolicy policy, int initval) {
+  TestBContainer* c = new TestBContainer();
+  c->clear(policy);
+  c->push_back(new TestB(initval));
+  c->push_back(new TestB(initval));
+  c->push_back(new TestB(initval+1));
+  return c;
+  
+}
+
+StatusCode noMixTest() {
+  BEGIN_TEST("noMixTest");
+  pStore->clearStore();
+  hns->reset();
+  hns->prepare();
+  
+  TestBContainer *b1 = makeContainer(SG::OWN_ELEMENTS, 2);
+  TestBContainer *b2 = makeContainer(SG::VIEW_ELEMENTS, 77);
+  TriggerElement* te =  makeTE(hns);
+  REPORT_AND_CONTINUE("Objects prepared");
+  std::string key_back; 
+
+  bool stat = hns->attachFeature(te, b1, Navigation::ObjectCreatedByNew, key_back, "BContainer1");  
+  if (  stat == false ) {
+    REPORT_AND_STOP("attachFeature failed");
+  }
+
+  REPORT_AND_CONTINUE("After attachFeture the container is " << view_or_own(b1));
+
+  stat = hns->attachFeature(te, b2, Navigation::ObjectCreatedByNew, key_back, "BContainer1");  
+  if (  stat == true ) {
+    REPORT_AND_STOP("attachFeature worked while it should not");
+  }
+  REPORT_AND_CONTINUE("The attachFeature was unsuccesfull");
+
+  END_TEST;
+}
+
+StatusCode firsInsertDecidesPolicy() {
+  BEGIN_TEST("testing if the insert operation on an empty container makes it a view container");
+  pStore->clearStore();
+  hns->reset();
+  hns->prepare();
+  
+  TestDContainer *b1 = new TestDContainer();
+  b1->clear(SG::VIEW_ELEMENTS, SG::NEVER_TRACK_INDICES);
+  b1->push_back(new TestD(9));
+  b1->push_back(new TestD(10));
+
+  TriggerElement* te =  makeTE(hns);
+  REPORT_AND_CONTINUE("Objects prepared");
+  std::string key_back; 
+
+  const TestDContainer* ewise(0);
+  if ( pStore->retrieve(ewise, "HLT_TestDContainer_DContainer1").isFailure() ) {
+    REPORT_AND_CONTINUE(pStore->dump());
+    REPORT_AND_STOP("could not get the event-wise container from SG");
+  }
+
+  REPORT_AND_CONTINUE("Event wise container has ownership policy " << view_or_own(ewise));  
+  if ( view_or_own(ewise) != "OWN" ) {
+    REPORT_AND_STOP("At start the event wise container is not OWNing");
+  }
+
+  // tested code
+  bool stat = hns->attachFeature(te, b1, Navigation::ObjectCreatedByNew, key_back, "DContainer1");  
+  if (  stat == false ) {
+    REPORT_AND_STOP("attachFeature failed");
+  }
+
+  ewise = 0;
+  if ( pStore->retrieve(ewise, "HLT_TestDContainer_DContainer1").isFailure() ) {
+    REPORT_AND_STOP("could not get the event-wise container from SG");
+  }
+
+  REPORT_AND_CONTINUE("After attachFeture the container is " << view_or_own(ewise));
+  if ( view_or_own(ewise) != "VIEW" ) {
+    REPORT_AND_STOP("At end the event wise container is not VIEW");
+  }
+
+  END_TEST;
+}
+
+
+
+int main() {
+
+
+   ISvcLocator* pSvcLoc;
+   if (!Athena_test::initGaudi("test.txt",  pSvcLoc)) {
+     cerr << "ERROR This test can not be run" << endl;
+     return 0;
+   }
+   assert(pSvcLoc);
+   MsgStream log(Athena::getMessageSvc(), "Ownership_test");
+   msglog = &log;
+
+  if( pSvcLoc->service("StoreGateSvc", pStore, true).isSuccess() ) {
+    *msglog << MSG::DEBUG << "SG pointer: " << pStore << endreq;
+  } else {
+    ABORT( "ERROR no SG available" );
+  }
+
+  IToolSvc* toolSvc;
+
+  if( pSvcLoc->service("ToolSvc", toolSvc, true).isSuccess()  ) {
+    log << MSG::DEBUG << "ToolSvc pointer: " << toolSvc << endreq;
+  } else 
+    ABORT ( "no ToolSvc available" );
+
+
+
+  IAlgTool* algTool;
+  if ( toolSvc->retrieveTool("HLT::Navigation/Navigation", algTool).isSuccess() ) {
+    log << MSG::DEBUG << "OK navigation tool retrieved" << endreq;
+    hns = dynamic_cast< HLT::Navigation*>(algTool);
+    if ( hns ) {
+      log << MSG::DEBUG << "OK navigation casted" << endreq;    
+    } else 
+      ABORT( "navigation cast failed" );    
+
+  } else  ABORT("navigation tool NOT retrieved" );
+
+  if ( firsInsertDecidesPolicy().isFailure() ) 
+    ABORT("");
+  
+  
+
+  if ( noMixTest().isFailure() ) 
+    ABORT("");
+  
+  
+
+
+  REPORT_AND_CONTINUE( "END all went fine" );
+  return 0;
+
+  *msglog << MSG::INFO << "SUCCESS " << endreq;
+  *msglog << MSG::DEBUG << "deleting messages below are related to scope exit " << endreq;
+  
+  return 0;
+}
diff --git a/Trigger/TrigEvent/TrigNavigation/test/Registration_test.cxx b/Trigger/TrigEvent/TrigNavigation/test/Registration_test.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..8ec41b76f767f76ab30acbabd7dbac11a9c4cb73
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/test/Registration_test.cxx
@@ -0,0 +1,102 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include <sys/time.h>
+#include <iostream>
+#include <iterator>
+#include "GaudiKernel/ClassID.h"
+#include "GaudiKernel/MsgStream.h"
+#include "StoreGate/StoreGate.h"
+#include "StoreGate/StoreGateSvc.h"
+#include "AthenaKernel/getMessageSvc.h"
+
+#include "TestTools/initGaudi.h"
+
+
+#include "TrigNavigation/TypeMaps.h"
+#include "TrigNavigation/TriggerElement.h"
+#include "TrigNavigation/Navigation.h"
+#include "TrigNavigation/RoICacheHelper.h"
+#include "TrigNavigation/TrigFeatureLink.h"
+
+
+
+// tests hack
+#include "TestTypes.h"
+#include "TestUtils.h"
+
+
+int main () {
+
+  //  using namespace Athena_test;
+  using namespace std;
+  using namespace HLT;
+
+
+  ISvcLocator* pSvcLoc;
+  if (!Athena_test::initGaudi("test.txt",  pSvcLoc)) {
+    cerr << "ERROR This test can not be run" << endl;
+    return 0;
+  }
+  assert(pSvcLoc);
+
+
+  MsgStream log(Athena::getMessageSvc(), "Registration_test"); 
+  msglog = &log;
+
+
+
+  StoreGateSvc* pStore(0);
+
+
+  if( pSvcLoc->service("StoreGateSvc", pStore, true).isSuccess() ) {
+    log << MSG::DEBUG << "SG pointer: " << pStore << endreq;
+  } else 
+    ABORT ( "ERROR no SG available" );
+  
+  IToolSvc* toolSvc;
+
+  if( pSvcLoc->service("ToolSvc", toolSvc, true).isSuccess()  ) {
+    log << MSG::DEBUG << "ToolSvc pointer: " << toolSvc << endreq;
+  } else 
+    ABORT( "ERROR no ToolSvc available" );
+
+
+  HLT::Navigation* hns;
+  IAlgTool* algTool;
+  if ( toolSvc->retrieveTool("HLT::Navigation/Navigation", algTool).isSuccess() ) {
+    log << MSG::DEBUG << "OK navigation tool retrieved" << endreq;
+    hns = dynamic_cast< HLT::Navigation*>(algTool);
+    if ( hns ) {
+      log << MSG::DEBUG << "OK navigation casted" << endreq;    
+    } else 
+      ABORT( "ERROR navigation casted" );    
+    
+  } else 
+    ABORT( "ERROR navigation tool NOT retrieved" );
+
+
+  hns->reset( );
+  hns->prepare();
+
+
+  /*
+  TestC* c = new TestC();
+  std::string key;
+  hns->attachFeature(hns->getInitialNode(), c, HLT::Navigation::ObjectCreatedByNew, key);
+
+  TrigFeatureLink fl = hns->object2FeatureLink(hns->getInitialNode(), key, c );
+  log << MSG::DEBUG << "fl " << fl.clid() << endreq;
+  const TestC* c_back = hns->featureLink2Object<TestC>(fl);
+  if ( c_back != c ) {
+    log << MSG::ERROR << "failing the TrigFeatureLink get/restore"  << endreq;
+  } else {
+    log << MSG::DEBUG << "TrigFeatureLink worked ok" << endreq;
+  }
+  */
+
+  log << MSG::DEBUG << pStore->dump() << endreq;
+  REPORT_AND_CONTINUE ( "Test finished" );
+  return 0;
+}
diff --git a/Trigger/TrigEvent/TrigNavigation/test/RoICache_test.cxx b/Trigger/TrigEvent/TrigNavigation/test/RoICache_test.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..e072fe2ea3abb3e9ff5949b14639cba5294dc701
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/test/RoICache_test.cxx
@@ -0,0 +1,363 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "GaudiKernel/ClassID.h"
+#include "GaudiKernel/MsgStream.h"
+#include "StoreGate/StoreGate.h"
+#include "StoreGate/StoreGateSvc.h"
+#include "AthenaKernel/getMessageSvc.h"
+
+
+
+#include "TestTools/initGaudi.h"
+
+#include "TrigNavigation/TriggerElement.h"
+
+#include "TrigNavigation/Navigation.h"
+#include "TrigNavigation/RoICacheHelper.h"
+
+#include "TestUtils.h"
+
+#include "TestTypes.h"
+#include "TestUtils.h"
+
+using namespace HLT;
+HLT::Navigation* hns;
+
+template<class GET, class ATTACH>
+class Alg : public RoICacheHelper {
+public:
+  Alg(const std::string& name, GET get, ATTACH attach) 
+    : m_s (name), m_get(get), m_attach(attach) {}
+  
+
+  StatusCode execute(TriggerElement* output ) {
+    MsgStream log(Athena::getMessageSvc(), "RoICache_test:"+m_s);
+    MsgStream *msglog = &log;
+    BEGIN_TEST("One algorithm test "+m_s);
+    REPORT_REGTEST("executing on " << output->getId());
+    if (needsExecution(output)) {
+      REPORT_REGTEST( "REAL execution needed on " << output->getId());;
+      if ( !startCaching(output)  )
+	REPORT_AND_STOP( "start caching failed "  << output->getId() );
+     
+      // imagine hre hard work to work out A and B features
+      
+      if ( m_get(output).isFailure() ) 
+	REPORT_AND_STOP( "get failed" );
+      if ( m_attach(output).isFailure() )
+	REPORT_AND_STOP( "attach failed" );      
+      
+      if ( !stopCaching(output) )
+	REPORT_AND_STOP("stop Caching failed "  << output->getId() );
+    } else {
+      REPORT_REGTEST( "CACHED execution needed on "  << output->getId() );
+      if ( !cache(output) ){
+	REPORT_AND_STOP("The Caching failed "  << output->getId() );
+      }
+    }
+    END_TEST;
+  }
+private:
+  std::string m_s; 
+  GET m_get;
+  ATTACH m_attach;
+};
+
+template<class GET, class ATTACH>
+Alg<GET, ATTACH> createAlgo(const std::string& name, GET get, ATTACH attach) {
+  return Alg<GET, ATTACH>(name, get, attach);
+}
+
+
+
+int main() {
+  using namespace std;
+
+  MsgStream log(Athena::getMessageSvc(), "RoICache_test");
+
+  MsgStream* msglog = &log;
+  BEGIN_TEST("RoIcaching test");
+
+  ISvcLocator* pSvcLoc;
+  if (!Athena_test::initGaudi("test.txt",  pSvcLoc)) {
+    REPORT_AND_STOP("Can not intit Gaudi");
+  }
+  assert(pSvcLoc);
+
+
+  StoreGateSvc* pStore(0);
+
+
+  if( pSvcLoc->service("StoreGateSvc", pStore, true).isSuccess() ) {
+    REPORT_AND_CONTINUE("SG pointer: " << pStore );
+  } else {
+    REPORT_AND_STOP("SG not available");
+  }
+
+  IToolSvc* toolSvc;
+
+  if( pSvcLoc->service("ToolSvc", toolSvc, true).isSuccess()  ) {
+    REPORT_AND_CONTINUE("ToolSvc pointer obtained: " << toolSvc );
+  } else {
+    REPORT_AND_STOP( "ToolSvc not available");
+  }
+
+
+  IAlgTool* algTool;
+  if ( toolSvc->retrieveTool("HLT::Navigation/Navigation", algTool).isSuccess() ) {
+    REPORT_AND_CONTINUE("OK navigation tool retrieved" );
+    hns = dynamic_cast< HLT::Navigation*>(algTool);
+    if ( hns ) {
+      REPORT_AND_CONTINUE("OK navigation casted" );
+    } else {
+      REPORT_AND_STOP("navigation not casted" );    
+    }
+  } else {
+    REPORT_AND_STOP( "ERROR navigation tool NOT retrieved" );
+  }
+
+  hns->reset();
+
+  
+ 
+  TriggerElement* initial =  hns->getInitialNode();
+
+  // we make an RoI with 3 branches 2 identical and one slightly modified (with different feature)
+  // let's make obejcts first
+  
+  TriggerElement* roi0 = hns->addRoINode(initial);
+  TriggerElement* roi1 = hns->addRoINode(initial);
+
+  std::string key;
+  TestA* a0 = new TestA(-34);
+  hns->attachFeature(roi0, a0, Navigation::ObjectCreatedByNew, key, "initialRoI");
+
+  TestA* a1 = new TestA(-34);
+  hns->attachFeature(roi1, a1, Navigation::ObjectCreatedByNew, key, "initialRoI");
+
+  TriggerElement* thresholdA = hns->addNode(roi0, 1);
+  TriggerElement* thresholdB = hns->addNode(roi0, 2);
+  TriggerElement* thresholdC = hns->addNode(roi0, 3);
+  TriggerElement* thresholdD = hns->addNode(roi0, 4);
+
+  TriggerElement* thresholdA1 = hns->addNode(roi1, 1);
+
+
+  
+  // make next layer
+  TriggerElement* clusterA = hns->addNode(thresholdA, 11);
+  TriggerElement* clusterB = hns->addNode(thresholdB, 12);
+  TriggerElement* clusterC = hns->addNode(thresholdC, 13);
+  TriggerElement* clusterD = hns->addNode(thresholdD, 14);
+
+  TriggerElement* clusterA1 = hns->addNode(thresholdA1, 1200);
+
+  REPORT_AND_CONTINUE("Navigation structure built");
+
+  auto calo = createAlgo("calo", 
+			 [](TriggerElement* te) -> StatusCode {   // get RoI
+			   const TestA* back(0);
+			   const TriggerElement* tsource;
+			   std::string  lsource;
+			   hns->getRecentFeature(te, back, "", tsource, lsource);
+			   return StatusCode::SUCCESS;
+			 }, 
+			 [](TriggerElement* te) -> StatusCode { // produces xAOD like type TestBContainer
+			   TestBContainer* a = new TestBContainer;
+			   TestAuxB aux;
+			   a->setStore(&aux);
+			   std::string key;
+			   hns->attachFeature(te, a, Navigation::ObjectCreatedByNew, key, "made_by_calo");	     	  
+			   return StatusCode::SUCCESS;
+			 });
+  if( calo.execute(clusterA).isFailure() ) ABORT("");
+  if( calo.execute(clusterB).isFailure() ) ABORT("");  
+  if( calo.execute(clusterC).isFailure() ) ABORT("");
+  if( calo.execute(clusterD).isFailure() ) ABORT("");
+
+  if( calo.execute(clusterA1).isFailure() ) ABORT("");
+
+  REPORT_AND_CONTINUE("Executed calo on clusters");
+    
+  // idea here is that only two clusters out of 4 obtain extra object
+  // next algo will depend on this extra objects and there shoudl be apropriate caching kicking in only wto times
+  auto caloaux = createAlgo("caux", 
+			    [](TriggerElement* te) -> StatusCode { // require TestBContainer
+			      const TestBContainer* back(0);
+			      const TriggerElement* tsource;
+			      std::string  lsource;
+			      hns->getRecentFeature(te, back, "", tsource, lsource);
+			      return StatusCode::SUCCESS; 
+			    },
+			    [](TriggerElement* te) -> StatusCode {
+			      TestA* a = new TestA(-38); 
+			      std::string key;
+			      hns->attachFeature(te, a, Navigation::ObjectCreatedByNew, key, "refined_by_aux");	     	  
+			      return StatusCode::SUCCESS; 
+			    }
+			    );
+  if( caloaux.execute(clusterC).isFailure() ) ABORT("");
+  if( caloaux.execute(clusterD).isFailure() ) ABORT("");
+
+
+
+  //log << MSG::INFO << "\n" << *hns << endreq;
+
+  auto calo2 = createAlgo("calo2",
+			  [&](TriggerElement* te) -> StatusCode {   // get RoI
+			    const TestA* back(0);
+			    const TriggerElement* tsource;
+			    std::string  lsource;
+			    hns->getRecentFeature(te, back, "", tsource, lsource);
+			    REPORT_AND_CONTINUE("got back object " << back->value());
+			    return StatusCode::SUCCESS;
+			  }, 
+			  [](TriggerElement* te) -> StatusCode { // produces xAOD like type TestBContainer
+			    TestBContainer* a = new TestBContainer;
+			    TestAuxB aux;
+			    a->setStore(&aux);
+			    std::string key;
+			    hns->attachFeature(te, a, Navigation::ObjectCreatedByNew, key, "made_by_calo2");	     	  
+			    return StatusCode::SUCCESS;
+			  });
+  if( calo2.execute(clusterD).isFailure() )    ABORT("");
+  if( calo2.execute(clusterC).isFailure() )    ABORT("");
+  if( calo2.execute(clusterB).isFailure() )    ABORT("");
+  if( calo2.execute(clusterA).isFailure() )    ABORT("");
+
+  if( calo2.execute(clusterA1).isFailure() )    ABORT("");
+
+  REPORT_AND_CONTINUE("Executed c2 on clusters");
+
+
+
+  //log << MSG::INFO << "\n" << *hns << endreq;
+
+  
+  TriggerElement* trackA = hns->addNode(clusterA, 101);
+  TriggerElement* trackB = hns->addNode(clusterB, 102);
+  TriggerElement* trackC = hns->addNode(clusterC, 103);
+  TriggerElement* trackD = hns->addNode(clusterD, 104);
+
+
+  TriggerElement* trackA1 = hns->addNode(clusterA1, 10100);
+
+
+  // we expect now high level of caching as we dpend on the common object
+  auto trk = createAlgo("trk", 
+			[&](TriggerElement* te) -> StatusCode {   // get RoI
+			  const TestA* back(0);
+			  const TriggerElement* tsource;
+			  std::string  lsource;
+			  hns->getRecentFeature(te, back, "initialRoI", tsource, lsource);
+			  if ( back )  REPORT_AND_CONTINUE("got back object " << back->value());
+			  return StatusCode::SUCCESS;
+			}, 
+			[](TriggerElement* te) -> StatusCode { // produces xAOD like type TestBContainer
+			  TestC* a = new TestC(77);
+			  std::string key;
+			  hns->attachFeature(te, a, Navigation::ObjectCreatedByNew, key, "made_by_trk");	     	  
+			  return StatusCode::SUCCESS;
+			});
+  if( trk.execute(trackB).isFailure() )  ABORT("");
+  if( trk.execute(trackD).isFailure() )  ABORT("");
+  if( trk.execute(trackC).isFailure() )  ABORT("");
+  if( trk.execute(trackA).isFailure() )  ABORT("");
+  if( trk.execute(trackA1).isFailure() ) ABORT("");
+
+
+
+  REPORT_AND_CONTINUE("Executed trk");
+
+  // now lets make the TrackA look different by attaching there an object of different type  
+  {
+    TestC* c = new TestC(55);
+    std::string key;
+    hns->attachFeature(trackA, c, Navigation::ObjectCreatedByNew, key, "made_by_tr2");	    
+  }
+  
+
+
+  
+  TriggerElement* eleA = hns->addNode(trackA, 1001);
+  TriggerElement* eleB = hns->addNode(trackB, 1002);
+  TriggerElement* eleC = hns->addNode(trackC, 1003);
+  TriggerElement* eleD = hns->addNode(trackD, 1004);
+
+  TriggerElement* eleA1 = hns->addNode(trackA1, 100100);
+
+
+  auto matcher = createAlgo("matcher", 
+			    [&](TriggerElement* te) -> StatusCode {   // get RoI
+			      const TestC* back(0);
+			      const TriggerElement* tsource;
+			      std::string  lsource;
+			      hns->getRecentFeature(te, back, "", tsource, lsource);
+			      if ( back ) {
+				REPORT_AND_CONTINUE("got back object " << back->value());
+			      } else {
+				REPORT_AND_CONTINUE("no object retrieved");
+			      }
+			      return StatusCode::SUCCESS;
+			    }, 
+			    [](TriggerElement* te) -> StatusCode { // produces xAOD like type TestBContainer
+			      TestDContainer* a = new TestDContainer;
+			      a->push_back(new TestD(98));
+			      std::string key;
+			      hns->attachFeature(te, a, Navigation::ObjectCreatedByNew, key, "made_by_ma");	     	  
+			      return StatusCode::SUCCESS;
+			});
+  if( matcher.execute(eleA).isFailure() ) ABORT("");
+  if( matcher.execute(eleB).isFailure() ) ABORT("");
+  if( matcher.execute(eleC).isFailure() ) ABORT("");
+  if( matcher.execute(eleD).isFailure() ) ABORT("");
+  if( matcher.execute(eleA1).isFailure() ) ABORT("");
+  REPORT_AND_CONTINUE("Executed ma on electron TEs");
+  
+
+  
+
+
+  // now make another topological TEs and check caching on them
+  // A bit of explanation.
+  // We make 3 topological TEs.
+  // In terms of RoIs used in them they are identical (i.e. both use roi0, roi1 pair)
+  // Execution lines leading to eleC and eleD are identical. I.e. all algorithms cached.
+  // While execution line leading to eleA is different. We should observe that 
+  // there shoudl be caching on ovCA1 and ovDA1 while ovAA1 shoudl always be executed.
+  //
+  std::vector<TriggerElement*> v;
+  v.push_back(eleC);
+  v.push_back(eleA1);
+
+  TriggerElement* ovCA1 = hns->addNode(v, 222);
+  v[0] = eleD;
+  TriggerElement* ovDA1 = hns->addNode(v, 223);
+  v[0] = eleA;
+  TriggerElement* ovAA1 = hns->addNode(v, 224);
+
+  auto overlap = createAlgo ("overlap",
+			     [&](TriggerElement* te) -> StatusCode {   // get obj made by ma
+			       const TestDContainer* back(0);
+			       const TriggerElement* tsource;
+			       std::string  lsource;
+			       hns->getRecentFeature(te, back, "", tsource, lsource);
+			       return StatusCode::SUCCESS;
+			     }, 
+			     [](TriggerElement* ) -> StatusCode {
+			       return StatusCode::SUCCESS;
+			     });
+  if ( overlap.execute(ovCA1).isFailure() ) ABORT("");
+  if ( overlap.execute(ovDA1).isFailure() ) ABORT("");
+  if ( overlap.execute(ovAA1).isFailure() ) ABORT("");
+
+
+  REPORT_AND_CONTINUE("Executed on topo TEs");
+  REPORT_AND_CONTINUE("ALLOK");
+
+
+  //log << MSG::INFO << *hns << endreq;
+  return 0;
+}
diff --git a/Trigger/TrigEvent/TrigNavigation/test/TestTypes.h b/Trigger/TrigEvent/TrigNavigation/test/TestTypes.h
new file mode 100644
index 0000000000000000000000000000000000000000..c9f924665c9da1fb8d398384e17d234a3c1195c0
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/test/TestTypes.h
@@ -0,0 +1,118 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#pragma once
+
+#include "AthContainers/AuxElement.h"
+#include "xAODCore/AuxContainerBase.h"
+
+#define TRIGSTORAGEDEF_MERGEPACKS
+#include "TrigNavigation/TypeRegistration.h"
+
+HLT_BEGIN_TYPE_REGISTRATION
+  HLT_REGISTER_TYPE(struct TestA, struct TestA, struct DataVector<TestA>, struct TestAuxA)
+  HLT_REGISTER_TYPE(struct TestB, struct TestBContainer, struct TestBContainer, struct TestAuxB)
+  HLT_REGISTER_TYPE(struct TestC, struct TestC, struct DataVector<TestC>)
+  HLT_REGISTER_TYPE(struct TestD, struct TestDContainer, struct TestDContainer)
+HLT_END_TYPE_REGISTRATION(TrigNavigationUnitTest)
+
+#define LTYPEMAPCLASS(name)\
+  struct class_##name{\
+    typedef TypeInfo_##name map;\
+    static const std::string package_name;\
+  };
+
+LTYPEMAPCLASS(TrigNavigationUnitTest)
+
+struct TypeInfo_EDM {
+  typedef  HLT::TypeInformation::newlist
+  ::add<class_TrigNavigationUnitTest>  ::go
+  ::done map;
+};
+REGISTER_PACKAGE_WITH_NAVI(TrigNavigationUnitTest)
+
+class TestA : public SG::AuxElement {
+public:
+  TestA(){a = 0;}
+  TestA(int arg){a = arg;}
+  ~TestA() { std::cerr << " deleteing TestA: "<< a << std::endl; }
+  int value() const { return a; }
+  int a;
+};
+
+
+CLASS_DEF(TestA, 6421, 1)
+CLASS_DEF(DataVector<TestA>, 64210, 1)
+typedef DataVector<TestA> TestAContainer;
+
+
+class TestAuxA : public xAOD::AuxContainerBase {
+public:
+  std::vector<float> detail;
+};
+DATAVECTOR_BASE(TestAuxA,xAOD::AuxContainerBase);
+CLASS_DEF(TestAuxA, 642300, 1)
+
+
+class TestB : public SG::AuxElement{
+public:
+  TestB() : b(0) {  }
+  TestB(int v) : b(v) {  }
+  ~TestB() { std::cerr << " deleteing TestB: "<< b << std::endl; }
+  int value() const { return b; }
+  int b;
+};
+
+
+class TestBContainer : public DataVector<TestB> {
+public:
+  TestBContainer(SG::OwnershipPolicy policy = SG::OWN_ELEMENTS)
+    : DataVector<TestB>(policy) { }
+}; 
+
+CLASS_DEF(TestBContainer, 96422, 1)
+
+
+
+class TestAuxB : public xAOD::AuxContainerBase {
+public:
+  std::vector<float> detail;
+};
+CLASS_DEF(TestAuxB, 642311, 1)
+DATAVECTOR_BASE(TestAuxB,xAOD::AuxContainerBase);
+//HLT::AuxInit<TestAuxB> t;
+
+
+class TestC {
+public:
+  TestC() :c(0) {}
+  TestC(int v) : c(v) {}
+  ~TestC()  {std::cerr << "Deleting TestC" << std::endl; }
+  int value() const { return c; }
+  int c;
+};
+
+CLASS_DEF(TestC, 7800, 1)
+CLASS_DEF(DataVector<TestC>, 78001, 1)
+
+class TestCtypeContainer : public DataVector<TestC> { };
+CLASS_DEF(TestCtypeContainer, 78002, 1)
+
+class TestD {
+public:
+  TestD() : b(0) {  }
+  TestD(int v) : b(v) {  }
+  ~TestD() { std::cerr << " deleteing TestD: "<< b << std::endl; }
+  int value() const { return b; }
+  int b;
+};
+
+
+class TestDContainer : public DataVector<TestD> {
+public:
+
+}; 
+
+CLASS_DEF(TestDContainer, 96477, 1)
+
diff --git a/Trigger/TrigEvent/TrigNavigation/test/TestUtils.h b/Trigger/TrigEvent/TrigNavigation/test/TestUtils.h
new file mode 100644
index 0000000000000000000000000000000000000000..c639abd439aa95032a7e2ac4712810c2892ba68b
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/test/TestUtils.h
@@ -0,0 +1,21 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#pragma once
+MsgStream* msglog;
+
+#define _LINE_ __LINE__ 
+#define REPORT_AND_RETURN(__message, __ret) { *msglog << MSG::ERROR << "LINE:" <<_LINE_ << " Test failed: " <<  __message << endreq; return __ret; }
+#define REPORT_AND_STOP(__message) REPORT_AND_RETURN(__message, StatusCode::FAILURE) 
+#define ABORT(__message) REPORT_AND_RETURN(__message, -1)
+
+
+#define REPORT_AND_CONTINUE(__message) {*msglog << MSG::INFO << "LINE:" <<_LINE_ << " Test progress fine:  " <<  __message << endreq;}
+#define REPORT_REGTEST(__message) {*msglog << MSG::INFO << "REGTEST " <<  __message << endreq;}
+
+
+
+#define BEGIN_TEST(__name) const std::string __TEST_NAME=__name;		\
+  *msglog << MSG::INFO << "LINE:" <<_LINE_ << " Start of the test: " <<  __TEST_NAME << endreq 
+#define END_TEST   *msglog << MSG::INFO << "LINE:" <<_LINE_ << " End of the test: " <<  __TEST_NAME << endreq; return StatusCode::SUCCESS
diff --git a/Trigger/TrigEvent/TrigNavigation/test/TrigNavigation.xml b/Trigger/TrigEvent/TrigNavigation/test/TrigNavigation.xml
new file mode 100644
index 0000000000000000000000000000000000000000..14139199f56b4bee36fd5e6f918ffb504fa7d32b
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/test/TrigNavigation.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<atn>
+   <TEST name="TrigNavigationTest" type="makecheck" suite="trigger">
+      <package>Trigger/TrigEvent/TrigNavigation</package>
+      <timelimit>15</timelimit>
+      <author> Tomasz Bold </author>
+      <mailto> Tomasz.Bold@cern.ch</mailto>
+      <expectations>
+         <returnValue>0</returnValue>
+      </expectations>
+   </TEST>
+</atn>
diff --git a/Trigger/TrigEvent/TrigNavigation/test/TriggerElement_test.cxx b/Trigger/TrigEvent/TrigNavigation/test/TriggerElement_test.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..cccd501c110f1d39271ff767a80751b74cf2d228
--- /dev/null
+++ b/Trigger/TrigEvent/TrigNavigation/test/TriggerElement_test.cxx
@@ -0,0 +1,96 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include <vector>
+#include "TrigNavigation/TriggerElement.h"
+
+
+#include "TestTools/initGaudi.h"
+#include "AthenaKernel/getMessageSvc.h"
+#include "GaudiKernel/MsgStream.h"
+
+
+#include "TestUtils.h"
+
+using namespace std;
+using namespace HLT;
+
+StatusCode unit0(const TriggerElement::ObjectIndex& orig, unsigned expSerializedSize, MsgStream& log ) {
+  BEGIN_TEST("Unit0 test");
+  vector<uint32_t> serial;
+  vector<uint32_t>::const_iterator sIt;
+  TriggerElement::ObjectIndex deserial;
+  orig.serialize(serial);
+
+  if (serial.size() != expSerializedSize) 
+    REPORT_AND_STOP( "orig ObjIdx serialized has size !=  " << expSerializedSize << " "  << serial.size() );
+
+  for ( sIt = serial.begin(); sIt != serial.end(); ++sIt ) {
+    log << MSG::INFO << "serialized word: 0x" << MSG::hex <<  *sIt << MSG::dec << endreq;
+  }
+  sIt = serial.begin();
+  deserial.deserialize(sIt);
+  
+  if ( deserial.isSameOrWithin(&orig) && orig.isSameOrWithin(&deserial)) {
+    log << MSG::INFO << "serialziation works well for orig     " << orig << endreq;
+    log << MSG::INFO << "original     " << orig << endreq;
+    log << MSG::INFO << "deserialized " << deserial << endreq;
+    
+  } else REPORT_AND_STOP( "orig ObjIdx serialization failed " );
+
+  END_TEST;
+  
+}
+
+
+int main () {  
+
+  /*
+   ISvcLocator* pSvcLoc;
+   if (!Athena_test::initGaudi("test.txt",  pSvcLoc)) {
+     cerr << "ERROR This test can not be run" << endl;
+     return 0;
+   }
+   assert(pSvcLoc);
+  */
+
+  MsgStream log(Athena::getMessageSvc(), "TriggerElement_test");
+  msglog = &log;
+
+  log << MSG::INFO << "small " << endreq;
+  // test ObjectIndex:
+  TriggerElement::ObjectIndex small1(12, 4, 5);
+  if ( unit0(small1, 1, log).isFailure() ) 
+    ABORT("");
+
+  TriggerElement::ObjectIndex small2(15, 4, 7);
+  if ( unit0(small2, 1, log).isFailure() )
+    ABORT("");
+
+
+  REPORT_AND_CONTINUE("big ");  
+  TriggerElement::ObjectIndex big1(345, 60000, 60001);
+  if ( unit0(big1, 2, log).isFailure() )
+    ABORT("");
+
+  TriggerElement::ObjectIndex big2(345, 60000, 62345);
+  if ( unit0(big2, 2, log).isFailure() )
+    ABORT("");
+
+
+  log << MSG::INFO << "huge "  << endreq;
+  try {
+  TriggerElement::ObjectIndex huge1(12, 65535, 65536);
+  if ( unit0(huge1, 3, log).isFailure() )
+    ABORT("");
+  } catch (std::exception& ex) {
+    ABORT("Execption from the test " <<  ex.what() );
+  }
+  TriggerElement::ObjectIndex huge2(12, 820000, 820001);
+  if ( unit0(huge2, 3, log).isFailure() )
+    ABORT("");
+  
+  REPORT_AND_CONTINUE("SUCCESS");
+  return 0;
+}