diff --git a/Control/AthenaMonitoring/python/TriggerInterface.py b/Control/AthenaMonitoring/python/TriggerInterface.py
index 85dc5d66cbb99121bfd7af73717e189ad2de9cd5..c2ba59e6872fc42bc11a469d199ff5e4aad4c1ff 100644
--- a/Control/AthenaMonitoring/python/TriggerInterface.py
+++ b/Control/AthenaMonitoring/python/TriggerInterface.py
@@ -8,57 +8,6 @@
 @brief Simple new configuration framework functions for getting a TrigDecisionTool. Probably do not work except for reading ESD and AOD. Will be superseded by proper code from Trigger.
 '''
 
-def getTrigConfigSvc(flags):
-    ''' Setup a TrigConfigSvc with DS information. Works on AOD, not vetted for anything else! '''
-    from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
-    from TrigConfigSvc.TrigConfigSvcConfig import DSConfigSvc, SetupTrigConfigSvc
-    from IOVDbSvc.IOVDbSvcConfig import addFolders
-    from EventInfoMgt.TagInfoMgrConfig import TagInfoMgrCfg
-
-    rv = ComponentAccumulator()
-    # is MC ? then set up XML reading and get out of here
-    if flags.Input.isMC:
-        from TrigConfigSvc.TrigConfigSvcConfig import (HLTConfigSvc, LVL1ConfigSvc, L1TopoConfigSvc, 
-                                                       findFileInXMLPATH, TrigConfigSvc)
-        hltcs = HLTConfigSvc("HLTConfigSvc")
-        hltcs.XMLMenuFile = findFileInXMLPATH(flags.Trigger.HLTConfigFile)
-        rv.addService(hltcs)
-        lvl1cs = LVL1ConfigSvc("LVL1ConfigSvc")
-        # Configures here via "newJO" but XMLs not generated for this menu name
-        lvl1XML = flags.Trigger.LVL1ConfigFile.replace('newJO_', '')
-        lvl1cs.XMLMenuFile = findFileInXMLPATH(lvl1XML)
-        rv.addService(lvl1cs)
-        l1topocs = L1TopoConfigSvc()
-        l1topocs.XMLMenuFile = findFileInXMLPATH(flags.Trigger.LVL1TopoConfigFile)
-        rv.addService(l1topocs)
-        ts = TrigConfigSvc("TrigConfigSvc")
-        # run3_dummy - temporary - until we have a proper HLT configuration source for the Run 3 trigger
-        ts.PriorityList = ["run3_dummy", 'xml']
-        rv.addService(ts)
-        return rv
-    rv.addService(DSConfigSvc('DSConfigSvc'))
-    tcs = SetupTrigConfigSvc()
-    # run3_dummy - temporary - until we have a proper HLT configuration source for the Run 3 trigger
-    tcs.SetStates(["run3_dummy", "ds"])
-    tcssvc = tcs.GetConfigurable()
-    rv.addService(tcssvc)
-
-    rv.merge(addFolders(flags, ['/TRIGGER/HLT/Menu',
-                                     '/TRIGGER/HLT/HltConfigKeys',
-                                     '/TRIGGER/LVL1/Lvl1ConfigKey',
-                                     '/TRIGGER/LVL1/Menu',
-                                     '/TRIGGER/LVL1/Prescales',
-                                     '/TRIGGER/LVL1/BunchGroupKey',
-                                     '/TRIGGER/LVL1/BunchGroupDescription',
-                                     '/TRIGGER/LVL1/BunchGroupContent',
-                                     '/TRIGGER/HLT/Prescales',
-                                     '/TRIGGER/HLT/PrescaleKey',
-                                     '/TRIGGER/LVL1/ItemDef'],
-                        'TRIGGER', tag='HEAD'))
-    
-    # the following should probably be set up by IOVDbSvc configuration?
-    rv.merge(TagInfoMgrCfg(flags)[0])
-    return rv
 
 def getTrigDecisionTool(flags):
     ''' Setup a TrigDecisionTool. Short-cuts deduplication with memoization.'''
@@ -66,6 +15,9 @@ def getTrigDecisionTool(flags):
         return getTrigDecisionTool.rv
     from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
     from TrigDecisionTool.TrigDecisionToolConf import Trig__TrigDecisionTool
+    from TrigConfxAOD.TrigConfxAODConf import TrigConf__xAODConfigTool
+
+
  
     rv = ComponentAccumulator()
 
@@ -74,18 +26,23 @@ def getTrigDecisionTool(flags):
         rv.addPublicTool(ToolSvc.TrigDecisionTool)
         getTrigDecisionTool.rv = rv
         return getTrigDecisionTool.rv
-
-    rv.merge(getTrigConfigSvc(flags))
     
-    tdt = Trig__TrigDecisionTool('TrigDecisionTool', TrigConfigSvc=rv.getService('TrigConfigSvc'))
+    tdt = Trig__TrigDecisionTool('TrigDecisionTool')
     from TrigEDMConfig.TriggerEDM import EDMLibraries
     tdt.Navigation.Dlls = [e for e in  EDMLibraries if 'TPCnv' not in e]
     
     # Other valid option "TriggerElement" for Run 2 navigation. 
     # This option to be removed and "TrigComposite" the only valid choice once a R2->R3 converter is put in place. 
     tdt.NavigationFormat = "TrigComposite"
+    tdt.OutputLevel = 1
+    print("TIMM")
+
+    cfgtool = TrigConf__xAODConfigTool('xAODConfigTool')
+    cfgtool.OutputLevel = 1
 
     rv.addPublicTool(tdt)
+    rv.addPublicTool(cfgtool)
+
     getTrigDecisionTool.rv = rv
     return rv
 getTrigDecisionTool.rv = None
diff --git a/HLT/Trigger/TrigControl/TrigExamples/TrigExPartialEB/python/MTCalibPebConfig.py b/HLT/Trigger/TrigControl/TrigExamples/TrigExPartialEB/python/MTCalibPebConfig.py
index 36d71f6d77fcdcd8e36561bcbbde0a77babbbecd..99ebd98f0120d6637dc4a81508400633ca0d6ade 100644
--- a/HLT/Trigger/TrigControl/TrigExamples/TrigExPartialEB/python/MTCalibPebConfig.py
+++ b/HLT/Trigger/TrigControl/TrigExamples/TrigExPartialEB/python/MTCalibPebConfig.py
@@ -231,7 +231,6 @@ def configure_hlt_result(hypo_algs):
     # Tool adding HLT bits to HLT result
     bitsmaker = TriggerBitsMakerTool()
     bitsmaker.ChainDecisions = 'HLTNav_Summary'
-    bitsmaker.HLTmenuFile = menu_json
 
     # Configure the HLT result maker to use the above tools
     from AthenaCommon.AppMgr import ServiceMgr as svcMgr
diff --git a/PhysicsAnalysis/PATJobTransforms/share/skeleton.PhysicsValidation_tf.py b/PhysicsAnalysis/PATJobTransforms/share/skeleton.PhysicsValidation_tf.py
index 805bd9872fe5cd7bd8fc43a6e0ecf97c3323ddfa..7c1b0dd8c6d60c630036379a5aad192a94fea4c6 100644
--- a/PhysicsAnalysis/PATJobTransforms/share/skeleton.PhysicsValidation_tf.py
+++ b/PhysicsAnalysis/PATJobTransforms/share/skeleton.PhysicsValidation_tf.py
@@ -150,12 +150,5 @@ if hasattr(runArgs,"postExec"):
 
 # Temporary (July 19) trigger additions
 if TriggerFlags.doMT() or TriggerFlags.EDMDecodingVersion() == 3:
-  ToolSvc.TrigDecisionTool.NavigationFormat="TrigComposite";
-  ToolSvc.TrigDecisionTool.TrigConfigSvc="Trig::TrigConfigSvc/TrigConfigSvc";
-  ServiceMgr.TrigConfigSvc.PriorityList=["run3_dummy", "xml"]
-  from TrigConfigSvc.TrigConfigSvcConfig import (findFileInXMLPATH,  LVL1ConfigSvc, L1TopoConfigSvc)
-  from AthenaConfiguration.AllConfigFlags import ConfigFlags
-  ServiceMgr += LVL1ConfigSvc("LVL1ConfigSvc")
-  ServiceMgr += L1TopoConfigSvc()
-  ServiceMgr.LVL1ConfigSvc.XMLMenuFile = findFileInXMLPATH(ConfigFlags.Trigger.LVL1ConfigFile.replace('newJO_', ''))
-  ServiceMgr.L1TopoConfigSvc.XMLMenuFile = findFileInXMLPATH(ConfigFlags.Trigger.LVL1TopoConfigFile)
\ No newline at end of file
+  if hasattr(ToolSvc, 'TrigDecisionTool'):
+    ToolSvc.TrigDecisionTool.NavigationFormat="TrigComposite"
diff --git a/Reconstruction/RecJobTransforms/share/skeleton.RDOtoRDOtrigger.py b/Reconstruction/RecJobTransforms/share/skeleton.RDOtoRDOtrigger.py
index 5c5134ebc38c702599dc8dc5d95e4d962d4642ab..f7940849d2437ce115923a44779b5f6e8f1871f8 100644
--- a/Reconstruction/RecJobTransforms/share/skeleton.RDOtoRDOtrigger.py
+++ b/Reconstruction/RecJobTransforms/share/skeleton.RDOtoRDOtrigger.py
@@ -134,6 +134,11 @@ if TriggerFlags.doMT():
     svcMgr.HLTConfigSvc.InputType = "file"
     svcMgr.HLTConfigSvc.JsonFileName = hltJsonFile
     recoLog.info("Configured HLTConfigSvc with InputType='file' and JsonFileName=%s" % hltJsonFile)
+    # We reverse the priority list here such that the HLTConfigSvc is used, rather than the DSConfigSvc
+    if not hasattr(svcMgr, 'TrigConfigSvc'):
+        from TrigConfigSvc.TrigConfigSvcConfig import TrigConfigSvc
+        ServiceMgr += TrigConfigSvc("TrigConfigSvc")
+    ServiceMgr.TrigConfigSvc.PriorityList = ["xml", "ds"]
 
     from L1Decoder.L1DecoderConfig import L1Decoder
     topSequence += L1Decoder()
@@ -148,6 +153,24 @@ if TriggerFlags.doMT():
     l1Decoder.ExtraInputs += [fakeTypeKey]
     l1Decoder.ctpUnpacker.ForceEnableAllChains=False # this will make HLT respecting L1 chain decisions
 
+    # Configure a stripped-down HLT Results Maker in order to generate the HLT trigger bits.
+    # Note: The HLTResultMT object is transient only here. It is used to fill the xAOD::TriggerDecision
+    # This ensures that trigger bits follow the same path online & in MC
+    from TrigOutputHandling.TrigOutputHandlingConf import HLTResultMTMakerAlg, TriggerBitsMakerTool
+    from TrigOutputHandling.TrigOutputHandlingConfig import HLTResultMTMakerCfg
+    bitsmakerTool                 = TriggerBitsMakerTool()
+    bitsmakerTool.OutputLevel = VERBOSE
+    #TIMM
+    hltResultMakerTool            = HLTResultMTMakerCfg("MakerTool")
+    hltResultMakerTool.MakerTools = [ bitsmakerTool ]
+    hltResultMakerAlg             = HLTResultMTMakerAlg()
+    hltResultMakerAlg.ResultMaker = hltResultMakerTool
+    topSequence += hltResultMakerAlg
+
+    # TIMM
+    ServiceMgr.MessageSvc.defaultLimit = 0
+    ServiceMgr.MessageSvc.enableSuppression = False
+
     from AthenaCommon.Configurable import Configurable
     Configurable.configurableRun3Behavior=True
     from TriggerJobOpts.TriggerConfig import triggerIDCCacheCreatorsCfg
@@ -236,19 +259,19 @@ for i in outSequence.getAllChildren():
 
     if "StreamRDO" in i.getName() and TriggerFlags.doMT():
 
+        ### Produce the trigger bits:
         from TrigDecisionMaker.TrigDecisionMakerConfig import TrigDecisionMakerMT
-        topSequence += TrigDecisionMakerMT('TrigDecMakerMT') # Replaces TrigDecMaker and finally deprecates Run 1 EDM
-        from AthenaCommon.Logging import logging
-        log = logging.getLogger( 'WriteTrigDecisionToAOD' )
-        log.info('TrigDecision writing enabled')
-
-        # Note: xAODMaker__TrigDecisionCnvAlg no longer needed. TrigDecisionMakerMT goes straight to xAOD
-        # Note: xAODMaker__TrigNavigationCnvAlg no longer needed. MT navigation is natively xAOD 
-        
-        # *** June 2019 TEMPORARY *** for use with TrigDecMakerMT until a proper config svc is available
-        from TrigConfigSvc.TrigConfigSvcConfig import TrigConfigSvc
-        ServiceMgr += TrigConfigSvc("TrigConfigSvc")
-        ServiceMgr.TrigConfigSvc.PriorityList = ["run3_dummy", "ds", "xml"]
+        tdm = TrigDecisionMakerMT('TrigDecMakerMT') # Replaces TrigDecMaker and finally deprecates Run 1 EDM
+        tdm.OutputLevel = VERBOSE         #  TIMM
+        topSequence += tdm
+        log.info('xTrigDecision writing enabled')
+
+        ### Produce the metadata:
+        from TrigConfxAOD.TrigConfxAODConf import TrigConf__xAODMenuWriterMT
+        md = TrigConf__xAODMenuWriterMT()
+        md.OutputLevel = VERBOSE # TIMM
+        topSequence += md
+        log.info('TriggerMenu Metadata writing enabled')
 
         # Still need to produce Run-2 style L1 xAOD output
         topSequence += RoIBResultToAOD("RoIBResultToxAOD")
@@ -273,15 +296,15 @@ for i in outSequence.getAllChildren():
         StreamRDO.MetadataItemList +=  [ "xAOD::TriggerMenuContainer#*", "xAOD::TriggerMenuAuxContainer#*" ]
 
 from AthenaCommon.AppMgr import ServiceMgr, ToolSvc
-from TrigDecisionTool.TrigDecisionToolConf import *
+
 
 if hasattr(ToolSvc, 'TrigDecisionTool'):
     if TriggerFlags.doMT():
-        ToolSvc.TrigDecisionTool.NavigationFormat = "TrigComposite"
-        # To pick up hacked config svc
-        ToolSvc.TrigDecisionTool.TrigConfigSvc = "Trig::TrigConfigSvc/TrigConfigSvc"
+        # No functional TDT in MT in RDOtoRDOTrigger
+        pass
     else:
     	# Causes TDT to use Run-1 style behaviour in this part of the transform
+        from TrigDecisionTool.TrigDecisionToolConf import *
         ToolSvc.TrigDecisionTool.TrigDecisionKey = "TrigDecision"
         ToolSvc.TrigDecisionTool.UseAODDecision = True
 
diff --git a/Trigger/TrigAnalysis/TrigDecisionTool/Root/TrigDecisionTool.cxx b/Trigger/TrigAnalysis/TrigDecisionTool/Root/TrigDecisionTool.cxx
index 140e78922e4c05e67151496dd4bb35a7a95ad446..2e755b1b36e01df6d0a17aaa032f04af8b6b0756 100644
--- a/Trigger/TrigAnalysis/TrigDecisionTool/Root/TrigDecisionTool.cxx
+++ b/Trigger/TrigAnalysis/TrigDecisionTool/Root/TrigDecisionTool.cxx
@@ -145,11 +145,12 @@ Trig::TrigDecisionTool::initialize() {
      }
    }
 
-
-   StatusCode sc = m_fullNavigation.retrieve();
-   if ( sc.isFailure() ) {
-     ATH_MSG_FATAL( "Unable to get Navigation tool");
-     return sc;
+   if (m_navigationFormat == "TriggerElement") {
+     StatusCode sc = m_fullNavigation.retrieve();
+     if ( sc.isFailure() ) {
+       ATH_MSG_FATAL( "Unable to get Navigation tool");
+       return sc;
+     }
    }
 #else
    ATH_CHECK(m_configTool.retrieve());
diff --git a/Trigger/TrigConfiguration/TrigConfData/src/HLTChain.cxx b/Trigger/TrigConfiguration/TrigConfData/src/HLTChain.cxx
index fc0956fcebda0e12b504587e48013fac46d3fc53..95ee01d5a01b410ffe4749d83f6c1f6c89ca085f 100644
--- a/Trigger/TrigConfiguration/TrigConfData/src/HLTChain.cxx
+++ b/Trigger/TrigConfiguration/TrigConfData/src/HLTChain.cxx
@@ -28,7 +28,7 @@ TrigConf::Chain::counter() const
 }
 
 unsigned int
-TrigConf::HLTChain::namehash() const
+TrigConf::Chain::namehash() const
 {
    return data().get_child("nameHash").get_value<unsigned int>();
 }
diff --git a/Trigger/TrigConfiguration/TrigConfigSvc/python/TrigConfigSvcConfig.py b/Trigger/TrigConfiguration/TrigConfigSvc/python/TrigConfigSvcConfig.py
index 64251b60ff0a6f2c6a6e1c6240d9c83ab7be12f5..2d11c1b4090a88ee42238dc681bf82fa2ebaadce 100755
--- a/Trigger/TrigConfiguration/TrigConfigSvc/python/TrigConfigSvcConfig.py
+++ b/Trigger/TrigConfiguration/TrigConfigSvc/python/TrigConfigSvcConfig.py
@@ -301,10 +301,9 @@ class SetupTrigConfigSvc(object):
             """
             state == xml -> read the trigger configuration from 2 xml files, one for L1, one for HLT
             stats == ds  -> read the trigger configuration from the detector store = esd header
-            state == run3_dummy -> use a hard-coded list of HLT chains until the HLT JSON is ready
             """
             self.states = ["xml"]
-            self.allowedStates = set(['run3_dummy','xml','ds'])
+            self.allowedStates = set(['xml','ds'])
             self.initialised = False
 
             from AthenaCommon.Logging import logging
diff --git a/Trigger/TrigConfiguration/TrigConfigSvc/src/ConfigSvcBase.cxx b/Trigger/TrigConfiguration/TrigConfigSvc/src/ConfigSvcBase.cxx
index 964563b2b71e9b69076ae09ab511a4c10f5518a5..4ed2b71a61b0c12544b1f9468996961cc107b782 100644
--- a/Trigger/TrigConfiguration/TrigConfigSvc/src/ConfigSvcBase.cxx
+++ b/Trigger/TrigConfiguration/TrigConfigSvc/src/ConfigSvcBase.cxx
@@ -27,7 +27,7 @@ ConfigSvcBase::~ConfigSvcBase()
 void
 ConfigSvcBase::declareCommonProperties() {
    declareProperty( "ConfigSource",     m_configSourceString,
-                    "Source of trigger configuration; can be \"XML\", \"MySQL\", \"Oracle\", \"DBLookup\" or \"RUN3_DUMMY\" ");
+                    "Source of trigger configuration; can be \"XML\", \"MySQL\", \"Oracle\", \"DBLookup\"");
    declareProperty( "XMLMenuFile",      m_xmlFile,
                     "XML file containing the trigger configuration.");
    declareProperty( "DBServer",         m_dbServer,
@@ -60,9 +60,7 @@ ConfigSvcBase::initialize() {
 
    string s(boost::to_lower_copy(m_configSourceString)); // lower case
 
-  if (s == "run3_dummy") {
-      ATH_MSG_WARNING("Configured to use Run-3 Dummy menu. This should never be seen in production");
-   } else if(s != "xml") {
+   if(s != "xml") {
       TrigDBConnectionConfig::DBType dbtype(TrigDBConnectionConfig::DBLookup);
       if (s == "oracle") { dbtype = TrigDBConnectionConfig::Oracle; }
       else if (s == "mysql")  { dbtype = TrigDBConnectionConfig::MySQL; }
diff --git a/Trigger/TrigConfiguration/TrigConfigSvc/src/HLTConfigSvc.cxx b/Trigger/TrigConfiguration/TrigConfigSvc/src/HLTConfigSvc.cxx
index ecb480b7b64622c0fb440903f56bdb78a3b1cb0e..d95e738d9dd7b98e3d10e804a1b962e798a0245c 100644
--- a/Trigger/TrigConfiguration/TrigConfigSvc/src/HLTConfigSvc.cxx
+++ b/Trigger/TrigConfiguration/TrigConfigSvc/src/HLTConfigSvc.cxx
@@ -153,135 +153,7 @@ HLTConfigSvc::initialize() {
           ATH_MSG_INFO( "This previous WARNING message is being ignored in the current transition phase. Once we rely entirely on the new menu providing mechanism, this will become a reason to abort.");
    }
 
-   //////////////////////////////////////////////////////////////
-   // BEGIN RUN-3 TESTING BLOCK - THIS SHOULD BE TEMPORARY
-   //////////////////////////////////////////////////////////////
-   string s(boost::to_lower_copy(m_configSourceString)); // lower case
-   if (s == "run3_dummy") {
-      std::map<std::string, std::string> dummyChains;
-      dummyChains["HLT_e3_etcut1step_L1EM3"] = "L1_EM3";
-      dummyChains["HLT_e3_etcut_L1EM3"] = "L1_EM3";
-      dummyChains["HLT_e3_etcut_mu6_L1EM8I_MU10"] = "L1_EM8I_MU10";
-      dummyChains["HLT_e5_etcut_L1EM3"] = "L1_EM3";
-      dummyChains["HLT_e7_etcut_L1EM3"] = "L1_EM3";
-      dummyChains["HLT_g5_etcut_L1EM3"] = "L1_EM3";
-      dummyChains["HLT_g5_etcut_LArPEB_L1EM3"] = "L1_EM3";
-      dummyChains["HLT_g20_etcut_LArPEB_L1EM15"] = "L1_EM15";
-      dummyChains["HLT_g10_etcut_L1EM7"] = "L1_EM7";
-      dummyChains["HLT_g15_etcut_L1EM12"] = "L1_EM12";
-      dummyChains["HLT_mu6_L1MU6"] = "L1_MU6";
-      dummyChains["HLT_mu6Comb_L1MU6"] = "L1_MU6";
-      dummyChains["HLT_2mu6Comb_L1MU6"] = "L1_MU6";
-      dummyChains["HLT_mu8_L1MU6"] = "L1_MU6";
-      dummyChains["HLT_mu10_L1MU10"] = "L1_MU10";
-      dummyChains["HLT_mu20_L1MU20"] = "L1_MU20";
-      dummyChains["HLT_j85_L1J20"] = "L1_J20";
-      dummyChains["HLT_j100_L1J20"] = "L1_J20";
-      // from egamma test
-      dummyChains["HLT_2e17_etcut_L12EM15VH"] = "L1_2EM15VH";
-      dummyChains["HLT_2e3_etcut"] = "L1_2EM3";
-      dummyChains["HLT_2e3_etcut_L12EM3"] = "L1_2EM3";
-      dummyChains["HLT_2g35_etcut_L12EM20VH"] = "L1_2EM20VH";
-      dummyChains["HLT_e26_etcut_L1EM22VHI"] = "L1_EM22VHI";
-      dummyChains["HLT_e3_e5_etcut"] = "L1_2EM3";
-      dummyChains["HLT_e3_etcut"] = "L1_EM3";
-      dummyChains["HLT_e3_etcut_L1EM3"] = "L1_EM3";
-      dummyChains["HLT_e5_etcut"] = "L1_EM3";
-      dummyChains["HLT_e5_etcut_L1EM3"] = "L1_EM3";
-      dummyChains["HLT_e7_etcut"] = "L1_EM7";
-      dummyChains["HLT_e7_etcut_L1EM3"] = "L1_EM3";
-      dummyChains["HLT_g140_etcut_L1EM24VHI"] = "L1_EM24VHI";
-      dummyChains["HLT_g5_etcut_L1EM3"] = "L1_EM3";
-      // for menu test
-      dummyChains["HLT_2j330_a10t_lcw_jes_35smcINF_L1J100"] = "L1_J100";
-      dummyChains["HLT_j460_a10t_lcw_jes_30smcINF_L1J100"] = "L1_J100";
-      dummyChains["HLT_mu26_ivarmedium_L1MU20"] = "L1_MU20";
-      dummyChains["HLT_mu50_L1MU20"] = "L1_MU20";
-      dummyChains["HLT_mu50_RPCPEBSecondaryReadout_L1MU20"] = "L1_MU20";
-      dummyChains["HLT_2mu14_L12MU10"] = "L1_2MU10";
-      dummyChains["HLT_j420_L1J100"] = "L1_J100";
-      dummyChains["HLT_j260_320eta490_L1J75_31ETA49"] = "L1_J75.31ETA49";
-      dummyChains["HLT_j460_a10r_L1J100"] = "L1_J100";
-      dummyChains["HLT_j460_a10_lcw_subjes_L1J100"] = "L1_J100";
-      dummyChains["HLT_j460_a10t_lcw_jes_L1J100"] = "L1_J100";
-      dummyChains["HLT_3j200_L1J100"] = "L1_J100";
-      dummyChains["HLT_tau160_mediumRNN_tracktwoMVA_L1TAU100"] = "L1_TAU100";
-      dummyChains["HLT_2mu4_bBmumu_L12MU4"] = "L1_2MU4";
-      dummyChains["HLT_2mu4_bDimu_L12MU4"] = "L1_2MU4";
-      dummyChains["HLT_2mu4_bJpsimumu_L12MU4"] = "L1_2MU4";
-      dummyChains["HLT_2mu4_bUpsimumu_L12MU4"] = "L1_2MU4";
-      dummyChains["HLT_2mu6_L12MU6"] = "L1_2MU6";
-      dummyChains["HLT_2mu6Comb_L12MU6"] = "L1_2MU6";
-      dummyChains["HLT_2mu6_bJpsimumu_L12MU6"] = "L1_2MU6";
-      dummyChains["HLT_2mu6_10invm70_L1MU6"] = "L1_2MU6";
-      dummyChains["HLT_3j200_L1J20"] = "L1_J20";
-      dummyChains["HLT_5j70_0eta240_L14J20"] = "L1_4J20";
-      dummyChains["HLT_e3_etcut1step_mu6fast_L1EM8I_MU10"] = "L1_EM8I_MU10";
-      dummyChains["HLT_e3_etcut_mu6"] = "L1_EM8I_MU10";
-      dummyChains["HLT_g5_etcut"] = "L1_EM3";
-      dummyChains["HLT_j0_vbenfSEP30etSEP34mass35SEP50fbet_L1J20"] = "L1_L1J20";
-      dummyChains["HLT_j225_gsc420_boffperf_split20"] = "L1_J100";
-      dummyChains["HLT_j260_320eta490_L1J20"] = "L1_J20";
-      dummyChains["HLT_j420_L1J20"] = "L1_J20";
-      dummyChains["HLT_j45_L1J15"] = "L1_J15";
-      dummyChains["HLT_j460_a10_lcw_subjes_L1J20"] = "L1_J20";
-      dummyChains["HLT_j460_a10r_L1J20"] = "L1_J20";
-      dummyChains["HLT_mu20_ivar_L1MU6"] = "L1_MU6";
-      dummyChains["HLT_mu6"] = "L1_MU6";
-      dummyChains["HLT_mu6_ivarmedium_L1MU6"] = "L1_MU6";
-      dummyChains["HLT_mu6Comb"] = "L1_MU6";
-      dummyChains["HLT_mu6fast_L1MU6"] = "L1_MU6";
-      dummyChains["HLT_mu6_msonly_L1MU6"] = "L1_MU6";
-      dummyChains["HLT_mu6noL1_L1MU6"] = "L1_MU6";
-      dummyChains["HLT_mu6_mu4_L12MU4"] = "L1_2MU4";
-      dummyChains["HLT_mu80_msonly_3layersEC_L1MU20"] = "L1_MU20";
-      dummyChains["HLT_xe30_cell_L1XE10"] = "L1_XE10";
-      dummyChains["HLT_xe30_tcpufit_L1XE10"] = "L1_XE10";
-      dummyChains["HLT_xe65_cell_L1XE50"] = "L1_XE510";
-      dummyChains["HLT_xe65_cell_L1XE50"] = "L1_XE510";
-      dummyChains["HLT_tau0_perf_ptonly_L1TAU12"] = "L1_TAU12";
-      dummyChains["HLT_tau25_medium1_tracktwo_L1TAU12IM"] = "L1_TAU12IM";
-      dummyChains["HLT_tau35_mediumRNN_tracktwoMVA_L1TAU12IM"] = "L1_TAU12IM";
-      dummyChains["HLT_j35_gsc45_boffperf_split_L1J20"] = "L1_J20";
-      dummyChains["HLT_j35_gsc45_bmv2c1070_split_L1J20"] = "L1_J20";
-      dummyChains["HLT_xe30_cell_xe30_tcpufit_L1XE10"] = "L1_XE10";
-      dummyChains["HLT_xe30_mht_L1XE10"] = "L1_XE10";
-      dummyChains["HLT_mu60_0eta105_msonly_L1MU20"] = "L1_MU20";
-      dummyChains["HLT_3mu6_L13MU6"] = "L1_3MU6";
-      dummyChains["HLT_3mu6_msonly_L13MU6"] = "L1_3MU6";
-      dummyChains["HLT_4mu4_L14MU4"] = "L1_4MU4";
-      dummyChains["HLT_j175_gsc225_bmv2c1040_split_L1J100"] = "L1_J100";
-      dummyChains["HLT_j225_gsc275_bmv2c1060_split_L1J100"] = "L1_J100";
-      dummyChains["HLT_j225_gsc300_bmv2c1070_split_L1J100"] = "L1_J100";
-      dummyChains["HLT_j225_gsc360_bmv2c1077_split_L1J100"] = "L1_J100";
-      dummyChains["HLT_tau160_mediumRNN_tracktwoMVA_L1TAU100"] = "L1_TAU100";
-      dummyChains["HLT_2mu10_bJpsimumu_L12MU10"] = "L1_2MU10";
-      dummyChains["HLT_2mu10_bUpsimumu_L12MU10"] = "L1_2MU10";
-      // ATR-19985
-      dummyChains["HLT_mu6_idperf_L1MU6"] = "L1_MU6";
-      dummyChains["HLT_mu24_idperf_L1MU20"] = "L1_MU20";
-      dummyChains["HLT_tau25_idperf_tracktwo_L1TAU12IM"] = "L1_TAU12IM";
-      dummyChains["HLT_tau25_idperf_tracktwoEF_L1TAU12IM"] = "L1_TAU12IM";
-      dummyChains["HLT_tau25_idperf_tracktwoMVA_L1TAU12IM"] = "L1_TAU12IM";
-
-      m_HLTFrame.setMergedHLT( m_setMergedHLT );
-      for (const auto& mapPair : dummyChains) {
-         const std::string& chainName = mapPair.first;
-         const std::string& chainSeed = mapPair.second;
-         const int chainCounter = std::distance(dummyChains.begin(), dummyChains.find(chainName));
-         HLTChain* chain = new HLTChain( chainName, chainCounter, 1, "HLT", chainSeed, 0, vector<HLTSignature*>() );
-         // Note: the ownership of chain is transfered to the frame, the frame will delete it on deconstruct.
-         m_HLTFrame.theHLTChainList().addHLTChain( chain );
-         ATH_MSG_INFO(" RUN 3 TESTING MODE! Adding dummy chain with hash:" << chain->chain_hash_id() << " : " << chainName << " [" << chainCounter << "] <- " << chainSeed); 
-      }
-      ATH_MSG_INFO(" RUN 3 TESTING MODE! Total number of chains: " << m_HLTFrame.chains().size()); 
-
-      return StatusCode::SUCCESS;
-
-   //////////////////////////////////////////////////////////////
-   // END RUN-3 TESTING BLOCK - THIS SHOULD BE TEMPORARY
-   //////////////////////////////////////////////////////////////
-   } else if( !fromDB() and m_xmlFile=="NONE" ) {
+   if( !fromDB() and m_xmlFile=="NONE" ) {
       ATH_MSG_INFO("xml file set to NONE, will not load HLT Menu");
       return StatusCode::SUCCESS;
    }
diff --git a/Trigger/TrigConfiguration/TrigConfigSvc/src/TrigConfigSvc.cxx b/Trigger/TrigConfiguration/TrigConfigSvc/src/TrigConfigSvc.cxx
index d7cc5c27f6e3d6b1abf0259cc6cda1b1e3ffccd2..a12ff25f82acc203a22a996e703f7a73f18908dc 100644
--- a/Trigger/TrigConfiguration/TrigConfigSvc/src/TrigConfigSvc.cxx
+++ b/Trigger/TrigConfiguration/TrigConfigSvc/src/TrigConfigSvc.cxx
@@ -52,24 +52,6 @@ TrigConfigSvc::initialize() {
 
       ATH_MSG_INFO("    => " << testsvc);
 
-      //////////////////////////////////////////////////////////////
-      // BEGIN RUN-3 TESTING BLOCK - THIS SHOULD BE TEMPORARY
-      ////////////////////////////////////////////////////////////// 
-      if ( testsvc == "run3_dummy" ) {
-         ATH_CHECK( AAH::setProperty( m_hltSvc, "ConfigSource", testsvc ) );
-         if (m_hltSvc.retrieve().isSuccess()) {
-            m_hltservice = m_hltSvc.operator->();
-            ATH_MSG_WARNING("Got HLT Svc " << m_hltSvc.typeAndName() << ", will use R3 dummy menu");
-            hltfromxml = true;
-         } else {
-            ATH_MSG_FATAL("failed to retrieve HLT ConfigSvc: " << m_hltSvc << " using R3 dummy menu");
-            return StatusCode::FAILURE;
-         }
-      }
-      //////////////////////////////////////////////////////////////
-      // END RUN-3 TESTING BLOCK - THIS SHOULD BE TEMPORARY
-      ////////////////////////////////////////////////////////////// 
-
       if ( testsvc == "ds" ) {
          if (m_dsSvc.retrieve().isSuccess()) {
             if(m_l1service==0) m_l1service = m_dsSvc.operator->();
diff --git a/Trigger/TrigConfiguration/TrigConfxAOD/CMakeLists.txt b/Trigger/TrigConfiguration/TrigConfxAOD/CMakeLists.txt
index 7da1f2db709e3593c00a6bbfb82c15aad4d51ace..40359dfa5cdd7c0c069cfeeac083f361d2b80fe6 100644
--- a/Trigger/TrigConfiguration/TrigConfxAOD/CMakeLists.txt
+++ b/Trigger/TrigConfiguration/TrigConfxAOD/CMakeLists.txt
@@ -20,6 +20,7 @@ atlas_depends_on_subdirs(
    PUBLIC
    Control/AthToolSupport/AsgTools
    Event/xAOD/xAODTrigger
+   Trigger/TrigConfiguration/TrigConfData
    Trigger/TrigConfiguration/TrigConfHLTData
    Trigger/TrigConfiguration/TrigConfInterfaces
    Trigger/TrigConfiguration/TrigConfL1Data
@@ -33,7 +34,7 @@ find_package( ROOT COMPONENTS Core RIO )
 atlas_add_library( TrigConfxAODLib
    TrigConfxAOD/*.h Root/*.cxx
    PUBLIC_HEADERS TrigConfxAOD
-   LINK_LIBRARIES AsgTools xAODTrigger TrigConfL1Data TrigConfHLTData
+   LINK_LIBRARIES AsgTools xAODTrigger TrigConfL1Data TrigConfHLTData TrigConfData
    TrigConfInterfaces )
 
 if( NOT XAOD_STANDALONE )
diff --git a/Trigger/TrigConfiguration/TrigConfxAOD/src/PrintVectorHelper.h b/Trigger/TrigConfiguration/TrigConfxAOD/src/PrintVectorHelper.h
new file mode 100644
index 0000000000000000000000000000000000000000..d8724c6b4fa532fa8819f918b26e2396331a0b86
--- /dev/null
+++ b/Trigger/TrigConfiguration/TrigConfxAOD/src/PrintVectorHelper.h
@@ -0,0 +1,30 @@
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TRIGCONFXAOD_PRINTVECTORHELPER_H
+#define TRIGCONFXAOD_PRINTVECTORHELPER_H
+
+namespace {
+   /// Helper operator for printing the contents of vectors
+   template< typename T >
+   MsgStream& operator<< ( MsgStream& out,
+                           const std::vector< T >& vec ) {
+
+      // A little prefix:
+      out << "[";
+      // Print the contents:
+      for( size_t i = 0; i < vec.size(); ++i ) {
+         out << vec[ i ];
+         if( i < vec.size() - 1 ) {
+            out << ", ";
+         }
+      }
+      // A little postfix:
+      out << "]";
+      // Return the stream:
+      return out;
+   }
+}
+
+#endif
diff --git a/Trigger/TrigConfiguration/TrigConfxAOD/src/components/TrigConfxAOD_entries.cxx b/Trigger/TrigConfiguration/TrigConfxAOD/src/components/TrigConfxAOD_entries.cxx
index d9cbad1f72d87f705cd1e948673155497f81fd79..f4c2ec1c3c4511654d0a1b38c318135a09870362 100644
--- a/Trigger/TrigConfiguration/TrigConfxAOD/src/components/TrigConfxAOD_entries.cxx
+++ b/Trigger/TrigConfiguration/TrigConfxAOD/src/components/TrigConfxAOD_entries.cxx
@@ -1,10 +1,12 @@
 #include "../xAODConfigSvc.h"
 #include "../xAODMenuWriter.h"
+#include "../xAODMenuWriterMT.h"
 #include "../xAODMenuReader.h"
 #include "TrigConfxAOD/xAODConfigTool.h"
 
 DECLARE_COMPONENT( TrigConf::xAODConfigSvc )
 DECLARE_COMPONENT( TrigConf::xAODMenuWriter )
+DECLARE_COMPONENT( TrigConf::xAODMenuWriterMT )
 DECLARE_COMPONENT( TrigConf::xAODMenuReader )
 DECLARE_COMPONENT( TrigConf::xAODConfigTool )
 
diff --git a/Trigger/TrigConfiguration/TrigConfxAOD/src/xAODMenuWriter.cxx b/Trigger/TrigConfiguration/TrigConfxAOD/src/xAODMenuWriter.cxx
index 9ed53ffef6351be1e2267b454a885a72686e3993..5ac47c5e7e85dbdcd894f182a48f4e59552ba036 100644
--- a/Trigger/TrigConfiguration/TrigConfxAOD/src/xAODMenuWriter.cxx
+++ b/Trigger/TrigConfiguration/TrigConfxAOD/src/xAODMenuWriter.cxx
@@ -27,28 +27,7 @@
 
 // Local include(s):
 #include "xAODMenuWriter.h"
-
-namespace {
-   /// Helper operator for printing the contents of vectors
-   template< typename T >
-   MsgStream& operator<< ( MsgStream& out,
-                           const std::vector< T >& vec ) {
-
-      // A little prefix:
-      out << "[";
-      // Print the contents:
-      for( size_t i = 0; i < vec.size(); ++i ) {
-         out << vec[ i ];
-         if( i < vec.size() - 1 ) {
-            out << ", ";
-         }
-      }
-      // A little postfix:
-      out << "]";
-      // Return the stream:
-      return out;
-   }
-}
+#include "PrintVectorHelper.h"
 
 namespace TrigConf {
 
diff --git a/Trigger/TrigConfiguration/TrigConfxAOD/src/xAODMenuWriterMT.cxx b/Trigger/TrigConfiguration/TrigConfxAOD/src/xAODMenuWriterMT.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..2b76e18fd0c3827d7f142c77bea85dc24bcf9af0
--- /dev/null
+++ b/Trigger/TrigConfiguration/TrigConfxAOD/src/xAODMenuWriterMT.cxx
@@ -0,0 +1,415 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: xAODMenuWriter.cxx 717661 2016-01-14 08:16:47Z tbold $
+
+// Gaudi/Athena include(s):
+#include "AthenaKernel/errorcheck.h"
+
+// Trigger configuration include(s):
+#include "TrigConfL1Data/CTPConfig.h"
+#include "TrigConfL1Data/Menu.h"
+#include "TrigConfL1Data/TriggerItem.h"
+#include "TrigConfL1Data/PrescaleSet.h"
+#include "TrigConfL1Data/BunchGroupSet.h"
+#include "TrigConfL1Data/BunchGroup.h"
+#include "TrigConfHLTData/HLTChainList.h"
+#include "TrigConfHLTData/HLTChain.h"
+#include "TrigConfHLTData/HLTSignature.h"
+#include "TrigConfHLTData/HLTTriggerElement.h"
+#include "TrigConfHLTData/HLTSequenceList.h"
+
+// EDM include(s):
+#include "xAODTrigger/TriggerMenu.h"
+#include "xAODTrigger/TriggerMenuAuxContainer.h"
+
+// Local include(s):
+#include "xAODMenuWriterMT.h"
+#include "PrintVectorHelper.h"
+
+
+namespace TrigConf {
+
+   xAODMenuWriterMT::xAODMenuWriterMT( const std::string& name,
+                                       ISvcLocator* svcLoc )
+      : AthReentrantAlgorithm( name, svcLoc ),
+        m_trigConf( "TrigConfigSvc", name ),
+        m_metaStore( "MetaDataStore", name ),
+        m_tmc( nullptr ) {
+   }
+
+   xAODMenuWriterMT::~xAODMenuWriterMT() {
+   }
+
+   StatusCode xAODMenuWriterMT::initialize() {
+
+      // Greet the user:
+      ATH_MSG_INFO( "Initialising - Package version: " << PACKAGE_VERSION );
+      ATH_MSG_DEBUG( "EventObjectName   = " << m_eventName );
+      ATH_MSG_DEBUG( "MetaObjectName    = " << m_metaName );
+      ATH_MSG_VERBOSE( "TrigConfigSvc = " << m_trigConf );
+      ATH_MSG_VERBOSE( "MetaDataStore = " << m_metaStore );
+
+      // Retrieve the necessary service(s):
+      CHECK( m_trigConf.retrieve() );
+      CHECK( m_metaStore.retrieve() );
+
+      CHECK( m_eventName.initialize() ); // WriteHandleKey
+
+      if (m_isJSONConfig) {
+         CHECK( m_HLTMenuKey.initialize() ); // ReadHandleKey
+         CHECK( m_L1MenuKey.initialize() ); // ReadHandleKey
+      }
+
+      // Clear the internal cache variable:
+      m_convertedKeys.clear();
+
+      // Create an empty trigger menu container:
+      xAOD::TriggerMenuAuxContainer* aux = new xAOD::TriggerMenuAuxContainer();
+      m_tmc = new xAOD::TriggerMenuContainer();
+      m_tmc->setStore( aux );
+
+      // Record the trigger configuration metadata into it:
+      CHECK( m_metaStore->record( aux, m_metaName + "Aux." ) );
+      CHECK( m_metaStore->record( m_tmc, m_metaName ) );
+
+      // Return gracefully:
+      return StatusCode::SUCCESS;
+   }
+
+   StatusCode xAODMenuWriterMT::execute(const EventContext& ctx) const {
+
+      std::unique_ptr<xAOD::TrigConfKeys> keys = std::make_unique<xAOD::TrigConfKeys>(
+         m_trigConf->masterKey(),
+         m_trigConf->lvl1PrescaleKey(),
+         m_trigConf->hltPrescaleKey() );
+
+      SG::WriteHandle<xAOD::TrigConfKeys> trigConfKeysWrite(m_eventName, ctx);
+      ATH_CHECK( trigConfKeysWrite.record( std::move(keys) ) );
+
+      // Create the keys in the "internal format":
+      const TrigKey_t ckeys =
+         std::make_pair( m_trigConf->masterKey(),
+                         std::make_pair( m_trigConf->lvl1PrescaleKey(),
+                                         m_trigConf->hltPrescaleKey() ) );
+
+      // The followign code must only run on one event at a time
+      std::lock_guard<std::mutex> lock(m_mutex);
+
+      // Check if we converted this configuration already:
+      if( ! m_convertedKeys.insert( ckeys ).second ) {
+         ATH_MSG_VERBOSE( "Configuration with keys SMK: "
+                          << ckeys.first << ", L1PSK: " << ckeys.second.first
+                          << ", HLTPSK: " << ckeys.second.second
+                          << " already translated" );
+         return StatusCode::SUCCESS;
+      }
+
+      // Tell the user what's happening:
+      ATH_MSG_INFO( "Converting configuration with keys SMK: "
+                    << ckeys.first << ", L1PSK: " << ckeys.second.first
+                    << ", HLTPSK: " << ckeys.second.second );
+
+      // Apparently not, so let's make a new object:
+      xAOD::TriggerMenu* menu = new xAOD::TriggerMenu();
+      m_tmc->push_back( menu ); // Now owned by MetaDataStore
+
+      //
+      // Set its keys:
+      //
+      menu->setSMK( m_trigConf->masterKey() );
+      menu->setL1psk( m_trigConf->lvl1PrescaleKey() );
+      menu->setHLTpsk( m_trigConf->hltPrescaleKey() );
+
+      if (m_isJSONConfig) {
+         CHECK( populateFromJSON(menu, ctx) );
+      } else {
+         CHECK( populateFromTrigConf(menu) );
+      }
+
+      CHECK( populateBunchGroup(menu) ); 
+
+      // Return gracefully:
+      return StatusCode::SUCCESS;
+   }
+
+   StatusCode xAODMenuWriterMT::populateFromJSON(xAOD::TriggerMenu* menu, const EventContext& ctx) const {
+      //
+      // Set its LVL1 information:
+      //
+      ATH_MSG_DEBUG( "Filling LVL1 information" );
+      SG::ReadHandle<TrigConf::L1Menu> l1MenuHandle = SG::makeHandle( m_L1MenuKey, ctx );
+      ATH_CHECK( l1MenuHandle.isValid() );
+      const size_t nL1Items = l1MenuHandle->size();
+      ATH_MSG_DEBUG("Configuring from " << m_L1MenuKey << " with " << nL1Items << " L1 items");
+
+      std::vector< uint16_t > ctpIds;
+      std::vector< std::string > itemNames;
+      std::vector< float > itemPrescales;
+
+      ctpIds.reserve(nL1Items);
+      itemNames.reserve(nL1Items);
+      itemPrescales.reserve(nL1Items);
+
+      for (const TrigConf::L1Item& l1 : *l1MenuHandle) {
+         // Extract the information:
+         ctpIds.push_back( l1.ctpId() );
+         itemNames.push_back( l1.name() );
+         itemPrescales.push_back( 1.0 ); // TODO
+
+         // Some verbose information:
+         ATH_MSG_VERBOSE( "  \"" << itemNames.back() << "\" CTP Id = "
+                          << ctpIds.back() << ", prescale = "
+                          << itemPrescales.back() );
+      }
+
+      menu->setItemCtpIds( ctpIds );
+      menu->setItemNames( itemNames );
+      menu->setItemPrescales( itemPrescales );
+
+      //
+      // Set its HLT information:
+      //
+      ATH_MSG_DEBUG( "Filling HLT information" );
+      SG::ReadHandle<TrigConf::HLTMenu> hltMenuHandle = SG::makeHandle( m_HLTMenuKey, ctx );
+      ATH_CHECK( hltMenuHandle.isValid() );
+      const size_t nChains = hltMenuHandle->size();
+      ATH_MSG_DEBUG("Configuring from " << m_HLTMenuKey << " with " << nChains << " chains");
+
+      std::vector< uint16_t > chainIds;
+      std::vector< std::string > chainNames, chainParentNames;
+      std::vector< float > chainPrescales, chainRerunPrescales,
+         chainPassthroughPrescales;
+
+      std::vector< std::vector< uint32_t > > chainSignatureCounters;
+      std::vector< std::vector< int > > chainSignatureLogics;
+      std::vector< std::vector< std::vector< std::string > > > chainSignatureOutputTEs;
+      std::vector< std::vector< std::string > > chainSignatureLabels;
+
+      chainIds.reserve(nChains);
+      chainNames.reserve(nChains);
+      chainParentNames.reserve(nChains);
+      chainPrescales.reserve(nChains);
+      chainRerunPrescales.reserve(nChains);
+      chainPassthroughPrescales.reserve(nChains);
+
+      chainSignatureCounters.reserve(nChains);
+      chainSignatureLogics.reserve(nChains);
+      chainSignatureOutputTEs.reserve(nChains);
+      chainSignatureLabels.reserve(nChains);
+
+      for (const TrigConf::Chain& ch : *hltMenuHandle) {
+         // Extract the information:
+         chainIds.push_back( ch.counter() );
+         chainNames.push_back( ch.name() );
+         chainParentNames.push_back( ch.l1item() );
+         chainPrescales.push_back( 1.0 ); // TODO
+         chainRerunPrescales.push_back( -1.0 ); // TODO
+         chainPassthroughPrescales.push_back( 0.0 ); // Unused in Run3
+
+         std::vector<uint32_t> counters;
+         std::vector<int> logics;
+         std::vector<std::vector<std::string> > outputTEs;
+         std::vector<std::string> labels;
+
+         // Per-step algorithms is TODO, these are blank for now.
+
+         chainSignatureCounters.push_back(counters);
+         chainSignatureLogics.push_back(logics);
+         chainSignatureOutputTEs.push_back(outputTEs);
+         chainSignatureLabels.push_back(labels);
+
+         // Some verbose information:
+         ATH_MSG_VERBOSE( "  \"" << chainNames.back() << "\" Chain Id = "
+                          << chainIds.back() << ", parent name = \""
+                          << chainParentNames.back() << "\", prescale = "
+                          << chainPrescales.back() << ", re-run prescale = "
+                          << chainRerunPrescales.back()
+                          << ", pass-through presclale = "
+                          << chainPassthroughPrescales.back() );
+      }
+
+      menu->setChainIds( chainIds );
+      menu->setChainNames( chainNames );
+      menu->setChainParentNames( chainParentNames );
+      menu->setChainPrescales( chainPrescales );
+      menu->setChainRerunPrescales( chainRerunPrescales );
+      menu->setChainPassthroughPrescales( chainPassthroughPrescales );
+
+      menu->setChainSignatureCounters(chainSignatureCounters);
+      menu->setChainSignatureLogics(chainSignatureLogics);
+      menu->setChainSignatureOutputTEs(chainSignatureOutputTEs);
+      menu->setChainSignatureLabels(chainSignatureLabels);
+
+      //
+      // Set its sequence information:
+      //
+      // TODO
+
+      return StatusCode::SUCCESS;
+   }
+
+
+   StatusCode xAODMenuWriterMT::populateFromTrigConf(xAOD::TriggerMenu* menu) const {
+      //
+      // Set its LVL1 information:
+      //
+      ATH_MSG_DEBUG( "Filling LVL1 information" );
+      std::vector< uint16_t > ctpIds;
+      std::vector< std::string > itemNames;
+      std::vector< float > itemPrescales;
+      TrigConf::ItemContainer::const_iterator item_itr =
+         m_trigConf->ctpConfig()->menu().items().begin();
+      TrigConf::ItemContainer::const_iterator item_end =
+         m_trigConf->ctpConfig()->menu().items().end();
+      std::vector< float > prescales =
+         m_trigConf->ctpConfig()->prescaleSet().prescales_float();
+      for( ; item_itr != item_end; ++item_itr ) {
+
+         // Extract the information:
+         ctpIds.push_back( ( *item_itr )->ctpId() );
+         itemNames.push_back( ( *item_itr )->name() );
+         itemPrescales.push_back( prescales[ ( *item_itr )->ctpId() ] );
+
+         // Some verbose information:
+         ATH_MSG_VERBOSE( "  \"" << itemNames.back() << "\" CTP Id = "
+                          << ctpIds.back() << ", prescale = "
+                          << itemPrescales.back() );
+      }
+      menu->setItemCtpIds( ctpIds );
+      menu->setItemNames( itemNames );
+      menu->setItemPrescales( itemPrescales );
+
+      //
+      // Set its HLT information:
+      //
+      ATH_MSG_DEBUG( "Filling HLT information" );
+      std::vector< uint16_t > chainIds;
+      std::vector< std::string > chainNames, chainParentNames;
+      std::vector< float > chainPrescales, chainRerunPrescales,
+         chainPassthroughPrescales;
+
+      std::vector< std::vector< uint32_t > > chainSignatureCounters;
+      std::vector< std::vector< int > > chainSignatureLogics;
+      std::vector< std::vector< std::vector< std::string > > > chainSignatureOutputTEs;
+      std::vector< std::vector< std::string > > chainSignatureLabels;
+
+      TrigConf::HLTChainList::const_iterator chain_itr =
+         m_trigConf->chains().begin();
+      TrigConf::HLTChainList::const_iterator chain_end =
+         m_trigConf->chains().end();
+      for( ; chain_itr != chain_end; ++chain_itr ) {
+
+         // Extract the information:
+         chainIds.push_back( ( *chain_itr )->chain_counter() );
+         chainNames.push_back( ( *chain_itr )->chain_name() );
+         chainParentNames.push_back( ( *chain_itr )->lower_chain_name() );
+         chainPrescales.push_back( ( *chain_itr )->prescale() );
+         chainRerunPrescales.push_back(
+                                       ( *chain_itr )->prescales().getRerunPrescale("").second );
+         chainPassthroughPrescales.push_back( ( *chain_itr )->pass_through() );
+
+         std::vector<uint32_t> counters;
+         std::vector<int> logics;
+         std::vector<std::vector<std::string> > outputTEs;
+         std::vector<std::string> labels;
+
+         ATH_MSG_VERBOSE((*chain_itr)->chain_name() << " has " << (*chain_itr)->signatureList().size() << " signatures");
+         for(auto& signature : (*chain_itr)->signatureList() ){
+            uint32_t cntr = signature->signature_counter();
+            counters.push_back(cntr);
+            logics.push_back(signature->logic());
+            labels.push_back(signature->label());
+            std::vector<std::string> outputTEids;
+            for(auto& outputTE : signature->outputTEs()){
+               outputTEids.push_back(outputTE->name());
+            }
+            outputTEs.push_back(outputTEids);
+            ATH_MSG_VERBOSE("converted this signature: " << *signature);
+         }
+         chainSignatureCounters.push_back(counters);
+         chainSignatureLogics.push_back(logics);
+         chainSignatureOutputTEs.push_back(outputTEs);
+         chainSignatureLabels.push_back(labels);
+
+         // Some verbose information:
+         ATH_MSG_VERBOSE( "  \"" << chainNames.back() << "\" Chain Id = "
+                          << chainIds.back() << ", parent name = \""
+                          << chainParentNames.back() << "\", prescale = "
+                          << chainPrescales.back() << ", re-run prescale = "
+                          << chainRerunPrescales.back()
+                          << ", pass-through presclale = "
+                          << chainPassthroughPrescales.back() );
+      }
+      menu->setChainIds( chainIds );
+      menu->setChainNames( chainNames );
+      menu->setChainParentNames( chainParentNames );
+      menu->setChainPrescales( chainPrescales );
+      menu->setChainRerunPrescales( chainRerunPrescales );
+      menu->setChainPassthroughPrescales( chainPassthroughPrescales );
+
+      menu->setChainSignatureCounters(chainSignatureCounters);
+      menu->setChainSignatureLogics(chainSignatureLogics);
+      menu->setChainSignatureOutputTEs(chainSignatureOutputTEs);
+      menu->setChainSignatureLabels(chainSignatureLabels);
+
+      //
+      // Set its sequence information:
+      //
+      ATH_MSG_DEBUG( "Filling sequence information" );
+      auto& sequenceList = m_trigConf->sequences();
+      std::vector<std::vector<std::string> > sequenceInputTEs;
+      std::vector<std::string> sequenceOutputTE;
+      std::vector<std::vector<std::string> > sequenceAlgorithms;
+
+      for(auto& seq : sequenceList){
+         std::vector<std::string> inputTEs;
+         for(auto& input : seq->inputTEs()) inputTEs.push_back(input->name());
+         sequenceInputTEs.push_back(inputTEs);
+         sequenceAlgorithms.push_back(seq->algorithms());
+         sequenceOutputTE.push_back(seq->outputTE()->name());
+
+         ATH_MSG_VERBOSE("original sequence: \n" << *seq);
+
+         ATH_MSG_VERBOSE("added sequence with: ");
+         ATH_MSG_VERBOSE("  inputTEs: " << sequenceInputTEs.back());
+         ATH_MSG_VERBOSE("     algos: " << sequenceAlgorithms.back());
+         ATH_MSG_VERBOSE("  outputTE: " << sequenceOutputTE.back());
+      }
+
+      menu->setSequenceInputTEs(sequenceInputTEs);
+      menu->setSequenceOutputTEs(sequenceOutputTE);
+      menu->setSequenceAlgorithms(sequenceAlgorithms);
+
+      return StatusCode::SUCCESS;
+   }
+
+   StatusCode xAODMenuWriterMT::populateBunchGroup(xAOD::TriggerMenu* menu) const {
+      //
+      // Set its bunch-group information:
+      //
+      ATH_MSG_DEBUG( "Filling bunch-group information" );
+      std::vector< std::vector< uint16_t > > bgs;
+      std::vector< BunchGroup >::const_iterator bg_itr =
+         m_trigConf->bunchGroupSet()->bunchGroups().begin();
+      std::vector< BunchGroup >::const_iterator bg_end =
+         m_trigConf->bunchGroupSet()->bunchGroups().end();
+      for( int i = 0; bg_itr != bg_end; ++bg_itr, ++i ) {
+
+         // Extract the information. Unfortunately we need to make
+         // and explicit conversion by hand.
+         const std::vector< uint16_t > bunches( bg_itr->bunches().begin(),
+                                                bg_itr->bunches().end() );
+         bgs.push_back( bunches );
+
+         // Some verbose information:
+         ATH_MSG_VERBOSE( "  Bunch group " << i << " bunches: "
+                          << bgs.back() );
+      }
+      menu->setBunchGroupBunches( bgs );
+
+      return StatusCode::SUCCESS;
+   }
+
+} // namespace TrigConf
diff --git a/Trigger/TrigConfiguration/TrigConfxAOD/src/xAODMenuWriterMT.h b/Trigger/TrigConfiguration/TrigConfxAOD/src/xAODMenuWriterMT.h
new file mode 100644
index 0000000000000000000000000000000000000000..ede39616dc848535455cb6569216f93b40afac8e
--- /dev/null
+++ b/Trigger/TrigConfiguration/TrigConfxAOD/src/xAODMenuWriterMT.h
@@ -0,0 +1,109 @@
+// Dear emacs, this is -*- c++ -*-
+
+/*
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef TRIGCONFXAOD_XAODMENUWRITERMT_H
+#define TRIGCONFXAOD_XAODMENUWRITERMT_H
+
+// System include(s):
+extern "C" {
+#   include <stdint.h>
+}
+#include <string>
+#include <set>
+#include <map> // For std::pair...
+
+// Gaudi/Athena include(s):
+#include "AthenaBaseComps/AthReentrantAlgorithm.h"
+#include "GaudiKernel/ServiceHandle.h"
+#include "StoreGate/StoreGateSvc.h"
+
+// Trigger include(s):
+#include "TrigConfInterfaces/ITrigConfigSvc.h"
+#include "TrigConfData/HLTMenu.h"
+#include "TrigConfData/L1Menu.h"
+
+// EDM include(s):
+#include "xAODTrigger/TriggerMenuContainer.h"
+#include "xAODTrigger/TrigConfKeys.h"
+
+namespace TrigConf {
+
+   /**
+    *  @short Algorithm used to write the light-weight xAOD configuration
+    *
+    *         This algorithm needs to be scheduled in jobs that write xAOD
+    *         files in Athena in order to write the trigger configuration
+    *         into the output file.
+    *
+    *         It puts a tiny amount of information into each event that is
+    *         later used to find the correct configuration of the events,
+    *         and also assembles the configuration metadata that is written
+    *         into the metadata TTree of the xAOD file at the end of the job.
+    *
+    * @author Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch>
+    * @author Tim Martin <Tim.Martin@cern.ch>
+    *
+    */
+   class xAODMenuWriterMT : public AthReentrantAlgorithm {
+
+   public:
+      /// Regular Algorithm constructor
+      xAODMenuWriterMT( const std::string& name, ISvcLocator* svcLoc );
+
+      virtual ~xAODMenuWriterMT();
+
+      /// Function initialising the algorithm
+      virtual StatusCode initialize() override;
+
+      /// Function executing the algorithm
+      virtual StatusCode execute(const EventContext& ctx) const override;
+
+   private:
+      /// 
+      SG::WriteHandleKey<xAOD::TrigConfKeys> m_eventName {this, "EventObjectName", "TrigConfKeys",
+        "StoreGate key for the event object"};
+
+       SG::ReadHandleKey<TrigConf::HLTMenu> m_HLTMenuKey {this, "HLTTriggerMenu", "DetectorStore+HLTTriggerMenu",
+        "HLT Menu key, for use if IsJSONConfig=True"};
+
+       SG::ReadHandleKey<TrigConf::L1Menu> m_L1MenuKey {this, "L1TriggerMenu", "DetectorStore+L1TriggerMenu",
+        "L1 Menu key, for use if IsJSONConfig=True"};
+
+      Gaudi::Property< std::string > m_metaName {this, "MetaObjectName", "TriggerMenu",
+        "StoreGate key for the configuration object"};
+
+      Gaudi::Property< bool > m_isJSONConfig {this, "IsJSONConfig", true,
+        "If converting from a JSON menu (Run3) or from the TrigConfigSvc (Runs 1, 2)"};
+
+      ServiceHandle< TrigConf::ITrigConfigSvc > m_trigConf {this, "TrigConfigSvc", "TrigConfigSvc",
+        "The TrigConfigSvc"};
+
+      ServiceHandle< StoreGateSvc > m_metaStore {this, "MetaDataStore", "MetaDataStore",
+        "The MetaDataStore"};
+
+      StatusCode populateFromTrigConf(xAOD::TriggerMenu* menu) const;
+
+      StatusCode populateFromJSON(xAOD::TriggerMenu* menu, const EventContext& ctx) const;
+
+      StatusCode populateBunchGroup(xAOD::TriggerMenu* menu) const;
+
+      /// Trigger configuration key type (used just internally)
+      typedef std::pair< uint32_t, std::pair< uint32_t, uint32_t > > TrigKey_t;
+
+      /// The configuration object that we are writing
+      mutable xAOD::TriggerMenuContainer* m_tmc;
+
+      /// Trigger configuration keys that are already converted
+      mutable std::set< TrigKey_t > m_convertedKeys;
+
+      /// The mutex to prevent us from writing more than one configuration at a time
+      mutable std::mutex m_mutex;
+
+   }; // class xAODMenuWriterMT
+
+} // namespace TrigConf
+
+#endif // TRIGCONFXAOD_XAODMENUWRITERMT_H
diff --git a/Trigger/TrigEvent/TrigSteeringEvent/src/HLTResultMT.cxx b/Trigger/TrigEvent/TrigSteeringEvent/src/HLTResultMT.cxx
index 5cd7623d59db634401b67e32f6d982767a20122a..d8c953c4db6dcd54c3b6e78f9c71cefc3d46a320 100644
--- a/Trigger/TrigEvent/TrigSteeringEvent/src/HLTResultMT.cxx
+++ b/Trigger/TrigEvent/TrigSteeringEvent/src/HLTResultMT.cxx
@@ -96,8 +96,8 @@ const std::vector<uint32_t>& HLT::HLTResultMT::getHltBitsAsWords() {
   }
   m_hltBitWords.resize(m_hltPassRawBits.num_blocks() + m_hltPrescaledBits.num_blocks() + m_hltRerunBits.num_blocks());
   boost::to_block_range(m_hltPassRawBits, m_hltBitWords.begin());
-  boost::to_block_range(m_hltPrescaledBits, m_hltBitWords.begin());
-  boost::to_block_range(m_hltRerunBits, m_hltBitWords.begin());
+  boost::to_block_range(m_hltPrescaledBits, m_hltBitWords.begin() + m_hltPassRawBits.num_blocks());
+  boost::to_block_range(m_hltRerunBits, m_hltBitWords.begin() + m_hltPassRawBits.num_blocks() + m_hltPrescaledBits.num_blocks());
   return m_hltBitWords;
 }
 
diff --git a/Trigger/TrigSteer/TrigOutputHandling/TrigOutputHandling/TriggerBitsMakerTool.h b/Trigger/TrigSteer/TrigOutputHandling/TrigOutputHandling/TriggerBitsMakerTool.h
index 12362df80f5e81dad6d1d6ae345b329ac6647ca4..63baa488f9529c7d2c02b35dcfb512b025b84bb4 100644
--- a/Trigger/TrigSteer/TrigOutputHandling/TrigOutputHandling/TriggerBitsMakerTool.h
+++ b/Trigger/TrigSteer/TrigOutputHandling/TrigOutputHandling/TriggerBitsMakerTool.h
@@ -8,7 +8,7 @@
 #include "DecisionHandling/TrigCompositeUtils.h"
 #include "AthenaBaseComps/AthAlgTool.h"
 #include "TrigOutputHandling/HLTResultMTMakerTool.h"
-
+#include "TrigConfData/HLTMenu.h"
 
 /**
  * @class TriggerBitsMakerTool
@@ -23,6 +23,7 @@ public:
   StatusCode fill( std::vector<uint32_t>& place ) const;
   
   virtual StatusCode initialize() override;
+  virtual StatusCode start() override;
   virtual StatusCode finalize() override;
 
 private:
@@ -40,7 +41,7 @@ private:
 
   SG::ReadHandleKey<TrigCompositeUtils::DecisionContainer> m_finalChainDecisions { this, "ChainDecisions", "HLTNav_Summary", "Container with final chain decisions"  };
 
-  Gaudi::Property<std::string> m_menuJSON {this, "HLTmenuFile", "UNSET", "Filename of just-generated HLT Menu JSON used to configure the TriggerBitsMakerTool"};
+  SG::ReadHandleKey<TrigConf::HLTMenu> m_HLTMenuKey{this, "HLTTriggerMenu", "DetectorStore+HLTTriggerMenu", "HLT Menu"};
 
   Gaudi::Property<std::map<std::string, uint32_t>> m_extraChainToBit { this, "ExtraChainToBit", {},
     "Special case and testing purposes hard-coded chain-to-bit mappings to use in addition to those from the HLT menu."};
diff --git a/Trigger/TrigSteer/TrigOutputHandling/src/TriggerBitsMakerTool.cxx b/Trigger/TrigSteer/TrigOutputHandling/src/TriggerBitsMakerTool.cxx
index 237964fa3ec68334b2ec605337e96a42f639fcd4..717d029b2ef7f24c285d7e049effa93d6e90d057 100644
--- a/Trigger/TrigSteer/TrigOutputHandling/src/TriggerBitsMakerTool.cxx
+++ b/Trigger/TrigSteer/TrigOutputHandling/src/TriggerBitsMakerTool.cxx
@@ -3,8 +3,6 @@
 */
 #include "DecisionHandling/HLTIdentifier.h"
 #include "TrigOutputHandling/TriggerBitsMakerTool.h"
-#include "TrigConfIO/JsonFileLoader.h"
-#include "TrigConfData/HLTMenu.h"
 #include "TrigConfHLTData/HLTUtils.h"
 
 #include <algorithm>
@@ -15,15 +13,20 @@ TriggerBitsMakerTool::TriggerBitsMakerTool(const std::string& type, const std::s
 TriggerBitsMakerTool::~TriggerBitsMakerTool() {}
 
 StatusCode TriggerBitsMakerTool::initialize() {
+
   ATH_CHECK( m_finalChainDecisions.initialize() );
+  ATH_CHECK( m_HLTMenuKey.initialize() );
+
+  return StatusCode::SUCCESS;
+}
 
-  TrigConf::JsonFileLoader fileLoader;
-  TrigConf::HLTMenu hltmenu;
-  ATH_CHECK( fileLoader.loadFile(m_menuJSON, hltmenu) );
-  ATH_MSG_INFO("Configuring from " << m_menuJSON << " with " << hltmenu.size() << " chains");
+StatusCode TriggerBitsMakerTool::start() {
+  SG::ReadHandle<TrigConf::HLTMenu>  hltMenuHandle = SG::makeHandle( m_HLTMenuKey );
+  ATH_CHECK( hltMenuHandle.isValid() );
+  ATH_MSG_INFO("Configuring from " << m_HLTMenuKey << " with " << hltMenuHandle->size() << " chains");
 
   m_largestBit = 0;
-  for(auto& ch : hltmenu) {
+  for (const TrigConf::Chain& ch : *hltMenuHandle) {
     ATH_MSG_DEBUG( "Chain " << ch.name() << " will flip " << ch.counter() <<  " bit" );
     ATH_CHECK(preInsertCheck(ch.name(), ch.counter()));
     ATH_CHECK(hashConsistencyCheck(ch.name(), ch.namehash()));
@@ -32,7 +35,7 @@ StatusCode TriggerBitsMakerTool::initialize() {
   }
 
   // This block allows extra mappings to be supplied by python, e.g. for testing purposes
-  for ( auto& chainAndBit: m_extraChainToBit ) {
+  for (const auto& chainAndBit: m_extraChainToBit ) {
     struct { std::string chain; uint32_t bit; } conf { chainAndBit.first, chainAndBit.second };    
     ATH_MSG_DEBUG( "Extra Chain " << conf.chain << " will flip  " << conf.bit <<  " bit" );
     ATH_CHECK(preInsertCheck(conf.chain, conf.bit));
@@ -55,7 +58,8 @@ StatusCode TriggerBitsMakerTool::hashConsistencyCheck(const std::string& chain,
 
 StatusCode TriggerBitsMakerTool::preInsertCheck(const std::string& chain, const uint32_t bit) const {
   const auto checkIt = std::find_if(
-    m_mapping.begin(), m_mapping.end(), [&](const std::pair<TrigCompositeUtils::DecisionID, uint32_t>& m) { return m.second == bit; }
+    m_mapping.begin(), m_mapping.end(),
+    [&](const std::pair<TrigCompositeUtils::DecisionID, uint32_t>& m) { return m.second == bit; }
   );
   if (checkIt != m_mapping.end()) {
     ATH_MSG_ERROR( "Multiple chains " << TrigConf::HLTUtils::hash2string(checkIt->first) 
@@ -121,7 +125,23 @@ StatusCode TriggerBitsMakerTool::fill( HLT::HLTResultMT& resultToFill ) const {
   }
 
   if ( msgLvl( MSG::DEBUG ) ) {
-    ATH_MSG_DEBUG("HLT result now has " << resultToFill.getHltBitsAsWords().size() << " words with trigger bits:");
+    const boost::dynamic_bitset<uint32_t> passRawBits = resultToFill.getHltPassRawBits();
+    std::vector<uint32_t> bitsTemp(passRawBits.num_blocks());
+    boost::to_block_range(passRawBits, bitsTemp.begin());
+    ATH_MSG_VERBOSE("HLT result now has " << bitsTemp.size() << " words with HLT pass raw bits:");
+    for (const auto& w : bitsTemp) ATH_MSG_VERBOSE("0x" << MSG::hex << w << MSG::dec);
+    //
+    const boost::dynamic_bitset<uint32_t> prescaleBits = resultToFill.getHltPrescaledBits();
+    boost::to_block_range(prescaleBits, bitsTemp.begin());
+    ATH_MSG_VERBOSE("HLT result now has " << bitsTemp.size() << " words with HLT prescale bits:");
+    for (const auto& w : bitsTemp) ATH_MSG_VERBOSE("0x" << MSG::hex << w << MSG::dec);
+    //
+    const boost::dynamic_bitset<uint32_t> rerunBits = resultToFill.getHltRerunBits();
+    boost::to_block_range(rerunBits, bitsTemp.begin());
+    ATH_MSG_VERBOSE("HLT result now has " << bitsTemp.size() << " words with HLT rerun bits:");
+    for (const auto& w : bitsTemp) ATH_MSG_VERBOSE("0x" << MSG::hex << w << MSG::dec);
+    //
+    ATH_MSG_DEBUG("HLT result now has " << resultToFill.getHltBitsAsWords().size() << " words with the final trigger bits:");
     for (const auto& w : resultToFill.getHltBitsAsWords()) ATH_MSG_DEBUG("0x" << MSG::hex << w << MSG::dec);
   }
   return StatusCode::SUCCESS;
@@ -136,7 +156,8 @@ StatusCode TriggerBitsMakerTool::setBit(const TrigCompositeUtils::DecisionID cha
     return StatusCode::FAILURE;
   }
   const int chainBitPosition = mappingIter->second;
-  ATH_MSG_DEBUG("Setting bit " << chainBitPosition << " corresponding to chain" << HLT::Identifier(chain) << " in BitCategory " << category);
+  static const std::vector<std::string> bitCategoryStr {"PassRaw","Prescaled","Rerun"};
+  ATH_MSG_DEBUG("Setting bit " << chainBitPosition << " corresponding to chain " << HLT::Identifier(chain) << " in BitCategory " << bitCategoryStr.at(category));
   switch (category) {
     case HLTPassRawCategory: ATH_CHECK(resultToFill.addHltPassRawBit(chainBitPosition)); break;
     case HLTPrescaledCategory: ATH_CHECK(resultToFill.addHltPrescaledBit(chainBitPosition)); break;
diff --git a/Trigger/TrigValidation/TrigUpgradeTest/share/full_menu.py b/Trigger/TrigValidation/TrigUpgradeTest/share/full_menu.py
index 397c8e6f1196e4e541d24d355fa42d3cb1f44dc1..dbbf244c71282d07b2705573381f97b56f9ea702 100644
--- a/Trigger/TrigValidation/TrigUpgradeTest/share/full_menu.py
+++ b/Trigger/TrigValidation/TrigUpgradeTest/share/full_menu.py
@@ -149,7 +149,6 @@ if configureBSResult:
             stmaker.PEBDecisionKeys.append(decisionKey)
 
     bitsmaker = TriggerBitsMakerTool()
-    bitsmaker.HLTmenuFile = TriggerFlags.outputHLTmenuJsonFile()
 
     # Configure the HLT result maker to use the above tools
     from AthenaCommon.AppMgr import ServiceMgr as svcMgr
diff --git a/Trigger/TriggerCommon/TrigEDMConfig/python/TriggerEDMRun3.py b/Trigger/TriggerCommon/TrigEDMConfig/python/TriggerEDMRun3.py
index aec4281492fd2791d231b96c67e68193dfd768ed..2442a21a42cd13be8aff230e49f71f34ada6eb73 100644
--- a/Trigger/TriggerCommon/TrigEDMConfig/python/TriggerEDMRun3.py
+++ b/Trigger/TriggerCommon/TrigEDMConfig/python/TriggerEDMRun3.py
@@ -87,6 +87,8 @@ TriggerHLTListRun3 = [
     ('xAOD::TrigCompositeContainer#HLT_TrigCostContainer',   'BS ESD', 'Steer'),
     ('xAOD::TrigCompositeAuxContainer#HLT_TrigCostContainerAux.alg.store.view.thread.slot.roi.start.stop.', 'BS ESD', 'Steer'),
 
+    ('HLT::HLTResultMT#HLTResultMT',                         'ESD', 'Steer'),
+
     # Run-2 L1 (temporary)
     ('xAOD::MuonRoIContainer#LVL1MuonRoIs' ,                 'ESD AODFULL AODSLIM AODVERYSLIM AODBLSSLIM', 'L1'),
     ('xAOD::MuonRoIAuxContainer#LVL1MuonRoIsAux.' ,          'ESD AODFULL AODSLIM AODVERYSLIM AODBLSSLIM', 'L1'),
diff --git a/Trigger/TriggerCommon/TriggerJobOpts/python/TriggerConfig.py b/Trigger/TriggerCommon/TriggerJobOpts/python/TriggerConfig.py
index d23dfa00b622ea1e2e1185d6feee318622f141d4..d66cdd2e23208225f337afb12ecc03a5dd9c16ef 100644
--- a/Trigger/TriggerCommon/TriggerJobOpts/python/TriggerConfig.py
+++ b/Trigger/TriggerCommon/TriggerJobOpts/python/TriggerConfig.py
@@ -242,7 +242,6 @@ def triggerBSOutputCfg( flags, decObj ):
     stmaker.HLTmenuFile = TriggerFlags.outputHLTmenuJsonFile()
         
     bitsmaker = TriggerBitsMakerTool()
-    bitsmaker.HLTmenuFile = flags.Trigger.HLTMenuJsonFile
     
     hltResultMakerTool            = HLTResultMTMakerCfg("MakerTool") # want short nme to see in the log
     hltResultMakerTool.MakerTools = [ serialiser, stmaker, bitsmaker ] 
diff --git a/Trigger/TriggerCommon/TriggerJobOpts/python/TriggerConfigFlags.py b/Trigger/TriggerCommon/TriggerJobOpts/python/TriggerConfigFlags.py
index a17df65d23780701927da142135c148a1fe48258..57b0e68f2c44bf533bd52d3428bb80b3ea680f44 100644
--- a/Trigger/TriggerCommon/TriggerJobOpts/python/TriggerConfigFlags.py
+++ b/Trigger/TriggerCommon/TriggerJobOpts/python/TriggerConfigFlags.py
@@ -102,7 +102,7 @@ def createTriggerFlags():
                 lambda prevFlags: 'HLTconfig_'+prevFlags.Trigger.triggerMenuSetup+'_' + prevFlags.Trigger.menuVersion + '.xml')
 
     # HLT JSON file name (R3)
-    flags.addFlag('Trigger.HLTMenuJsonFile',
+    flags.addFlag('Trigger.outputHLTmenuJsonFile',
                 lambda prevFlags: 'HLTmenu_'+prevFlags.Trigger.triggerMenuSetup+'_' + prevFlags.Trigger.menuVersion + '.json')
 
     # generate or not the L1 configuration
diff --git a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/HLTMenuJSON.py b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/HLTMenuJSON.py
index 98c2d96d79b58248a08149b8a6ccf6cc0e529fba..04d1d8c02e81c5acf33226ba2111e02fc0d104f7 100644
--- a/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/HLTMenuJSON.py
+++ b/Trigger/TriggerCommon/TriggerMenuMT/python/HLTMenuConfig/Menu/HLTMenuJSON.py
@@ -5,7 +5,7 @@ from AthenaCommon.Logging import logging
 __log = logging.getLogger( 'HLTMenuJSON.py' )
 
 
-def __generateJSON( chainDicts, chainConfigs, menuName ):
+def __generateJSON( chainDicts, chainConfigs, menuName, menuFileName ):
     """ Generates JSON given the ChainProps and sequences
     """
     menuDict = {"name": menuName, "chains": []}
@@ -56,8 +56,8 @@ def __generateJSON( chainDicts, chainConfigs, menuName ):
 
         menuDict["chains"].append( chainDict )
 
-    __log.info( "Writing trigger menu to %s", fileName )
-    with open( fileName, 'w' ) as fp:
+    __log.info( "Writing trigger menu to %s", menuFileName )
+    with open( menuFileName, 'w' ) as fp:
         json.dump( menuDict, fp, indent=4, sort_keys=True )
 
 def generateJSON():
@@ -65,11 +65,18 @@ def generateJSON():
     from TriggerJobOpts.TriggerFlags import TriggerFlags
     from TriggerMenuMT.HLTMenuConfig.Menu.TriggerConfigHLT import TriggerConfigHLT
 
-
-    return __generateJSON( TriggerConfigHLT.dictsList(), TriggerConfigHLT.configsList(), TriggerFlags.triggerMenuSetup() )
+    return __generateJSON(
+        TriggerConfigHLT.dictsList(),
+        TriggerConfigHLT.configsList(),
+        TriggerFlags.triggerMenuSetup(),
+        TriggerFlags.outputHLTmenuJsonFile() )
     
 def generateJSON_newJO( chainDicts, chainConfigs ):
     __log.info("Generating HLT JSON config in the new JO")
     from AthenaConfiguration.AllConfigFlags import ConfigFlags
                                     
-    return __generateJSON( chainDicts, chainConfigs, ConfigFlags.Trigger.triggerMenuSetup )
+    return __generateJSON(
+        chainDicts,
+        chainConfigs,
+        ConfigFlags.Trigger.triggerMenuSetup,
+        ConfigFlags.Trigger.outputHLTmenuJsonFile )