diff --git a/HLT/Trigger/TrigControl/TrigServices/TrigServices/HltEventLoopMgr.h b/HLT/Trigger/TrigControl/TrigServices/TrigServices/HltEventLoopMgr.h
index 1d047b8bf919583aa2f2b38ffcdf910ea72a5a7a..2a35beeb4ac4e6e5eabb56ee77d709c52ea301f6 100644
--- a/HLT/Trigger/TrigControl/TrigServices/TrigServices/HltEventLoopMgr.h
+++ b/HLT/Trigger/TrigControl/TrigServices/TrigServices/HltEventLoopMgr.h
@@ -36,6 +36,7 @@
 // Forward declarations
 class IIncidentSvc;
 class IAlgContextSvc;
+class IAlgExecStateSvc;
 class StoreGateSvc;
 class IROBDataProviderSvc;
 class ITHistSvc;
@@ -291,6 +292,9 @@ private:
   // check whether a subdetector is in the run, according to the current detmask
   bool isSubDetectorIn(eformat::SubDetector sd) const;
 
+  // Helper to create EventContext
+  StatusCode installEventContext (const EventInfo* pEvent, EventID::number_type run);
+
   /** Handles to required services/tools **/
   typedef ServiceHandle<IIncidentSvc> IIncidentSvc_t;
   IIncidentSvc_t         m_incidentSvc;
@@ -306,6 +310,8 @@ private:
   typedef ServiceHandle<ITHistSvc> ITHistSvc_t;
   ITHistSvc_t            m_THistSvc;
 
+  ServiceHandle<IAlgExecStateSvc> m_aess;
+
   ToolHandle<TrigISHelper>            m_isHelper;
   ToolHandle<TrigCOOLUpdateHelper>    m_coolHelper;
 
@@ -443,7 +449,7 @@ private:
   /// we need this maintain the data
   uint32_t                  m_status_words[3] = {0};
 
-  EventContext* m_eventContext;
+  EventContext m_eventContext;
 };
 
 //=========================================================================
diff --git a/HLT/Trigger/TrigControl/TrigServices/python/TriggerUnixStandardSetup.py b/HLT/Trigger/TrigControl/TrigServices/python/TriggerUnixStandardSetup.py
index 06ca2b2d7eb66bbc158849212b74a19890ef784e..a23e44b44b7d34c0ee87a0518d9a406aa16663d0 100644
--- a/HLT/Trigger/TrigControl/TrigServices/python/TriggerUnixStandardSetup.py
+++ b/HLT/Trigger/TrigControl/TrigServices/python/TriggerUnixStandardSetup.py
@@ -1,4 +1,4 @@
-# Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+# Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
 
 ## @file TriggerUnixStandardSetup.py
 ## @brief py-module to configure the Athena AppMgr for trigger
@@ -81,12 +81,6 @@ def _setupCommonServices():
     from TrigServices.TrigServicesConf import TrigISHelper
     ToolSvc += TrigISHelper("TrigISHelper")
 
-    # Configure TrigPreFlightCheck
-    from TrigServices.TrigServicesConf import TrigPreFlightCheck
-    ToolSvc += TrigPreFlightCheck("TrigPreFlightCheck",
-                                  ReleaseDirs = ["AtlasP1HLT","AtlasHLT"]
-                                  )
-
     # Configure CoreDumpSvc
     if not hasattr(svcMgr,"CoreDumpSvc"):
         from AthenaServices.Configurables import CoreDumpSvc
diff --git a/HLT/Trigger/TrigControl/TrigServices/src/HltEventLoopMgr.cxx b/HLT/Trigger/TrigControl/TrigServices/src/HltEventLoopMgr.cxx
index 1e70db0df9297816f589380416922867fc826c34..8fb7371777cf078249488c6b5ccdad919204c9bc 100644
--- a/HLT/Trigger/TrigControl/TrigServices/src/HltEventLoopMgr.cxx
+++ b/HLT/Trigger/TrigControl/TrigServices/src/HltEventLoopMgr.cxx
@@ -11,12 +11,15 @@
 #include "GaudiKernel/ITHistSvc.h"
 #include "GaudiKernel/Timing.h"
 #include "GaudiKernel/IAlgContextSvc.h"
+#include "GaudiKernel/IAlgExecStateSvc.h"
 #include "GaudiKernel/IAlgManager.h"
 #include "GaudiKernel/ServiceLocatorHelper.h"
 #include "GaudiKernel/SmartIF.h"
 #include "GaudiKernel/EventContext.h"
 
 // Athena includes
+#include "AthenaKernel/ExtendedEventContext.h"
+#include "AthenaKernel/EventContextClid.h"
 #include "StoreGate/StoreGateSvc.h"
 #include "EventInfo/EventIncident.h"
 #include "EventInfo/EventInfo.h"
@@ -36,7 +39,6 @@ static std::string CMT_PACKAGE_VERSION = PACKAGE_VERSION;
 #include "TrigServices/HltEventLoopMgr.h"
 #include "TrigServices/TrigISHelper.h"
 #include "TrigServices/TrigHLTIssues.h"
-#include "TrigPreFlightCheck.h"
 #include "TrigCOOLUpdateHelper.h"
 #include "TrigSORFromPtreeHelper.h"
 #include "TrigConfInterfaces/IHLTConfigSvc.h"
@@ -272,6 +274,7 @@ HltEventLoopMgr::HltEventLoopMgr(const std::string& nam,
   m_inputMetaDataStore( "StoreGateSvc/InputMetaDataStore", nam ),
   m_robDataProviderSvc( "ROBDataProviderSvc",nam ),
   m_THistSvc( "THistSvc", nam ),
+  m_aess( "AlgExecStateSvc", nam),
   m_isHelper( "TrigISHelper", this),
   m_coolHelper( "TrigCOOLUpdateHelper", this),
   m_sorTime_stamp(2,0),
@@ -284,8 +287,7 @@ HltEventLoopMgr::HltEventLoopMgr(const std::string& nam,
   m_histProp_numStreamTags(Gaudi::Histo1DDef("NumberOfStreamTags",-.5,19.5,20)),
   m_histProp_streamTagNames(Gaudi::Histo1DDef("StreamTagNames",-.5,.5,1)),
   m_histProp_num_partial_eb_robs(Gaudi::Histo1DDef("NumberROBsPartialEB",-.5,199.5,200)),
-  m_histProp_Hlt_Edm_Sizes(Gaudi::Histo1DDef("HltEDMSizes",0.,10000.,100)),
-  m_eventContext(nullptr)
+  m_histProp_Hlt_Edm_Sizes(Gaudi::Histo1DDef("HltEDMSizes",0.,10000.,100))
 {
   m_mandatoryL1ROBs.value() = {begin(L1R_MANDATORY_ROBS), end(L1R_MANDATORY_ROBS)};
 
@@ -504,8 +506,6 @@ StatusCode HltEventLoopMgr::initialize()
   msgStream() << MSG::INFO << " ---> Debug stream name for events with truncated HLT result  = " << m_HltTruncationDebugStreamName << endmsg;
   msgStream() << MSG::INFO << " ---> Stream names of events with a truncated HLT result which will not be send to the debug stream  = " << m_excludeFromHltTruncationDebugStream << endmsg;
 
-  m_eventContext = new EventContext();
-
   //-------------------------------------------------------------------------
   // Setup the StoreGateSvc
   //-------------------------------------------------------------------------
@@ -566,6 +566,8 @@ StatusCode HltEventLoopMgr::initialize()
     return sc;
   }
 
+  ATH_CHECK(m_aess.retrieve());
+
   //--------------------------------------------------------------------------
   // Setup the TrigISHelper
   //--------------------------------------------------------------------------
@@ -599,28 +601,6 @@ StatusCode HltEventLoopMgr::initialize()
     msgStream() << MSG::DEBUG << "No AlgContextSvc available" << endmsg;
   }
 
-  //--------------------------------------------------------------------------
-  // Pre flight check
-  //--------------------------------------------------------------------------
-  ToolHandle<TrigPreFlightCheck> preFlightCheck;
-  if (preFlightCheck.retrieve().isFailure()) {
-    msgStream() << MSG::FATAL << "Error retrieving TrigPreFlightCheck "+preFlightCheck << endmsg;
-    return StatusCode::FAILURE;
-  }
-
-  // A failed pre-flight check is fatal in a partition
-  if ( validPartition() ) {
-    if ( preFlightCheck->check(MSG::ERROR).isFailure() ) {
-      msgStream() << MSG::FATAL << "Pre-flight check for HLT failed." << endmsg;
-      return StatusCode::FAILURE;
-    }
-  }
-  else {
-    if ( preFlightCheck->check(MSG::WARNING).isFailure() )
-      msgStream() << MSG::WARNING << "Pre-flight check for HLT failed." << endmsg;
-  }    
-  preFlightCheck->release();
-
   // The remainder of this method used to be in the L2/EF specialization
 
   // fill CTP ROB id vector
@@ -712,7 +692,6 @@ StatusCode HltEventLoopMgr::finalize()
     msgStream() << MSG::ERROR << "Error in MinimalEventLoopMgr Finalize" << endmsg;
   }
 
-  delete m_eventContext; m_eventContext = nullptr;
 
   // Release all interfaces
   m_incidentSvc.release().ignore();
@@ -767,25 +746,13 @@ StatusCode HltEventLoopMgr::reinitialize()
 
 StatusCode HltEventLoopMgr::executeAlgorithms()
 {
-  // Call the resetExecuted() method of ALL "known" algorithms
-  // (before we were reseting only the topalgs)
-  SmartIF<IAlgManager> algMan(serviceLocator());
-  if ( algMan.isValid() ) {
-    const auto& allAlgs = algMan->getAlgorithms() ;
-    for( auto ialg = allAlgs.begin() ; allAlgs.end() != ialg ; ++ialg ) {
-      if ( 0 != *ialg ) (*ialg)->resetExecuted();
-    }
-  }
+  // Reset all algorithms
+  m_aess->reset(m_eventContext);
 
   // Call the execute() method of all top algorithms
-
   StatusCode sc;
   for(auto alg : m_topAlgList) {
-#ifdef GAUDI_SYSEXECUTE_WITHCONTEXT
-    sc = alg->sysExecute(*m_eventContext);
-#else
-    sc = alg->sysExecute();
-#endif
+    sc = alg->sysExecute(m_eventContext);
     if(sc.isFailure()) {
       msgStream() << MSG::ERROR << "Execution of algorithm " << alg->name()
                   << " failed" << endmsg;
@@ -826,8 +793,11 @@ StatusCode HltEventLoopMgr::executeEvent(void* par)
                   << *(m_currentEvent->event_ID()) << endmsg;
   }
   
-  m_eventContext->setEventID( *((EventIDBase*) m_currentEvent->event_ID()) );
-  
+  //-----------------------------------------------------------------------
+  // Create EventContext
+  //-----------------------------------------------------------------------
+  ATH_CHECK(installEventContext(m_currentEvent, m_currentRun));
+
   //-----------------------------------------------------------------------
   // obtain the HLT conditions update counters from the CTP fragment
   //-----------------------------------------------------------------------
@@ -977,8 +947,7 @@ StatusCode HltEventLoopMgr::executeEvent(void* par)
   if (sc.isSuccess()) {
     // Call the execute() method of all output streams
     for (auto o : m_outStreamList ) {
-      o->resetExecuted();
-      sc = o->sysExecute(*m_eventContext);
+      sc = o->sysExecute(m_eventContext);
       if(sc.isFailure())  {
         msgStream() << MSG::WARNING << "Execution of output stream " << o->name() << " failed" << endmsg;
         eventFailed = true;
@@ -995,6 +964,7 @@ StatusCode HltEventLoopMgr::executeEvent(void* par)
   return eventFailed ? StatusCode::FAILURE : StatusCode::SUCCESS;
 }
 
+
 //=========================================================================
 // prepare for run step
 //=========================================================================
@@ -1050,6 +1020,21 @@ StatusCode HltEventLoopMgr::prepareForRun(const ptree & pt)
   return StatusCode::FAILURE;
 }
 
+StatusCode HltEventLoopMgr::installEventContext(const EventInfo* pEvent, EventID::number_type run)
+{
+  if (pEvent) m_eventContext.setEventID( *((EventIDBase*) pEvent->event_ID()) );
+  m_eventContext.set(m_total_evt ,0);
+
+  m_eventContext.setExtension( Atlas::ExtendedEventContext( m_evtStore->hiveProxyDict(), run) );
+  Gaudi::Hive::setCurrentContext( m_eventContext );
+
+  m_aess->reset(m_eventContext);
+  ATH_CHECK(m_evtStore->record(std::make_unique<EventContext> (m_eventContext), "EventContext"));
+
+  return StatusCode::SUCCESS;
+}
+
+
 //=========================================================================
 // allow for updates after forking the workers and issue an incident
 // to inform the clients
@@ -1937,7 +1922,7 @@ void HltEventLoopMgr::bookHistograms()
   regHistsTProfile.reserve(4);
 
   // monitoring information root directory
-  const std::string histPath = std::string("/EXPERT/");
+  const std::string histPath = std::string("/EXPERT/") + name() + "/";
 
   //     +--------------------+
   // *-- | Event accept flags |
@@ -2230,7 +2215,7 @@ void HltEventLoopMgr::HltBookHistograms()
   if ( !m_doMonitoring.value() ) { return; }
 
   // monitoring information root directory
-  std::string path = std::string("/EXPERT/");
+  std::string path = std::string("/EXPERT/") + name() + "/";
 
   // *-- SubDetectors from l1 ROBs
   auto nbins = L1R_BINS.size() + 2;
@@ -2469,9 +2454,11 @@ const SOR * HltEventLoopMgr::processRunParams(const ptree & pt)
   // update the run number
   m_currentRun = pt.get<uint32_t>("RunParams.run_number");
 
+  ATH_CHECK(installEventContext(nullptr, m_currentRun), nullptr);
+
   // Fill SOR parameters from the ptree
   TrigSORFromPtreeHelper sorhelp{msgStream()};
-  auto sor = sorhelp.fillSOR(pt.get_child("RunParams"), *m_eventContext);
+  auto sor = sorhelp.fillSOR(pt.get_child("RunParams"), m_eventContext);
   if(!sor)
     msgStream() << MSG::ERROR << ST_WHERE
                 << "setup of SOR from ptree failed" << endmsg;
diff --git a/HLT/Trigger/TrigControl/TrigServices/src/HltROBDataProviderSvc.cxx b/HLT/Trigger/TrigControl/TrigServices/src/HltROBDataProviderSvc.cxx
index d063fafc783dc39d32fa3463783187945d6143eb..d68ed1b638553f97a5f8ed8c44ba853472f88981 100644
--- a/HLT/Trigger/TrigControl/TrigServices/src/HltROBDataProviderSvc.cxx
+++ b/HLT/Trigger/TrigControl/TrigServices/src/HltROBDataProviderSvc.cxx
@@ -935,7 +935,7 @@ void HltROBDataProviderSvc::handle(const Incident& incident) {
   }
 
   // *-- booking path
-  std::string path = std::string("/EXPERT/");
+  std::string path = std::string("/EXPERT/") + name() + "/";
 
   // *-- number of bins for sub detector plots (55 SubDet max.)
   uint32_t n_bins_partEBSubDet = eformat::helper::SubDetectorDictionary.size();
diff --git a/HLT/Trigger/TrigControl/TrigServices/src/THistSvcHLT.cxx b/HLT/Trigger/TrigControl/TrigServices/src/THistSvcHLT.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..12da877f9d143dcd246f86ac2902333c08abb14b
--- /dev/null
+++ b/HLT/Trigger/TrigControl/TrigServices/src/THistSvcHLT.cxx
@@ -0,0 +1,2023 @@
+/*
+ * This is a copy of GaudiSvc/src/THistSvc with THistSvc renamed to THistSvcHLT
+ * to allow inheritance of this class by TrigMonTHistSvc.
+ */
+// system headers
+#include <cstdio>
+#include <sstream>
+#include <streambuf>
+
+// boost headers
+#include "boost/algorithm/string/case_conv.hpp"
+
+// ROOT headers
+#include "TDirectory.h"
+#include "TError.h"
+#include "TFile.h"
+#include "TGraph.h"
+#include "TKey.h"
+#include "TROOT.h"
+
+// Gaudi headers
+#include "GaudiKernel/AttribStringParser.h"
+#include "GaudiKernel/FileIncident.h"
+#include "GaudiKernel/GaudiException.h"
+#include "GaudiKernel/IEventProcessor.h"
+#include "GaudiKernel/IFileMgr.h"
+#include "GaudiKernel/IIncidentSvc.h"
+#include "GaudiKernel/IIoComponentMgr.h"
+#include "GaudiKernel/IJobOptionsSvc.h"
+#include "GaudiKernel/ISvcLocator.h"
+#include "GaudiKernel/Property.h"
+
+// local headers
+#include "THistSvcHLT.h"
+
+DECLARE_COMPONENT( THistSvcHLT )
+
+namespace
+{
+  template <typename InputIterator, typename OutputIterator, typename UnaryOperation, typename UnaryPredicate>
+  OutputIterator transform_if( InputIterator first, InputIterator last, OutputIterator result, UnaryOperation op,
+                               UnaryPredicate pred )
+  {
+    while ( first != last ) {
+      if ( pred( *first ) ) *result++ = op( *first );
+      ++first;
+    }
+    return result;
+  }
+
+  constexpr struct select1st_t {
+    template <typename T, typename S>
+    const T& operator()( const std::pair<T, S>& p ) const
+    {
+      return p.first;
+    }
+  } select1st{};
+}
+
+//*************************************************************************//
+
+THistSvcHLT::THistSvcHLT( const std::string& name, ISvcLocator* svc ) : base_class( name, svc )
+{
+  m_compressionLevel.declareUpdateHandler( &THistSvcHLT::setupCompressionLevel, this );
+  m_outputfile.declareUpdateHandler( &THistSvcHLT::setupOutputFile, this );
+  m_inputfile.declareUpdateHandler( &THistSvcHLT::setupInputFile, this );
+}
+
+StatusCode THistSvcHLT::initialize()
+{
+  GlobalDirectoryRestore restore( m_svcMut );
+
+  StatusCode status = Service::initialize();
+
+  if ( status.isFailure() ) {
+    error() << "initializing service" << endmsg;
+    return status;
+  }
+
+  StatusCode st( StatusCode::SUCCESS );
+
+  try {
+    setupOutputFile( m_outputfile );
+  } catch ( GaudiException& err ) {
+    error() << "Caught: " << err << endmsg;
+    st = StatusCode::FAILURE;
+  }
+
+  try {
+    setupInputFile( m_inputfile );
+  } catch ( GaudiException& err ) {
+    error() << "Caught: " << err << endmsg;
+    st = StatusCode::FAILURE;
+  }
+
+  // Protect against multiple instances of TROOT
+  if ( !gROOT ) {
+    static TROOT root( "root", "ROOT I/O" );
+    // gDebug = 99;
+  } else {
+    if ( msgLevel( MSG::VERBOSE ) ) {
+      verbose() << "ROOT already initialized, debug = " << gDebug << endmsg;
+    }
+  }
+
+  if ( service( "IncidentSvc", p_incSvc, true ).isFailure() ) {
+    error() << "unable to get the IncidentSvc" << endmsg;
+    st = StatusCode::FAILURE;
+  } else {
+    p_incSvc->addListener( this, "EndEvent", 100, true );
+  }
+
+  if ( service( "FileMgr", p_fileMgr, true ).isFailure() ) {
+    error() << "unable to get the FileMgr" << endmsg;
+    st = StatusCode::FAILURE;
+  } else {
+    debug() << "got the FileMgr" << endmsg;
+  }
+
+  // Register open/close callback actions
+  using namespace std::placeholders;
+  auto boa = [this]( const Io::FileAttr* fa, const std::string& caller ) { return this->rootOpenAction( fa, caller ); };
+  if ( p_fileMgr->regAction( boa, Io::OPEN, Io::ROOT ).isFailure() ) {
+    error() << "unable to register ROOT file open action with FileMgr" << endmsg;
+  }
+  auto bea = [this]( const Io::FileAttr* fa, const std::string& caller ) {
+    return this->rootOpenErrAction( fa, caller );
+  };
+  if ( p_fileMgr->regAction( bea, Io::OPEN_ERR, Io::ROOT ).isFailure() ) {
+    error() << "unable to register ROOT file open Error action with FileMgr" << endmsg;
+  }
+
+  m_okToConnect = true;
+  if ( m_delayConnect ) {
+    if ( !m_inputfile.value().empty() ) {
+      setupInputFile( m_inputfile );
+    }
+    if ( !m_outputfile.value().empty() ) {
+      setupOutputFile( m_outputfile );
+    }
+
+    m_delayConnect = false;
+  }
+  m_alreadyConnectedOutFiles.clear();
+  m_alreadyConnectedInFiles.clear();
+
+  IIoComponentMgr* iomgr = nullptr;
+  if ( service( "IoComponentMgr", iomgr, true ).isFailure() ) {
+    error() << "unable to get the IoComponentMgr" << endmsg;
+    st = StatusCode::FAILURE;
+  } else {
+    if ( !iomgr->io_register( this ).isSuccess() ) {
+      error() << "could not register with the I/O component manager !" << endmsg;
+      st = StatusCode::FAILURE;
+    } else {
+      bool all_good = true;
+      // register input/output files...
+      for ( const auto& reg : m_files ) {
+        const std::string& fname = reg.second.first->GetName();
+        const IIoComponentMgr::IoMode::Type iomode =
+            ( reg.second.second == THistSvcHLT::READ ? IIoComponentMgr::IoMode::READ : IIoComponentMgr::IoMode::WRITE );
+        if ( !iomgr->io_register( this, iomode, fname ).isSuccess() ) {
+          warning() << "could not register file [" << fname << "] with the I/O component manager..." << endmsg;
+          all_good = false;
+        } else {
+          info() << "registered file [" << fname << "]... [ok]" << endmsg;
+        }
+      }
+      if ( !all_good ) {
+        error() << "problem while registering input/output files with "
+                << "the I/O component manager !" << endmsg;
+        st = StatusCode::FAILURE;
+      }
+    }
+  }
+
+  if ( st.isFailure() ) {
+    fatal() << "Unable to initialize THistSvcHLT" << endmsg;
+  }
+
+  return st;
+}
+
+StatusCode THistSvcHLT::reinitialize()
+{
+  GlobalDirectoryRestore restore( m_svcMut );
+  warning() << "reinitialize not implemented" << endmsg;
+  return StatusCode::SUCCESS;
+}
+
+StatusCode THistSvcHLT::finalize()
+{
+  GlobalDirectoryRestore restore( m_svcMut );
+
+  if ( msgLevel( MSG::DEBUG ) ) {
+    dump();
+    debug() << "THistSvcHLT::finalize" << endmsg;
+  }
+
+#ifndef NDEBUG
+  if ( msgLevel( MSG::DEBUG ) ) {
+    for ( const auto& itr : m_uids ) {
+      THistID& thid = itr.second->at( 0 );
+      TObject* tobj = thid.obj;
+
+      std::string dirname( "none" );
+      if ( tobj && tobj->IsA()->InheritsFrom( "TTree" ) ) {
+        TTree* tree = dynamic_cast<TTree*>( tobj );
+        if ( tree->GetDirectory() != 0 ) {
+          dirname = tree->GetDirectory()->GetPath();
+        }
+      } else if ( tobj && tobj->IsA()->InheritsFrom( "TGraph" ) ) {
+        if ( !thid.temp ) {
+          dirname = thid.file->GetPath();
+          std::string id2( thid.id );
+          id2.erase( 0, id2.find( "/", 1 ) );
+          id2.erase( id2.rfind( "/" ), id2.length() );
+          if ( id2.find( "/" ) == 0 ) {
+            id2.erase( 0, 1 );
+          }
+          dirname += id2;
+        } else {
+          dirname = "/tmp";
+        }
+      } else if ( tobj && tobj->IsA()->InheritsFrom( "TH1" ) ) {
+        TH1* th = dynamic_cast<TH1*>( tobj );
+        if ( th == nullptr ) {
+          error() << "Couldn't dcast: " << itr.first << endmsg;
+        } else {
+          if ( th->GetDirectory() != 0 ) {
+            dirname = th->GetDirectory()->GetPath();
+          }
+        }
+      } else if ( !tobj ) {
+        warning() << itr.first << " has NULL TObject ptr" << endmsg;
+      }
+      debug() << "finalize: " << thid << endmsg;
+    }
+  }
+#endif
+
+  if ( writeObjectsToFile().isFailure() ) {
+    error() << "problems writing histograms" << endmsg;
+  }
+
+  if ( m_print ) {
+    info() << "Listing contents of ROOT files: " << endmsg;
+  }
+  std::vector<TFile*> deleted_files;
+  for ( auto& itr : m_files ) {
+    if ( std::find( deleted_files.begin(), deleted_files.end(), itr.second.first ) == deleted_files.end() ) {
+      deleted_files.push_back( itr.second.first );
+
+#ifndef NDEBUG
+      if ( msgLevel( MSG::DEBUG ) ) {
+        debug() << "finalizing stream/file " << itr.first << ":" << itr.second.first->GetName() << endmsg;
+      }
+#endif
+    } else {
+#ifndef NDEBUG
+      if ( msgLevel( MSG::DEBUG ) ) {
+        debug() << "already finalized stream " << itr.first << endmsg;
+      }
+#endif
+      continue;
+    }
+
+    if ( m_print && msgLevel( MSG::INFO ) ) {
+      info() << "==> File: " << itr.second.first->GetName() << "  stream: " << itr.first << endmsg;
+
+      itr.second.first->Print( "base" );
+    }
+
+    std::string tmpfn = itr.second.first->GetName();
+
+    p_fileMgr->close( itr.second.first, name() );
+
+    IIncidentSvc* pIncidentSvc = nullptr;
+    if ( service( "IncidentSvc", pIncidentSvc ).isFailure() ) {
+      error() << "Unable to get the IncidentSvc" << endmsg;
+      return StatusCode::FAILURE;
+    }
+
+    if ( itr.second.second == SHARE ) {
+      // Merge File
+      void* vfile = nullptr;
+      int returncode =
+          p_fileMgr->open( Io::ROOT, name(), m_sharedFiles[itr.first], Io::WRITE | Io::APPEND, vfile, "HIST" );
+
+      if ( returncode ) {
+        error() << "unable to open Final Output File: \"" << m_sharedFiles[itr.first] << "\" for merging" << endmsg;
+        return StatusCode::FAILURE;
+      }
+
+      TFile* outputfile = (TFile*)vfile;
+      pIncidentSvc->fireIncident( FileIncident( name(), IncidentType::WroteToOutputFile, m_sharedFiles[itr.first] ) );
+
+      if ( msgLevel( MSG::DEBUG ) ) {
+        debug() << "THistSvcHLT::writeObjectsToFile()::Merging Rootfile " << endmsg;
+      }
+
+      vfile      = nullptr;
+      returncode = p_fileMgr->open( Io::ROOT, name(), tmpfn, Io::READ, vfile, "HIST" );
+
+      if ( returncode ) {
+        error() << "unable to open temporary file: \"" << tmpfn << endmsg;
+        return StatusCode::FAILURE;
+      }
+
+      TFile* inputfile = (TFile*)vfile;
+
+      outputfile->SetCompressionLevel( inputfile->GetCompressionLevel() );
+
+      MergeRootFile( outputfile, inputfile );
+
+      outputfile->Write();
+      p_fileMgr->close( outputfile, name() );
+      p_fileMgr->close( inputfile, name() );
+
+      if ( msgLevel( MSG::DEBUG ) ) {
+        debug() << "Trying to remove temporary file \"" << tmpfn << "\"" << endmsg;
+      }
+
+      std::remove( tmpfn.c_str() );
+    }
+    delete itr.second.first;
+  }
+
+  m_files.clear();
+  m_sharedFiles.clear();
+  m_fileStreams.clear();
+  m_hlist.clear(); // vhid* is deleted in m_tobjs
+  m_uids.clear();  // vhid* is deleted in m_tobjs
+  m_ids.clear();   // vhid* is deleted in m_tobjs
+
+  for ( auto& obj : m_tobjs ) {
+    // TObject*'s are already dealt with through root file i/o
+    delete obj.second.first; // delete vhid*
+  }
+  m_tobjs.clear();
+
+  return Service::finalize();
+}
+
+//*************************************************************************//
+
+StatusCode THistSvcHLT::regHist( const std::string& id )
+{
+  std::unique_ptr<TH1> hist = nullptr;
+  return regHist_i( std::move( hist ), id, false );
+}
+
+StatusCode THistSvcHLT::regHist( const std::string& id, std::unique_ptr<TH1> hist )
+{
+  return regHist_i( std::move( hist ), id, false );
+}
+
+StatusCode THistSvcHLT::regHist( const std::string& id, std::unique_ptr<TH1> hist, TH1* hist_ptr )
+{
+  // This is only to support a common use case where the histogram is used after its registration
+  if ( hist_ptr != nullptr ) {
+    hist_ptr = hist.get();
+  }
+  return regHist_i( std::move( hist ), id, false );
+}
+
+StatusCode THistSvcHLT::regHist( const std::string& id, TH1* hist_ptr )
+{
+  std::unique_ptr<TH1> hist( hist_ptr );
+  return regHist_i( std::move( hist ), id, false );
+}
+
+StatusCode THistSvcHLT::getHist( const std::string& id, TH1*& hist, size_t ind ) const
+{
+  hist = getHist_i<TH1>( id, ind );
+  if ( hist != nullptr ) {
+    return StatusCode::SUCCESS;
+  } else {
+    return StatusCode::FAILURE;
+  }
+}
+
+StatusCode THistSvcHLT::getHist( const std::string& id, TH2*& hist, size_t ind ) const
+{
+  hist = getHist_i<TH2>( id, ind );
+  if ( hist != nullptr ) {
+    return StatusCode::SUCCESS;
+  } else {
+    return StatusCode::FAILURE;
+  }
+}
+
+StatusCode THistSvcHLT::getHist( const std::string& id, TH3*& hist, size_t ind ) const
+{
+  hist = getHist_i<TH3>( id, ind );
+  if ( hist != nullptr ) {
+    return StatusCode::SUCCESS;
+  } else {
+    return StatusCode::FAILURE;
+  }
+}
+
+StatusCode THistSvcHLT::regTree( const std::string& id )
+{
+  std::unique_ptr<TTree> tree = nullptr;
+  return regHist_i( std::move( tree ), id, false );
+}
+
+StatusCode THistSvcHLT::regTree( const std::string& id, std::unique_ptr<TTree> tree )
+{
+  StatusCode sc = regHist_i( std::move( tree ), id, false );
+  TTree* tr     = nullptr;
+  if ( getTree( id, tr ).isSuccess() && sc.isSuccess() ) {
+    if ( m_autoSave != 0 ) {
+      tr->SetAutoSave( m_autoSave );
+    }
+    tr->SetAutoFlush( m_autoFlush );
+  }
+  return sc;
+}
+
+StatusCode THistSvcHLT::regTree( const std::string& id, TTree* tree_ptr )
+{
+  std::unique_ptr<TTree> tree( tree_ptr );
+  StatusCode sc = regHist_i( std::move( tree ), id, false );
+  TTree* tr     = nullptr;
+  if ( getTree( id, tr ).isSuccess() && sc.isSuccess() ) {
+    if ( m_autoSave != 0 ) {
+      tr->SetAutoSave( m_autoSave );
+    }
+    tr->SetAutoFlush( m_autoFlush );
+  }
+  return sc;
+}
+
+StatusCode THistSvcHLT::getTree( const std::string& id, TTree*& tree ) const
+{
+  tree = getHist_i<TTree>( id );
+  if ( tree != nullptr ) {
+    return StatusCode::SUCCESS;
+  } else {
+    return StatusCode::FAILURE;
+  }
+}
+
+StatusCode THistSvcHLT::regGraph( const std::string& id )
+{
+  std::unique_ptr<TGraph> graph = std::make_unique<TGraph>();
+  return regHist_i( std::move( graph ), id, false );
+}
+
+StatusCode THistSvcHLT::regGraph( const std::string& id, std::unique_ptr<TGraph> graph )
+{
+  if ( strcmp( graph->GetName(), "Graph" ) == 0 ) {
+    std::string id2( id );
+    std::string::size_type i = id2.rfind( "/" );
+    if ( i != std::string::npos ) {
+      id2.erase( 0, i + 1 );
+    }
+
+    info() << "setting name of TGraph id: \"" << id << "\" to \"" << id2 << "\" since it is unset" << endmsg;
+    graph->SetName( id2.c_str() );
+  }
+
+  return regHist_i( std::move( graph ), id, false );
+}
+
+StatusCode THistSvcHLT::regGraph( const std::string& id, TGraph* graph_ptr )
+{
+  std::unique_ptr<TGraph> graph( graph_ptr );
+  if ( strcmp( graph->GetName(), "Graph" ) == 0 ) {
+    std::string id2( id );
+    std::string::size_type i = id2.rfind( "/" );
+    if ( i != std::string::npos ) {
+      id2.erase( 0, i + 1 );
+    }
+
+    info() << "setting name of TGraph id: \"" << id << "\" to \"" << id2 << "\" since it is unset" << endmsg;
+    graph->SetName( id2.c_str() );
+  }
+
+  return regHist_i( std::move( graph ), id, false );
+}
+
+StatusCode THistSvcHLT::getGraph( const std::string& id, TGraph*& graph ) const
+{
+  graph = getHist_i<TGraph>( id );
+  if ( graph != nullptr ) {
+    return StatusCode::SUCCESS;
+  } else {
+    return StatusCode::FAILURE;
+  }
+}
+
+StatusCode THistSvcHLT::regShared( const std::string& id, std::unique_ptr<TH1> hist, LockedHandle<TH1>& lh )
+{
+  lh = regShared_i<TH1>( id, std::move( hist ) );
+  if ( lh ) {
+    return StatusCode::SUCCESS;
+  } else {
+    return StatusCode::FAILURE;
+  }
+}
+
+StatusCode THistSvcHLT::regShared( const std::string& id, std::unique_ptr<TH2> hist, LockedHandle<TH2>& lh )
+{
+  lh = regShared_i<TH2>( id, std::move( hist ) );
+  if ( lh ) {
+    return StatusCode::SUCCESS;
+  } else {
+    return StatusCode::FAILURE;
+  }
+}
+
+StatusCode THistSvcHLT::regShared( const std::string& id, std::unique_ptr<TH3> hist, LockedHandle<TH3>& lh )
+{
+  lh = regShared_i<TH3>( id, std::move( hist ) );
+  if ( lh ) {
+    return StatusCode::SUCCESS;
+  } else {
+    return StatusCode::FAILURE;
+  }
+}
+
+StatusCode THistSvcHLT::regShared( const std::string& id, std::unique_ptr<TGraph> graph, LockedHandle<TGraph>& lh )
+{
+  lh = regShared_i<TGraph>( id, std::move( graph ) );
+  if ( lh ) {
+    return StatusCode::SUCCESS;
+  } else {
+    return StatusCode::FAILURE;
+  }
+}
+
+StatusCode THistSvcHLT::getShared( const std::string& name, LockedHandle<TH1>& lh ) const
+{
+  lh = getShared_i<TH1>( name );
+  if ( lh ) {
+    return StatusCode::SUCCESS;
+  } else {
+    return StatusCode::FAILURE;
+  }
+}
+
+StatusCode THistSvcHLT::getShared( const std::string& name, LockedHandle<TH2>& lh ) const
+{
+  lh = getShared_i<TH2>( name );
+  if ( lh ) {
+    return StatusCode::SUCCESS;
+  } else {
+    return StatusCode::FAILURE;
+  }
+}
+
+StatusCode THistSvcHLT::getShared( const std::string& name, LockedHandle<TH3>& lh ) const
+{
+  lh = getShared_i<TH3>( name );
+  if ( lh ) {
+    return StatusCode::SUCCESS;
+  } else {
+    return StatusCode::FAILURE;
+  }
+}
+
+StatusCode THistSvcHLT::getShared( const std::string& name, LockedHandle<TGraph>& lh ) const
+{
+  lh = getShared_i<TGraph>( name );
+  if ( lh ) {
+    return StatusCode::SUCCESS;
+  } else {
+    return StatusCode::FAILURE;
+  }
+}
+
+StatusCode THistSvcHLT::deReg( const std::string& id )
+{
+  auto itr = m_uids.find( id );
+  if ( itr == m_uids.end() ) {
+    error() << "Problem deregistering id \"" << id << "\": not found in registry" << endmsg;
+    return StatusCode::FAILURE;
+  }
+
+  vhid_t* vh = itr->second;
+  debug() << "will deregister " << vh->size() << " elements of id \"" << id << "\"" << endmsg;
+  StatusCode sc( StatusCode::SUCCESS );
+  while ( vh->size() > 0 ) {
+    if ( deReg( vh->back().obj ).isFailure() ) {
+      sc = StatusCode::FAILURE;
+      error() << "Problems deRegistering " << vh->size() << " element of id \"" << id << "\"" << endmsg;
+      break;
+    }
+  }
+
+  return sc;
+}
+
+StatusCode THistSvcHLT::deReg( TObject* obj )
+{
+  objMap_t::iterator obj_itr = m_tobjs.find( obj );
+  if ( obj_itr != m_tobjs.end() ) {
+    vhid_t* vhid = obj_itr->second.first;
+    THistID hid  = obj_itr->second.first->at( obj_itr->second.second );
+
+    auto uid_itr = m_uids.find( hid.id );
+    if ( uid_itr == m_uids.end() ) {
+      error() << "Problems deregistering TObject \"" << obj->GetName() << "\" with id \"" << hid.id
+              << "\": not in uidMap" << endmsg;
+      return StatusCode::FAILURE;
+    }
+
+    if ( vhid->size() == 1 ) {
+      // We are the last object, so we have to delete vhid properly
+      debug() << "vhid for " << hid.id << " is empty. deleting" << endmsg;
+
+      std::string root, rem;
+      parseString( hid.id, root, rem );
+
+      auto mitr   = m_ids.equal_range( rem );
+      auto id_itr = std::find_if( mitr.first, mitr.second,
+                                  [&]( idMap_t::const_reference i ) { return i.second->at( 0 ).obj == obj; } );
+      if ( id_itr == mitr.second ) {
+        error() << "Problems deregistering TObject \"" << obj->GetName() << "\" with id \"" << hid.id
+                << "\": not in idMap" << endmsg;
+        return StatusCode::FAILURE;
+      }
+
+      auto hlist_itr = std::find( m_hlist.begin(), m_hlist.end(), vhid );
+      if ( hlist_itr == m_hlist.end() ) {
+        error() << "Problems deregistering TObject \"" << obj->GetName() << "\" with id \"" << hid.id
+                << "\": not in hlist" << endmsg;
+        return StatusCode::FAILURE;
+      }
+
+      m_tobjs.erase( obj_itr );
+      vhid->erase( vhid->begin() + obj_itr->second.second );
+
+      m_uids.erase( uid_itr );
+      m_ids.erase( id_itr );
+      m_hlist.erase( hlist_itr );
+
+      delete vhid;
+
+    } else if ( vhid->size() > 1 ) {
+      m_tobjs.erase( obj_itr );
+      vhid->erase( vhid->begin() + obj_itr->second.second );
+
+      // vector of THistID is still not empty (i.e. other instances with same name registered)
+    } else {
+      error() << "Deregistration failed unexpectedly. (bug in THistSvcHLT?)" << endmsg;
+    }
+    return StatusCode::SUCCESS;
+  } else {
+    error() << "Cannot unregister TObject \"" << obj->GetName() << "\": not known to THistSvcHLT" << endmsg;
+    return StatusCode::FAILURE;
+  }
+}
+
+StatusCode THistSvcHLT::merge( const std::string& name )
+{
+  uidMap_t::iterator itr = m_uids.find( name );
+  if ( itr == m_uids.end() ) {
+    error() << "merge: id \"" << name << "\" not found" << endmsg;
+    return StatusCode::FAILURE;
+  }
+
+  return merge( itr->second );
+}
+
+StatusCode THistSvcHLT::merge( TObject* obj )
+{
+  objMap_t::iterator itr = m_tobjs.find( obj );
+  if ( itr != m_tobjs.end() ) {
+    return merge( itr->second.first );
+  } else {
+    error() << "merge: unknown object " << obj << endmsg;
+    return StatusCode::FAILURE;
+  }
+}
+
+bool THistSvcHLT::exists( const std::string& name ) const { return ( getHist_i<TH1>( name, 0, true ) != nullptr ); }
+
+std::vector<std::string> THistSvcHLT::getHists() const
+{
+  std::vector<std::string> names;
+  names.reserve( m_uids.size() );
+  transform_if( std::begin( m_uids ), std::end( m_uids ), std::back_inserter( names ), select1st,
+                []( uidMap_t::const_reference i ) { return i.second->at( 0 ).obj->IsA()->InheritsFrom( "TH1" ); } );
+  return names;
+}
+
+std::vector<std::string> THistSvcHLT::getTrees() const
+{
+  std::vector<std::string> names;
+  names.reserve( m_uids.size() );
+  transform_if( std::begin( m_uids ), std::end( m_uids ), std::back_inserter( names ), select1st,
+                []( uidMap_t::const_reference i ) { return i.second->at( 0 ).obj->IsA()->InheritsFrom( "TTree" ); } );
+  return names;
+}
+
+std::vector<std::string> THistSvcHLT::getGraphs() const
+{
+  std::vector<std::string> names;
+  names.reserve( m_uids.size() );
+  transform_if( std::begin( m_uids ), std::end( m_uids ), std::back_inserter( names ), select1st,
+                []( uidMap_t::const_reference i ) { return i.second->at( 0 ).obj->IsA()->InheritsFrom( "TGraph" ); } );
+  return names;
+}
+
+StatusCode THistSvcHLT::getTHists( TDirectory* td, TList& tl, bool rcs ) const
+{
+  GlobalDirectoryRestore restore( m_svcMut );
+
+  gErrorIgnoreLevel = kBreak;
+
+  if ( !td->cd() ) {
+    error() << "getTHists: No such TDirectory \"" << td->GetPath() << "\"" << endmsg;
+    return StatusCode::FAILURE;
+  }
+
+  if ( msgLevel( MSG::DEBUG ) ) {
+    debug() << "getTHists: \"" << td->GetPath() << "\": found " << td->GetListOfKeys()->GetSize() << " keys" << endmsg;
+  }
+
+  TIter nextkey( td->GetListOfKeys() );
+  while ( TKey* key = (TKey*)nextkey() ) {
+    auto& log = debug();
+    if ( msgLevel( MSG::DEBUG ) ) log << "  key: " << key->GetName();
+    TObject* obj = key->ReadObj();
+    if ( obj != 0 && obj->IsA()->InheritsFrom( "TDirectory" ) ) {
+      if ( msgLevel( MSG::DEBUG ) ) log << " (" << obj->IsA()->GetName() << ")";
+    } else if ( obj != 0 && obj->IsA()->InheritsFrom( "TH1" ) ) {
+      if ( msgLevel( MSG::DEBUG ) ) log << " (" << obj->IsA()->GetName() << ")";
+      tl.Add( obj );
+    } else if ( obj != 0 ) {
+      if ( msgLevel( MSG::DEBUG ) ) log << " [" << obj->IsA()->GetName() << "]";
+    }
+    if ( msgLevel( MSG::DEBUG ) ) log << endmsg;
+  }
+
+  // operate recursively
+  if ( rcs ) {
+    nextkey = td->GetListOfKeys();
+    while ( TKey* key = (TKey*)nextkey() ) {
+      TObject* obj = key->ReadObj();
+      if ( obj && obj->IsA()->InheritsFrom( "TDirectory" ) ) {
+        TDirectory* tt = dynamic_cast<TDirectory*>( obj );
+        getTHists( tt, tl, rcs );
+      }
+    }
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode THistSvcHLT::getTHists( const std::string& dir, TList& tl, bool rcs ) const
+{
+
+  GlobalDirectoryRestore restore( m_svcMut );
+
+  gErrorIgnoreLevel = kBreak;
+
+  StatusCode sc;
+
+  std::string stream, rem, r2;
+  parseString( dir, stream, rem );
+
+  auto itr = m_files.find( stream );
+  if ( itr != m_files.end() ) {
+    r2 = itr->second.first->GetName();
+    r2 += ":/";
+    r2 += rem;
+
+    if ( msgLevel( MSG::DEBUG ) ) {
+      debug() << "getTHists: \"" << dir << "\" looks like a stream name."
+              << " associated TFile: \"" << itr->second.first->GetName() << "\"" << endmsg;
+    }
+
+    if ( gDirectory->cd( r2.c_str() ) ) {
+      m_curstream = stream;
+      sc          = getTHists( gDirectory, tl, rcs );
+      m_curstream = "";
+      return sc;
+    } else {
+      if ( msgLevel( MSG::DEBUG ) ) {
+        debug() << "getTHists: no such TDirectory \"" << r2 << "\"" << endmsg;
+      }
+    }
+
+  } else {
+    if ( msgLevel( MSG::DEBUG ) ) {
+      debug() << "getTHists: stream \"" << stream << "\" not found" << endmsg;
+    }
+  }
+
+  if ( !gDirectory->cd( dir.c_str() ) ) {
+    error() << "getTHists: No such TDirectory/stream \"" << dir << "\"" << endmsg;
+    sc = StatusCode::FAILURE;
+  } else {
+    sc = getTHists( gDirectory, tl, rcs );
+  }
+
+  return sc;
+}
+
+StatusCode THistSvcHLT::getTHists( TDirectory* td, TList& tl, bool rcs, bool reg )
+{
+  GlobalDirectoryRestore restore( m_svcMut );
+
+  gErrorIgnoreLevel = kBreak;
+
+  if ( !td->cd() ) {
+    error() << "getTHists: No such TDirectory \"" << td->GetPath() << "\"" << endmsg;
+    return StatusCode::FAILURE;
+  }
+
+  if ( msgLevel( MSG::DEBUG ) ) {
+    debug() << "getTHists: \"" << td->GetPath() << "\": found " << td->GetListOfKeys()->GetSize() << " keys" << endmsg;
+  }
+
+  TIter nextkey( td->GetListOfKeys() );
+  while ( TKey* key = (TKey*)nextkey() ) {
+    auto& log = debug();
+    if ( msgLevel( MSG::DEBUG ) ) log << "  key: " << key->GetName();
+    TObject* obj = key->ReadObj();
+    if ( obj && obj->IsA()->InheritsFrom( "TDirectory" ) ) {
+      if ( msgLevel( MSG::DEBUG ) ) log << " (" << obj->IsA()->GetName() << ")";
+    } else if ( obj && obj->IsA()->InheritsFrom( "TH1" ) ) {
+      if ( msgLevel( MSG::DEBUG ) ) log << " (" << obj->IsA()->GetName() << ")";
+      tl.Add( obj );
+      if ( reg && m_curstream != "" ) {
+        std::string dir = td->GetPath();
+        std::string fil = td->GetFile()->GetName();
+        dir.erase( 0, fil.length() + 1 );
+        std::string id = "/" + m_curstream;
+        if ( dir == "/" ) {
+          id = id + "/" + key->GetName();
+        } else {
+          id = id + dir + "/" + key->GetName();
+        }
+        if ( !exists( id ) ) {
+          if ( msgLevel( MSG::DEBUG ) ) log << "  reg as \"" << id << "\"";
+          regHist( id ).ignore();
+        } else {
+          if ( msgLevel( MSG::DEBUG ) ) log << "  already registered";
+        }
+      }
+    } else if ( obj ) {
+      if ( msgLevel( MSG::DEBUG ) ) log << " [" << obj->IsA()->GetName() << "]";
+    }
+    if ( msgLevel( MSG::DEBUG ) ) log << endmsg;
+  }
+
+  // operate recursively
+  if ( rcs ) {
+    nextkey = td->GetListOfKeys();
+    while ( TKey* key = (TKey*)nextkey() ) {
+      TObject* obj = key->ReadObj();
+      if ( obj && obj->IsA()->InheritsFrom( "TDirectory" ) ) {
+        TDirectory* tt = dynamic_cast<TDirectory*>( obj );
+        getTHists( tt, tl, rcs, reg );
+      }
+    }
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode THistSvcHLT::getTHists( const std::string& dir, TList& tl, bool rcs, bool reg )
+{
+  GlobalDirectoryRestore restore( m_svcMut );
+
+  gErrorIgnoreLevel = kBreak;
+
+  StatusCode sc;
+
+  std::string stream, rem, r2;
+  parseString( dir, stream, rem );
+
+  auto itr = m_files.find( stream );
+  if ( itr != m_files.end() ) {
+    r2 = itr->second.first->GetName();
+    r2 += ":/";
+    r2 += rem;
+
+    if ( msgLevel( MSG::DEBUG ) ) {
+      debug() << "getTHists: \"" << dir << "\" looks like a stream name."
+              << " associated TFile: \"" << itr->second.first->GetName() << "\"" << endmsg;
+    }
+
+    if ( gDirectory->cd( r2.c_str() ) ) {
+      m_curstream = stream;
+      sc          = getTHists( gDirectory, tl, rcs, reg );
+      m_curstream.clear();
+      return sc;
+    }
+    if ( msgLevel( MSG::DEBUG ) ) {
+      debug() << "getTHists: no such TDirectory \"" << r2 << "\"" << endmsg;
+    }
+  } else {
+    if ( msgLevel( MSG::DEBUG ) ) {
+      debug() << "getTHists: stream \"" << stream << "\" not found" << endmsg;
+    }
+  }
+
+  if ( !gDirectory->cd( dir.c_str() ) ) {
+    error() << "getTHists: No such TDirectory/stream \"" << dir << "\"" << endmsg;
+    sc = StatusCode::FAILURE;
+  } else {
+    if ( reg ) {
+      warning() << "Unable to register histograms automatically "
+                << "without a valid stream name" << endmsg;
+      reg = false;
+    }
+    sc = getTHists( gDirectory, tl, rcs, reg );
+  }
+
+  return sc;
+}
+
+StatusCode THistSvcHLT::getTTrees( TDirectory* td, TList& tl, bool rcs ) const
+{
+  GlobalDirectoryRestore restore( m_svcMut );
+
+  gErrorIgnoreLevel = kBreak;
+
+  if ( !td->cd() ) {
+    error() << "getTTrees: No such TDirectory \"" << td->GetPath() << "\"" << endmsg;
+    return StatusCode::FAILURE;
+  }
+
+  if ( msgLevel( MSG::DEBUG ) ) {
+    debug() << "getTHists: \"" << td->GetPath() << "\": found " << td->GetListOfKeys()->GetSize() << " keys" << endmsg;
+  }
+
+  TIter nextkey( td->GetListOfKeys() );
+  while ( TKey* key = (TKey*)nextkey() ) {
+    auto& log = debug();
+    if ( msgLevel( MSG::DEBUG ) ) log << "  key: " << key->GetName();
+    TObject* obj = key->ReadObj();
+    if ( obj != 0 && obj->IsA()->InheritsFrom( "TDirectory" ) ) {
+      if ( msgLevel( MSG::DEBUG ) ) log << " (" << obj->IsA()->GetName() << ")";
+    } else if ( obj != 0 && obj->IsA()->InheritsFrom( "TTree" ) ) {
+      if ( msgLevel( MSG::DEBUG ) ) log << " (" << obj->IsA()->GetName() << ")";
+      tl.Add( obj );
+    } else if ( obj != 0 ) {
+      if ( msgLevel( MSG::DEBUG ) ) log << " [" << obj->IsA()->GetName() << "]";
+    }
+    log << endmsg;
+  }
+
+  // operate recursively
+  if ( rcs ) {
+    nextkey = td->GetListOfKeys();
+    while ( TKey* key = (TKey*)nextkey() ) {
+      TObject* obj = key->ReadObj();
+      if ( obj && obj->IsA()->InheritsFrom( "TDirectory" ) ) {
+        TDirectory* tt = dynamic_cast<TDirectory*>( obj );
+        getTTrees( tt, tl, rcs );
+      }
+    }
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode THistSvcHLT::getTTrees( const std::string& dir, TList& tl, bool rcs ) const
+{
+  GlobalDirectoryRestore restore( m_svcMut );
+
+  gErrorIgnoreLevel = kBreak;
+
+  StatusCode sc;
+
+  std::string stream, rem, r2;
+  parseString( dir, stream, rem );
+
+  auto itr = m_files.find( stream );
+  if ( itr != m_files.end() ) {
+    r2 = itr->second.first->GetName();
+    r2 += ":/";
+    r2 += rem;
+
+    if ( msgLevel( MSG::DEBUG ) ) {
+      debug() << "getTTrees: \"" << dir << "\" looks like a stream name."
+              << " associated TFile: \"" << itr->second.first->GetName() << "\"" << endmsg;
+    }
+
+    if ( gDirectory->cd( r2.c_str() ) ) {
+      return getTTrees( gDirectory, tl, rcs );
+    }
+    if ( msgLevel( MSG::DEBUG ) ) {
+      debug() << "getTTrees: no such TDirectory \"" << r2 << "\"" << endmsg;
+    }
+  } else {
+    if ( msgLevel( MSG::DEBUG ) ) {
+      debug() << "getTTrees: stream \"" << stream << "\" not found" << endmsg;
+    }
+  }
+
+  if ( !gDirectory->cd( dir.c_str() ) ) {
+    error() << "getTTrees: No such TDirectory/stream \"" << dir << "\"" << endmsg;
+    sc = StatusCode::FAILURE;
+  } else {
+    sc = getTTrees( gDirectory, tl, rcs );
+  }
+  return sc;
+}
+
+StatusCode THistSvcHLT::getTTrees( TDirectory* td, TList& tl, bool rcs, bool reg )
+{
+  GlobalDirectoryRestore restore( m_svcMut );
+
+  gErrorIgnoreLevel = kBreak;
+
+  if ( !td->cd() ) {
+    error() << "getTTrees: No such TDirectory \"" << td->GetPath() << "\"" << endmsg;
+    return StatusCode::FAILURE;
+  }
+
+  if ( msgLevel( MSG::DEBUG ) ) {
+    debug() << "getTHists: \"" << td->GetPath() << "\": found " << td->GetListOfKeys()->GetSize() << " keys" << endmsg;
+  }
+
+  TIter nextkey( td->GetListOfKeys() );
+  while ( TKey* key = (TKey*)nextkey() ) {
+    auto& log = debug();
+    if ( msgLevel( MSG::DEBUG ) ) log << "  key: " << key->GetName();
+    TObject* obj = key->ReadObj();
+    if ( obj && obj->IsA()->InheritsFrom( "TDirectory" ) ) {
+      if ( msgLevel( MSG::DEBUG ) ) log << " (" << obj->IsA()->GetName() << ")";
+    } else if ( obj && obj->IsA()->InheritsFrom( "TTree" ) ) {
+      if ( msgLevel( MSG::DEBUG ) ) log << " (" << obj->IsA()->GetName() << ")";
+      tl.Add( obj );
+      if ( reg && m_curstream != "" ) {
+        std::string dir = td->GetPath();
+        std::string fil = td->GetFile()->GetName();
+        dir.erase( 0, fil.length() + 1 );
+        std::string id = "/" + m_curstream;
+        if ( dir == "/" ) {
+          id = id + "/" + key->GetName();
+        } else {
+          id = id + dir + "/" + key->GetName();
+        }
+        if ( !exists( id ) ) {
+          if ( msgLevel( MSG::DEBUG ) ) log << "  reg as \"" << id << "\"";
+          regHist( id ).ignore();
+        } else {
+          if ( msgLevel( MSG::DEBUG ) ) log << "  already registered";
+        }
+      }
+    } else if ( obj != 0 ) {
+      if ( msgLevel( MSG::DEBUG ) ) log << " [" << obj->IsA()->GetName() << "]";
+    }
+    if ( msgLevel( MSG::DEBUG ) ) log << endmsg;
+  }
+
+  // operate recursively
+  if ( rcs ) {
+    nextkey = td->GetListOfKeys();
+    while ( TKey* key = (TKey*)nextkey() ) {
+      TObject* obj = key->ReadObj();
+      if ( obj && obj->IsA()->InheritsFrom( "TDirectory" ) ) {
+        TDirectory* tt = dynamic_cast<TDirectory*>( obj );
+        getTTrees( tt, tl, rcs, reg );
+      }
+    }
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode THistSvcHLT::getTTrees( const std::string& dir, TList& tl, bool rcs, bool reg )
+{
+  GlobalDirectoryRestore restore( m_svcMut );
+
+  gErrorIgnoreLevel = kBreak;
+
+  StatusCode sc;
+
+  std::string stream, rem, r2;
+  parseString( dir, stream, rem );
+
+  auto itr = m_files.find( stream );
+  if ( itr != m_files.end() ) {
+    r2 = itr->second.first->GetName();
+    r2 += ":/";
+    r2 += rem;
+
+    if ( msgLevel( MSG::DEBUG ) ) {
+      debug() << "getTTrees: \"" << dir << "\" looks like a stream name."
+              << " associated TFile: \"" << itr->second.first->GetName() << "\"" << endmsg;
+    }
+
+    if ( gDirectory->cd( r2.c_str() ) ) {
+      return getTTrees( gDirectory, tl, rcs, reg );
+    } else {
+      if ( msgLevel( MSG::DEBUG ) ) {
+        debug() << "getTTrees: no such TDirectory \"" << r2 << "\"" << endmsg;
+      }
+    }
+  } else {
+    if ( msgLevel( MSG::DEBUG ) ) {
+      debug() << "getTTrees: stream \"" << stream << "\" not found" << endmsg;
+    }
+  }
+
+  if ( !gDirectory->cd( dir.c_str() ) ) {
+    error() << "getTTrees: No such TDirectory/stream \"" << dir << "\"" << endmsg;
+    return StatusCode::FAILURE;
+  }
+
+  return getTTrees( gDirectory, tl, rcs, reg );
+}
+
+//*************************************************************************//
+
+void THistSvcHLT::handle( const Incident& /* inc */ )
+{
+  if ( m_signaledStop ) return;
+
+  if ( m_maxFileSize.value() == -1 ) return;
+
+  // convert to bytes.
+  Long64_t mfs      = (Long64_t)m_maxFileSize.value() * (Long64_t)1048576;
+  Long64_t mfs_warn = mfs * 95 / 100;
+
+  updateFiles();
+
+  std::map<std::string, std::pair<TFile*, Mode>>::const_iterator itr;
+  for ( const auto& f : m_files ) {
+    TFile* tf = f.second.first;
+
+#ifndef NDEBUG
+    if ( msgLevel( MSG::DEBUG ) ) {
+      debug() << "stream: " << f.first << "  name: " << tf->GetName() << "  size: " << tf->GetSize() << endmsg;
+    }
+#endif
+
+    // Signal job to terminate if output file is too large
+    if ( tf->GetSize() > mfs ) {
+
+      m_signaledStop = true;
+
+      fatal() << "file \"" << tf->GetName() << "\" associated with stream \"" << f.first
+              << "\" has exceeded the max file size of " << m_maxFileSize.value() << "MB. Terminating Job." << endmsg;
+
+      IEventProcessor* evt = nullptr;
+      if ( service( "ApplicationMgr", evt, true ).isSuccess() ) {
+        evt->stopRun();
+        evt->release();
+      } else {
+        abort();
+      }
+    } else if ( tf->GetSize() > mfs_warn ) {
+      warning() << "file \"" << tf->GetName() << "\" associated with stream \"" << f.first
+                << "\" is at 95% of its maximum allowable file size of " << m_maxFileSize.value() << "MB" << endmsg;
+    }
+  }
+}
+
+/** @brief callback method to reinitialize the internal state of
+ *         the component for I/O purposes (e.g. upon @c fork(2))
+ */
+StatusCode THistSvcHLT::io_reinit()
+{
+  bool all_good = true;
+  if ( msgLevel( MSG::DEBUG ) ) {
+    debug() << "reinitializing I/O..." << endmsg;
+  }
+
+  // retrieve the I/O component manager...
+
+  IIoComponentMgr* iomgr = nullptr;
+
+  if ( service( "IoComponentMgr", iomgr, true ).isFailure() ) {
+    error() << "could not retrieve I/O component manager !" << endmsg;
+    return StatusCode::FAILURE;
+  }
+
+  GlobalDirectoryRestore restore( m_svcMut );
+  // to hide the expected errors upon closing the files whose
+  // file descriptors have been swept under the rug...
+  gErrorIgnoreLevel = kFatal;
+
+  for ( auto& ifile : m_files ) {
+    TFile* f          = ifile.second.first;
+    std::string fname = f->GetName();
+    if ( msgLevel( MSG::DEBUG ) ) {
+      debug() << "file [" << fname << "] mode: [" << f->GetOption() << "] r:" << f->GetFileBytesRead()
+              << " w:" << f->GetFileBytesWritten() << " cnt:" << f->GetFileCounter() << endmsg;
+    }
+
+    if ( ifile.second.second == READ ) {
+      if ( msgLevel( MSG::DEBUG ) ) {
+        debug() << "  TFile opened in READ mode: not reassigning names" << endmsg;
+      }
+      continue;
+    }
+
+    if ( !iomgr->io_retrieve( this, fname ).isSuccess() ) {
+      error() << "could not retrieve new name for [" << fname << "] !!" << endmsg;
+      all_good = false;
+      continue;
+    } else {
+      if ( msgLevel( MSG::DEBUG ) ) {
+        debug() << "got a new name [" << fname << "]..." << endmsg;
+      }
+    }
+
+    void* vf       = nullptr;
+    Option_t* opts = f->GetOption();
+    int r          = p_fileMgr->open( Io::ROOT, name(), fname, Io::WRITE, vf, "HIST" );
+    if ( r != 0 ) {
+      error() << "unable to open file \"" << fname << "\" for writing" << endmsg;
+      return StatusCode::FAILURE;
+    }
+    TFile* newfile = (TFile*)vf;
+    newfile->SetOption( opts );
+
+    if ( ifile.second.second != THistSvcHLT::READ ) {
+      copyFileLayout( newfile, f );
+      ifile.second.first = newfile;
+    }
+
+    // loop over all uids and migrate them to the new file
+    for ( auto& uid : m_uids ) {
+      for ( auto& hid : *uid.second ) {
+        if ( hid.file != f ) continue;
+        TDirectory* olddir = this->changeDir( hid );
+        hid.file           = newfile;
+        // side-effect: create needed directories...
+        TDirectory* newdir = this->changeDir( hid );
+        TClass* cl         = hid.obj->IsA();
+
+        // migrate the objects to the new file.
+        // thanks to the object model of ROOT, it is super easy.
+        if ( cl->InheritsFrom( "TTree" ) ) {
+          dynamic_cast<TTree*>( hid.obj )->SetDirectory( newdir );
+          dynamic_cast<TTree*>( hid.obj )->Reset();
+        } else if ( cl->InheritsFrom( "TH1" ) ) {
+          dynamic_cast<TH1*>( hid.obj )->SetDirectory( newdir );
+          dynamic_cast<TH1*>( hid.obj )->Reset();
+        } else if ( cl->InheritsFrom( "TGraph" ) ) {
+          olddir->Remove( hid.obj );
+          newdir->Append( hid.obj );
+        } else {
+          error() << "id: \"" << hid.id << "\" is not a inheriting from a class "
+                  << "we know how to handle (received [" << cl->GetName() << "], "
+                  << "expected [TTree, TH1 or TGraph]) !" << endmsg << "attaching to current dir [" << newdir->GetPath()
+                  << "] "
+                  << "nonetheless..." << endmsg;
+          olddir->Remove( hid.obj );
+          newdir->Append( hid.obj );
+        }
+      }
+    }
+    f->ReOpen( "READ" );
+    p_fileMgr->close( f, name() );
+    f = newfile;
+  }
+
+  return all_good ? StatusCode::SUCCESS : StatusCode::FAILURE;
+}
+
+//*************************************************************************//
+
+THistSvcHLT::GlobalDirectoryRestore::GlobalDirectoryRestore( THistSvcMutex_t& mut ) : m_lock( mut )
+{
+  m_gDirectory        = gDirectory;
+  m_gFile             = gFile;
+  m_gErrorIgnoreLevel = gErrorIgnoreLevel;
+}
+
+THistSvcHLT::GlobalDirectoryRestore::~GlobalDirectoryRestore()
+{
+  gDirectory        = m_gDirectory;
+  gFile             = m_gFile;
+  gErrorIgnoreLevel = m_gErrorIgnoreLevel;
+}
+
+//*************************************************************************//
+
+template <typename T>
+T* THistSvcHLT::readHist( const std::string& id ) const
+{
+  return dynamic_cast<T*>( readHist_i<T>( id ) );
+}
+
+TTree* THistSvcHLT::readTree( const std::string& id ) const { return dynamic_cast<TTree*>( readHist_i<TTree>( id ) ); }
+
+void THistSvcHLT::updateFiles()
+{
+  // If TTrees grow beyond TTree::fgMaxTreeSize, a new file is
+  // automatically created by root, and the old one closed. We
+  // need to migrate all the UIDs over to show the correct file
+  // pointer. This is ugly.
+
+  if ( msgLevel( MSG::DEBUG ) ) debug() << "updateFiles()" << endmsg;
+
+  for ( auto uitr = m_uids.begin(); uitr != m_uids.end(); ++uitr ) {
+    for ( auto& hid : *( uitr->second ) ) {
+#ifndef NDEBUG
+      if ( msgLevel( MSG::VERBOSE ) )
+        verbose() << " update: " << uitr->first << " " << hid.id << " " << hid.mode << endmsg;
+#endif
+      TObject* to    = hid.obj;
+      TFile* oldFile = hid.file;
+      if ( !to ) {
+        warning() << uitr->first << ": TObject == 0" << endmsg;
+      } else if ( hid.temp || hid.mode == READ ) {
+// do nothing - no need to check how big the file is since we
+// are just reading it.
+#ifndef NDEBUG
+        if ( msgLevel( MSG::VERBOSE ) ) verbose() << "     skipping" << endmsg;
+#endif
+      } else if ( to->IsA()->InheritsFrom( "TTree" ) ) {
+        TTree* tr      = dynamic_cast<TTree*>( to );
+        TFile* newFile = tr->GetCurrentFile();
+
+        if ( oldFile != newFile ) {
+          std::string newFileName = newFile->GetName();
+          std::string oldFileName, streamName, rem;
+          TFile* dummy = nullptr;
+          findStream( hid.id, streamName, rem, dummy );
+
+          for ( auto& itr : m_files ) {
+            if ( itr.second.first == oldFile ) {
+              itr.second.first = newFile;
+            }
+          }
+
+          for ( auto uitr2 = uitr; uitr2 != m_uids.end(); ++uitr2 ) {
+            for ( auto& hid2 : *( uitr2->second ) ) {
+              if ( hid2.file == oldFile ) {
+                hid2.file = newFile;
+              }
+            }
+          }
+
+          auto sitr = std::find_if( std::begin( m_fileStreams ), std::end( m_fileStreams ),
+                                    [&]( streamMap::const_reference s ) { return s.second == streamName; } );
+          if ( sitr != std::end( m_fileStreams ) ) oldFileName = sitr->first;
+
+#ifndef NDEBUG
+          if ( msgLevel( MSG::DEBUG ) ) {
+            debug() << "migrating uid: " << hid.id << "   stream: " << streamName << "   oldFile: " << oldFileName
+                    << "   newFile: " << newFileName << endmsg;
+          }
+#endif
+
+          if ( !oldFileName.empty() ) {
+            auto i = m_fileStreams.lower_bound( oldFileName );
+            while ( i != std::end( m_fileStreams ) && i->first == oldFileName ) {
+#ifndef NDEBUG
+              if ( msgLevel( MSG::DEBUG ) ) {
+                debug() << "changing filename \"" << i->first << "\" to \"" << newFileName << "\" for stream \""
+                        << i->second << "\"" << endmsg;
+              }
+#endif
+              std::string nm = std::move( i->second );
+              i              = m_fileStreams.erase( i );
+              m_fileStreams.emplace( newFileName, std::move( nm ) );
+            }
+          } else {
+            error() << "Problems updating fileStreams with new file name" << endmsg;
+          }
+        }
+      }
+    }
+  }
+}
+
+StatusCode THistSvcHLT::writeObjectsToFile()
+{
+  updateFiles();
+
+  std::for_each( m_files.begin(), m_files.end(), []( std::pair<const std::string, std::pair<TFile*, Mode>>& i ) {
+    auto mode = i.second.second;
+    auto file = i.second.first;
+    if ( mode == WRITE || mode == UPDATE || mode == SHARE ) {
+      file->Write( "", TObject::kOverwrite );
+    } else if ( mode == APPEND ) {
+      file->Write( "" );
+    }
+  } );
+
+  if ( msgLevel( MSG::DEBUG ) ) {
+    debug() << "THistSvcHLT::writeObjectsToFile()::List of Files connected in ROOT " << endmsg;
+    TSeqCollection* filelist = gROOT->GetListOfFiles();
+    for ( int ii = 0; ii < filelist->GetEntries(); ii++ ) {
+      debug() << "THistSvcHLT::writeObjectsToFile()::List of Files connected in ROOT: \"" << filelist->At( ii )->GetName()
+              << "\"" << endmsg;
+    }
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode THistSvcHLT::connect( const std::string& ident )
+{
+  auto loc           = ident.find( " " );
+  std::string stream = ident.substr( 0, loc );
+  char typ( 0 );
+  typedef std::pair<std::string, std::string> Prop;
+  std::vector<Prop> props;
+  std::string filename, db_typ( "ROOT" );
+  int cl( 1 );
+
+  if ( loc != std::string::npos ) {
+    using Parser = Gaudi::Utils::AttribStringParser;
+    for ( auto attrib : Parser( ident.substr( loc + 1 ) ) ) {
+      auto TAG = boost::algorithm::to_upper_copy( attrib.tag );
+      auto VAL = boost::algorithm::to_upper_copy( attrib.value );
+
+      if ( TAG == "FILE" || TAG == "DATAFILE" ) {
+        filename = attrib.value;
+        removeDoubleSlash( filename );
+      } else if ( TAG == "OPT" ) {
+        if ( VAL == "APPEND" || VAL == "UPDATE" ) {
+          typ = 'A';
+        } else if ( VAL == "CREATE" || VAL == "NEW" || VAL == "WRITE" ) {
+          typ = 'N';
+        } else if ( VAL == "RECREATE" ) {
+          typ = 'R';
+        } else if ( VAL == "SHARE" ) {
+          typ = 'S';
+        } else if ( VAL == "OLD" || VAL == "READ" ) {
+          typ = 'O';
+        } else {
+          error() << "Unknown OPT: \"" << attrib.value << "\"" << endmsg;
+          typ = 0;
+        }
+      } else if ( TAG == "TYP" ) {
+        db_typ = std::move( attrib.value );
+      } else if ( TAG == "CL" ) {
+        cl = std::stoi( attrib.value );
+      } else {
+        props.emplace_back( attrib.tag, attrib.value );
+      }
+    }
+  }
+
+  if ( stream == "temp" ) {
+    error() << "in JobOption \"" << ident << "\": stream name \"temp\" reserved." << endmsg;
+    return StatusCode::FAILURE;
+  }
+
+  if ( db_typ != "ROOT" ) {
+    error() << "in JobOption \"" << ident << "\": technology type \"" << db_typ << "\" not supported." << endmsg;
+    return StatusCode::FAILURE;
+  }
+
+  if ( m_files.find( stream ) != m_files.end() ) {
+    error() << "in JobOption \"" << ident << "\":\n stream \"" << stream << "\" already connected to file: \""
+            << m_files[stream].first->GetName() << "\"" << endmsg;
+    return StatusCode::FAILURE;
+  }
+
+  Mode newMode;
+  if ( typ == 'O' ) {
+    newMode = THistSvcHLT::READ;
+  } else if ( typ == 'N' ) {
+    newMode = THistSvcHLT::WRITE;
+  } else if ( typ == 'A' ) {
+    newMode = THistSvcHLT::APPEND;
+  } else if ( typ == 'R' ) {
+    newMode = THistSvcHLT::UPDATE;
+  } else if ( typ == 'S' ) {
+    newMode = THistSvcHLT::SHARE;
+  } else {
+    // something else?
+    error() << "No OPT= specified or unknown access mode in: " << ident << endmsg;
+    return StatusCode::FAILURE;
+  }
+
+  // Is this file already connected to another stream?
+  if ( m_fileStreams.find( filename ) != m_fileStreams.end() ) {
+    auto fitr = m_fileStreams.equal_range( filename );
+
+    const std::string& oldstream = fitr.first->second;
+
+    const auto& f_info = m_files[oldstream];
+
+    if ( newMode != f_info.second ) {
+      error() << "in JobOption \"" << ident << "\":\n file \"" << filename << "\" already opened by stream: \""
+              << oldstream << "\" with different access mode." << endmsg;
+      return StatusCode::FAILURE;
+    } else {
+      TFile* f2       = f_info.first;
+      m_files[stream] = std::make_pair( f2, newMode );
+      if ( msgLevel( MSG::DEBUG ) )
+        debug() << "Connecting stream: \"" << stream << "\" to previously opened TFile: \"" << filename << "\""
+                << endmsg;
+      return StatusCode::SUCCESS;
+    }
+  }
+
+  IIncidentSvc* pi = nullptr;
+  if ( service( "IncidentSvc", pi ).isFailure() ) {
+    error() << "Unable to get the IncidentSvc" << endmsg;
+    return StatusCode::FAILURE;
+  }
+
+  void* vf = nullptr;
+  TFile* f = nullptr;
+
+  if ( newMode == THistSvcHLT::READ ) {
+    // old file
+    int r = p_fileMgr->open( Io::ROOT, name(), filename, Io::READ, vf, "HIST" );
+
+    if ( r != 0 ) {
+      error() << "Unable to open ROOT file " << filename << " for reading" << endmsg;
+      return StatusCode::FAILURE;
+    }
+
+    f = (TFile*)vf;
+
+    // FIX ME!
+    pi->fireIncident( FileIncident( name(), "BeginHistFile", filename ) );
+
+  } else if ( newMode == THistSvcHLT::WRITE ) {
+    // new file. error if file exists
+    int r = p_fileMgr->open( Io::ROOT, name(), filename, ( Io::WRITE | Io::CREATE | Io::EXCL ), vf, "HIST" );
+
+    if ( r != 0 ) {
+      error() << "Unable to open ROOT file " << filename << " for writing" << endmsg;
+      return StatusCode::FAILURE;
+    }
+
+    f = (TFile*)vf;
+
+  } else if ( newMode == THistSvcHLT::APPEND ) {
+    // update file
+    int r = p_fileMgr->open( Io::ROOT, name(), filename, ( Io::WRITE | Io::APPEND ), vf, "HIST" );
+    if ( r != 0 ) {
+      error() << "unable to open file \"" << filename << "\" for appending" << endmsg;
+      return StatusCode::FAILURE;
+    }
+
+    f = (TFile*)vf;
+
+  } else if ( newMode == THistSvcHLT::SHARE ) {
+    // SHARE file type
+    // For SHARE files, all data will be stored in a temp file and will be
+    // merged into the target file in writeObjectsToFile() when finalize(),
+    // this help to solve some confliction. e.g. with storegate
+    static int ishared       = 0;
+    std::string realfilename = filename;
+    filename                 = "tmp_THistSvcHLT_" + std::to_string( ishared++ ) + ".root";
+
+    if ( msgLevel( MSG::DEBUG ) ) {
+      debug() << "Creating temp file \"" << filename << "\" and realfilename=" << realfilename << endmsg;
+    }
+    m_sharedFiles[stream] = realfilename;
+
+    int r = p_fileMgr->open( Io::ROOT, name(), filename, ( Io::WRITE | Io::CREATE | Io::EXCL ), vf, "HIST" );
+
+    if ( r != 0 ) {
+      error() << "Unable to open ROOT file " << filename << " for writing" << endmsg;
+      return StatusCode::FAILURE;
+    }
+
+    f = (TFile*)vf;
+
+  } else if ( newMode == THistSvcHLT::UPDATE ) {
+    // update file
+    int r = p_fileMgr->open( Io::ROOT, name(), filename, ( Io::WRITE | Io::CREATE ), vf, "HIST" );
+
+    if ( r != 0 ) {
+      error() << "Unable to open ROOT file " << filename << " for appending" << endmsg;
+      return StatusCode::FAILURE;
+    }
+
+    f = (TFile*)vf;
+  }
+
+  m_files[stream] = std::make_pair( f, newMode );
+  m_fileStreams.insert( std::make_pair( filename, stream ) );
+
+  if ( msgLevel( MSG::DEBUG ) ) {
+    debug() << "Opening TFile \"" << filename << "\"  stream: \"" << stream << "\"  mode: \"" << typ << "\""
+            << " comp level: " << cl << endmsg;
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+TDirectory* THistSvcHLT::changeDir( const THistSvcHLT::THistID& hid ) const
+{
+  std::string uid = hid.id;
+  TFile* file     = hid.file;
+  std::string stream, fdir, bdir, dir, id;
+
+  if ( file ) {
+    file->cd( "/" );
+  } else {
+    gROOT->cd();
+  }
+
+  fdir = uid;
+  bdir = stripDirectoryName( fdir );
+
+  while ( ( dir = stripDirectoryName( fdir ) ) != "" ) {
+    if ( !gDirectory->GetKey( dir.c_str() ) ) {
+      gDirectory->mkdir( dir.c_str() );
+    }
+    gDirectory->cd( dir.c_str() );
+  }
+
+  return gDirectory;
+}
+
+std::string THistSvcHLT::stripDirectoryName( std::string& dir ) const
+{
+  std::string::size_type i = dir.find( "/" );
+
+  if ( i == std::string::npos ) return {};
+
+  if ( i == 0 ) {
+    dir.erase( 0, 1 );
+    return stripDirectoryName( dir );
+  }
+
+  std::string root = dir.substr( 0, i );
+  dir.erase( 0, i );
+
+  return root;
+}
+
+void THistSvcHLT::removeDoubleSlash( std::string& id ) const
+{
+  while ( id.find( "//" ) != std::string::npos ) {
+    id.replace( id.find( "//" ), 2, "/" );
+  }
+}
+
+void THistSvcHLT::MergeRootFile( TDirectory* target, TDirectory* source )
+{
+  if ( msgLevel( MSG::DEBUG ) ) {
+    debug() << "Target path: " << target->GetPath() << endmsg;
+  }
+  TString path( (char*)strstr( target->GetPath(), ":" ) );
+  path.Remove( 0, 2 );
+
+  source->cd( path );
+  TDirectory* current_sourcedir = gDirectory;
+
+  // loop over all keys in this directory
+  TList* lkeys = current_sourcedir->GetListOfKeys();
+  int nkeys    = lkeys->GetEntries();
+  TKey* key    = nullptr;
+  for ( int jj = 0; jj < nkeys; jj++ ) {
+    key                          = (TKey*)lkeys->At( jj );
+    std::string pathnameinsource = current_sourcedir->GetPath() + std::string( "/" ) + key->GetName();
+    if ( msgLevel( MSG::DEBUG ) ) {
+      debug() << "Reading Key:" << pathnameinsource << endmsg;
+    }
+    TObject* obj = source->Get( pathnameinsource.c_str() );
+
+    if ( obj ) {
+      if ( obj->IsA()->InheritsFrom( "TDirectory" ) ) {
+        // it's a subdirectory
+        if ( msgLevel( MSG::DEBUG ) ) {
+          debug() << "Found subdirectory " << obj->GetName() << endmsg;
+        }
+
+        // create a new subdir of same name and title in the target file
+        target->cd();
+        TDirectory* newtargetdir = target->mkdir( obj->GetName(), obj->GetTitle() );
+
+        MergeRootFile( newtargetdir, source );
+
+      } else if ( obj->IsA()->InheritsFrom( "TTree" ) ) {
+        if ( msgLevel( MSG::DEBUG ) ) {
+          debug() << "Found TTree " << obj->GetName() << endmsg;
+        }
+        TTree* mytree = dynamic_cast<TTree*>( obj );
+        int nentries  = (int)mytree->GetEntries();
+        mytree->SetBranchStatus( "*", 1 );
+
+        if ( msgLevel( MSG::DEBUG ) ) {
+          debug() << "Dumping TTree " << nentries << " entries" << endmsg;
+        }
+        target->cd();
+        mytree->CloneTree();
+
+      } else {
+        target->cd();
+        obj->Write( key->GetName() );
+      }
+    }
+  }
+}
+
+bool THistSvcHLT::findStream( const std::string& id, std::string& stream, std::string& rem, TFile*& file ) const
+{
+  auto pos = id.find( "/" );
+
+  if ( pos == std::string::npos ) {
+    // no "/" in id
+    stream = "temp";
+    rem    = id;
+  } else if ( pos != 0 ) {
+    // id does not start with "/"
+    stream = "temp";
+    rem    = id;
+  } else {
+    // id starts with "/"
+
+    auto pos2 = id.find( "/", pos + 1 );
+
+    if ( pos2 == std::string::npos ) {
+      // need at least 2 "/" in format "/STREAM/name" or "/STREAM/dir/name"
+      error() << "badly formed Hist/Tree id: \"" << id << "\"" << endmsg;
+      return false;
+    }
+    parseString( id, stream, rem );
+  }
+
+  if ( stream == "temp" ) {
+    file = nullptr;
+    return true;
+  }
+
+  auto itr = m_files.find( stream );
+  file     = ( itr != m_files.end() ? itr->second.first : nullptr );
+  if ( !file ) {
+    warning() << "no stream \"" << stream << "\" associated with id: \"" << id << "\"" << endmsg;
+  }
+
+  return true;
+}
+
+void THistSvcHLT::parseString( const std::string& id, std::string& root, std::string& rem ) const
+{
+  auto pos = id.find( "/" );
+
+  if ( pos == std::string::npos ) {
+    root.clear();
+    rem = id;
+  } else if ( pos == 0 ) {
+    parseString( id.substr( 1 ), root, rem );
+  } else {
+    root = id.substr( 0, pos );
+    rem  = id.substr( pos + 1 );
+  }
+}
+
+void THistSvcHLT::setupInputFile( Gaudi::Details::PropertyBase&
+                               /*m_inputfile*/ )
+{
+  if ( FSMState() < Gaudi::StateMachine::CONFIGURED || !m_okToConnect ) {
+    debug() << "Delaying connection of Input Files until Initialize"
+            << ". now in " << FSMState() << endmsg;
+
+    m_delayConnect = true;
+  } else {
+    debug() << "Now connecting of Input Files" << endmsg;
+
+    StatusCode sc = StatusCode::SUCCESS;
+
+    for ( const auto& itr : m_inputfile.value() ) {
+      if ( m_alreadyConnectedInFiles.end() != m_alreadyConnectedInFiles.find( itr ) ) {
+        continue;
+      }
+      if ( connect( itr ).isFailure() ) {
+        sc = StatusCode::FAILURE;
+      } else {
+        m_alreadyConnectedInFiles.insert( itr );
+      }
+    }
+
+    if ( !sc.isSuccess() ) {
+      throw GaudiException( "Problem connecting inputfile !!", name(), StatusCode::FAILURE );
+    }
+  }
+}
+
+void THistSvcHLT::setupOutputFile( Gaudi::Details::PropertyBase&
+                                /*m_outputfile*/ )
+{
+  if ( FSMState() < Gaudi::StateMachine::CONFIGURED || !m_okToConnect ) {
+    debug() << "Delaying connection of Input Files until Initialize"
+            << ". now in " << FSMState() << endmsg;
+    m_delayConnect = true;
+  } else {
+    StatusCode sc = StatusCode::SUCCESS;
+    for ( const auto& itr : m_outputfile.value() ) {
+      if ( m_alreadyConnectedOutFiles.end() != m_alreadyConnectedOutFiles.find( itr ) ) {
+        continue;
+      }
+      if ( connect( itr ).isFailure() ) {
+        sc = StatusCode::FAILURE;
+      } else {
+        m_alreadyConnectedOutFiles.insert( itr );
+      }
+    }
+
+    if ( !sc.isSuccess() ) {
+      throw GaudiException( "Problem connecting outputfile !!", name(), StatusCode::FAILURE );
+    }
+  }
+}
+
+void THistSvcHLT::setupCompressionLevel( Gaudi::Details::PropertyBase&
+                                      /* cl */ )
+{
+  warning() << "\"CompressionLevel\" Property has been deprecated. "
+            << "Set it via the \"CL=\" parameter in the \"Output\" Property" << endmsg;
+}
+
+void THistSvcHLT::copyFileLayout( TDirectory* destination, TDirectory* source )
+{
+  if ( msgLevel( MSG::DEBUG ) ) {
+    debug() << "copyFileLayout() to destination path: " << destination->GetPath() << endmsg;
+  }
+
+  // strip out URLs
+  TString path( (char*)strstr( destination->GetPath(), ":" ) );
+  path.Remove( 0, 2 );
+
+  source->cd( path );
+  TDirectory* current_source_dir = gDirectory;
+
+  // loop over all keys in this directory
+  TList* key_list = current_source_dir->GetListOfKeys();
+  int n           = key_list->GetEntries();
+  for ( int j = 0; j < n; ++j ) {
+    TKey* k                           = (TKey*)key_list->At( j );
+    const std::string source_pathname = current_source_dir->GetPath() + std::string( "/" ) + k->GetName();
+    TObject* o                        = source->Get( source_pathname.c_str() );
+
+    if ( o && o->IsA()->InheritsFrom( "TDirectory" ) ) {
+      if ( msgLevel( MSG::VERBOSE ) ) {
+        verbose() << " subdir [" << o->GetName() << "]..." << endmsg;
+      }
+      destination->cd();
+      TDirectory* destination_dir = destination->mkdir( o->GetName(), o->GetTitle() );
+      copyFileLayout( destination_dir, source );
+    }
+  } // loop over keys
+  return;
+}
+
+size_t THistSvcHLT::findHistID( const std::string& id, const THistID*& hid, const size_t& index ) const
+{
+  GlobalDirectoryRestore restore( m_svcMut );
+
+  std::string idr( id );
+  removeDoubleSlash( idr );
+
+  hid = 0;
+
+  if ( idr.find( "/" ) == 0 ) {
+    // fully specified name, starts with "/"
+    auto itr = m_uids.find( idr );
+    if ( itr == m_uids.end() ) {
+      // no matches found
+      return 0;
+    } else {
+      // one or more matches found (clones).
+      if ( index >= itr->second->size() ) {
+        error() << "no index " << index << " found for Hist " << idr << endmsg;
+        return 0;
+      }
+      hid = &( itr->second->at( index ) );
+      return 1;
+    }
+  } else {
+    // name not fully specified.
+    auto mitr = m_ids.equal_range( idr );
+    if ( mitr.first == mitr.second ) {
+      // not found
+      return 0;
+    } else if ( distance( mitr.first, mitr.second ) == 1 ) {
+      // one found
+      if ( index >= mitr.first->second->size() ) {
+        error() << "no index " << index << " found for Hist " << idr << endmsg;
+        return 0;
+      }
+      hid = &( mitr.first->second->at( 0 ) );
+      return 1;
+    } else {
+      // multiple matches
+      hid = &( mitr.first->second->at( 0 ) );
+      return distance( mitr.first, mitr.second );
+    }
+  }
+}
+
+void THistSvcHLT::dump() const
+{
+  std::ostringstream ost;
+
+  // list< vector<THistID> >
+  ost << "m_hlist:  size: " << m_hlist.size() << "\n";
+  for ( auto& vh : m_hlist ) {
+    ost << " - " << vh->at( 0 ) << " :: [" << vh << "] " << vh->size() << " {";
+    for ( auto& e : *vh ) {
+      TObject* o = e.obj;
+      ost << "[" << o << "]";
+    }
+    ost << "}\n";
+  }
+
+  // map uid -> vector<THistID>*
+  ost << "\n"
+      << "m_uids: " << m_uids.size() << "\n";
+  for ( auto& e : m_uids ) {
+    ost << " - " << e.first << "  [" << e.second << "]" << std::endl;
+  }
+
+  // multimap id -> vector<THistID>*
+  ost << "\n"
+      << "m_ids: " << m_ids.size() << "\n";
+  for ( auto& e : m_ids ) {
+    ost << " - " << e.first << "  [" << e.second << "]" << std::endl;
+  }
+
+  // map TObject* -> THistID*
+  ost << "\n"
+      << "m_tobjs: " << m_tobjs.size() << "\n";
+  for ( auto& e : m_tobjs ) {
+    TObject* o = e.first;
+    THistID& i = e.second.first->at( e.second.second );
+    ost << " - " << o << " -> " << i << std::endl;
+  }
+
+  debug() << "dumping THistSvcHLT contents\n" << ost.str() << endmsg;
+}
+
+StatusCode THistSvcHLT::merge( const THistID& hid ) { return merge( hid.id ); }
+
+StatusCode THistSvcHLT::merge( vhid_t* vh )
+{
+  const std::string& name = vh->at( 0 ).id;
+  if ( vh->size() == 1 ) {
+    debug() << "merge: id: \"" << name << "\" is size 1. nothing to do" << endmsg;
+    return StatusCode::SUCCESS;
+  }
+
+  if ( !vh->at( 0 ).obj->IsA()->InheritsFrom( "TH1" ) ) {
+    error() << "merge: id \"" << name << "\" is not a THn. Cannot merge" << endmsg;
+    return StatusCode::FAILURE;
+  }
+
+  TList* l = new TList();
+  for ( size_t i = 1; i < vh->size(); ++i ) {
+    debug() << "merge: id: \"" << name << "\" (" << vh->at( i ).obj << ") adding index " << i << endmsg;
+    l->Add( vh->at( i ).obj );
+  }
+
+  TH1* t0 = dynamic_cast<TH1*>( vh->at( 0 ).obj );
+  if ( t0 == 0 ) {
+    error() << "merge: could not dcast " << name << "(" << t0 << ") index " << 0 << " to TH1" << endmsg;
+    return StatusCode::FAILURE;
+  }
+
+  Long64_t n = t0->Merge( l );
+
+  debug() << "merge: id: \"" << name << "\" merged " << n << " entries" << endmsg;
+
+  for ( size_t i = 1; i < vh->size(); ++i ) {
+    TH1* th = dynamic_cast<TH1*>( vh->at( i ).obj );
+    if ( th != 0 ) {
+      debug() << "clearing index " << i << "(" << th << ")" << endmsg;
+      th->SetDirectory( nullptr );
+      th->Reset();
+    } else {
+      error() << "merge: could not dcast " << name << " index " << i << " to TH1" << endmsg;
+      return StatusCode::FAILURE;
+    }
+  }
+  return StatusCode::SUCCESS;
+}
+
+StatusCode THistSvcHLT::rootOpenAction( const Io::FileAttr* fa, const std::string& caller )
+{
+  if ( fa->tech() != Io::ROOT ) {
+    // This should never happen
+    return StatusCode::SUCCESS;
+  }
+
+  if ( fa->desc() != "HIST" ) {
+    return StatusCode::SUCCESS;
+  }
+
+  p_incSvc->fireIncident( FileIncident( caller, "OpenHistFile", fa->name() ) );
+
+  if ( fa->flags().isRead() ) {
+    p_incSvc->fireIncident( FileIncident( caller, "BeginHistFile", fa->name() ) );
+  } else if ( fa->flags().isWrite() ) {
+    p_incSvc->fireIncident( FileIncident( caller, IncidentType::BeginOutputFile, fa->name() ) );
+  } else {
+    // for Io::RW
+    p_incSvc->fireIncident( FileIncident( caller, IncidentType::BeginOutputFile, fa->name() ) );
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode THistSvcHLT::rootOpenErrAction( const Io::FileAttr* fa, const std::string& caller )
+{
+  if ( fa->tech() != Io::ROOT ) {
+    // This should never happen
+    return StatusCode::SUCCESS;
+  }
+
+  if ( fa->desc() != "HIST" ) {
+    return StatusCode::SUCCESS;
+  }
+
+  if ( fa->flags().isRead() ) {
+    p_incSvc->fireIncident( FileIncident( caller, IncidentType::FailInputFile, fa->name() ) );
+  } else if ( fa->flags().isWrite() ) {
+    p_incSvc->fireIncident( FileIncident( caller, IncidentType::FailOutputFile, fa->name() ) );
+  } else {
+    // for Io::RW
+    p_incSvc->fireIncident( FileIncident( caller, "FailRWFile", fa->name() ) );
+  }
+
+  return StatusCode::SUCCESS;
+}
diff --git a/HLT/Trigger/TrigControl/TrigServices/src/THistSvcHLT.cxx.bak b/HLT/Trigger/TrigControl/TrigServices/src/THistSvcHLT.cxx.bak
deleted file mode 100644
index eafaf3e89009bca51cf5e2cd582dffa87ce68357..0000000000000000000000000000000000000000
--- a/HLT/Trigger/TrigControl/TrigServices/src/THistSvcHLT.cxx.bak
+++ /dev/null
@@ -1,2087 +0,0 @@
-/*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-*/
-
-#ifdef __ICC
-// disable icc remark #2259: non-pointer conversion from "X" to "Y" may lose significant bits
-//   TODO: To be removed, since it comes from ROOT TMathBase.h
-#pragma warning(disable:2259)
-#endif
-
-#include "THistSvcHLT.h"
-
-#include "GaudiKernel/ISvcLocator.h"
-#include "GaudiKernel/AttribStringParser.h"
-#include "GaudiKernel/GaudiException.h"
-#include "GaudiKernel/Property.h"
-#include "GaudiKernel/IIncidentSvc.h"
-#include "GaudiKernel/FileIncident.h"
-#include "GaudiKernel/IEventProcessor.h"
-#include "GaudiKernel/IJobOptionsSvc.h"
-#include "GaudiKernel/IIoComponentMgr.h"
-#include "GaudiKernel/IFileMgr.h"
-#include "boost/algorithm/string/case_conv.hpp"
-
-#include "TROOT.h"
-#include "TFile.h"
-#include "TDirectory.h"
-#include "TKey.h"
-#include "TError.h"
-#include "TGraph.h"
-
-#include <sstream>
-#include <streambuf>
-#include <cstdio>
-
-using namespace std;
-
-
-DECLARE_COMPONENT(THistSvcHLT)
-
-namespace {
-
-template <typename InputIterator, typename OutputIterator, typename UnaryOperation, typename UnaryPredicate>
-OutputIterator transform_if( InputIterator first, InputIterator last,
-                             OutputIterator result,
-                             UnaryOperation op, 
-                             UnaryPredicate pred) {
-    while (first != last) {
-        if (pred(*first)) *result++ = op(*first);
-        ++first;
-    }
-    return result;
-}
-
-constexpr struct select1st_t {
-    template <typename T, typename S> 
-    const T& operator()(const std::pair<T,S>& p) const { return p.first; }
-} select1st {} ;
-
-
-}
-
-
-//*************************************************************************//
-
-THistSvcHLT::THistSvcHLT( const std::string& name, ISvcLocator* svc )
-  : base_class(name, svc), m_log(msgSvc(), name )
-{    
-  declareProperty ("AutoSave", m_autoSave=0 );
-  declareProperty ("AutoFlush", m_autoFlush=0 );
-  declareProperty ("PrintAll", m_print=false);
-  declareProperty ("MaxFileSize", m_maxFileSize=10240,
-		   "maximum file size in MB. if exceeded, will cause an abort. -1 to never check.");
-  declareProperty ("CompressionLevel", m_compressionLevel=1 )->declareUpdateHandler( &THistSvcHLT::setupCompressionLevel, this );
-  declareProperty ("Output", m_outputfile )->declareUpdateHandler( &THistSvcHLT::setupOutputFile, this );
-  declareProperty ("Input", m_inputfile )->declareUpdateHandler ( &THistSvcHLT::setupInputFile,  this );
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::initialize() {
-  GlobalDirectoryRestore restore;
-
-  // Super ugly hack to make sure we have the OutputLevel set first, so we
-  // can see DEBUG printouts in update handlers.
-  auto jos = serviceLocator()->service<IJobOptionsSvc>( "JobOptionsSvc", true );
-  if( jos ) { 
-    const auto props = jos->getProperties( name() );
-
-    if ( props ) {
-      auto i = std::find_if(std::begin(*props),std::end(*props),
-                            [](const Property* p) { return p->name() == "OutputLevel"; } );
-      if ( i != std::end(*props)) {
-          setProperty( **i ).ignore();
-          m_log.setLevel( m_outputLevel.value() );
-      }
-    }
-  }
-
-
-  StatusCode status = Service::initialize();
-  m_log.setLevel( m_outputLevel.value() );
-
-  if (status.isFailure()) {
-    m_log << MSG::ERROR << "initializing service" << endmsg;
-    return status;
-  }
-
-  StatusCode st(StatusCode::SUCCESS);
-
-  try {
-    setupOutputFile( m_outputfile );
-  } catch ( GaudiException& err ) {
-    m_log << MSG::ERROR
-          << "Caught: " << err << endmsg;
-    st = StatusCode::FAILURE;
-  }
-
-  try {
-    setupInputFile( m_inputfile );
-  } catch ( GaudiException& err ) {
-    m_log << MSG::ERROR
-          << "Caught: " << err << endmsg;
-    st = StatusCode::FAILURE;
-  }
-
-  // Protect against multiple instances of TROOT
-  if ( !gROOT )   {
-    static TROOT root("root","ROOT I/O");
-    //    gDebug = 99;
-  } else {
-    if (m_log.level() <= MSG::VERBOSE)
-      m_log << MSG::VERBOSE << "ROOT already initialized, debug = "
-            << gDebug<< endmsg;
-  }
-
-  if (service("IncidentSvc", p_incSvc, true).isFailure()) {
-    m_log << MSG::ERROR << "unable to get the IncidentSvc" << endmsg;
-    st = StatusCode::FAILURE;
-  } else {
-    p_incSvc->addListener( this, "EndEvent", 100, true);
-  }
-
-  if (service("FileMgr",p_fileMgr,true).isFailure()) {
-    m_log << MSG::ERROR << "unable to get the FileMgr" << endmsg;
-    st = StatusCode::FAILURE;
-  } else {
-    m_log << MSG::DEBUG << "got the FileMgr" << endmsg;
-  }
-
-
-  // Register open/close callback actions
-
-  using namespace std::placeholders;
-  auto boa = [this](const Io::FileAttr* fa, const std::string& caller) { return this->rootOpenAction(fa,caller); };
-  if (p_fileMgr->regAction(boa, Io::OPEN, Io::ROOT).isFailure()) {
-    m_log << MSG::ERROR
-	  << "unable to register ROOT file open action with FileMgr"
-	  << endmsg;
-  }
-  auto bea = [this](const Io::FileAttr* fa, const std::string& caller) { return this->rootOpenErrAction(fa,caller); };
-  if (p_fileMgr->regAction(bea, Io::OPEN_ERR, Io::ROOT).isFailure()) {
-    m_log << MSG::ERROR
-	  << "unable to register ROOT file open Error action with FileMgr"
-	  << endmsg;
-  }
-
-
-  m_okToConnect = true;
-
-  if (m_delayConnect) {
-    if (!m_inputfile.value().empty()) { setupInputFile(m_inputfile); }
-    if (!m_outputfile.value().empty()) { setupOutputFile(m_outputfile); }
-
-    m_delayConnect = false;
-
-  }
-  m_alreadyConnectedOutFiles.clear();
-  m_alreadyConnectedInFiles.clear();
-
-
-  IIoComponentMgr* iomgr = nullptr;
-
-  if (service("IoComponentMgr", iomgr, true).isFailure()) {
-    m_log << MSG::ERROR << "unable to get the IoComponentMgr" << endmsg;
-    st = StatusCode::FAILURE;
-  } else {
-
-    if ( !iomgr->io_register (this).isSuccess() ) {
-      m_log << MSG::ERROR
-            << "could not register with the I/O component manager !"
-            << endmsg;
-      st = StatusCode::FAILURE;
-    } else {
-      bool all_good = true;
-      // register input/output files...
-      for ( const auto& reg : m_files ) { 
-        const std::string& fname = reg.second.first->GetName();
-        const IIoComponentMgr::IoMode::Type iomode =
-          ( reg.second.second==THistSvcHLT::READ
-	    ? IIoComponentMgr::IoMode::READ
-	    : IIoComponentMgr::IoMode::WRITE );
-        if ( !iomgr->io_register (this, iomode, fname).isSuccess () ) {
-          m_log << MSG::WARNING << "could not register file ["
-                << fname << "] with the I/O component manager..." << endmsg;
-          all_good = false;
-        } else {
-          m_log << MSG::INFO << "registered file [" << fname << "]... [ok]"
-              << endmsg;
-        }
-      }
-      if (!all_good) {
-        m_log << MSG::ERROR
-              << "problem while registering input/output files with "
-              << "the I/O component manager !" << endmsg;
-        st = StatusCode::FAILURE;
-      }
-    }
-
-  }
-
-  if (st.isFailure()) {
-    m_log << MSG::FATAL << "Unable to initialize THistSvcHLT" << endmsg;
-  }
-
-  return st;
-
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::reinitialize() {
-
-  GlobalDirectoryRestore restore;
-  m_log << MSG::WARNING << "reinitialize not implemented" << endmsg;
-  return StatusCode::SUCCESS;
-
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::finalize() {
-
-  GlobalDirectoryRestore restore;
-
-  if (m_log.level() <= MSG::DEBUG)
-    m_log << MSG::DEBUG << "THistSvcHLT::finalize" << endmsg;
-
-#ifndef NDEBUG
-  if (m_log.level() <= MSG::DEBUG) {
-  for (const auto& uid : m_uids ) {
-
-    TObject* to = uid.second.obj;
-
-    string dirname("none");
-      if (to && to->IsA()->InheritsFrom("TTree")) {
-      TTree* tr = dynamic_cast<TTree*>(to);
-      if (tr->GetDirectory() != 0) {
-        dirname = tr->GetDirectory()->GetPath();
-      }
-      } else if (to && to->IsA()->InheritsFrom("TGraph")) {
-      if (!uid.second.temp) {
-        dirname = uid.second.file->GetPath();
-        string id2(uid.second.id);
-        id2.erase(0,id2.find("/",1));
-        id2.erase(id2.rfind("/"), id2.length());
-        if (id2.find("/") == 0) {
-          id2.erase(0,1);
-        }
-        dirname += id2;
-      } else {
-        dirname = "/tmp";
-      }
-      } else if (to && to->IsA()->InheritsFrom("TH1")) {
-      TH1* th = dynamic_cast<TH1*>(to);
-      if (th == 0) {
-        m_log << MSG::ERROR << "Couldn't dcast: " << uid.first << endmsg;
-      } else {
-        if (th->GetDirectory() != 0) {
-          dirname = th->GetDirectory()->GetPath();
-        }
-      }
-      } else if (! to ) {
-	m_log << MSG::WARNING << uid.first << " has NULL TObject ptr"
-	      << endmsg;
-    }
-
-      m_log << MSG::DEBUG << "uid: \"" << uid.first << "\"  temp: "
-            << uid.second.temp << "  dir: " << dirname
-            << endmsg;
-  }
-  }
-#endif
-
-  StatusCode sc = write();
-  if (sc.isFailure()) {
-    m_log << MSG::ERROR << "problems writing histograms" << endmsg;
-  }
-
-  if (m_print) {
-    m_log << MSG::INFO << "Listing contents of ROOT files: " << endmsg;
-  }
-  vector<TFile*> deleted_files;
-  for (auto& itr : m_files ) {
-
-    if (find(deleted_files.begin(), deleted_files.end(), itr.second.first) ==
-        deleted_files.end()) {
-      deleted_files.push_back(itr.second.first);
-
-#ifndef NDEBUG
-      if (m_log.level() <= MSG::DEBUG)
-        m_log << MSG::DEBUG << "finalizing stream/file " << itr.first << ":"
-              << itr.second.first->GetName()
-              << endmsg;
-#endif
-    } else {
-#ifndef NDEBUG
-      if (m_log.level() <= MSG::DEBUG)
-        m_log << MSG::DEBUG << "already finalized stream " << itr.first << endmsg;
-#endif
-      continue;
-    }
-
-
-    if (m_print && m_log.level() <= MSG::INFO) {
-
-      m_log << MSG::INFO;
-      m_log << "==> File: " << itr.second.first->GetName()
-            << "  stream: " << itr.first << endmsg;
-
-      itr.second.first->Print("base");
-    }
-
-    string tmpfn=itr.second.first->GetName();
-
-    p_fileMgr->close(itr.second.first, name());
-
-    IIncidentSvc *pi = nullptr;
-    if (service("IncidentSvc",pi).isFailure()) {
-      m_log << MSG::ERROR << "Unable to get the IncidentSvc" << endmsg;
-      return StatusCode::FAILURE;
-    }
-
-    if (itr.second.second==SHARE) {
-
-      //Merge File
-      void* vf = nullptr;
-      int r = p_fileMgr->open(Io::ROOT,name(), m_sharedFiles[itr.first],
-			      Io::WRITE|Io::APPEND,vf,"HIST");
-
-      if (r) {
-	m_log << MSG::ERROR << "unable to open Final Output File: \""
-	      << m_sharedFiles[itr.first] << "\" for merging"
-	      << endmsg;
-        return StatusCode::FAILURE;
-      }
-
-      TFile *outputfile = (TFile*) vf;
-      pi->fireIncident(FileIncident(name(), IncidentType::WroteToOutputFile,
-                                     m_sharedFiles[itr.first]));
-
-      if (m_log.level() <= MSG::DEBUG)
-        m_log << MSG::DEBUG << "THistSvcHLT::write()::Merging Rootfile "<<endmsg;
-
-      vf = nullptr;
-      r = p_fileMgr->open(Io::ROOT,name(),tmpfn,Io::READ,vf,"HIST");
-
-      if (r) {
-	m_log << MSG::ERROR << "unable to open temporary file: \""
-	      << tmpfn << endmsg;
-        return StatusCode::FAILURE;
-      }
-
-      TFile *inputfile = (TFile*) vf;
-
-      outputfile->SetCompressionLevel( inputfile->GetCompressionLevel() );
-
-      MergeRootFile(outputfile, inputfile);
-
-      outputfile->Write();
-      p_fileMgr->close(outputfile,name());
-      p_fileMgr->close(inputfile,name());
-
-      if (m_log.level() <= MSG::DEBUG)
-        m_log << MSG::DEBUG << "Trying to remove temporary file \"" << tmpfn
-              << "\""<<endmsg;
-
-      std::remove(tmpfn.c_str());
-    }
-    delete itr.second.first;
-  }
-
-  m_sharedFiles.clear();
-  m_fileStreams.clear();
-  m_files.clear();
-  m_uids.clear();
-  m_ids.clear();
-  m_tobjs.clear();
-
-  return Service::finalize();
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-bool
-THistSvcHLT::browseTDir(TDirectory *dir) const {
-
-  if (!dir) {
-    std::cerr << "TDirectory == 0" << std::endl;
-    return false;
-  }
-
-  GlobalDirectoryRestore restore;
-
-  dir->cd();
-
-
-  cout << "-> " << dir->GetPath() << "  "
-       << dir->GetListOfKeys()->GetSize() << endl;
-
-  //  TIter nextkey(dir->GetListOfKeys());
-  TIter nextkey(dir->GetList());
-  while (TKey *key = (TKey*)nextkey()) {
-
-    TObject *obj = key->ReadObj();
-    if (!obj) { cout << key->GetName() << " obj==0"<< endl; continue; }
-    //    if (obj->IsA()->InheritsFrom("TDirectory")) {
-      cout << "  Key: " << key->GetName() << "   "
-           << " tit: " << obj->GetTitle() << "   "
-           << " (" << key->GetClassName() << ")" << endl;
-      //    }
-  }
-
-  nextkey = dir->GetListOfKeys();
-  while (TKey *key = (TKey*)nextkey()) {
-
-    TObject *obj = key->ReadObj();
-    if (!obj) { cout << key->GetName() << " obj==0"<< endl; continue; }
-    if (obj->IsA()->InheritsFrom("TDirectory")) {
-      TDirectory *tt = dynamic_cast<TDirectory*>(obj);
-      browseTDir(tt);
-    }
-  }
-
-  return true;
-}
-
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::getTHists(TDirectory *td, TList & tl, bool rcs) const {
-  GlobalDirectoryRestore restore;
-
-  gErrorIgnoreLevel = kBreak;
-
-  if (!td->cd()) {
-    m_log << MSG::ERROR << "getTHists: No such TDirectory \"" << td->GetPath()
-          << "\"" << endmsg;
-    return StatusCode::FAILURE;
-  }
-
-  if (m_log.level() <= MSG::DEBUG)
-    m_log << MSG::DEBUG << "getTHists: \"" << td->GetPath() << "\": found "
-          << td->GetListOfKeys()->GetSize() << " keys" << endmsg;
-
-  TIter nextkey(td->GetListOfKeys());
-  while (TKey *key = (TKey*)nextkey()) {
-    if (m_log.level() <= MSG::DEBUG)
-      m_log << MSG::DEBUG << "  key: " << key->GetName();
-    TObject *obj = key->ReadObj();
-    if (obj != 0 && obj->IsA()->InheritsFrom("TDirectory")) {
-      if (m_log.level() <= MSG::DEBUG)
-        m_log << " (" << obj->IsA()->GetName() << ")";
-    } else if (obj != 0 && obj->IsA()->InheritsFrom("TH1")) {
-      if (m_log.level() <= MSG::DEBUG)
-        m_log << " (" << obj->IsA()->GetName() << ")";
-      tl.Add(obj);
-    } else if (obj != 0) {
-      if (m_log.level() <= MSG::DEBUG)
-        m_log << " [" << obj->IsA()->GetName() << "]";
-    }
-    if (m_log.level() <= MSG::DEBUG)
-      m_log << endmsg;
-  }
-
-  // operate recursively
-  if (rcs) {
-    nextkey = td->GetListOfKeys();
-    while (TKey *key = (TKey*)nextkey()) {
-      TObject *obj = key->ReadObj();
-      if (obj && obj->IsA()->InheritsFrom("TDirectory")) {
-          TDirectory *tt = dynamic_cast<TDirectory*>(obj);
-          getTHists(tt, tl, rcs);
-      }
-    }
-  }
-
-  return StatusCode::SUCCESS;
-
-
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::getTHists(const std::string& dir, TList & tl, bool rcs) const {
-
-  GlobalDirectoryRestore restore;
-
-  gErrorIgnoreLevel = kBreak;
-
-  StatusCode sc;
-
-  std::string stream,rem,r2;
-  parseString(dir,stream,rem);
-
-  auto itr = m_files.find(stream);
-  if (itr != m_files.end()) {
-    r2 = itr->second.first->GetName();
-    r2 += ":/";
-    r2 += rem;
-
-    if (m_log.level() <= MSG::DEBUG)
-      m_log << MSG::DEBUG << "getTHists: \"" << dir
-            << "\" looks like a stream name."  << " associated TFile: \""
-            << itr->second.first->GetName() << "\"" << endmsg;
-
-    if (gDirectory->cd(r2.c_str())) {
-      m_curstream = stream;
-      sc = getTHists(gDirectory,tl,rcs);
-      m_curstream = "";
-      return sc;
-    } else {
-      if (m_log.level() <= MSG::DEBUG)
-        m_log << MSG::DEBUG << "getTHists: no such TDirectory \""
-              << r2 << "\"" << endmsg;
-    }
-
-  } else {
-    if (m_log.level() <= MSG::DEBUG)
-      m_log << MSG::DEBUG << "getTHists: stream \"" << stream << "\" not found"
-            << endmsg;
-  }
-
-  if (!gDirectory->cd(dir.c_str())) {
-    m_log << MSG::ERROR << "getTHists: No such TDirectory/stream \"" << dir
-          << "\"" << endmsg;
-    sc = StatusCode::FAILURE;
-  } else {
-    sc = getTHists(gDirectory,tl,rcs);
-  }
-
-  return sc;
-
-}
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::getTTrees(TDirectory *td, TList & tl, bool rcs) const {
-  GlobalDirectoryRestore restore;
-
-  gErrorIgnoreLevel = kBreak;
-
-  if (!td->cd()) {
-    m_log << MSG::ERROR << "getTTrees: No such TDirectory \""
-          << td->GetPath() << "\"" << endmsg;
-    return StatusCode::FAILURE;
-  }
-
-  if (m_log.level() <= MSG::DEBUG)
-    m_log << MSG::DEBUG << "getTHists: \"" << td->GetPath() << "\": found "
-          << td->GetListOfKeys()->GetSize() << " keys" << endmsg;
-
-  TIter nextkey(td->GetListOfKeys());
-  while (TKey *key = (TKey*)nextkey()) {
-    if (m_log.level() <= MSG::DEBUG)
-      m_log << MSG::DEBUG << "  key: " << key->GetName();
-    TObject *obj = key->ReadObj();
-    if (obj != 0 && obj->IsA()->InheritsFrom("TDirectory")) {
-      if (m_log.level() <= MSG::DEBUG)
-        m_log << " (" << obj->IsA()->GetName() << ")";
-    } else if (obj != 0 && obj->IsA()->InheritsFrom("TTree")) {
-      if (m_log.level() <= MSG::DEBUG)
-        m_log << " (" << obj->IsA()->GetName() << ")";
-      tl.Add(obj);
-    } else if (obj != 0) {
-      if (m_log.level() <= MSG::DEBUG)
-        m_log << " [" << obj->IsA()->GetName() << "]";
-    }
-    m_log << endmsg;
-  }
-
-  // operate recursively
-  if (rcs) {
-    nextkey = td->GetListOfKeys();
-    while (TKey *key = (TKey*)nextkey()) {
-      TObject *obj = key->ReadObj();
-      if (obj && obj->IsA()->InheritsFrom("TDirectory")) {
-          TDirectory *tt = dynamic_cast<TDirectory*>(obj);
-          getTTrees(tt, tl, rcs);
-      }
-    }
-  }
-
-  return StatusCode::SUCCESS;
-
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::getTTrees(const std::string& dir, TList & tl, bool rcs) const {
-  GlobalDirectoryRestore restore;
-
-  gErrorIgnoreLevel = kBreak;
-
-  StatusCode sc;
-
-  std::string stream,rem,r2;
-  parseString(dir,stream,rem);
-
-  auto itr = m_files.find(stream);
-  if (itr != m_files.end()) {
-    r2 = itr->second.first->GetName();
-    r2 += ":/";
-    r2 += rem;
-
-    if (m_log.level() <= MSG::DEBUG)
-      m_log << MSG::DEBUG << "getTTrees: \"" << dir
-            << "\" looks like a stream name."  << " associated TFile: \""
-            << itr->second.first->GetName() << "\"" << endmsg;
-
-    if (gDirectory->cd(r2.c_str())) {
-      return getTTrees(gDirectory,tl,rcs);
-    }
-    if (m_log.level() <= MSG::DEBUG)
-      m_log << MSG::DEBUG << "getTTrees: no such TDirectory \""
-            << r2 << "\"" << endmsg;
-  } else {
-    if (m_log.level() <= MSG::DEBUG)
-      m_log << MSG::DEBUG << "getTTrees: stream \"" << stream << "\" not found"
-            << endmsg;
-  }
-
-  if (!gDirectory->cd(dir.c_str())) {
-    m_log << MSG::ERROR << "getTTrees: No such TDirectory/stream \"" << dir
-          << "\"" << endmsg;
-    sc = StatusCode::FAILURE;
-  } else {
-    sc = getTTrees(gDirectory,tl,rcs);
-  }
-  return sc;
-}
-
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::getTHists(TDirectory *td, TList & tl, bool rcs, bool reg) {
-
-  GlobalDirectoryRestore restore;
-
-  gErrorIgnoreLevel = kBreak;
-
-  if (!td->cd()) {
-    m_log << MSG::ERROR << "getTHists: No such TDirectory \"" << td->GetPath()
-          << "\"" << endmsg;
-    return StatusCode::FAILURE;
-  }
-
-  if (m_log.level() <= MSG::DEBUG)
-    m_log << MSG::DEBUG << "getTHists: \"" << td->GetPath() << "\": found "
-          << td->GetListOfKeys()->GetSize() << " keys" << endmsg;
-
-  TIter nextkey(td->GetListOfKeys());
-  while (TKey *key = (TKey*)nextkey()) {
-    if (m_log.level() <= MSG::DEBUG)
-      m_log << MSG::DEBUG << "  key: " << key->GetName();
-    TObject *obj = key->ReadObj();
-    if (obj && obj->IsA()->InheritsFrom("TDirectory")) {
-      if (m_log.level() <= MSG::DEBUG)
-        m_log << " (" << obj->IsA()->GetName() << ")";
-    } else if (obj && obj->IsA()->InheritsFrom("TH1")) {
-      if (m_log.level() <= MSG::DEBUG)
-        m_log << " (" << obj->IsA()->GetName() << ")";
-      tl.Add(obj);
-      if (reg && m_curstream != "") {
-        string dir = td->GetPath();
-        string fil = td->GetFile()->GetName();
-        dir.erase(0,fil.length()+1);
-        string id = "/" + m_curstream;
-        if ( dir == "/" ) {
-          id = id + "/" + key->GetName();
-        } else {
-          id = id + dir + "/" + key->GetName();
-        }
-        if (!exists(id)) {
-          if (m_log.level() <= MSG::DEBUG)
-            m_log << "  reg as \"" << id << "\"";
-          regHist(id).ignore();
-        } else {
-          if (m_log.level() <= MSG::DEBUG)
-            m_log << "  already registered";
-        }
-      }
-    } else if (obj) {
-      if (m_log.level() <= MSG::DEBUG)
-        m_log << " [" << obj->IsA()->GetName() << "]";
-    }
-    if (m_log.level() <= MSG::DEBUG)
-      m_log << endmsg;
-  }
-
-  // operate recursively
-  if (rcs) {
-    nextkey = td->GetListOfKeys();
-    while (TKey *key = (TKey*)nextkey()) {
-      TObject *obj = key->ReadObj();
-      if (obj && obj->IsA()->InheritsFrom("TDirectory")) {
-          TDirectory *tt = dynamic_cast<TDirectory*>(obj);
-          getTHists(tt, tl, rcs, reg);
-      }
-    }
-  }
-
-  return StatusCode::SUCCESS;
-
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::getTHists(const std::string& dir, TList & tl, bool rcs, bool reg) {
-
-  GlobalDirectoryRestore restore;
-
-  gErrorIgnoreLevel = kBreak;
-
-  StatusCode sc;
-
-  std::string stream,rem,r2;
-  parseString(dir,stream,rem);
-
-  auto itr = m_files.find(stream);
-  if (itr != m_files.end()) {
-    r2 = itr->second.first->GetName();
-    r2 += ":/";
-    r2 += rem;
-
-    if (m_log.level() <= MSG::DEBUG)
-      m_log << MSG::DEBUG << "getTHists: \"" << dir
-            << "\" looks like a stream name."  << " associated TFile: \""
-            << itr->second.first->GetName() << "\"" << endmsg;
-
-    if (gDirectory->cd(r2.c_str())) {
-      m_curstream = stream;
-      sc = getTHists(gDirectory,tl,rcs,reg);
-      m_curstream.clear();
-      return sc;
-    } 
-    if (m_log.level() <= MSG::DEBUG)
-      m_log << MSG::DEBUG << "getTHists: no such TDirectory \""
-            << r2 << "\"" << endmsg;
-
-  } else {
-    if (m_log.level() <= MSG::DEBUG)
-      m_log << MSG::DEBUG << "getTHists: stream \"" << stream << "\" not found"
-            << endmsg;
-  }
-
-  if (!gDirectory->cd(dir.c_str())) {
-    m_log << MSG::ERROR << "getTHists: No such TDirectory/stream \"" << dir
-          << "\"" << endmsg;
-    sc = StatusCode::FAILURE;
-  } else {
-    if (reg) {
-      m_log << MSG::WARNING << "Unable to register histograms automatically "
-            << "without a valid stream name" << endmsg;
-      reg = false;
-    }
-    sc = getTHists(gDirectory,tl,rcs,reg);
-  }
-
-  return sc;
-
-}
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::getTTrees(TDirectory *td, TList & tl, bool rcs, bool reg) {
-
-  GlobalDirectoryRestore restore;
-
-  gErrorIgnoreLevel = kBreak;
-
-  if (!td->cd()) {
-    m_log << MSG::ERROR << "getTTrees: No such TDirectory \""
-          << td->GetPath() << "\"" << endmsg;
-    return StatusCode::FAILURE;
-  }
-
-  if (m_log.level() <= MSG::DEBUG)
-    m_log << MSG::DEBUG << "getTHists: \"" << td->GetPath() << "\": found "
-          << td->GetListOfKeys()->GetSize() << " keys" << endmsg;
-
-  TIter nextkey(td->GetListOfKeys());
-  while (TKey *key = (TKey*)nextkey()) {
-    if (m_log.level() <= MSG::DEBUG)
-      m_log << MSG::DEBUG << "  key: " << key->GetName();
-    TObject *obj = key->ReadObj();
-    if (obj && obj->IsA()->InheritsFrom("TDirectory")) {
-      if (m_log.level() <= MSG::DEBUG)
-        m_log << " (" << obj->IsA()->GetName() << ")";
-    } else if (obj && obj->IsA()->InheritsFrom("TTree")) {
-      if (m_log.level() <= MSG::DEBUG)
-        m_log << " (" << obj->IsA()->GetName() << ")";
-      tl.Add(obj);
-      if (reg && m_curstream != "") {
-        string dir = td->GetPath();
-        string fil = td->GetFile()->GetName();
-        dir.erase(0,fil.length()+1);
-        string id = "/" + m_curstream;
-        if ( dir == "/" ) {
-          id = id + "/" + key->GetName();
-        } else {
-          id = id + dir + "/" + key->GetName();
-        }
-        if (!exists(id)) {
-          if (m_log.level() <= MSG::DEBUG)
-            m_log << "  reg as \"" << id << "\"";
-          regHist(id).ignore();
-        } else {
-          if (m_log.level() <= MSG::DEBUG)
-            m_log << "  already registered";
-        }
-      }
-    } else if (obj != 0) {
-      if (m_log.level() <= MSG::DEBUG)
-        m_log << " [" << obj->IsA()->GetName() << "]";
-    }
-    if (m_log.level() <= MSG::DEBUG)
-      m_log << endmsg;
-  }
-
-  // operate recursively
-  if (rcs) {
-    nextkey = td->GetListOfKeys();
-    while (TKey *key = (TKey*)nextkey()) {
-      TObject *obj = key->ReadObj();
-      if (obj && obj->IsA()->InheritsFrom("TDirectory")) {
-          TDirectory *tt = dynamic_cast<TDirectory*>(obj);
-          getTTrees(tt, tl, rcs, reg);
-      }
-    }
-  }
-
-  return StatusCode::SUCCESS;
-
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::getTTrees(const std::string& dir, TList & tl, bool rcs, bool reg) {
-
-  GlobalDirectoryRestore restore;
-
-  gErrorIgnoreLevel = kBreak;
-
-  StatusCode sc;
-
-  std::string stream,rem,r2;
-  parseString(dir,stream,rem);
-
-  auto itr = m_files.find(stream);
-  if (itr != m_files.end()) {
-    r2 = itr->second.first->GetName();
-    r2 += ":/";
-    r2 += rem;
-
-    if (m_log.level() <= MSG::DEBUG)
-      m_log << MSG::DEBUG << "getTTrees: \"" << dir
-            << "\" looks like a stream name."  << " associated TFile: \""
-            << itr->second.first->GetName() << "\"" << endmsg;
-
-    if (gDirectory->cd(r2.c_str())) {
-      return getTTrees(gDirectory,tl,rcs,reg);
-    } else {
-      if (m_log.level() <= MSG::DEBUG)
-        m_log << MSG::DEBUG << "getTTrees: no such TDirectory \""
-              << r2 << "\"" << endmsg;
-    }
-
-  } else {
-    if (m_log.level() <= MSG::DEBUG)
-      m_log << MSG::DEBUG << "getTTrees: stream \"" << stream << "\" not found"
-            << endmsg;
-  }
-
-  if (!gDirectory->cd(dir.c_str())) {
-    m_log << MSG::ERROR << "getTTrees: No such TDirectory/stream \"" << dir
-          << "\"" << endmsg;
-    return StatusCode::FAILURE;
-  } 
-
-  return getTTrees(gDirectory,tl,rcs,reg);
-
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::deReg(TObject* obj) {
-
-  auto itr = m_tobjs.find(obj);
-  if (itr != m_tobjs.end()) {
-    THistID hid = itr->second;
-
-    auto itr2 = m_uids.find(hid.id);
-    if (itr2 == m_uids.end()) {
-      m_log << MSG::ERROR << "Problems deregistering TObject \""
-            << obj->GetName()
-            << "\" with id \"" << hid.id << "\"" << endmsg;
-      return StatusCode::FAILURE;
-    }
-
-    std::string id,root,rem;
-    parseString(hid.id, root, rem);
-
-    auto mitr = m_ids.equal_range(rem);
-    auto itr3 = std::find_if( mitr.first, mitr.second, [&](idMap::const_reference i) 
-                                   { return i.second.obj == obj; } ) ;
-    if (itr3 != mitr.second ) {
-      m_log << MSG::ERROR << "Problems deregistering TObject \""
-            << obj->GetName()
-            << "\" with id \"" << hid.id << "\"" << endmsg;
-      return StatusCode::FAILURE;
-    }
-
-    m_tobjs.erase(itr);
-    m_uids.erase(itr2);
-    m_ids.erase(itr3);
-
-    return StatusCode::SUCCESS;
-
-  } else {
-    m_log << MSG::ERROR << "Cannot unregister TObject \"" << obj->GetName()
-          << "\": not known to THistSvcHLT" << endmsg;
-    return StatusCode::FAILURE;
-  }
-
-}
-
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::deReg(const std::string& id) {
-
-  auto itr = m_uids.find(id);
-  if (itr == m_uids.end()) {
-    m_log << MSG::ERROR << "Problems deregistering id \""
-          << id << "\"" << endmsg;
-    return StatusCode::FAILURE;
-  }
-
-  TObject* obj = itr->second.obj;
-  return deReg(obj);
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::regHist(const std::string& id) {
-
-  TH1 *hist = nullptr;
-  return regHist_i(hist, id);
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::regHist(const std::string& id, TH1* hist) {
-  return regHist_i(hist, id);
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::regHist(const std::string& id, TH2* hist) {
-  return regHist_i(hist, id);
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::regHist(const std::string& id, TH3* hist) {
-  return regHist_i(hist, id);
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::regTree(const std::string& id) {
-  TTree *hist = nullptr;
-  return regHist_i(hist, id);
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::regTree(const std::string& id, TTree* hist) {
-  StatusCode sc = regHist_i(hist, id);
-  if (hist && sc.isSuccess()) {
-    if (m_autoSave != 0) hist->SetAutoSave(m_autoSave);
-    hist->SetAutoFlush(m_autoFlush);
-  }
-  return sc;
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::regGraph(const std::string& id) {
-  TGraph *hist = nullptr;
-  return regHist_i(hist, id);
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::regGraph(const std::string& id, TGraph* hist) {
-  if ( strcmp(hist->GetName(),"Graph") == 0 ) {
-
-    std::string id2(id);
-    string::size_type i = id2.rfind("/");
-    if (i != string::npos) {
-      id2.erase(0,i+1);
-    }
-
-    m_log << MSG::INFO << "setting name of TGraph id: \"" << id << "\" to \""
-          << id2 << "\" since it is unset" << endmsg;
-    hist->SetName(id2.c_str());
-  }
-
-  return regHist_i(hist, id);
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::getHist(const std::string& id, TH1*& hist) const {
-  return getHist_i(id, hist);
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::getHist(const std::string& id, TH2*& hist) const {
-  return getHist_i(id, hist);
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::getHist(const std::string& id, TH3*& hist) const {
-  return getHist_i(id, hist);
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-std::vector<std::string>
-THistSvcHLT::getHists() const {
-
-  std::vector<std::string> names;
-  names.reserve(m_uids.size());
-  transform_if( std::begin(m_uids), std::end(m_uids),
-                std::back_inserter(names), select1st,
-                [](uidMap::const_reference i) { 
-                    return i.second.obj->IsA()->InheritsFrom("TH11"); }
-  );
-  return names;
-
-}
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::getTree(const std::string& id, TTree*& hist) const {
-  return getHist_i(id, hist);
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-std::vector<std::string>
-THistSvcHLT::getTrees() const {
-
-  std::vector<std::string> names;
-  names.reserve(m_uids.size());
-  transform_if( std::begin(m_uids), std::end(m_uids),
-                std::back_inserter(names),
-                select1st,
-                [](uidMap::const_reference i) { 
-                    return i.second.obj->IsA()->InheritsFrom("TTree"); }
-  );
-  return names;
-
-}
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::getGraph(const std::string& id, TGraph*& hist) const {
-  return getHist_i(id, hist);
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-std::vector<std::string>
-THistSvcHLT::getGraphs() const {
-
-  std::vector<std::string> names;
-  names.reserve(m_uids.size());
-  transform_if( std::begin(m_uids), std::end(m_uids),
-                std::back_inserter(names), select1st,
-                [](uidMap::const_reference i) { 
-                    return i.second.obj->IsA()->InheritsFrom("TTree"); }
-  );
-  return names;
-
-}
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::readHist(const std::string& id, TH1*& hist) const {
-  return readHist_i(id, hist);
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::readHist(const std::string& id, TH2*& hist) const {
-  return readHist_i(id, hist);
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::readHist(const std::string& id, TH3*& hist) const {
-  return readHist_i(id, hist);
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::readTree(const std::string& id, TTree*& hist) const {
-  return readHist_i(id, hist);
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-bool
-THistSvcHLT::findStream(const string& id, string& stream, string& rem,
-                   TFile*& file) const {
-
-  auto pos = id.find("/");
-
-  if (pos == string::npos) {
-    stream = "temp";
-    rem = id;
-  } else if (pos != 0) {
-    stream = "temp";
-    rem = id;
-  } else {
-
-    auto pos2 = id.find("/",pos+1);
-
-    if (pos2 == string::npos) {
-      m_log << MSG::ERROR << "badly formed Hist/Tree id: \"" << id << "\""
-            << endmsg;
-      return false;
-    }
-
-    parseString(id,stream,rem);
-
-  }
-
-  if (stream == "temp") {
-    file = nullptr;
-    return true;
-  }
-
-  auto itr = m_files.find(stream);
-  file = (itr != m_files.end() ? itr->second.first : nullptr );
-  if (!file) {
-    m_log << MSG::WARNING << "no stream \"" << stream
-          << "\" associated with id: \"" << id << "\""
-          << endmsg;
-  }
-
-  return true;
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-void
-THistSvcHLT::parseString(const string& id, string& root, string& rem) const {
-  auto pos = id.find("/");
-
-  if (pos == string::npos) {
-    root.clear();
-    rem = id;
-  } else if (pos == 0) {
-    parseString(id.substr(1),root,rem);
-  } else {
-    root = id.substr(0,pos);
-    rem = id.substr(pos+1);
-  }
-
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-void
-THistSvcHLT::setupCompressionLevel( Property& /* cl */ )
-{
-
-  m_log << MSG::WARNING << "\"CompressionLevel\" Property has been deprecated. "
-        << "Set it via the \"CL=\" parameter in the \"Output\" Property"
-        << endmsg;
-
-}
-
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-void
-THistSvcHLT::setupInputFile( Property& /*m_inputfile*/ )
-{
-
-  if (FSMState() < Gaudi::StateMachine::CONFIGURED || !m_okToConnect ) {
-
-    m_log <<MSG::DEBUG << "Delaying connection of Input Files until Initialize"
-	  << ". now in " << FSMState()
-	  << endmsg;
-
-    m_delayConnect = true;
-  } else {
-
-    m_log <<MSG::DEBUG << "Now connecting of Input Files"
-	  << endmsg;
-
-    StatusCode sc = StatusCode::SUCCESS;
-
-    for ( const auto& itr : m_inputfile.value() ) {
-      if ( m_alreadyConnectedInFiles.end() != 
-           m_alreadyConnectedInFiles.find( itr ) ) continue;
-      if ( connect(itr).isFailure() ) {
-        sc = StatusCode::FAILURE;
-      } else {
-        m_alreadyConnectedInFiles.insert( itr );
-      }
-      
-    }
-
-    if ( !sc.isSuccess() ) {
-      throw GaudiException( "Problem connecting inputfile !!", name(),
-                            StatusCode::FAILURE );
-    }
-
-  }
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-void
-THistSvcHLT::setupOutputFile( Property& /*m_outputfile*/ )
-{
-  if (FSMState() < Gaudi::StateMachine::CONFIGURED || !m_okToConnect) {
-    m_log <<MSG::DEBUG << "Delaying connection of Input Files until Initialize"
-	  << ". now in " << FSMState()
-	  << endmsg;
-    m_delayConnect = true;
-  } else {
-
-    StatusCode sc = StatusCode::SUCCESS;
-    for ( const auto & itr : m_outputfile.value() ) {
-      if ( m_alreadyConnectedOutFiles.end() !=
-           m_alreadyConnectedOutFiles.find( itr ) ) continue;
-      if ( connect(itr).isFailure() ) {
-        sc = StatusCode::FAILURE;
-      } else {
-        m_alreadyConnectedOutFiles.insert( itr );
-      }
-    }
-
-    if ( !sc.isSuccess() ) {
-      throw GaudiException( "Problem connecting outputfile !!", name(),
-                            StatusCode::FAILURE );
-    }
-  }
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-void
-THistSvcHLT::updateFiles() {
-
-  // If TTrees grow beyond TTree::fgMaxTreeSize, a new file is
-  // automatically created by root, and the old one closed. We
-  // need to migrate all the UIDs over to show the correct file
-  // pointer. This is ugly.
-
-  if (m_log.level() <= MSG::DEBUG)
-    m_log << MSG::DEBUG << "updateFiles()" << endmsg;
-
-
-  for (auto uitr=m_uids.begin(); uitr != m_uids.end(); ++uitr) {
-#ifndef NDEBUG
-    if (m_log.level() <= MSG::VERBOSE)
-      m_log << MSG::VERBOSE << " update: " << uitr->first << " "
-	    << uitr->second.id << " " << uitr->second.mode << endmsg;
-#endif
-    TObject* to = uitr->second.obj;
-    TFile* oldFile = uitr->second.file;
-    if (!to) {
-      m_log << MSG::WARNING << uitr->first << ": TObject == 0" << endmsg;
-    } else if ( uitr->second.temp || uitr->second.mode == READ ) {
-      // do nothing - no need to check how big the file is since we
-      // are just reading it.
-#ifndef NDEBUG
-    if (m_log.level() <= MSG::VERBOSE)
-      m_log << MSG::VERBOSE << "     skipping" << endmsg;
-#endif
-
-    } else if (to->IsA()->InheritsFrom("TTree")) {
-      TTree* tr = dynamic_cast<TTree*>(to);
-      TFile* newFile = tr->GetCurrentFile();
-
-      if (oldFile != newFile) {
-        std::string newFileName = newFile->GetName();
-        std::string oldFileName, streamName, rem;
-        TFile* dummy = nullptr;
-        findStream(uitr->second.id, streamName, rem, dummy);
-
-        for (auto& itr : m_files ) {
-          if (itr.second.first == oldFile) itr.second.first = newFile;
-        }
-
-        for (auto uitr2 = uitr; uitr2 != m_uids.end(); ++uitr2) {
-          if (uitr2->second.file == oldFile) {
-            uitr2->second.file = newFile;
-          }
-        }
-
-        auto sitr = std::find_if( std::begin(m_fileStreams), std::end(m_fileStreams),
-                                  [&](streamMap::const_reference s) {
-                                      return s.second == streamName;
-        });
-        if (sitr!=std::end(m_fileStreams)) oldFileName = sitr->first;
-
-#ifndef NDEBUG
-      if (m_log.level() <= MSG::DEBUG)
-        m_log << MSG::DEBUG << "migrating uid: " << uitr->second.id
-              << "   stream: " << streamName
-              << "   oldFile: " << oldFileName
-              << "   newFile: " << newFileName
-              << endmsg;
-#endif
-
-
-        if (!oldFileName.empty()) {
-          auto i = m_fileStreams.lower_bound(oldFileName);
-          while (i != std::end(m_fileStreams) && i->first == oldFileName) {
-
-#ifndef NDEBUG
-            if (m_log.level() <= MSG::DEBUG)
-              m_log << MSG::DEBUG << "changing filename \"" << i->first
-                    << "\" to \"" << newFileName << "\" for stream \""
-                    << i->second << "\"" << endmsg;
-#endif
-            std::string nm = std::move(i->second);
-            i = m_fileStreams.erase(i);
-	        m_fileStreams.emplace( newFileName, std::move(nm) ); 
-          }
-
-
-        } else {
-          m_log << MSG::ERROR
-                << "Problems updating fileStreams with new file name" << endmsg;
-        }
-
-      }
-    }
-  }
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::write() {
-
-  updateFiles();
-
-  std::for_each( m_files.begin(), m_files.end(), [](std::pair<const std::string,std::pair<TFile*,Mode>>& i) {
-      auto mode = i.second.second;
-      auto file = i.second.first;
-      if ( mode == WRITE || mode == UPDATE || mode == SHARE ) {
-          file->Write("",TObject::kOverwrite);
-      } else if ( mode == APPEND ) {
-          file->Write("");
-      }
-  } );
-
-  if (m_log.level() <= MSG::DEBUG) {
-    m_log << MSG::DEBUG << "THistSvcHLT::write()::List of Files connected in ROOT "
-          << endmsg;
-    TSeqCollection *filelist=gROOT->GetListOfFiles();
-    for (int ii=0; ii<filelist->GetEntries(); ii++) {
-        m_log << MSG::DEBUG
-              << "THistSvcHLT::write()::List of Files connected in ROOT: \""
-              << filelist->At(ii)->GetName()<<"\""<<endmsg;
-    }
-  }
-
-  return StatusCode::SUCCESS;
-
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::connect(const std::string& ident) {
-
-  auto loc = ident.find(" ");
-  string stream = ident.substr(0,loc);
-  char typ(0);
-  typedef std::pair<std::string,std::string>      Prop;
-  std::vector<Prop> props;
-  string filename, db_typ("ROOT");
-  int cl(1);
-
-  if (loc != string::npos) {
-    using Parser = Gaudi::Utils::AttribStringParser;
-    for (auto attrib: Parser(ident.substr(loc + 1))) {
-      auto TAG = boost::algorithm::to_upper_copy(attrib.tag);
-      auto VAL = boost::algorithm::to_upper_copy(attrib.value);
-
-      if (TAG == "FILE" || TAG == "DATAFILE") {
-        filename = attrib.value;
-        removeDoubleSlash( filename );
-      } else if ( TAG == "OPT" ) {
-        if ( VAL == "APPEND" || VAL == "UPDATE" ) {
-          typ = 'A';
-        } else if ( VAL == "CREATE" || VAL == "NEW" || VAL == "WRITE" ) {
-          typ = 'N';
-        } else if ( VAL == "RECREATE" ) {
-          typ = 'R';
-        } else if (VAL == "SHARE") {
-          typ = 'S';
-        } else if ( VAL == "OLD" || VAL == "READ" ) {
-          typ = 'O';
-        } else {
-          m_log << MSG::ERROR << "Unknown OPT: \"" << attrib.value << "\""
-              << endmsg;
-          typ = 0;
-        }
-      } else if (TAG == "TYP") {
-        db_typ = std::move(attrib.value);
-      } else if (TAG == "CL") {
-        cl = std::stoi(attrib.value);
-      } else {
-        props.emplace_back( attrib.tag, attrib.value);
-      }
-
-    }
-  }
-
-  if (stream == "temp") {
-    m_log << MSG::ERROR << "in JobOption \"" << ident
-          << "\": stream name \"temp\" reserved."
-          << endmsg;
-    return StatusCode::FAILURE;
-  }
-
-  if (db_typ != "ROOT") {
-    m_log << MSG::ERROR << "in JobOption \"" << ident
-          << "\": technology type \"" << db_typ << "\" not supported."
-          << endmsg;
-    return StatusCode::FAILURE;
-  }
-
-
-  if (m_files.find(stream) != m_files.end()) {
-    m_log << MSG::ERROR << "in JobOption \"" << ident
-          << "\":\n stream \"" << stream << "\" already connected to file: \""
-          << m_files[stream].first->GetName() << "\""
-          << endmsg;
-    return StatusCode::FAILURE;
-  }
-
-  Mode newMode;
-  if (typ == 'O') {
-    newMode = THistSvcHLT::READ;
-  } else if (typ == 'N') {
-    newMode = THistSvcHLT::WRITE;
-  } else if (typ == 'A') {
-    newMode = THistSvcHLT::APPEND;
-  } else if (typ == 'R') {
-    newMode = THistSvcHLT::UPDATE;
-  } else if (typ == 'S') {
-    newMode = THistSvcHLT::SHARE;
-  } else {
-    // something else?
-    m_log << MSG::ERROR << "No OPT= specified or unknown access mode in: "
-          << ident << endmsg;
-    return StatusCode::FAILURE;
-  }
-
-  // Is this file already connected to another stream?
-  if (m_fileStreams.find(filename) != m_fileStreams.end()) {
-    auto fitr = m_fileStreams.equal_range(filename);
-
-    const std::string& oldstream = fitr.first->second;
-
-    const auto& f_info = m_files[oldstream];
-
-    if (newMode != f_info.second) {
-      m_log << MSG::ERROR << "in JobOption \"" << ident
-            << "\":\n file \"" << filename << "\" already opened by stream: \""
-            << oldstream << "\" with different access mode."
-            << endmsg;
-      return StatusCode::FAILURE;
-    } else {
-      TFile *f2 = f_info.first;
-      m_files[stream] = make_pair(f2,newMode);
-      if (m_log.level() <= MSG::DEBUG)
-        m_log << MSG::DEBUG << "Connecting stream: \"" << stream
-              << "\" to previously opened TFile: \"" << filename << "\""
-              << endmsg;
-      return StatusCode::SUCCESS;
-    }
-  }
-
-
-  IIncidentSvc *pi = nullptr;
-  if (service("IncidentSvc",pi).isFailure()) {
-    m_log << MSG::ERROR << "Unable to get the IncidentSvc" << endmsg;
-    return StatusCode::FAILURE;
-  }
-
-  void* vf = nullptr;
-  TFile *f = nullptr;
-
-  if (newMode == THistSvcHLT::READ) {
-    // old file
-
-    int r = p_fileMgr->open(Io::ROOT,name(), filename,Io::READ,vf,"HIST");
-
-    if (r != 0) {
-      m_log << "Unable to open ROOT file " << filename << " for reading"
-	    << endmsg;
-      return StatusCode::FAILURE;
-    }
-
-
-    f = (TFile*) vf;
-
-    // FIX ME!
-    pi->fireIncident(FileIncident(name(), "BeginHistFile", filename));
-
-
-  } else if (newMode == THistSvcHLT::WRITE) {
-    // new file. error if file exists
-
-    int r = p_fileMgr->open(Io::ROOT,name(),filename, (Io::WRITE|Io::CREATE|Io::EXCL),
-			    vf,"HIST");
-
-    if (r != 0) {
-      m_log << "Unable to open ROOT file " << filename << " for writing"
-	    << endmsg;
-      return StatusCode::FAILURE;
-    }
-
-    f = (TFile*)vf;
-
-  } else if (newMode == THistSvcHLT::APPEND) {
-    // update file
-
-    int r = p_fileMgr->open(Io::ROOT,name(),filename, (Io::WRITE | Io::APPEND),
-			    vf,"HIST");
-    if (r != 0) {
-      m_log << MSG::ERROR << "unable to open file \"" << filename
-            << "\" for appending" << endmsg;
-      return StatusCode::FAILURE;
-    }
-
-    f = (TFile*) vf;
-
-
-  } else if (newMode == THistSvcHLT::SHARE) {
-    // SHARE file type
-    //For SHARE files, all data will be stored in a temp file and will be merged into the target file
-    //in write() when finalize(), this help to solve some confliction. e.g. with storegate
-
-    static int ishared = 0;
-    string realfilename=filename;
-    filename = "tmp_THistSvcHLT_"+ std::to_string(ishared++)+".root";
-
-    if (m_log.level() <= MSG::DEBUG)
-      m_log << MSG::DEBUG << "Creating temp file \"" << filename
-            << "\" and realfilename="<<realfilename << endmsg;
-    m_sharedFiles[stream]=realfilename;
-
-
-    int r = p_fileMgr->open(Io::ROOT,name(), filename, (Io::WRITE|Io::CREATE|Io::EXCL),
-			    vf,"HIST");
-
-    if (r != 0) {
-      m_log << "Unable to open ROOT file " << filename << " for writing"
-	    << endmsg;
-      return StatusCode::FAILURE;
-    }
-
-    f = (TFile*)vf;
-
-  } else if (newMode == THistSvcHLT::UPDATE) {
-    // update file
-
-    int r = p_fileMgr->open(Io::ROOT,name(), filename, (Io::WRITE|Io::CREATE),
-			    vf, "HIST");
-
-    if (r != 0) {
-      m_log << "Unable to open ROOT file " << filename << " for appending"
-	    << endmsg;
-      return StatusCode::FAILURE;
-    }
-
-    f = (TFile*)vf;
-
-  }
-
-  m_files[stream] = make_pair(f,newMode);
-  m_fileStreams.insert(make_pair(filename,stream));
-
-  if (m_log.level() <= MSG::DEBUG)
-    m_log << MSG::DEBUG << "Opening TFile \"" << filename << "\"  stream: \""
-          << stream << "\"  mode: \"" << typ << "\"" << " comp level: " << cl
-          << endmsg;
-
-  return StatusCode::SUCCESS;
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-TDirectory*
-THistSvcHLT::changeDir(const THistSvcHLT::THistID& hid) const {
-
-  string uid = hid.id;
-  TFile* file = hid.file;
-  string stream, fdir, bdir, dir, id;
-
-  if (file) {
-    file->cd("/");
-  } else {
-    gROOT->cd();
-  }
-
-  fdir = uid;
-  bdir = dirname(fdir);
-
-  while ( (dir = dirname(fdir)) != "") {
-    if (! gDirectory->GetKey(dir.c_str())) {
-      gDirectory->mkdir(dir.c_str());
-    }
-    gDirectory->cd(dir.c_str());
-  }
-
-  return gDirectory;
-
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-std::string
-THistSvcHLT::dirname(std::string& dir) const {
-
-
-  string::size_type i = dir.find("/");
-
-  if (i == string::npos) return {};
-
-  if ( i == 0 ) {
-    dir.erase(0,1);
-    return dirname(dir);
-  }
-
-  string root = dir.substr(0,i);
-  dir.erase(0,i);
-
-  return root;
-
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-THistSvcHLT::GlobalDirectoryRestore::GlobalDirectoryRestore() {
-  m_gd = gDirectory;
-  m_gf = gFile;
-  m_ge = gErrorIgnoreLevel;
-}
-
-THistSvcHLT::GlobalDirectoryRestore::~GlobalDirectoryRestore() {
-  gDirectory = m_gd;
-  gFile = m_gf;
-  gErrorIgnoreLevel = m_ge;
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-void
-THistSvcHLT::removeDoubleSlash(std::string& id) const {
-
-  while (id.find("//") != std::string::npos) {
-    id.replace(id.find("//"),2,"/");
-  }
-
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-void THistSvcHLT::MergeRootFile(TDirectory *target, TDirectory *source) {
-
-  if (m_log.level() <= MSG::DEBUG)
-    m_log <<MSG::DEBUG << "Target path: " << target->GetPath() << endmsg;
-  TString path( (char*)strstr(target->GetPath(), ":") );
-  path.Remove( 0, 2);
-
-  source->cd(path);
-  TDirectory *current_sourcedir = gDirectory;
-
-  // loop over all keys in this directory
-  TList *lkeys=current_sourcedir->GetListOfKeys();
-  int nkeys=lkeys->GetEntries();
-  TKey *key;
-  for (int jj=0; jj<nkeys; jj++) {
-    key=(TKey*) lkeys->At(jj);
-    string pathnameinsource=current_sourcedir->GetPath()+string("/")+key->GetName();
-    if (m_log.level() <= MSG::DEBUG)
-      m_log <<MSG::DEBUG << "Reading Key:" << pathnameinsource << endmsg;
-    //key->Dump();
-    //TObject *obj=key->ReadObj();
-    TObject *obj=source->Get(pathnameinsource.c_str());
-
-    if (obj) {
-    if (obj->IsA()->InheritsFrom("TDirectory") ) {
-      // it's a subdirectory
-
-      if (m_log.level() <= MSG::DEBUG)
-        m_log <<MSG::DEBUG << "Found subdirectory " << obj->GetName()
-              << endmsg;
-
-      // create a new subdir of same name and title in the target file
-      target->cd();
-      TDirectory *newtargetdir =
-        target->mkdir(obj->GetName(), obj->GetTitle() );
-
-      MergeRootFile(newtargetdir, source);
-
-    } else if (obj->IsA()->InheritsFrom("TTree")) {
-      if (m_log.level() <= MSG::DEBUG)
-        m_log <<MSG::DEBUG << "Found TTree " << obj->GetName() << endmsg;
-      TTree *mytree=dynamic_cast<TTree*>(obj);
-      int nentries=(int) mytree->GetEntries();
-      mytree->SetBranchStatus("*",1);
-
-      if (m_log.level() <= MSG::DEBUG)
-        m_log <<MSG::DEBUG << "Dumping TTree " << nentries <<" entries"
-              << endmsg;
-      //mytree->Print();
-      //for (int ij=0; ij<nentries; ij++) {
-      //m_log <<MSG::DEBUG << "Dumping TTree Show( " << ij <<" )"
-      //<< endmsg;
-      //mytree->Show(ij);
-      //}
-      target->cd();
-      mytree->CloneTree();
-
-      //m_log <<MSG::DEBUG << "Writing TTree to target file: ( "
-      //<< mycopiedtree->Write(key->GetName()) <<" ) bytes written"
-      //<< endmsg;
-
-    } else {
-      target->cd();
-      obj->Write(key->GetName() );
-    }
-    }
-
-  } // while ( ( TKey *key = (TKey*)nextkey() ) )
-
-  // save modifications to target file
-
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-bool
-THistSvcHLT::exists( const std::string& name ) const {
-
-  TH1* h;
-  return getHist_i(name,h,true).isSuccess();
-
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-void
-THistSvcHLT::handle( const Incident& /* inc */ ) {
-
-  if (signaledStop) return ;
-
-  if (m_maxFileSize.value() == -1) return;
-
-  // convert to bytes.
-  Long64_t mfs = (Long64_t)m_maxFileSize.value() * (Long64_t)1048576;
-  Long64_t mfs_warn = mfs * 95 / 100;
-
-  updateFiles();
-
-  map<string, pair<TFile*,Mode> >::const_iterator itr;
-  for (const auto& f : m_files) {
-    TFile* tf = f.second.first;
-
-#ifndef NDEBUG
-    if (m_log.level() <= MSG::DEBUG)
-      m_log << MSG::DEBUG << "stream: " << f.first << "  name: "
-            << tf->GetName() << "  size: " << tf->GetSize()
-            << endmsg;
-#endif
-
-    // Signal job to terminate if output file is too large
-    if (tf->GetSize() > mfs) {
-
-      signaledStop = true;
-
-      m_log << MSG::FATAL << "file \"" << tf->GetName()
-            << "\" associated with stream \"" << f.first
-            << "\" has exceeded the max file size of "
-            << m_maxFileSize.value() << "MB. Terminating Job."
-            << endmsg;
-
-      IEventProcessor* evt = nullptr;
-      if (service("ApplicationMgr", evt, true).isSuccess()) {
-        evt->stopRun();
-        evt->release();
-      } else {
-        abort();
-      }
-    } else if (tf->GetSize() > mfs_warn) {
-      m_log << MSG::WARNING << "file \"" << tf->GetName()
-            << "\" associated with stream \"" << f.first
-            << "\" is at 95% of its maximum allowable file size of "
-            << m_maxFileSize.value() << "MB"
-            << endmsg;
-    }
-  }
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-/** helper function to recursively copy the layout of a TFile into a new TFile
- */
-void
-THistSvcHLT::copyFileLayout (TDirectory *dst, TDirectory *src) {
-
-  if (m_log.level() <= MSG::DEBUG)
-    m_log << MSG::DEBUG << "copyFileLayout() to dst path: " << dst->GetPath () << endmsg;
-
-  // strip out URLs
-  TString path ((char*)strstr (dst->GetPath(), ":"));
-  path.Remove (0, 2);
-  
-  src->cd (path);
-  TDirectory *cur_src_dir = gDirectory;
-  
-  // loop over all keys in this directory
-  TList *key_list = cur_src_dir->GetListOfKeys ();
-  int n = key_list->GetEntries ();
-  for ( int j = 0; j < n; ++j ) {
-    TKey *k = (TKey*)key_list->At (j);
-    const std::string src_pathname = cur_src_dir->GetPath()
-      + std::string("/")
-      + k->GetName();
-    TObject *o=src->Get (src_pathname.c_str());
-    
-    if ( o && o->IsA()->InheritsFrom ("TDirectory")) {
-      if (m_log.level() <= MSG::VERBOSE)
-        m_log << MSG::VERBOSE << " subdir [" << o->GetName() << "]..." << endmsg;
-      dst->cd ();
-      TDirectory * dst_dir = dst->mkdir (o->GetName(), o->GetTitle());
-      copyFileLayout (dst_dir, src);
-    }
-  } // loop over keys
-  return;
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-/** @brief callback method to reinitialize the internal state of
- *         the component for I/O purposes (e.g. upon @c fork(2))
- */
-StatusCode
-THistSvcHLT::io_reinit ()
-{
-  bool all_good = true;
-  if (m_log.level() <= MSG::DEBUG)
-    m_log << MSG::DEBUG << "reinitializing I/O..." << endmsg;
-
-  // retrieve the I/O component manager...
-
-  IIoComponentMgr* iomgr = nullptr;
-
-  if (service("IoComponentMgr", iomgr, true).isFailure()) {
-    m_log << MSG::ERROR << "could not retrieve I/O component manager !"
-          << endmsg;
-    return StatusCode::FAILURE;
-  }
-
-  GlobalDirectoryRestore restore;
-  // to hide the expected errors upon closing the files whose
-  // file descriptors have been swept under the rug...
-  gErrorIgnoreLevel = kFatal;
-
-  typedef std::map<std::string, std::pair<TFile*,Mode> > FileReg_t;
-
-  for (auto & ifile : m_files ) {
-    TFile *f = ifile.second.first;
-    std::string fname = f->GetName();
-    if (m_log.level() <= MSG::DEBUG)
-      m_log << MSG::DEBUG << "file [" << fname << "] mode: ["
-          << f->GetOption() << "] r:"
-          << f->GetFileBytesRead()
-          << " w:" << f->GetFileBytesWritten()
-          << " cnt:" << f->GetFileCounter()
-          << endmsg;
-
-    if ( ifile.second.second == READ ) {
-      if (m_log.level() <= MSG::DEBUG)
-	m_log << MSG::DEBUG
-            << "  TFile opened in READ mode: not reassigning names" << endmsg;
-      continue;
-    }
-
-    if ( !iomgr->io_retrieve (this, fname).isSuccess () ) {
-      m_log << MSG::ERROR << "could not retrieve new name for [" << fname
-            << "] !!" << endmsg;
-      all_good = false;
-      continue;
-    } else {
-      if (m_log.level() <= MSG::DEBUG)
-	m_log << MSG::DEBUG << "got a new name [" << fname << "]..." << endmsg;
-    }
-    // create a new TFile
-    // TFile *newfile = TFile::Open (fname.c_str(), f->GetOption());
-
-    void* vf;
-    Option_t *opts = f->GetOption();
-    int r = p_fileMgr->open(Io::ROOT,name(),fname,Io::WRITE,vf,"HIST");
-    if (r != 0) {
-      m_log << MSG::ERROR << "unable to open file \"" << fname
-	    << "\" for writing" << endmsg;
-      return StatusCode::FAILURE;
-    }
-    TFile *newfile = (TFile*) vf;
-    newfile->SetOption(opts);
-
-
-    if (ifile.second.second != THistSvcHLT::READ) {
-      copyFileLayout (newfile, f);
-      ifile.second.first = newfile;
-    }
-
-    // loop over all uids and migrate them to the new file
-    // XXX FIXME: this double loop sucks...
-    for ( auto& uid : m_uids ) {
-      THistID& hid = uid.second;
-      if ( hid.file != f ) continue;
-      TDirectory *olddir = this->changeDir (hid);
-      hid.file = newfile;
-      // side-effect: create needed directories...
-      TDirectory *newdir = this->changeDir (hid);
-      TClass *cl = hid.obj->IsA();
-
-      // migrate the objects to the new file.
-      // thanks to the object model of ROOT, it is super easy.
-      if (cl->InheritsFrom ("TTree")) {
-        dynamic_cast<TTree*> (hid.obj)->SetDirectory (newdir);
-        dynamic_cast<TTree*> (hid.obj)->Reset();
-      }
-      else if (cl->InheritsFrom ("TH1")) {
-        dynamic_cast<TH1*> (hid.obj)->SetDirectory (newdir);
-        dynamic_cast<TH1*> (hid.obj)->Reset();
-      }
-      else if (cl->InheritsFrom ("TGraph")) {
-        olddir->Remove (hid.obj);
-        newdir->Append (hid.obj);
-      } else {
-        m_log << MSG::ERROR
-              << "id: \"" << hid.id << "\" is not a inheriting from a class "
-              << "we know how to handle (received [" << cl->GetName()
-              << "], " << "expected [TTree, TH1 or TGraph]) !"
-              << endmsg
-              << "attaching to current dir [" << newdir->GetPath() << "] "
-              << "nonetheless..." << endmsg;
-        olddir->Remove (hid.obj);
-        newdir->Append (hid.obj);
-      }
-    }
-    f->ReOpen ("READ");
-    p_fileMgr->close(f,name());
-    f = newfile;
-  }
-
-  return all_good ? StatusCode::SUCCESS : StatusCode::FAILURE;
-}
-
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::rootOpenAction( const Io::FileAttr* fa, const std::string& caller) {
-
-  if (fa->tech() != Io::ROOT) {
-    // This should never happen
-    return StatusCode::SUCCESS;
-  }
-
-  if (fa->desc() != "HIST") {
-    return StatusCode::SUCCESS;
-  }
-
-  p_incSvc->fireIncident(FileIncident(caller, "OpenHistFile", fa->name()));
-
-  if ( fa->flags().isRead() ) {
-    p_incSvc->fireIncident(FileIncident(caller, "BeginHistFile", fa->name()));
-  } else if ( fa->flags().isWrite() ) {
-    p_incSvc->fireIncident(FileIncident(caller, IncidentType::BeginOutputFile,
-					fa->name()));
-  } else {
-    // for Io::RW
-    p_incSvc->fireIncident(FileIncident(caller, IncidentType::BeginOutputFile,
-					fa->name()));
-  }
-
-  return StatusCode::SUCCESS;
-
-
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-StatusCode
-THistSvcHLT::rootOpenErrAction( const Io::FileAttr* fa, const std::string& caller) {
-
-  if (fa->tech() != Io::ROOT) {
-    // This should never happen
-    return StatusCode::SUCCESS;
-  }
-
-  if (fa->desc() != "HIST") {
-    return StatusCode::SUCCESS;
-  }
-
-  if ( fa->flags().isRead() ) {
-    p_incSvc->fireIncident(FileIncident(caller, IncidentType::FailInputFile,
-					fa->name()));
-  } else if ( fa->flags().isWrite() ) {
-    p_incSvc->fireIncident(FileIncident(caller, IncidentType::FailOutputFile,
-					fa->name()));
-  } else {
-    // for Io::RW
-    p_incSvc->fireIncident(FileIncident(caller, "FailRWFile", fa->name()));
-  }
-
-  return StatusCode::SUCCESS;
-}
diff --git a/HLT/Trigger/TrigControl/TrigServices/src/THistSvcHLT.h b/HLT/Trigger/TrigControl/TrigServices/src/THistSvcHLT.h
new file mode 100644
index 0000000000000000000000000000000000000000..9ff4a578f276ff5c752ba50195169f4282c7b4b7
--- /dev/null
+++ b/HLT/Trigger/TrigControl/TrigServices/src/THistSvcHLT.h
@@ -0,0 +1,361 @@
+/*
+ * This is a copy of GaudiSvc/src/THistSvc with THistSvc renamed to THistSvcHLT
+ * to allow inheritance of this class by TrigMonTHistSvc.
+ */
+#ifndef THISTSVCHLT_H
+#define THISTSVCHLT_H
+
+// system includes:
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+// Gaudi includes:
+#include "GaudiKernel/IFileMgr.h"
+#include "GaudiKernel/IIncidentListener.h"
+#include "GaudiKernel/IIoComponent.h"
+#include "GaudiKernel/ITHistSvc.h"
+#include "GaudiKernel/MsgStream.h"
+#include "GaudiKernel/Service.h"
+
+// ROOT includes:
+#include "TGraph.h"
+#include "TH1.h"
+#include "TH2.h"
+#include "TH3.h"
+#include "TList.h"
+#include "TObject.h"
+#include "TTree.h"
+
+class IIncidentSvc;
+
+class THistSvcHLT : public extends<Service, ITHistSvc, IIncidentListener, IIoComponent>
+{
+public:
+  THistSvcHLT( const std::string& name, ISvcLocator* svc );
+
+  StatusCode initialize() override;
+  StatusCode reinitialize() override;
+  StatusCode finalize() override;
+
+public:
+  // Methods from ITHistSvc
+  /// @name Functions to manage ROOT histograms of any kind
+  /// @{
+
+  /// Register a new ROOT histogram TH*X with a name
+  StatusCode regHist( const std::string& name ) override;
+  /// Register an existing ROOT histogram TH*X with name and moved unique_ptr
+  /// @param [in] name      defines the histogram id/name under which it is recorded
+  /// @param [in] hist      transfers ownership of the histogram to the THistSvc
+  StatusCode regHist( const std::string& name, std::unique_ptr<TH1> hist ) override;
+  /// Register an existing ROOT histogram TH*X with name and moved unique_ptr
+  /// @param [in] name      defines the histogram id/name under which it is recorded
+  /// @param [in] hist      transfers ownership of the histogram to the THistSvc
+  /// @param [out] hist_ptr for compatibility: return raw pointer to managed object to support common usage in Athena
+  StatusCode regHist( const std::string& name, std::unique_ptr<TH1> hist, TH1* hist_ptr ) override;
+  /// @deprecated {Just for compatibility purposes. Ownership should be clearly managed.}
+  /// Register an existing ROOT histogram TH*X with name and pointer
+  StatusCode regHist( const std::string& name, TH1* ) override;
+
+  /// Return histogram with given name as TH1*, THistSvcMT still owns object.
+  StatusCode getHist( const std::string& name, TH1*&, size_t index = 0 ) const override;
+  /// Return histogram with given name as TH2*, THistSvcMT still owns object.
+  StatusCode getHist( const std::string& name, TH2*&, size_t index = 0 ) const override;
+  /// Return histogram with given name as TH3*, THistSvcMT still owns object.
+  StatusCode getHist( const std::string& name, TH3*&, size_t index = 0 ) const override;
+
+  /// @}
+
+  /// @name Functions to manage TTrees
+  /// @{
+
+  /// Register a new TTree with a given name
+  StatusCode regTree( const std::string& name ) override;
+  /// Register an existing TTree with a given name and moved unique_ptr
+  StatusCode regTree( const std::string& name, std::unique_ptr<TTree> ) override;
+  /// @deprecated {Just kept for compatibiltiy to current ATLAS code. Pleas use std::unique_ptrs instead!}
+  /// Register a new TTree with a given name and a raw pointer
+  StatusCode regTree( const std::string& name, TTree* ) override;
+  /// Return TTree with given name
+  StatusCode getTree( const std::string& name, TTree*& ) const override;
+
+  /// @}
+
+  /// @name Functions to manage TGraphs
+  /// @{
+
+  /// Register a new TGraph with a given name
+  StatusCode regGraph( const std::string& name ) override;
+  /// Register an existing TGraph with a given name and moved unique_ptr
+  StatusCode regGraph( const std::string& name, std::unique_ptr<TGraph> ) override;
+  /// @deprecated {Just kept for compatibiltiy to current ATLAS code. Pleas use std::unique_ptrs instead!}
+  /// Register a new TGraph with a given name and a raw pointer
+  virtual StatusCode regGraph( const std::string& name, TGraph* ) override;
+  /// Return TGraph with given name
+  StatusCode getGraph( const std::string& name, TGraph*& ) const override;
+
+  /// @}
+
+  /// @name Functions managing shared objects
+  /// @{
+
+  /// Register shared object of type TH1 and return LockedHandle for that object
+  StatusCode regShared( const std::string& name, std::unique_ptr<TH1>, LockedHandle<TH1>& ) override;
+  /// Register shared object of type TH2 and return LockedHandle for that object
+  StatusCode regShared( const std::string& name, std::unique_ptr<TH2>, LockedHandle<TH2>& ) override;
+  /// Register shared object of type TH3 and return LockedHandle for that object
+  StatusCode regShared( const std::string& name, std::unique_ptr<TH3>, LockedHandle<TH3>& ) override;
+  /// Register shared object of type TGraph and return LockedHandle for that object
+  StatusCode regShared( const std::string& name, std::unique_ptr<TGraph>, LockedHandle<TGraph>& ) override;
+  /// Retrieve shared object with given name as TH1 through LockedHandle
+  StatusCode getShared( const std::string& name, LockedHandle<TH1>& ) const override;
+  /// Retrieve shared object with given name as TH2 through LockedHandle
+  StatusCode getShared( const std::string& name, LockedHandle<TH2>& ) const override;
+  /// Retrieve shared object with given name as TH3 through LockedHandle
+  StatusCode getShared( const std::string& name, LockedHandle<TH3>& ) const override;
+  /// Retrieve shared object with given name as TGraph through LockedHandle
+  StatusCode getShared( const std::string& name, LockedHandle<TGraph>& ) const override;
+
+  /// @}
+
+  /// @name Functions that work on any TObject in the THistSvcMT
+  /// @{
+
+  /// Deregister object with given name and give up ownership (without deletion!)
+  StatusCode deReg( const std::string& name ) override;
+  /// Deregister obejct identified by TObject* and give up ownership (without deletion!)
+  StatusCode deReg( TObject* obj ) override;
+
+  /// Merge all clones for object with a given id
+  StatusCode merge( const std::string& id ) override;
+  /// Merge all clones for given TObject*
+  StatusCode merge( TObject* ) override;
+
+  /// Check if object with given name is managed by THistSvcMT
+  bool exists( const std::string& name ) const override;
+
+  /// @}
+
+  /// @name Functions returning lists of all histograms, trees and graphs
+  /// @{
+
+  std::vector<std::string> getHists() const override;
+  std::vector<std::string> getTrees() const override;
+  std::vector<std::string> getGraphs() const override;
+
+  StatusCode getTHists( TDirectory* td, TList&, bool recurse = false ) const override;
+  StatusCode getTHists( const std::string& name, TList&, bool recurse = false ) const override;
+  StatusCode getTHists( TDirectory* td, TList& tl, bool recurse = false, bool reg = false ) override;
+  StatusCode getTHists( const std::string& name, TList& tl, bool recurse = false, bool reg = false ) override;
+
+  StatusCode getTTrees( TDirectory* td, TList&, bool recurse = false ) const override;
+  StatusCode getTTrees( const std::string& name, TList&, bool recurse = false ) const override;
+  StatusCode getTTrees( TDirectory* td, TList& tl, bool recurse = false, bool reg = false ) override;
+  StatusCode getTTrees( const std::string& name, TList& tl, bool recurse = false, bool reg = false ) override;
+
+  /// @}
+
+public:
+  // Methods from other interfaces
+  // From IIncidentListener
+  void handle( const Incident& ) override;
+
+  // From IIoComponent
+  StatusCode io_reinit() override;
+
+private:
+  typedef std::recursive_mutex THistSvcMutex_t;
+  typedef std::mutex histMut_t;
+
+  /// Helper class that manages ROOts global directory and file
+  class GlobalDirectoryRestore
+  {
+  public:
+    GlobalDirectoryRestore( THistSvcMutex_t& mut );
+    ~GlobalDirectoryRestore();
+
+  private:
+    TDirectory* m_gDirectory;
+    TFile* m_gFile;
+    int m_gErrorIgnoreLevel;
+    std::lock_guard<THistSvcMutex_t> m_lock;
+  };
+
+  /// Enumerating all possible file access modes
+  enum Mode { READ, WRITE, UPDATE, APPEND, SHARE, INVALID };
+
+  /// Helper struct that bundles the histogram ID with a mutex, TFile and TObject*
+  struct THistID {
+    std::string id{""};
+    bool temp{true};
+    TObject* obj{nullptr};
+    TFile* file{nullptr};
+    Mode mode{INVALID};
+    histMut_t* mutex{nullptr};
+    bool shared{false};
+
+    THistID()                     = default;
+    THistID( const THistID& rhs ) = default;
+    THistID( std::string& i, bool& t, TObject* o, TFile* f ) : id( i ), temp( t ), obj( o ), file( f ) {}
+    THistID( std::string& i, bool& t, TObject* o, TFile* f, Mode m )
+        : id( i ), temp( t ), obj( o ), file( f ), mode( m )
+    {
+    }
+
+    void reset()
+    {
+      id     = "";
+      temp   = true;
+      obj    = nullptr;
+      file   = nullptr;
+      mode   = INVALID;
+      mutex  = nullptr;
+      shared = false;
+    }
+
+    bool operator<( THistID const& rhs ) const { return ( obj < rhs.obj ); }
+
+    friend std::ostream& operator<<( std::ostream& ost, const THistID& hid )
+    {
+      ost << "id: " << hid.id << " t: " << hid.temp << " s: " << hid.shared << " M: " << hid.mode << " m: " << hid.mutex
+          << " o: " << hid.obj << " " << hid.obj->IsA()->GetName();
+      return ost;
+    }
+  };
+
+  /// @name Container definitions
+  /// @{
+
+  std::vector<std::string> m_Rstream, m_Wstream;
+
+  /// list of already connected files. This is to keep track of files
+  /// registered by the setupInputFile callback method
+  std::set<std::string> m_alreadyConnectedInFiles;
+
+  /// list of already connected files. This is to keep track of files
+  /// registered by the setupOutputFile callback method
+  std::set<std::string> m_alreadyConnectedOutFiles;
+
+  // containers for fast lookups
+  // same uid for all elements in vec
+  typedef std::vector<THistID> vhid_t;
+  // all THistIDs
+  typedef std::list<vhid_t*> hlist_t;
+  // uid: /stream/name -> vhid
+  typedef std::unordered_map<std::string, vhid_t*> uidMap_t;
+  // name -> vhid
+  typedef std::unordered_multimap<std::string, vhid_t*> idMap_t;
+  typedef std::unordered_map<TObject*, std::pair<vhid_t*, size_t>> objMap_t;
+
+  hlist_t m_hlist;
+  uidMap_t m_uids;
+  idMap_t m_ids;
+
+  // Container holding all TObjects and vhid*s
+  objMap_t m_tobjs;
+
+  std::map<std::string, std::pair<TFile*, Mode>> m_files; // stream->file
+  typedef std::multimap<std::string, std::string> streamMap;
+  streamMap m_fileStreams; // fileName->streams
+
+  // stream->filename of shared files
+  std::map<std::string, std::string> m_sharedFiles;
+
+  /// @}
+
+  /// @name Templated helper functions to register and retrieve Histograms and TObjects
+  /// @{
+
+  template <typename T>
+  StatusCode regHist_i( std::unique_ptr<T> hist, const std::string& name, bool shared );
+  template <typename T>
+  StatusCode regHist_i( std::unique_ptr<T> hist, const std::string& name, bool shared, THistID*& hid );
+  template <typename T>
+  T* getHist_i( const std::string& name, const size_t& ind = 0, bool quiet = false ) const;
+  template <typename T>
+  T* readHist_i( const std::string& name ) const;
+
+  template <typename T>
+  LockedHandle<T> regShared_i( const std::string& id, std::unique_ptr<T> hist );
+  template <typename T>
+  LockedHandle<T> getShared_i( const std::string& name ) const;
+
+  /// @}
+
+  /// @name Collection of private helper methods
+  /// @{
+
+  template <typename T>
+  T* readHist( const std::string& name ) const;
+  TTree* readTree( const std::string& name ) const;
+
+  /// Handle case where TTree grows beyond TTree::fgMaxTreeSize
+  void updateFiles();
+  StatusCode writeObjectsToFile();
+  StatusCode connect( const std::string& );
+  TDirectory* changeDir( const THistSvcHLT::THistID& hid ) const;
+  std::string stripDirectoryName( std::string& dir ) const;
+  void removeDoubleSlash( std::string& ) const;
+
+  void MergeRootFile( TDirectory*, TDirectory* );
+
+  bool findStream( const std::string& name, std::string& root, std::string& rem, TFile*& file ) const;
+  void parseString( const std::string& id, std::string& root, std::string& rem ) const;
+
+  /// call-back method to handle input stream property
+  void setupInputFile( Gaudi::Details::PropertyBase& inputfile );
+
+  /// call-back method to handle output stream property
+  void setupOutputFile( Gaudi::Details::PropertyBase& outputfile );
+
+  void setupCompressionLevel( Gaudi::Details::PropertyBase& cmp );
+
+  /// helper function to recursively copy the layout of a TFile into a new TFile
+  void copyFileLayout( TDirectory*, TDirectory* );
+
+  size_t findHistID( const std::string& id, const THistID*& hid, const size_t& index = 0 ) const;
+
+  void dump() const;
+
+  /// Helper method to merge THistID objects
+  StatusCode merge( const THistID& );
+  /// Helper method to merge vectors of THistID
+  StatusCode merge( vhid_t* );
+
+  StatusCode rootOpenAction( FILEMGR_CALLBACK_ARGS );
+  StatusCode rootOpenErrAction( FILEMGR_CALLBACK_ARGS );
+
+  /// @}
+
+  /// @name Gaudi properties
+  /// @{
+
+  Gaudi::Property<int> m_autoSave{this, "AutoSave", 0};
+  Gaudi::Property<int> m_autoFlush{this, "AutoFlush", 0};
+  Gaudi::Property<bool> m_print{this, "PrintAll", false};
+  Gaudi::Property<int> m_maxFileSize{this, "MaxFileSize", 10240, "maximum file size in MB. if exceeded,"
+                                                                 " will cause an abort. -1 to never check."};
+  Gaudi::Property<int> m_compressionLevel{this, "CompressionLevel", 1};
+  Gaudi::Property<std::vector<std::string>> m_outputfile{this, "Output", {}};
+  Gaudi::Property<std::vector<std::string>> m_inputfile{this, "Input", {}};
+
+  /// @}
+
+  IIncidentSvc* p_incSvc = nullptr;
+  IFileMgr* p_fileMgr    = nullptr;
+
+  bool m_signaledStop = false;
+  bool m_delayConnect = false;
+  bool m_okToConnect  = false;
+
+  mutable std::string m_curstream;
+
+  mutable THistSvcMutex_t m_svcMut;
+};
+
+// Include template implementation
+#include "THistSvcHLT.icc"
+
+#endif // THISTSVCHLT_H
diff --git a/HLT/Trigger/TrigControl/TrigServices/src/THistSvcHLT.h.bak b/HLT/Trigger/TrigControl/TrigServices/src/THistSvcHLT.h.bak
deleted file mode 100644
index cec1ef7d50e4cf042c4af0b0a480426b2caab66b..0000000000000000000000000000000000000000
--- a/HLT/Trigger/TrigControl/TrigServices/src/THistSvcHLT.h.bak
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-*/
-
-#ifndef THISTSVCHLT_H
-#define THISTSVCHLT_H
-
-#include "GaudiKernel/Service.h"
-#include "GaudiKernel/ITHistSvc.h"
-#include "GaudiKernel/IFileMgr.h"
-#include "GaudiKernel/IIncidentListener.h"
-#include "GaudiKernel/IIoComponent.h"
-#include "GaudiKernel/MsgStream.h"
-
-#include "TObject.h"
-#include "TH1.h"
-#include "TH2.h"
-#include "TH3.h"
-#include "TTree.h"
-#include "TGraph.h"
-#include "TList.h"
-
-
-#include <vector>
-#include <string>
-#include <set>
-#include <map>
-
-class IIncidentSvc;
-class THistSvcHLT: public extends3<Service, ITHistSvc, IIncidentListener,
-				IIoComponent> {
-
-public:
-
-  StatusCode initialize() override;
-  StatusCode reinitialize() override;
-  StatusCode finalize() override;
-
-  StatusCode regHist(const std::string& name) override;
-  StatusCode regHist(const std::string& name, TH1*) override;
-  StatusCode regHist(const std::string& name, TH2*) override;
-  StatusCode regHist(const std::string& name, TH3*) override;
-
-  StatusCode getHist(const std::string& name, TH1*&) const override;
-  StatusCode getHist(const std::string& name, TH2*&) const override;
-  StatusCode getHist(const std::string& name, TH3*&) const override;
-
-  StatusCode regTree(const std::string& name) override;
-  StatusCode regTree(const std::string& name, TTree*) override;
-  StatusCode getTree(const std::string& name, TTree*&) const override;
-
-  StatusCode regGraph(const std::string& name) override;
-  StatusCode regGraph(const std::string& name, TGraph*) override;
-  StatusCode getGraph(const std::string& name, TGraph*&) const override;
-
-  StatusCode deReg(TObject* obj) override;
-  StatusCode deReg(const std::string& name) override;
-
-  std::vector<std::string> getHists() const override;
-  std::vector<std::string> getTrees() const override;
-  std::vector<std::string> getGraphs() const override;
-
-  StatusCode getTHists(TDirectory *td, TList &,
-           bool recurse=false) const override;
-  StatusCode getTHists(const std::string& name, TList &,
-           bool recurse=false) const override;
-
-  StatusCode getTHists(TDirectory *td, TList &tl,
-           bool recurse=false, bool reg=false) override;
-  StatusCode getTHists(const std::string& name, TList &tl,
-		  bool recurse=false, bool reg=false) override;
-
-  StatusCode getTTrees(TDirectory *td, TList &,
-           bool recurse=false) const override;
-  StatusCode getTTrees(const std::string& name, TList &,
-           bool recurse=false) const override;
-
-  StatusCode getTTrees(TDirectory *td, TList & tl,
-           bool recurse=false, bool reg=false) override;
-  StatusCode getTTrees(const std::string& name, TList & tl,
-           bool recurse=false, bool reg=false) override;
-
-  bool exists(const std::string& name) const override;
-
-  THistSvcHLT(const std::string& name, ISvcLocator *svc );
-
-  void handle(const Incident&) override;
-
-  // From IIoComponent
-  StatusCode io_reinit () override;
-
-
-protected:
-
-  ~THistSvcHLT() override = default;
-
-private:
-
-  class GlobalDirectoryRestore {
-  public:
-    GlobalDirectoryRestore();
-    ~GlobalDirectoryRestore();
-  private:
-    TDirectory* m_gd;
-    TFile* m_gf;
-    int m_ge;
-  };
-
-  enum Mode {
-    READ,
-    WRITE,
-    UPDATE,
-    APPEND,
-    SHARE,
-    INVALID
-  };
-
-  struct THistID {
-    std::string id;
-    bool        temp;
-    TObject*    obj;
-    TFile*      file;
-    Mode        mode;
-
-    THistID():id(""),temp(true),obj(0),file(0),mode(INVALID) {}
-    THistID(const THistID& rhs):id(rhs.id), temp(rhs.temp),
-                                obj(rhs.obj), file(rhs.file), mode(rhs.mode) {}
-    THistID(std::string& i, bool& t, TObject* o, TFile* f)
-      : id(i), temp(t), obj(o), file(f), mode(INVALID){
-    }
-    THistID(std::string& i, bool& t, TObject* o, TFile* f, Mode m)
-      : id(i), temp(t), obj(o), file(f), mode(m){
-    }
-
-    bool operator < (THistID const &rhs) const {
-      return (obj < rhs.obj);
-    }
-  };
-
-
-  template <typename T>
-  StatusCode regHist_i(T* hist, const std::string& name);
-  template <typename T>
-  StatusCode getHist_i(const std::string& name, T*& hist, bool quiet=false) const;
-  template <typename T>
-  StatusCode readHist_i(const std::string& name, T*& hist) const;
-
-
-  StatusCode readHist(const std::string& name, TH1*&) const;
-  StatusCode readHist(const std::string& name, TH2*&) const;
-  StatusCode readHist(const std::string& name, TH3*&) const;
-  StatusCode readTree(const std::string& name, TTree*&) const;
-
-  void updateFiles();
-  StatusCode write();
-  StatusCode connect(const std::string&);
-  TDirectory* changeDir(const THistSvcHLT::THistID& hid) const;
-  std::string dirname(std::string& dir) const;
-  void removeDoubleSlash(std::string&) const;
-
-  bool browseTDir(TDirectory* dir) const;
-
-  bool findStream(const std::string& name, std::string& root,
-                  std::string& rem, TFile*& file) const;
-  void parseString(const std::string& id, std::string& root, std::string& rem)
-    const;
-
-  /// call-back method to handle input stream property
-  void setupInputFile( Property& inputfile );
-
-  /// call-back method to handle output stream property
-  void setupOutputFile( Property& outputfile );
-
-  void setupCompressionLevel( Property& cmp );
-
-  void copyFileLayout(TDirectory*, TDirectory*);
-
-  void MergeRootFile( TDirectory *target, TDirectory *source); 
-
-  ////////
-
-  mutable MsgStream m_log;
-
-  StringArrayProperty m_inputfile, m_outputfile;
-  std::vector<std::string> m_Rstream, m_Wstream;
-  IntegerProperty m_autoSave, m_autoFlush, m_compressionLevel, m_maxFileSize;
-  BooleanProperty m_print;
-
-  /// list of already connected files. This is to keep track of files
-  /// registered by the setupInputFile callback method
-  std::set<std::string> m_alreadyConnectedInFiles;
-
-  /// list of already connected files. This is to keep track of files
-  /// registered by the setupOutputFile callback method
-  std::set<std::string> m_alreadyConnectedOutFiles;
-
-
-  typedef std::map<std::string, THistID> uidMap;
-  typedef std::multimap<std::string, THistID> idMap;
-  typedef std::map<TObject*, THistID> objMap;
-  typedef std::multimap<std::string, std::string> streamMap;
-
-  uidMap m_uids;
-  idMap  m_ids;
-  objMap m_tobjs;
-
-  std::map<std::string, std::pair<TFile*,Mode> > m_files; // stream->file
-  streamMap m_fileStreams;                                // fileName->streams
-
-  std::map<std::string, std::string > m_sharedFiles; // stream->filename of shared files
-
-  bool signaledStop = false;
-  bool m_delayConnect = false, m_okToConnect = false;
-
-  mutable std::string m_curstream;
-
-  IIncidentSvc* p_incSvc = nullptr;
-  IFileMgr* p_fileMgr = nullptr;
-
-  StatusCode rootOpenAction( FILEMGR_CALLBACK_ARGS );
-  StatusCode rootOpenErrAction( FILEMGR_CALLBACK_ARGS );
-
-};
-
-#ifndef THISTSVCHLT_ICC
- #include "THistSvcHLT.icc"
-#endif
-
-
-#endif
diff --git a/HLT/Trigger/TrigControl/TrigServices/src/THistSvcHLT.icc b/HLT/Trigger/TrigControl/TrigServices/src/THistSvcHLT.icc
new file mode 100644
index 0000000000000000000000000000000000000000..9595c3a580e6b9b9c1d288618d742daf6e098e03
--- /dev/null
+++ b/HLT/Trigger/TrigControl/TrigServices/src/THistSvcHLT.icc
@@ -0,0 +1,338 @@
+/*
+ * This is a copy of GaudiSvc/src/THistSvc with THistSvc renamed to THistSvcHLT
+ * to allow inheritance of this class by TrigMonTHistSvc.
+ */
+#ifndef THISTSVCHLT_ICC
+#define THISTSVCHLT_ICC
+
+#include <map>
+#include <string>
+
+#include "TFile.h"
+#include "TObject.h"
+
+#ifndef GAUDIKERNEL_MSGSTREAM_H
+#include "GaudiKernel/MsgStream.h"
+#endif
+
+#include "GaudiKernel/System.h"
+
+template <typename T>
+StatusCode THistSvcHLT::regHist_i( std::unique_ptr<T> hist, const std::string& id, bool shared )
+{
+  THistID* hid = nullptr ;
+  return regHist_i( std::move(hist), id, shared, hid );
+}
+
+template <typename T>
+StatusCode THistSvcHLT::regHist_i( std::unique_ptr<T> hist_unique, const std::string& id, bool shared, THistID*& phid )
+{
+  GlobalDirectoryRestore restore( m_svcMut );
+  phid = nullptr;
+
+  // It is sad that we lose propper memory management here
+  T* hist = nullptr;
+  if( hist_unique.get() != nullptr ) {
+    hist = hist_unique.release();
+  }
+  debug() << "regHist_i obj: " << hist << "  id: " << id << "  s: " << shared << endmsg;
+
+  std::string idr( id );
+  removeDoubleSlash( idr );
+
+  if ( idr.find( "/" ) == idr.length() ) {
+    error() << "Badly formed identifier \"" << idr << "\": "
+            << "Must not end with a /" << endmsg;
+    delete hist;
+    return StatusCode::FAILURE;
+  }
+
+  TFile* f = nullptr;
+  std::string stream, name;
+  if ( !findStream( idr, stream, name, f ) ) {
+    error() << "Could not register id: \"" << idr << "\"" << endmsg;
+    delete hist;
+    return StatusCode::FAILURE;
+  }
+
+  std::string uid = "/" + stream + "/" + name;
+
+  uidMap_t::iterator uitr = m_uids.find( uid );
+  bool exists( false );
+  if ( uitr != m_uids.end() ) {
+    exists      = true;
+    TObject* t1 = uitr->second->at( 0 ).obj;
+    if ( hist->Compare( t1 ) != 0 ) {
+      error() << "previously registered object with identifier \"" << uid << "\" does not compare to this one"
+              << endmsg;
+      delete hist;
+      return StatusCode::FAILURE;
+    } else {
+      debug() << "previously registered id \"" << uid << "\": num " << uitr->second->size() << endmsg;
+    }
+  }
+
+  bool temp = false;
+  if ( !f ) {
+    temp = true;
+    if ( msgLevel( MSG::DEBUG ) ) {
+      debug() << "Historgram with id \"" << idr << "\" is temporary" << endmsg;
+    }
+  }
+
+  TObject* to = nullptr;
+  THistID hid;
+  // check to see if this hist is to be read in;
+  if ( !temp && m_files.find( stream )->second.second == READ ) {
+    if ( hist != 0 ) {
+      warning() << "Registering id: \"" << idr << "\" with non zero pointer!" << endmsg;
+    }
+
+    hist = readHist_i<T>( idr );
+    if ( hist == nullptr ) {
+      error() << "Unable to read in hist" << endmsg;
+      delete hist;
+      return StatusCode::FAILURE;
+    }
+    to  = dynamic_cast<TObject*>( hist );
+    hid = THistID( uid, temp, to, f, m_files.find( stream )->second.second );
+  } else if ( !hist ) {
+    error() << "Unable to read in hist with id: \"" << idr << "\"" << endmsg;
+    delete hist;
+    return StatusCode::FAILURE;
+  } else {
+    to = dynamic_cast<TObject*>( hist );
+    if ( to == nullptr ) {
+      error() << "Could not dcast to TObject. id: \"" << idr << "\"" << endmsg;
+      delete hist;
+      return StatusCode::FAILURE;
+    }
+
+    auto oitr = m_tobjs.find( to );
+    if ( oitr != m_tobjs.end() ) {
+      error() << "already registered id: \"" << idr << "\" with identifier \""
+              << oitr->second.first->at( oitr->second.second ).id << "\"" << endmsg;
+      delete hist;
+      return StatusCode::FAILURE;
+    }
+
+    hid             = THistID( uid, temp, to, f, m_files.find( stream )->second.second );
+    hid.shared      = shared;
+    TDirectory* dir = changeDir( hid );
+
+    if ( dynamic_cast<TTree*>( hist ) ) {
+      dynamic_cast<TTree*>( hist )->SetDirectory( dir );
+    } else if ( dynamic_cast<TH1*>( hist) ) {
+      dynamic_cast<TH1*>( hist )->SetDirectory( dir );
+    } else if ( dynamic_cast<TGraph*>( hist ) ) {
+      dir->Append( hist );
+    } else {
+      error() << "id: \"" << idr << "\" is not a TH, TTree, or TGraph. Attaching it to current dir." << endmsg;
+      dir->Append( hist );
+    }
+  }
+
+  std::string fname;
+  if ( !f ) {
+    fname = "none";
+  } else {
+    fname = f->GetName();
+  }
+
+  debug() << "Registering" << ( shared ? " shared " : " " ) << System::typeinfoName( typeid( *hist ) ) << " title: \""
+          << hist->GetTitle() << "\"  id: \"" << uid
+          << "\"  dir: "
+          //          << hist->GetDirectory()->GetPath() << "  "
+          << changeDir( hid )->GetPath() << "  file: " << fname << endmsg;
+
+  // create a mutex for all shared histograms
+  if ( shared ) {
+    hid.mutex = new histMut_t;
+  }
+
+  if ( exists ) {
+    vhid_t* vi = uitr->second;
+    vi->push_back( hid );
+    phid = &( vi->back() );
+
+    m_tobjs.emplace( to, std::pair<vhid_t*, size_t>( vi, vi->size() - 1 ) );
+  } else {
+    vhid_t* vi = new vhid_t{hid};
+    m_hlist.emplace( m_hlist.end(), vi );
+
+    phid = &( vi->back() );
+    m_uids.emplace( uid, vi );
+    m_ids.emplace( name, vi );
+
+    m_tobjs.emplace( to, std::pair<vhid_t*, size_t>( vi, 0 ) );
+  }
+
+  debug() << "regHist_i  THistID: " << hid << endmsg;
+
+  return StatusCode::SUCCESS;
+}
+
+template <typename T>
+T* THistSvcHLT::getHist_i( const std::string& id, const size_t& ind, bool quiet ) const
+{
+  // id starts with "/": unique
+
+  GlobalDirectoryRestore restore( m_svcMut );
+
+  T* hist = nullptr;
+  const THistID* hid = nullptr;
+  size_t num = findHistID( id, hid, ind );
+  if ( num == 0 ) {
+    // no matches found
+    if ( !quiet ) {
+      error() << "could not locate Hist with id \"" << id << "\"" << endmsg;
+    }
+    return nullptr;
+  } else if ( num > 1 ) {
+    if ( !quiet ) {
+      // return failure if trying to GET a single hist
+      error() << "Multiple matches with id \"" << id << "\"."
+              << " Further specifications required." << endmsg;
+      return nullptr;
+    } else {
+      info() << "Found multiple matches with id \"" << id << "\"" << endmsg;
+      // return first match if just INQUIRING (i.e. != nullptr)
+      hist = dynamic_cast<T*>( hid->obj );
+      if ( hist == nullptr ) {
+        error() << "dcast failed, Hist id: \"" << id << "\"" << endmsg;
+        return nullptr;
+      }
+    }
+  } else {
+    hist = dynamic_cast<T*>( hid->obj );
+    if ( hist == nullptr ) {
+      error() << "dcast failed, Hist id: \"" << id << "\"" << endmsg;
+      return nullptr;
+    }
+    verbose() << "found unique Hist title: \"" << hist->GetTitle() << "\"  id: \"" << id << "\"" << endmsg;
+  }
+
+  return hist;
+}
+
+template <typename T>
+T* THistSvcHLT::readHist_i( const std::string& id ) const
+{
+  GlobalDirectoryRestore restore( m_svcMut );
+
+  std::string idr( id );
+  removeDoubleSlash( idr );
+
+  std::string stream, rem, dir, fdir, bdir, fdir2;
+  TFile* file = nullptr;
+
+  if ( !findStream( idr, stream, rem, file ) ) {
+    return nullptr;
+  }
+
+  if ( !file ) {
+    error() << "no associated file found" << endmsg;
+    return nullptr;
+  }
+
+  file->cd( "/" );
+
+  fdir  = idr;
+  bdir  = stripDirectoryName( fdir );
+  fdir2 = fdir;
+  while ( ( dir = stripDirectoryName( fdir ) ) != "" ) {
+    if ( !gDirectory->GetKey( dir.c_str() ) ) {
+      error() << "Directory \"" << fdir2 << "\" doesnt exist in " << file->GetName() << endmsg;
+      return nullptr;
+    }
+    gDirectory->cd( dir.c_str() );
+  }
+
+  TObject* to = nullptr;
+  gDirectory->GetObject( fdir.c_str(), to );
+
+  if ( !to ) {
+    error() << "Could not get obj \"" << fdir << "\" in " << gDirectory->GetPath() << endmsg;
+    return nullptr;
+  }
+
+  T* hist = dynamic_cast<T*>( to );
+  if ( hist == nullptr ) {
+    error() << "Could not convert \"" << idr << "\" to a " << System::typeinfoName( typeid( *hist ) ) << " as is a "
+            << to->IsA()->GetName() << endmsg;
+    return nullptr;
+  }
+
+  if ( msgLevel( MSG::DEBUG ) ) {
+    debug() << "Read in " << hist->IsA()->GetName() << "  \"" << hist->GetName() << "\" from file " << file->GetName()
+            << endmsg;
+    hist->Print();
+  }
+
+  return hist;
+}
+
+template <typename T>
+LockedHandle<T> THistSvcHLT::regShared_i( const std::string& id, std::unique_ptr<T> hist )
+{
+  LockedHandle<T> lh( nullptr, nullptr );
+  const THistID* hid = nullptr;
+  if ( findHistID( id, hid ) == 0 ) {
+    T* phist = hist.get();
+    THistID* phid = nullptr;
+    if ( regHist_i( std::move(hist), id, true, phid ).isSuccess() ) {
+      lh.set( phist, phid->mutex );
+
+    } else {
+      error() << "regSharedHist: unable to register shared hist with id \"" << id << "\"" << endmsg;
+    }
+  } else {
+    if ( !hid->shared ) {
+      error() << "regSharedHist: previously register Hist with id \"" << id << "\" was not marked shared" << endmsg;
+    }
+
+    if ( hist->Compare( hid->obj ) != 0 ) {
+      error() << "regSharedHist: Histogram " << id << " does not compare with " << hid << endmsg;
+    } else {
+      T* phist = dynamic_cast<T*>( hid->obj );
+      if ( phist == 0 ) {
+        error() << "regSharedHist: unable to dcast retrieved shared hist \"" << id << "\" of type "
+                << hid->obj->IsA()->GetName() << " to requested type " << System::typeinfoName( typeid( T ) ) << endmsg;
+      } else {
+        lh.set( phist, hid->mutex );
+        delete hist.release();
+      }
+    }
+  }
+  return lh;
+}
+
+template <typename T>
+LockedHandle<T> THistSvcHLT::getShared_i( const std::string& name ) const
+{
+  GlobalDirectoryRestore restore( m_svcMut );
+
+  const THistID* hid = nullptr;
+  size_t i = findHistID( name, hid );
+
+  LockedHandle<T> hist( nullptr, nullptr );
+
+  if ( i == 1 ) {
+    if ( !hid->shared ) {
+      error() << "getSharedHist: found Hist with id \"" << name << "\", but it's not marked as shared" << endmsg;
+      return hist;
+    }
+    T* h1 = dynamic_cast<T*>( hid->obj );
+    hist = LockedHandle<T>( h1, hid->mutex );
+
+    debug() << "getSharedHist: found THistID: " << *hid << endmsg;
+  } else if ( i == 0 ) {
+    error() << "no histograms matching id \"" << name << "\" found" << endmsg;
+  } else {
+    info() << "multiple matches for id \"" << name << "\" found [" << i << "], probably from different streams"
+           << endmsg;
+  }
+  return hist;
+}
+
+#endif // GAUDISVC_THISTSVC_ICC
diff --git a/HLT/Trigger/TrigControl/TrigServices/src/THistSvcHLT.icc.bak b/HLT/Trigger/TrigControl/TrigServices/src/THistSvcHLT.icc.bak
deleted file mode 100644
index 45c635ac545365cbc98b7b409b21daec6fcaeca2..0000000000000000000000000000000000000000
--- a/HLT/Trigger/TrigControl/TrigServices/src/THistSvcHLT.icc.bak
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-*/
-
-#ifndef THISTSVCHLT_ICC
-#define THISTSVCHLT_ICC
-
-#ifndef GAUDIKERNEL_MSGSTREAM_H
- #include "GaudiKernel/MsgStream.h"
-#endif
-
-#include "GaudiKernel/System.h"
-
-#include <string>
-#include <map>
-
-#include "TObject.h"
-#include "TFile.h"
-
-template <typename T>
-StatusCode THistSvcHLT::regHist_i(T* hist, const std::string& id) {
-
-  GlobalDirectoryRestore restore;
-
-  std::string idr(id);
-  removeDoubleSlash( idr );
-
-  if (idr.find("/") == idr.length()) {
-    m_log << MSG::ERROR << "Badly formed identifier \"" << idr << "\": "
-        << "Must not end with a /" << endmsg;
-    return StatusCode::FAILURE;
-  }
-
-
-  TFile *f = nullptr;
-  std::string stream,rem;
-  if (!findStream(idr, stream, rem, f)) {
-    m_log << MSG::ERROR << "Could not register id: \"" << idr << "\""
-        << endmsg;
-    return StatusCode::FAILURE;
-  }
-
-  std::string uid = "/" + stream + "/" + rem;
-  auto itr = m_uids.find(uid);
-  if (itr != m_uids.end()) {
-    m_log << MSG::ERROR << "already registered an object with identifier \""
-	  << idr << "\"" << endmsg;
-    return StatusCode::FAILURE;
-  }
-
-
-  bool temp = false;
-  if ( !f ) {
-    temp = true;
-    if (m_log.level() <= MSG::DEBUG)
-      m_log << MSG::DEBUG << "Historgram with id \"" << idr << "\" is temporary"
-	    << endmsg;
-  }
-
-
-  TObject *to = nullptr;
-  THistID hid;
-
-  // check to see if this hist is to be read in;
-  if (!temp && m_files.find(stream)->second.second == READ) {
-
-    if (hist != 0) {
-      m_log << MSG::WARNING <<  "Registering id: \"" << idr
-	    << "\" with non zero pointer!" << endmsg;
-    }
-
-    if (readHist_i(idr,hist).isFailure()) {
-      m_log << MSG::ERROR <<  "Unable to read in hist" << endmsg;
-      return StatusCode::FAILURE;
-    }
-    to = dynamic_cast<TObject*>(hist);
-    hid = THistID(uid,temp,to,f,m_files.find(stream)->second.second);
-
-  } else if (hist == 0) {
-    m_log << MSG::ERROR << "Unable to read in hist with id: \""
-	  << idr << "\"" << endmsg;
-    return StatusCode::FAILURE;
-
-  } else {
-
-    to = dynamic_cast<TObject*>(hist);
-    if (to == 0) {
-      m_log << MSG::ERROR << "Could not dcast to TObject. id: \"" << idr
-	    << "\"" << endmsg;
-      return StatusCode::FAILURE;
-    }
-
-    auto oitr = m_tobjs.find(to);
-    if (oitr != m_tobjs.end()) {
-      m_log << MSG::ERROR << "already registered id: \"" << idr
-	    << "\" with identifier \"" << oitr->second.id << "\"" << endmsg;
-      return StatusCode::FAILURE;
-    }
-
-    hid = THistID(uid,temp,to,f,m_files.find(stream)->second.second);
-    TDirectory* dir = changeDir(hid);
-
-    if ( dynamic_cast<TTree*>(hist) ) {
-      dynamic_cast<TTree*>(hist)->SetDirectory(dir);
-    } else if ( dynamic_cast<TH1*>(hist) ) {
-      dynamic_cast<TH1*>(hist)->SetDirectory(dir);
-    } else if ( dynamic_cast<TGraph*>(hist) ) {
-      dir->Append(hist);
-    } else {
-      m_log << MSG::ERROR << "id: \"" << idr
-	    << "\" is not a TH, TTree, or TGraph. Attaching it to current dir."
-	    << endmsg;
-      dir->Append(hist);
-    }
-
-  }
-
-  std::string fname;
-  if ( !f ) {
-    fname = "none";
-  } else {
-    fname = f->GetName();
-  }
-
-  if (m_log.level() <= MSG::DEBUG) 
-    m_log << MSG::DEBUG << "Registering " << System::typeinfoName(typeid(*hist))
-	  << " title: \"" << hist->GetTitle()
-	  << "\"  id: \"" << uid << "\"  dir: "
-      //      << hist->GetDirectory()->GetPath() << "  "
-	  << changeDir(hid)->GetPath()
-	  << "  file: " << fname
-	  << endmsg;
-
-  m_ids.emplace(rem, hid);
-  m_uids[uid] = hid;
-  m_tobjs[to] = hid;
-
-  return StatusCode::SUCCESS;
-
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-template <typename T>
-StatusCode 
-THistSvcHLT::getHist_i(const std::string& id, T*& hist, bool quiet) const {
-  // id starts with "/": unique
-
-  GlobalDirectoryRestore restore;
-
-  std::string idr(id);
-  removeDoubleSlash( idr );
-
-  if (idr.find("/") == 0) {
-    auto itr = m_uids.find(id);
-    if (itr == m_uids.end()) {
-      if (!quiet) {
-	m_log << MSG::ERROR << "Could not locate Hist with id \"" << idr << "\""
-	      << endmsg;
-      }
-      hist = nullptr;
-      return StatusCode::FAILURE;
-    }
-
-    THistID hid = itr->second;
-    if (!quiet) {
-      hist = dynamic_cast<T*>(hid.obj);
-      if ( !hist ) {
-	m_log << MSG::ERROR << "dcast failed, Hist id: \"" << idr << "\"" 
-	      << endmsg;
-	return StatusCode::FAILURE;
-      }
-      if (m_log.level() <= MSG::VERBOSE) {
-	m_log << MSG::VERBOSE << "found unique Hist title: \"" 
-	      << hist->GetTitle()
-	      << "\"  id: \"" << idr << "\"" << endmsg;
-      }
-    } else {
-      if (m_log.level() <= MSG::VERBOSE) {
-	m_log << MSG::VERBOSE << "found unique Hist id: \"" << idr 
-	      << "\" type: \"" << hid.obj->IsA()->GetName() << "\""
-	      << endmsg;
-      }
-    }
-
-    return StatusCode::SUCCESS;
-
-
-    // not necessarily unique
-  } else {
-
-      auto mitr = m_ids.equal_range(idr);
-
-
-    if (mitr.first == mitr.second) {
-      m_log << MSG::ERROR << "Could not locate Hist with id \"" << idr << "\""
-	    << endmsg;
-      hist = nullptr;
-      return StatusCode::FAILURE;
-    } else {
-
-      if (distance(mitr.first,mitr.second) == 1) {
-        THistID hid = mitr.first->second;
-	if (!quiet) {
-	  hist = dynamic_cast<T*>(hid.obj);
-	  if (hist == 0) {
-	    m_log << MSG::ERROR << "dcast failed" << endmsg;
-	    return StatusCode::FAILURE;
-	  }
-	  if (m_log.level() <= MSG::VERBOSE) {
-	    m_log << MSG::VERBOSE << "found Hist title: \"" << hist->GetTitle()
-		  << "\"  id: \"" << idr << "\"" << endmsg;
-	  }
-	} else {
-	  if (m_log.level() <= MSG::VERBOSE) {
-	    m_log << MSG::VERBOSE << "found Hist id: \"" << idr << "\" type: \""
-		  << hid.obj->IsA()->GetName() << "\""
-		  << endmsg;
-	  }
-	}
-        return StatusCode::SUCCESS;
-      } else {
-	if (!quiet) {
-	  // return failure if trying to GET a single hist
-	  m_log << MSG::ERROR << "Multiple matches with id \"" << idr << "\"."
-		<< " Further specifications required."
-		<< endmsg;
-	  hist = nullptr;
-	  return StatusCode::FAILURE;
-	} else {
-	  // return a SUCCESS if just INQUIRING
-	  m_log << MSG::INFO << "Found multiple matches with id \"" << idr 
-	      << "\"" << endmsg;
-	  hist = nullptr;
-	  return StatusCode::SUCCESS;
-	}
-      }
-    }
-  }
-}
-
-//* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *//
-
-template <typename T>
-StatusCode
-THistSvcHLT::readHist_i(const std::string& id, T*& hist) const {
-
-  GlobalDirectoryRestore restore;
-
-  std::string idr(id);
-  removeDoubleSlash( idr );
-
-  std::string stream, rem, dir, fdir, bdir, fdir2;
-  TFile *file;
-
-  if (!findStream(idr, stream, rem, file) ) {
-    return StatusCode::FAILURE;
-  }
-
-  if ( !file ) {
-    m_log << MSG::ERROR << "no associated file found" << endmsg;
-    return StatusCode::FAILURE;
-  }
-
-  file->cd("/");
-
-  fdir = idr;
-  bdir = dirname(fdir);
-  fdir2 = fdir;
-  while ( (dir=dirname(fdir)) != "" ) {
-    if (! gDirectory->GetKey(dir.c_str())) {
-      m_log << MSG::ERROR << "Directory \"" << fdir2 << "\" doesnt exist in "
-	    << file->GetName() << endmsg;
-      return StatusCode::FAILURE;
-    }
-    gDirectory->cd(dir.c_str());
-  }
-
-  TObject *to=nullptr;
-  gDirectory->GetObject(fdir.c_str(), to);
-
-  if ( !to ) {
-    m_log << MSG::ERROR << "Could not get obj \"" << fdir << "\" in "
-	  << gDirectory->GetPath() << endmsg;
-    return StatusCode::FAILURE;
-  }
-
-
-
-  hist = dynamic_cast<T*>(to);
-  if ( !hist ) {
-    m_log << MSG::ERROR << "Could not convert \"" << idr << "\" to a "
-	  << System::typeinfoName(typeid(*hist)) << " as is a "
-	  << to->IsA()->GetName()
-	  << endmsg;
-    return StatusCode::FAILURE;
-  }
-
-
-  if (m_log.level() <= MSG::DEBUG) {
-    m_log << MSG::DEBUG << "Read in " << hist->IsA()->GetName() << "  \""
-	  << hist->GetName() << "\" from file "
-	  << file->GetName() << endmsg;
-    hist->Print();
-  }
-
-  return StatusCode::SUCCESS;
-
-}
-
-#endif
diff --git a/HLT/Trigger/TrigControl/TrigServices/src/TrigMonTHistSvc.cxx.bak b/HLT/Trigger/TrigControl/TrigServices/src/TrigMonTHistSvc.cxx
similarity index 81%
rename from HLT/Trigger/TrigControl/TrigServices/src/TrigMonTHistSvc.cxx.bak
rename to HLT/Trigger/TrigControl/TrigServices/src/TrigMonTHistSvc.cxx
index ad52ec62fcf32f0c462e92a31dfc365694431d5b..18d55195216e4de726513dad35c0860f9898959e 100644
--- a/HLT/Trigger/TrigControl/TrigServices/src/TrigMonTHistSvc.cxx.bak
+++ b/HLT/Trigger/TrigControl/TrigServices/src/TrigMonTHistSvc.cxx
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
 */
 
 
@@ -113,57 +113,59 @@ StatusCode TrigMonTHistSvc::regHist(const std::string& id) {
   return THistSvcHLT::regHist(id);
 }
 
-StatusCode TrigMonTHistSvc::regHist(const std::string& id, TH1* hist) {
-    return regHist_i(hist, id);
-}
 
-StatusCode TrigMonTHistSvc::regHist(const std::string& id, TH2* hist) {
-    return regHist_i(hist, id);
+StatusCode TrigMonTHistSvc::regHist(const std::string& id, std::unique_ptr<TH1> hist) {
+  return regHist_i(std::move(hist), id, false);
 }
 
-StatusCode TrigMonTHistSvc::regHist(const std::string& id, TH3* hist) {
-    return regHist_i(hist, id);
+StatusCode TrigMonTHistSvc::regHist(const std::string& id, std::unique_ptr<TH1> hist, TH1* hist_ptr) {
+  // This is only to support a common use case where the histogram is used after its registration
+  if ( hist_ptr != nullptr ) {
+    hist_ptr = hist.get();
+  }
+  return regHist_i( std::move( hist ), id, false );
+}
+  
+StatusCode TrigMonTHistSvc::regHist(const std::string& id, TH1* hist_ptr) {
+  std::unique_ptr<TH1> hist( hist_ptr );
+  return regHist_i( std::move( hist ), id, false );
 }
 
+
+
 StatusCode TrigMonTHistSvc::regTree(const std::string& id) {
   return THistSvcHLT::regTree(id);
 }
 
-StatusCode TrigMonTHistSvc::regTree(const std::string&, TTree* hist) {
-    // we do not support the trees; then let's make them not to be memory consumers
+StatusCode TrigMonTHistSvc::regTree(const std::string&, std::unique_ptr<TTree> tree) {
+  // we do not support the trees; then let's make them not to be memory consumers
   ATH_MSG_WARNING("The ROOT TTree is not supported by this service" 
-                  << " TTree \"" << hist->GetName() << "\" will be unsaved but will not consume all memory as well" 
+                  << " TTree \"" << tree->GetName() << "\" will be unsaved but will not consume all memory as well" 
                   );
-  hist->SetCircular(1);
+  tree->SetCircular(1);
   return StatusCode::SUCCESS;
 }
 
-StatusCode TrigMonTHistSvc::getHist(const std::string& id, TH1*& hist) const {
-  return THistSvcHLT::getHist(id, hist);  
-}
-
-
-StatusCode TrigMonTHistSvc::getHist(const std::string& id, TH2*& hist) const {
-  return THistSvcHLT::getHist(id, hist);  
-}
-
-
-StatusCode TrigMonTHistSvc::getHist(const std::string& id, TH3*& hist) const {
-  return THistSvcHLT::getHist(id, hist);
+StatusCode TrigMonTHistSvc::regTree(const std::string& id, TTree* tree_ptr) {
+  std::unique_ptr<TTree> tree( tree_ptr );
+  return regTree(id, std::move(tree));
 }
 
-StatusCode TrigMonTHistSvc::getTree(const std::string& id, TTree*& hist) const {
-  return THistSvcHLT::getTree(id, hist);
+StatusCode TrigMonTHistSvc::getTree(const std::string&, TTree*&) const {
+  ATH_MSG_WARNING("The ROOT TTree is not supported by this service");
+  return StatusCode::SUCCESS;
 }
 
 
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-//  Needs proper implementation
-//
 StatusCode TrigMonTHistSvc::regGraph(const std::string& id) {
   return THistSvcHLT::regGraph(id);
 }
 
+StatusCode TrigMonTHistSvc::regGraph(const std::string&, std::unique_ptr<TGraph>) {
+  ATH_MSG_WARNING("The regGraph is not suported by this service");
+  return StatusCode::SUCCESS; 
+}
+
 StatusCode TrigMonTHistSvc::regGraph(const std::string&, TGraph*) {
   ATH_MSG_WARNING("The regGraph is not suported by this service");
   return StatusCode::SUCCESS; 
@@ -174,24 +176,30 @@ StatusCode TrigMonTHistSvc::getGraph(const std::string& id, TGraph*& g) const {
 }
 
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-template <typename T> StatusCode TrigMonTHistSvc::regHist_i(T* hist, const std::string& id) {
+template <typename T> StatusCode TrigMonTHistSvc::regHist_i(std::unique_ptr<T> hist_unique, const std::string& id, bool /*shared*/) {
 
-    std::string regid;
-    if ( isObjectAllowed(id, hist).isFailure() ) {
+  // We need to pass ownership to the hist registry now
+  T* hist = nullptr;
+  if( hist_unique.get() != nullptr ) {
+    hist = hist_unique.release();
+  }
+  
+  std::string regid;
+  if ( isObjectAllowed(id, hist).isFailure() ) {
 	return  StatusCode::FAILURE;
-    }
-    regid = id;
-
-    if (hist->Class()->InheritsFrom(TH1::Class())) {
-        hltinterface::IInfoRegister::instance()->registerTObject(name(), regid, hist);
-        ATH_MSG_DEBUG("Histogram " << hist->GetName() 
-                      << " registered under " << regid << " " << name());
-    } else {
-      ATH_MSG_ERROR("Trying to register " << hist->ClassName() 
-                    << " but this does not inherit from TH1 histogram");
-      return StatusCode::SUCCESS; 
-    }
+  }
+  regid = id;
+  
+  if (hist->Class()->InheritsFrom(TH1::Class())) {
+    hltinterface::IInfoRegister::instance()->registerTObject(name(), regid, hist);
+    ATH_MSG_DEBUG("Histogram " << hist->GetName() 
+                  << " registered under " << regid << " " << name());
+  } else {
+    ATH_MSG_ERROR("Trying to register " << hist->ClassName() 
+                  << " but this does not inherit from TH1 histogram");
     return StatusCode::SUCCESS; 
+  }
+  return StatusCode::SUCCESS; 
 }
 
 StatusCode TrigMonTHistSvc::deReg(TObject* optr) {
@@ -271,7 +279,7 @@ StatusCode TrigMonTHistSvc::getTTrees(const std::string&, TList &) const {
 //  internal methods 
 //==========================================================================
 //
-StatusCode  TrigMonTHistSvc::isObjectAllowed(std::string path, const TObject *o) {
+StatusCode TrigMonTHistSvc::isObjectAllowed(std::string path, const TObject *o) {
 
     boost::cmatch what;
 
@@ -379,3 +387,8 @@ StatusCode TrigMonTHistSvc::getTTrees(const std::string&, TList &, bool, bool) {
 bool TrigMonTHistSvc::exists( const std::string& name ) const {
   return THistSvcHLT::exists(name);
 }
+
+StatusCode TrigMonTHistSvc::notSupported() const {
+  ATH_MSG_WARNING("Shared histograms are not yet supported in TrigMonTHistSvc");
+  return StatusCode::SUCCESS;
+}
diff --git a/HLT/Trigger/TrigControl/TrigServices/src/TrigMonTHistSvc.h.bak b/HLT/Trigger/TrigControl/TrigServices/src/TrigMonTHistSvc.h
similarity index 69%
rename from HLT/Trigger/TrigControl/TrigServices/src/TrigMonTHistSvc.h.bak
rename to HLT/Trigger/TrigControl/TrigServices/src/TrigMonTHistSvc.h
index ea1aa382df8e5ec1fa53b6b261a7a94dd22a5bc1..fe23b7e7c6d2b7f82d4146726fbdd6a6c6d10b1a 100644
--- a/HLT/Trigger/TrigControl/TrigServices/src/TrigMonTHistSvc.h.bak
+++ b/HLT/Trigger/TrigControl/TrigServices/src/TrigMonTHistSvc.h
@@ -1,7 +1,7 @@
 // -*- c++ -*-
 
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef TRIGMONTHISTSVC_THISTSVC_H
@@ -33,9 +33,6 @@ class TTree;
 
 #include <boost/regex.hpp>
 
-// Forward declarations
-template <class TYPE> class SvcFactory;
-
 class TrigMonTHistSvc: virtual public THistSvcHLT,
                        public AthMessaging
 { 
@@ -44,30 +41,27 @@ public:
   // fwd compat w/ gaudi-21
   using AthMessaging::msg;
 
+  TrigMonTHistSvc(const std::string& name, ISvcLocator *svc );
+  virtual ~TrigMonTHistSvc();
+
+  virtual StatusCode queryInterface( const InterfaceID& riid, 
+                                     void** ppvInterface );
+  
   // implemenataion of the interface from TrigNetTHistSvc
   virtual StatusCode initialize();
   virtual StatusCode reinitialize();
   virtual StatusCode finalize();
   
-  // Query the interfaces.
-  virtual StatusCode queryInterface( const InterfaceID& riid, 
-  				     void** ppvInterface );
-  
-
   virtual StatusCode regHist(const std::string& name);
+  virtual StatusCode regHist(const std::string& name, std::unique_ptr<TH1> hist);
+  virtual StatusCode regHist(const std::string& name, std::unique_ptr<TH1> hist, TH1* hist_ptr);
   virtual StatusCode regHist(const std::string& name, TH1*);
-  virtual StatusCode regHist(const std::string& name, TH2*);
-  virtual StatusCode regHist(const std::string& name, TH3*);
-  
-  virtual StatusCode getHist(const std::string& name, TH1*&) const;
-  virtual StatusCode getHist(const std::string& name, TH2*&) const;
-  virtual StatusCode getHist(const std::string& name, TH3*&) const;
 
   virtual StatusCode regTree(const std::string& name);
+  virtual StatusCode regTree(const std::string& name, std::unique_ptr<TTree>);
   virtual StatusCode regTree(const std::string& name, TTree*);
   virtual StatusCode getTree(const std::string& name, TTree*&) const;
 
-  // new since Gaudi 0.16.1.11
   virtual StatusCode deReg(TObject* obj);            //<! very slow
   virtual StatusCode deReg(const std::string& name); //<! use this instead
 
@@ -80,14 +74,19 @@ public:
   virtual StatusCode getTTrees(TDirectory *td, TList &) const;
   virtual StatusCode getTTrees(const std::string& name, TList &) const;
 
-  // new since Gaudi 19
   virtual StatusCode regGraph(const std::string& name);
+  virtual StatusCode regGraph(const std::string& name, std::unique_ptr<TGraph>);
   virtual StatusCode regGraph(const std::string& name, TGraph*);
   virtual StatusCode getGraph(const std::string& name, TGraph*&) const;
 
-  TrigMonTHistSvc(const std::string& name, ISvcLocator *svc );
-
-  // new since Gaudi 20
+  virtual StatusCode regShared( const std::string&, std::unique_ptr<TH1>, LockedHandle<TH1>& ) { return notSupported(); }
+  virtual StatusCode regShared( const std::string&, std::unique_ptr<TH2>, LockedHandle<TH2>& ) { return notSupported(); }
+  virtual StatusCode regShared( const std::string&, std::unique_ptr<TH3>, LockedHandle<TH3>& ) { return notSupported(); }
+  virtual StatusCode regShared( const std::string&, std::unique_ptr<TGraph>, LockedHandle<TGraph>& )  { return notSupported(); }
+  virtual StatusCode getShared( const std::string&, LockedHandle<TH1>& ) const { return notSupported(); }
+  virtual StatusCode getShared( const std::string&, LockedHandle<TH2>& ) const { return notSupported(); }
+  virtual StatusCode getShared( const std::string&, LockedHandle<TH3>& ) const { return notSupported(); }
+  virtual StatusCode getShared( const std::string&, LockedHandle<TGraph>& ) const { return notSupported(); }
 
   virtual StatusCode getTHists(TDirectory *td, TList &,
                                bool recurse=false) const;
@@ -110,15 +109,16 @@ public:
   virtual bool exists(const std::string& name) const;
 
 protected:
-  StatusCode  isObjectAllowed(std::string path, const TObject *o);
+  StatusCode isObjectAllowed(std::string path, const TObject *o);
 
   StatusCode getTHists_i(const std::string& name, TList &) const;
   
-  virtual ~TrigMonTHistSvc();
 
 private:
   template <typename T>
-  StatusCode regHist_i(T* hist, const std::string& name);
+  StatusCode regHist_i(std::unique_ptr<T> hist, const std::string& name, bool shared);
+  StatusCode notSupported() const;
+
   std::string m_excludeType;
   std::string m_includeType;
   std::string m_excludeName;
diff --git a/HLT/Trigger/TrigControl/TrigServices/src/TrigPreFlightCheck.cxx b/HLT/Trigger/TrigControl/TrigServices/src/TrigPreFlightCheck.cxx
deleted file mode 100644
index 2f890c6dd803b0d1c7ff4231784e57ff40ac7b97..0000000000000000000000000000000000000000
--- a/HLT/Trigger/TrigControl/TrigServices/src/TrigPreFlightCheck.cxx
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-*/
-
-/**
- * @file   TrigPreFlightCheck.cxx
- * @brief  Does some generic checks to make sure we can run the HLT
- * @author Frank Winklmeier
- *
- * $Id: TrigPreFlightCheck.cxx 5 2013-05-14 10:33:04Z ricab $
- */
-
-#include "TrigPreFlightCheck.h"
-
-#include <boost/tokenizer.hpp>
-#include <boost/filesystem.hpp>
-
-#include <stdlib.h>
-
-using namespace std;
-namespace fs = boost::filesystem;
-
-//=========================================================================
-// Standard methods
-//=========================================================================
-TrigPreFlightCheck::TrigPreFlightCheck(const std::string &type,
-                           const std::string &name,
-                           const IInterface *parent)
-  : AthAlgTool(type, name, parent)
-{
-  // No abstract interface
-  declareInterface<TrigPreFlightCheck>(this);
-
-  declareProperty("ReleaseDirs",
-                  m_releaseDirs,
-                  "Directories within LD_LIBRARY_PATH to check for existence");  
-}
-
-
-TrigPreFlightCheck::~TrigPreFlightCheck()
-{}
-
-
-StatusCode TrigPreFlightCheck::initialize()
-{
-  return StatusCode::SUCCESS;
-}
-
-StatusCode TrigPreFlightCheck::check(const MSG::Level& errLvl)
-{
-  // Only one check so far
-  return checkRelease(errLvl);
-}
-
-
-StatusCode TrigPreFlightCheck::checkRelease(const MSG::Level& errLvl)
-{
-  const char* ld_lib_path = getenv("LD_LIBRARY_PATH");
-  if ( ld_lib_path==0 ) {
-    msg() << errLvl << "Cannot read LD_LIBRARY_PATH" << endmsg;
-    return StatusCode::FAILURE;
-  }
-  
-  typedef boost::tokenizer<boost::char_separator<char> > Tokenizer;
-  string s(ld_lib_path);
-  Tokenizer tok(s, boost::char_separator<char>(":"));
-
-  // Loop over elements of LD_LIBRARY_PATH
-  for (Tokenizer::iterator it = tok.begin(); it!=tok.end(); ++it) {
-    
-    // Loop over directories to check
-    for (vector<string>::const_iterator dir = m_releaseDirs.begin();
-         dir != m_releaseDirs.end(); ++dir) {
-      
-      if ( it->find(*dir)!=string::npos ) {
-        if ( fs::exists(*it) ) {
-          ATH_MSG_DEBUG("Checking " << (*it) << ": OK");
-        }
-        else {
-          msg() << errLvl << (*it) << " does not exist" << endmsg;
-          return StatusCode::FAILURE;
-        }
-      }
-    }
-  }
-  return StatusCode::SUCCESS;
-}
diff --git a/HLT/Trigger/TrigControl/TrigServices/src/TrigPreFlightCheck.h b/HLT/Trigger/TrigControl/TrigServices/src/TrigPreFlightCheck.h
deleted file mode 100644
index cf4f301d2abf1cf1fa796d717b8dc04e1d2399b9..0000000000000000000000000000000000000000
--- a/HLT/Trigger/TrigControl/TrigServices/src/TrigPreFlightCheck.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
-*/
-
-#ifndef TRIGSERVICES_TRIGPREFLIGHTCHECK_H
-#define TRIGSERVICES_TRIGPREFLIGHTCHECK_H
-/**
- * @file   TrigPreFlightCheck.h
- * @brief  Does some generic checks to make sure we can run the HLT
- * @author Frank Winklmeier
- *
- * $Id: TrigPreFlightCheck.h 5 2013-05-14 10:33:04Z ricab $
- */
-
-// STL includes
-#include <string>
-#include <vector>
-
-// Framework includes
-#include "AthenaBaseComps/AthAlgTool.h"
-#include "GaudiKernel/StatusCode.h"
-
-/**
- * @brief Tool to do some basic checks ensuring the HLT is usable
- *
- * The tool has several checkXYZ() methods each returning a StatusCode for
- * the specific check it is doing. In addition, the check() method performs
- * all the checks and returns the logical AND of the individual checks.
- */
-class TrigPreFlightCheck : public AthAlgTool {
-
-public:
-
-  TrigPreFlightCheck(const std::string &type, const std::string &name, const IInterface *parent);    
-  virtual ~TrigPreFlightCheck();
-
-  static const InterfaceID& interfaceID();  
-  virtual StatusCode initialize();
-  
-  /**
-   * @brief Check whether the relase is installed properly
-   *
-   * @param  errLvl   Message level used for failure messages
-   * @return SUCCESS  Release properly installed
-   *         FAILURE  Some parts of the release is missing
-   */
-  StatusCode checkRelease(const MSG::Level& errLvl);
-
-  /**
-   * @brief Perform all checks
-   *
-   * @param  errLvl   Message level used for failure messages
-   * @return SUCCESS  All checks OK
-   *         FAILURE  At least one check failed
-   */
-  StatusCode check(const MSG::Level& errLvl);
-
-private:
-  /** Directories to check for existence in checkRelease() */
-  std::vector<std::string> m_releaseDirs;
-};
-
-
-inline const InterfaceID& TrigPreFlightCheck::interfaceID()
-{
-  static const InterfaceID IID("TrigPreFlightCheck", 1, 0);
-  return IID;
-}
-
-#endif
diff --git a/HLT/Trigger/TrigControl/TrigServices/src/components/TrigServices_entries.cxx b/HLT/Trigger/TrigControl/TrigServices/src/components/TrigServices_entries.cxx
index 50cf70610717330d35d53b910828e939123167b3..a1845cfcb1fce4bb6a81d0a34f558b2956f3103e 100644
--- a/HLT/Trigger/TrigControl/TrigServices/src/components/TrigServices_entries.cxx
+++ b/HLT/Trigger/TrigControl/TrigServices/src/components/TrigServices_entries.cxx
@@ -1,18 +1,16 @@
 #include "TrigServices/TrigMessageSvc.h"
-//#include "../TrigMonTHistSvc.h"
+#include "../TrigMonTHistSvc.h"
 #include "TrigServices/HltEventLoopMgr.h"
 #include "TrigServices/HltROBDataProviderSvc.h"
 #include "TrigServices/TrigIS.h"
 #include "TrigServices/TrigISHelper.h"
-#include "../TrigPreFlightCheck.h"
 #include "../TrigCOOLUpdateHelper.h"
 
 DECLARE_COMPONENT( TrigMessageSvc )
-//DECLARE_COMPONENT( TrigMonTHistSvc )
+DECLARE_COMPONENT( TrigMonTHistSvc )
 DECLARE_COMPONENT( TrigIS )
 DECLARE_COMPONENT( HltEventLoopMgr )
 DECLARE_COMPONENT( HltROBDataProviderSvc )
 DECLARE_COMPONENT( TrigISHelper )
-DECLARE_COMPONENT( TrigPreFlightCheck )
 DECLARE_COMPONENT( TrigCOOLUpdateHelper )