From 9faa77a1ac0d32b9d73c31075c638112b71bb28d Mon Sep 17 00:00:00 2001
From: William Axel Leight <william.axel.leight@cern.ch>
Date: Tue, 21 Aug 2018 15:52:23 +0000
Subject: [PATCH] Resolve ATLASRECTS-4285

Former-commit-id: a88141f57da02c1403437a9138b7e7be89a98391
---
 .../MuGirl/src/MuGirlRecoTool.cxx             |   8 +-
 .../MuonCombinedAlgs/src/MuonCombinedAlg.cxx  |  26 ++-
 .../MuonCombinedAlgs/src/MuonCombinedAlg.h    |  13 +-
 .../src/MuonCombinedInDetExtensionAlg.cxx     |  12 +-
 .../src/MuonCombinedInDetExtensionAlg.h       |   4 +-
 .../MuonCombinedAlgs/src/MuonCreatorAlg.cxx   |  87 +++++-----
 .../MuonCombinedAlgs/src/MuonCreatorAlg.h     |   5 +-
 .../src/MuonSegmentTagAlg.cxx                 |   8 +-
 .../MuonCombinedAlgs/src/MuonSegmentTagAlg.h  |   4 +-
 .../src/MuGirlTagTool.cxx                     |  11 +-
 .../MuonCombinedBaseTools/src/MuGirlTagTool.h |   8 +-
 .../src/MuonCaloTagTool.cxx                   |  25 +--
 .../src/MuonCaloTagTool.h                     |  18 +--
 .../src/MuonCombinedDebuggerTool.h            |   4 +-
 .../src/MuonCombinedFitTagTool.cxx            | 107 +++++++------
 .../src/MuonCombinedFitTagTool.h              |   5 +-
 .../src/MuonCombinedStacoTagTool.cxx          |  12 +-
 .../src/MuonCombinedStacoTagTool.h            |   5 +-
 .../src/MuonCombinedTool.cxx                  |  24 +--
 .../src/MuonCombinedTool.h                    |   7 +-
 .../src/MuonCreatorTool.cxx                   | 150 ++++++------------
 .../src/MuonCreatorTool.h                     |  15 +-
 .../src/MuonSegmentTagTool.cxx                |  11 +-
 .../src/MuonSegmentTagTool.h                  |   6 +-
 .../src/SortInDetCandidates.h                 |  17 +-
 .../MuonCombinedEvent/InDetCandidate.h        |  39 -----
 .../InDetCandidateToTagMap.h                  |  36 +++++
 .../MuonCombinedEvent/src/InDetCandidate.cxx  |   6 +-
 .../src/InDetCandidateToTagMap.cxx            |  38 +++++
 .../python/MuonCombinedAlgs.py                |   4 +
 .../IMuonCombinedInDetExtensionTool.h         |   9 +-
 .../IMuonCombinedTagTool.h                    |   5 +-
 .../IMuonCombinedTool.h                       |   4 +-
 .../IMuonCombinedTrigCaloTagExtensionTool.h   |   3 +-
 .../IMuonCreatorTool.h                        |  12 +-
 .../IMuonSegmentTagTool.h                     |   6 +-
 .../src/MuonInsideOutRecoTool.cxx             |  30 ++--
 .../src/MuonInsideOutRecoTool.h               |  20 +--
 .../src/MuonStauRecoTool.cxx                  |  20 +--
 .../src/MuonStauRecoTool.h                    |  12 +-
 .../TrigMuSuperEF/src/TrigMuSuperEF.cxx       |  73 ++++++---
 .../TrigMuSuperEF/src/TrigMuSuperEF.h         |   6 +-
 42 files changed, 484 insertions(+), 431 deletions(-)
 create mode 100644 Reconstruction/MuonIdentification/MuonCombinedEvent/MuonCombinedEvent/InDetCandidateToTagMap.h
 create mode 100644 Reconstruction/MuonIdentification/MuonCombinedEvent/src/InDetCandidateToTagMap.cxx

diff --git a/Reconstruction/MuonIdentification/MuGirl/src/MuGirlRecoTool.cxx b/Reconstruction/MuonIdentification/MuGirl/src/MuGirlRecoTool.cxx
index 53fd684bec99..9d7ff706e84c 100644
--- a/Reconstruction/MuonIdentification/MuGirl/src/MuGirlRecoTool.cxx
+++ b/Reconstruction/MuonIdentification/MuGirl/src/MuGirlRecoTool.cxx
@@ -481,7 +481,7 @@ bool MuGirlRecoTool::RunFromID(MuGirlNS::CandidateSummaryList& summaryList)
                         lowbetatag->setStauSummary(stauSummary.release());
                         lowbetatag->setStauExtras(stauExtras.release());
 
-                        pParticle->pInDetCandidate->addTag(*lowbetatag);
+                        //pParticle->pInDetCandidate->addTag(*lowbetatag);
 
                     } else {
                         ATH_MSG_DEBUG("stauRefittedTrack is NULL");
@@ -514,7 +514,7 @@ bool MuGirlRecoTool::RunFromID(MuGirlNS::CandidateSummaryList& summaryList)
                         MuonCombined::MuGirlLowBetaTag* lowbetatag
                                 = new MuonCombined::MuGirlLowBetaTag(pTrackParticle->track(), std::vector<const Muon::MuonSegment*>());
                         lowbetatag->setRHExtras(rhExtras.release());
-                        pParticle->pInDetCandidate->addTag(*lowbetatag);
+                        //pParticle->pInDetCandidate->addTag(*lowbetatag);
                     }
                     ATH_MSG_DEBUG("RunFromID: doRH == true - done");
                 }
@@ -539,7 +539,7 @@ bool MuGirlRecoTool::RunFromID(MuGirlNS::CandidateSummaryList& summaryList)
 	    }
             else tag = new MuonCombined::MuGirlTag(summary->pTrkRefitted, muonSegmentList);
 	    tag->setUpdatedExtrapolatedTrack(std::move(summary->pTrkMSRefitted));
-            pParticle->pInDetCandidate->addTag(*tag);
+            //pParticle->pInDetCandidate->addTag(*tag);
             //set the segment into SegmentManager undeletable 
             m_pSegmentManager->setInStore(muonSegmentList, true);
             summary->saveStau = 0;
@@ -555,7 +555,7 @@ bool MuGirlRecoTool::RunFromID(MuGirlNS::CandidateSummaryList& summaryList)
             std::vector<const Muon::MuonSegment*> muonSegmentList = summary->muonSegmentList;
             MuonCombined::MuGirlTag* tag = new MuonCombined::MuGirlTag(summary->pTrkLowBeta, muonSegmentList);
 	    tag->setUpdatedExtrapolatedTrack(nullptr);
-            pParticle->pInDetCandidate->addTag(*tag);
+            //pParticle->pInDetCandidate->addTag(*tag);
             //set the segment into SegmentManager undeletable 
             m_pSegmentManager->setInStore(muonSegmentList, true);
 
diff --git a/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonCombinedAlg.cxx b/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonCombinedAlg.cxx
index f6ceb096bd9c..badea7d2eb6b 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonCombinedAlg.cxx
+++ b/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonCombinedAlg.cxx
@@ -1,10 +1,9 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "MuonCombinedAlg.h"
 
-
 MuonCombinedAlg::MuonCombinedAlg(const std::string& name, ISvcLocator* pSvcLocator):
   AthAlgorithm(name,pSvcLocator)
 {}
@@ -16,18 +15,20 @@ StatusCode MuonCombinedAlg::initialize()
   ATH_CHECK(m_muonCombinedTool.retrieve());
   ATH_CHECK(m_indetCandidateCollectionName.initialize());
   ATH_CHECK(m_muonCandidateCollectionName.initialize());
+  ATH_CHECK(m_combTagMaps.initialize());
+
   return StatusCode::SUCCESS; 
 }
 
 StatusCode MuonCombinedAlg::execute()
 {
 
-  SG::ReadHandle<InDetCandidateCollection> indetCandidateCollection(m_indetCandidateCollectionName);
-  if(!indetCandidateCollection.isValid()){
+  SG::ReadHandle<InDetCandidateCollection> inDetCandidateCollection(m_indetCandidateCollectionName);
+  if(!inDetCandidateCollection.isValid()){
     ATH_MSG_ERROR("Could not read "<< m_indetCandidateCollectionName);
     return StatusCode::FAILURE;
   }
-  if(!indetCandidateCollection.isPresent()){
+  if(!inDetCandidateCollection.isPresent()){
     ATH_MSG_WARNING(m_indetCandidateCollectionName<<" not present");
     return StatusCode::SUCCESS;
   }
@@ -41,12 +42,21 @@ StatusCode MuonCombinedAlg::execute()
     ATH_MSG_WARNING(m_muonCandidateCollectionName<<" not present");
     return StatusCode::SUCCESS;
   }
-  
-  m_muonCombinedTool->combine(*muonCandidateCollection,*indetCandidateCollection);
+
+  std::vector<SG::WriteHandle<MuonCombined::InDetCandidateToTagMap> > tagMaps=m_combTagMaps.makeHandles();
+  std::vector<MuonCombined::InDetCandidateToTagMap*> maps;
+  for(auto& h : tagMaps){
+    ATH_CHECK( h.record (std::make_unique<MuonCombined::InDetCandidateToTagMap>()) );
+    maps.push_back(h.ptr());
+  }
+
+  if(inDetCandidateCollection->empty() || muonCandidateCollection->empty()) return StatusCode::SUCCESS;
+
+  m_muonCombinedTool->combine(*muonCandidateCollection,*inDetCandidateCollection,maps);
+
   return StatusCode::SUCCESS;
 }
 
-
 StatusCode MuonCombinedAlg::finalize()
 {
   return StatusCode::SUCCESS;
diff --git a/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonCombinedAlg.h b/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonCombinedAlg.h
index d1d46cee6bc2..4af8c52449b8 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonCombinedAlg.h
+++ b/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonCombinedAlg.h
@@ -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
 */
 
 #ifndef MUONCOMBINEDALGS_MUONCOMBINEDALG_H
@@ -10,11 +10,16 @@
 #include "StoreGate/ReadHandleKey.h"
 #include "MuonCombinedEvent/InDetCandidateCollection.h"
 #include "MuonCombinedEvent/MuonCandidateCollection.h"
+#include "MuonCombinedEvent/InDetCandidate.h"
+#include "MuonCombinedEvent/MuonCandidate.h"
+#include "MuonCombinedEvent/InDetCandidateToTagMap.h"
 #include "MuonCombinedToolInterfaces/IMuonCombinedTool.h"
 #include <string>
+#include <vector>
 
-namespace MuonCombined {
-  class IMuonCombinedTool;
+namespace Muon
+{
+  class MuonEDMPrinterTool;
 }
 
 class MuonCombinedAlg : public AthAlgorithm
@@ -29,9 +34,11 @@ class MuonCombinedAlg : public AthAlgorithm
   StatusCode finalize();
 
  private:
+
   ToolHandle<MuonCombined::IMuonCombinedTool> m_muonCombinedTool{this,"MuonCombinedTool","MuonCombined::MuonCombinedTool/MuonCombinedTool","muon combined tool"};
   SG::ReadHandleKey<InDetCandidateCollection> m_indetCandidateCollectionName{this,"InDetCandidateLocation","InDetCandidates","name of ID candidate collection"};
   SG::ReadHandleKey<MuonCandidateCollection> m_muonCandidateCollectionName{this,"MuonCandidateLocation","MuonCandidates","name of muon candidate collection"};
+  SG::WriteHandleKeyArray<MuonCombined::InDetCandidateToTagMap> m_combTagMaps{this,"CombinedTagMaps",{"muidcoTagMap","stacoTagMap"},"combined muon tag maps"};
 
 };
 
diff --git a/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonCombinedInDetExtensionAlg.cxx b/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonCombinedInDetExtensionAlg.cxx
index 9335065050d1..213cc00ab4e7 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonCombinedInDetExtensionAlg.cxx
+++ b/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonCombinedInDetExtensionAlg.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
 */
 
 #include "MuonCombinedInDetExtensionAlg.h"
@@ -27,6 +27,7 @@ StatusCode MuonCombinedInDetExtensionAlg::initialize()
   ATH_CHECK(m_CSC_ContainerName.initialize(m_usePRDs && !m_useNSW));
   ATH_CHECK(m_sTGC_ContainerName.initialize(m_usePRDs && m_useNSW));
   ATH_CHECK(m_MM_ContainerName.initialize(m_usePRDs && m_useNSW));
+  ATH_CHECK(m_tagMap.initialize());
 
   return StatusCode::SUCCESS; 
 }
@@ -40,6 +41,9 @@ StatusCode MuonCombinedInDetExtensionAlg::execute()
     return StatusCode::FAILURE;
   }
 
+  SG::WriteHandle<MuonCombined::InDetCandidateToTagMap> tagMap(m_tagMap);
+  ATH_CHECK( tagMap.record (std::make_unique<MuonCombined::InDetCandidateToTagMap>()) );
+
   if(m_usePRDs){
     SG::ReadHandle<Muon::MdtPrepDataContainer> mdtPRDContainer(m_MDT_ContainerName);
     SG::ReadHandle<Muon::CscPrepDataContainer> cscPRDContainer(m_CSC_ContainerName);
@@ -49,14 +53,14 @@ StatusCode MuonCombinedInDetExtensionAlg::execute()
       SG::ReadHandle<Muon::sTgcPrepDataContainer> stgcPRDContainer(m_sTGC_ContainerName);
       SG::ReadHandle<Muon::MMPrepDataContainer> mmPRDContainer(m_MM_ContainerName);
       for(auto& tool : m_muonCombinedInDetExtensionTools)
-        tool->extendWithPRDs(*indetCandidateCollection,mdtPRDContainer.cptr(),cscPRDContainer.cptr(),rpcPRDContainer.cptr(),tgcPRDContainer.cptr(),stgcPRDContainer.cptr(),mmPRDContainer.cptr());
+        tool->extendWithPRDs(*indetCandidateCollection,tagMap.ptr(),mdtPRDContainer.cptr(),cscPRDContainer.cptr(),rpcPRDContainer.cptr(),tgcPRDContainer.cptr(),stgcPRDContainer.cptr(),mmPRDContainer.cptr());
      } else {
        for(auto& tool : m_muonCombinedInDetExtensionTools)
-         tool->extendWithPRDs(*indetCandidateCollection,mdtPRDContainer.cptr(),cscPRDContainer.cptr(),rpcPRDContainer.cptr(),tgcPRDContainer.cptr(),0,0);
+         tool->extendWithPRDs(*indetCandidateCollection,tagMap.ptr(),mdtPRDContainer.cptr(),cscPRDContainer.cptr(),rpcPRDContainer.cptr(),tgcPRDContainer.cptr(),0,0);
      }
   } else{
     for(auto& tool : m_muonCombinedInDetExtensionTools)
-      tool->extend(*indetCandidateCollection);
+      tool->extend(*indetCandidateCollection,tagMap.ptr());
   }
   
   return StatusCode::SUCCESS;
diff --git a/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonCombinedInDetExtensionAlg.h b/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonCombinedInDetExtensionAlg.h
index 1233215345ba..a3854bbc5ab4 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonCombinedInDetExtensionAlg.h
+++ b/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonCombinedInDetExtensionAlg.h
@@ -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
 */
 
 #ifndef MUONCOMBINEDALGS_MUONCOMBINEDINDETEXTENSIONALG_H
@@ -9,6 +9,7 @@
 #include "GaudiKernel/ToolHandle.h"
 #include "StoreGate/ReadHandleKey.h"
 #include "MuonCombinedEvent/InDetCandidateCollection.h"
+#include "MuonCombinedEvent/InDetCandidateToTagMap.h"
 #include "MuonPrepRawData/MuonPrepDataContainer.h"
 #include "MuonPrepRawData/MMPrepDataContainer.h"
 #include "MuonPrepRawData/sTgcPrepDataContainer.h"
@@ -38,6 +39,7 @@ class MuonCombinedInDetExtensionAlg : public AthAlgorithm
   SG::ReadHandleKey<Muon::TgcPrepDataContainer> m_TGC_ContainerName{this,"TGCPrepDataLocation","TGC_Measurements","TGC prep data"};
   SG::ReadHandleKey<Muon::sTgcPrepDataContainer> m_sTGC_ContainerName{this,"sTGCPrepDataLocation","sTGC_Clusters","sTGC prep data"};
   SG::ReadHandleKey<Muon::MMPrepDataContainer> m_MM_ContainerName{this,"MMPrepDataLocation","MM_Clusters","MM prep data"};
+  SG::WriteHandleKey<MuonCombined::InDetCandidateToTagMap> m_tagMap{this,"TagMap","muGirlTagMap","tag map"};
   bool m_usePRDs;
   bool m_useNSW;
 };
diff --git a/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonCreatorAlg.cxx b/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonCreatorAlg.cxx
index 314103127c20..ded803cbad03 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonCreatorAlg.cxx
+++ b/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonCreatorAlg.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
 */
 
 #include "MuonCreatorAlg.h"
@@ -16,6 +16,7 @@
 #include "xAODMuon/SlowMuonAuxContainer.h"
 #include "xAODCaloEvent/CaloClusterContainer.h"
 #include "xAODCaloEvent/CaloClusterAuxContainer.h"
+#include <vector>
 
 MuonCreatorAlg::MuonCreatorAlg(const std::string& name, ISvcLocator* pSvcLocator):
   AthAlgorithm(name,pSvcLocator),
@@ -34,9 +35,11 @@ StatusCode MuonCreatorAlg::initialize()
 
   ATH_CHECK(m_muonCreatorTool.retrieve());
   ATH_CHECK(m_muonCollectionName.initialize());
-  ATH_CHECK(m_slowMuonCollectionName.initialize());
+  ATH_CHECK(m_slowMuonCollectionName.initialize(m_buildSlowMuon));
   ATH_CHECK(m_indetCandidateCollectionName.initialize(!m_doSA));
   ATH_CHECK(m_muonCandidateCollectionName.initialize(!m_buildSlowMuon));
+  //Can't use a flag in intialize for an array of keys
+  if(!m_doSA) ATH_CHECK(m_tagMaps.initialize());
   m_segTrkContainerName = "Trk"+m_segContainerName.key();
   m_segContainerName = "xaod"+m_segContainerName.key();
   ATH_CHECK(m_segContainerName.initialize());
@@ -53,11 +56,9 @@ StatusCode MuonCreatorAlg::initialize()
   m_msOnlyExtrapolatedCollectionName = m_msOnlyExtrapolatedCollectionName.key()+"TrackParticles";
   ATH_CHECK(m_msOnlyExtrapolatedCollectionName.initialize());
   ATH_CHECK(m_msOnlyExtrapolatedTrkCollectionName.initialize());
-  if(m_clusterContainerName.key()!=""){
-    ATH_CHECK(m_clusterContainerName.initialize());
-    m_clusterContainerLinkName = m_clusterContainerName.key()+"_links";
-    ATH_CHECK(m_clusterContainerLinkName.initialize());
-  }
+  ATH_CHECK(m_clusterContainerName.initialize());
+  m_clusterContainerLinkName = m_clusterContainerName.key()+"_links";
+  ATH_CHECK(m_clusterContainerLinkName.initialize());
 
   return StatusCode::SUCCESS; 
 }
@@ -66,6 +67,7 @@ StatusCode MuonCreatorAlg::execute()
 {
 
   const InDetCandidateCollection *indetCandidateCollection = 0;
+  std::vector<const MuonCombined::InDetCandidateToTagMap*> tagMaps;
   if(!m_doSA){
     SG::ReadHandle<InDetCandidateCollection> indetRH(m_indetCandidateCollectionName);
     if(!indetRH.isValid()){
@@ -75,18 +77,20 @@ StatusCode MuonCreatorAlg::execute()
     else{
       indetCandidateCollection = indetRH.cptr();
     }
+    std::vector<SG::ReadHandle<MuonCombined::InDetCandidateToTagMap> > mapHandles=m_tagMaps.makeHandles();
+    for(auto& h : mapHandles) tagMaps.push_back(h.cptr());
   }
 
   // Create the xAOD container and its auxiliary store:
   SG::WriteHandle<xAOD::MuonContainer> wh_muons(m_muonCollectionName);
   ATH_CHECK(wh_muons.record(std::make_unique<xAOD::MuonContainer>(), std::make_unique<xAOD::MuonAuxContainer>()));
-  ATH_MSG_DEBUG( "Recorded Muons with key: " << m_muonCollectionName.key() );    
+  ATH_MSG_DEBUG( "Recorded Muons with key: " << m_muonCollectionName.key() );
   
   MuonCombined::IMuonCreatorTool::OutputData output(*(wh_muons.ptr()));
 
 
 
-  // Create the and record track particles:
+  // Create and record track particles:
   //combined tracks
   SG::WriteHandle<xAOD::TrackParticleContainer> wh_combtp(m_combinedCollectionName);
   SG::WriteHandle<TrackCollection> wh_combtrk(m_combinedTrkCollectionName);
@@ -121,18 +125,27 @@ StatusCode MuonCreatorAlg::execute()
   ATH_CHECK(wh_segmentTrk.record(std::make_unique<Trk::SegmentCollection>()));
   output.muonSegmentCollection=wh_segmentTrk.ptr();
 
-  xAOD::SlowMuonContainer *slowMuons=0;
-  xAOD::SlowMuonAuxContainer *slowMuonsAux=0;
-  if (m_buildSlowMuon){
-    slowMuons = new xAOD::SlowMuonContainer(); 
-    slowMuonsAux = new xAOD::SlowMuonAuxContainer();
-    slowMuons->setStore(slowMuonsAux);
-    output.slowMuonContainer = slowMuons;    
-  }
+  // calo clusters
+  xAOD::CaloClusterContainer *caloclusters = new xAOD::CaloClusterContainer();
+  xAOD::CaloClusterAuxContainer *caloclustersaux = new xAOD::CaloClusterAuxContainer();
+  caloclusters->setStore(caloclustersaux);
+  output.clusterContainer = caloclusters;
+  CaloClusterCellLinkContainer *clusterlinks = new CaloClusterCellLinkContainer();
+  SG::WriteHandle<xAOD::CaloClusterContainer> wh_clusters(m_clusterContainerName);
+  SG::WriteHandle<CaloClusterCellLinkContainer> wh_clusterslink(m_clusterContainerLinkName);
+
+  //record clusters and set the links
+  ATH_CHECK(wh_clusters.record(std::unique_ptr<xAOD::CaloClusterContainer>(caloclusters),std::unique_ptr<xAOD::CaloClusterAuxContainer>(caloclustersaux)));
 
   const MuonCandidateCollection *muonCandidateCollection =0;
 
-  if(!m_buildSlowMuon){
+  SG::WriteHandle<xAOD::SlowMuonContainer> wh_slowmuon;
+  if (m_buildSlowMuon){
+    wh_slowmuon=SG::WriteHandle<xAOD::SlowMuonContainer>(m_slowMuonCollectionName);
+    ATH_CHECK(wh_slowmuon.record(std::make_unique<xAOD::SlowMuonContainer>(),std::make_unique<xAOD::SlowMuonAuxContainer>()));
+    output.slowMuonContainer=wh_slowmuon.ptr();
+  }
+  else{
     SG::ReadHandle<MuonCandidateCollection> muonCandidateRH(m_muonCandidateCollectionName);
     if(!muonCandidateRH.isValid()){
       ATH_MSG_ERROR("Could not read "<< m_muonCandidateCollectionName);
@@ -140,42 +153,14 @@ StatusCode MuonCreatorAlg::execute()
     }
     muonCandidateCollection = muonCandidateRH.cptr();
   }
-
   
-  // calo clusters
-  if( m_clusterContainerName.key() != "" ){
-    xAOD::CaloClusterContainer *caloclusters = new xAOD::CaloClusterContainer();
-    xAOD::CaloClusterAuxContainer *caloclustersaux = new xAOD::CaloClusterAuxContainer();
-    caloclusters->setStore(caloclustersaux);
-    output.clusterContainer = caloclusters;
-    CaloClusterCellLinkContainer *clusterlinks = new CaloClusterCellLinkContainer();
-    SG::WriteHandle<xAOD::CaloClusterContainer> wh_clusters(m_clusterContainerName);
-    SG::WriteHandle<CaloClusterCellLinkContainer> wh_clusterslink(m_clusterContainerLinkName);
-    m_muonCreatorTool->create(muonCandidateCollection, indetCandidateCollection,output);
-
-    //record clusters and set the links
-    ATH_CHECK(wh_clusters.record(std::unique_ptr<xAOD::CaloClusterContainer>(caloclusters),std::unique_ptr<xAOD::CaloClusterAuxContainer>(caloclustersaux)));
-    auto sg = wh_clusters.storeHandle().get();
-    for (xAOD::CaloCluster* cl : *caloclusters) {
-      cl->setLink(clusterlinks, sg);
-    }
-    ATH_CHECK(wh_clusterslink.record(std::unique_ptr<CaloClusterCellLinkContainer>(clusterlinks)));
-
-
-  }  
-  else{
+  m_muonCreatorTool->create(muonCandidateCollection, indetCandidateCollection, tagMaps, output);
 
-    // build muons
-    if(!(muonCandidateCollection)){
-      ATH_MSG_WARNING("candidate collection missing, skip muon creation");
-    }
-    else m_muonCreatorTool->create(muonCandidateCollection, indetCandidateCollection ,output);
-  }
-
-  if (m_buildSlowMuon){
-    SG::WriteHandle<xAOD::SlowMuonContainer> wh_slowmuon(m_slowMuonCollectionName);
-    ATH_CHECK(wh_slowmuon.record(std::unique_ptr<xAOD::SlowMuonContainer>(slowMuons),std::unique_ptr<xAOD::SlowMuonAuxContainer>(slowMuonsAux)));
+  auto sg = wh_clusters.storeHandle().get();
+  for (xAOD::CaloCluster* cl : *caloclusters) {
+    cl->setLink(clusterlinks, sg);
   }
+  ATH_CHECK(wh_clusterslink.record(std::unique_ptr<CaloClusterCellLinkContainer>(clusterlinks)));
 
   return StatusCode::SUCCESS;
 }
diff --git a/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonCreatorAlg.h b/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonCreatorAlg.h
index b0e69d8228fe..4e4a6bc0c34f 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonCreatorAlg.h
+++ b/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonCreatorAlg.h
@@ -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
 */
 
 #ifndef MUONCOMBINEDALGS_MUONCREATORALG_H
@@ -9,9 +9,11 @@
 #include "GaudiKernel/ToolHandle.h"
 #include <string>
 #include "StoreGate/ReadHandleKey.h"
+#include "StoreGate/ReadHandleKeyArray.h"
 
 #include "MuonCombinedEvent/InDetCandidateCollection.h"
 #include "MuonCombinedEvent/MuonCandidateCollection.h"
+#include "MuonCombinedEvent/InDetCandidateToTagMap.h"
 
 #include "xAODMuon/MuonContainer.h"
 #include "xAODMuon/SlowMuonContainer.h"
@@ -47,6 +49,7 @@ class MuonCreatorAlg : public AthAlgorithm
   SG::WriteHandleKey<TrackCollection> m_msOnlyExtrapolatedTrkCollectionName{this,"MSOnlyExtrapolatedTrackLocation","MSOnlyExtrapolatedMuon","MS extrapolated muon tracks"};
   SG::ReadHandleKey<InDetCandidateCollection> m_indetCandidateCollectionName{this,"InDetCandidateLocation","InDetCandidates","ID candidates"};
   SG::ReadHandleKey<MuonCandidateCollection> m_muonCandidateCollectionName{this,"MuonCandidateLocation","MuonCandidates","Muon candidates"};
+  SG::ReadHandleKeyArray<MuonCombined::InDetCandidateToTagMap> m_tagMaps{this,"TagMaps",{"muidcoTagMap","stacoTagMap","muGirlTagMap","caloTagMap","segmentTagMap"},"ID candidate to tag maps"};
   SG::WriteHandleKey<xAOD::MuonSegmentContainer> m_segContainerName{this, "SegmentContainerName", "MuonSegments", "Segments"};
   SG::WriteHandleKey<Trk::SegmentCollection> m_segTrkContainerName{this,"TrackSegmentContainerName","MuonSegments","Track segments"};
   SG::WriteHandleKey<xAOD::CaloClusterContainer> m_clusterContainerName{this, "ClusterContainerName", "MuonClusterCollection", "Clusters"};
diff --git a/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonSegmentTagAlg.cxx b/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonSegmentTagAlg.cxx
index 589371456107..65dbe54343f4 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonSegmentTagAlg.cxx
+++ b/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonSegmentTagAlg.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
 */
 
 #include "MuonSegmentTagAlg.h"
@@ -21,6 +21,7 @@ StatusCode MuonSegmentTagAlg::initialize()
   ATH_CHECK(m_muonSegmentTagTool.retrieve());
   ATH_CHECK(m_indetCandidateCollectionName.initialize());
   ATH_CHECK(m_muonSegmentCollectionName.initialize());
+  ATH_CHECK(m_tagMap.initialize());
   
   return StatusCode::SUCCESS; 
 }
@@ -48,7 +49,10 @@ StatusCode MuonSegmentTagAlg::execute()
     return StatusCode::FAILURE;
   }
 
-  m_muonSegmentTagTool->tag(*indetCandidateCollection,*segments);
+  SG::WriteHandle<MuonCombined::InDetCandidateToTagMap> tagMap(m_tagMap);
+  ATH_CHECK( tagMap.record (std::make_unique<MuonCombined::InDetCandidateToTagMap>()) );
+
+  m_muonSegmentTagTool->tag(*indetCandidateCollection,*segments,tagMap.ptr());
   
   return StatusCode::SUCCESS;
 }
diff --git a/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonSegmentTagAlg.h b/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonSegmentTagAlg.h
index 7f50b54433c1..b06d8d5ad0c8 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonSegmentTagAlg.h
+++ b/Reconstruction/MuonIdentification/MuonCombinedAlgs/src/MuonSegmentTagAlg.h
@@ -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
 */
 
 #ifndef MUONCOMBINEDALGS_MUONSEGMENTAGALG_H
@@ -10,6 +10,7 @@
 #include "StoreGate/WriteDecorHandleKey.h"
 #include "xAODMuon/MuonSegmentContainer.h"
 #include "MuonCombinedEvent/InDetCandidateCollection.h"
+#include "MuonCombinedEvent/InDetCandidateToTagMap.h"
 #include "GaudiKernel/ToolHandle.h"
 
 namespace MuonCombined {
@@ -31,6 +32,7 @@ class MuonSegmentTagAlg : public AthAlgorithm
   ToolHandle<MuonCombined::IMuonSegmentTagTool> m_muonSegmentTagTool;
   Gaudi::Property<SG::ReadHandleKey<InDetCandidateCollection> > m_indetCandidateCollectionName{this,"InDetCandidateLocation","InDetCandidates","name of ID candidate collection"};
   Gaudi::Property<SG::ReadHandleKey<xAOD::MuonSegmentContainer> >m_muonSegmentCollectionName{this,"MuonSegmentLocation","MuonSegments","name of muon segment container"};
+  SG::WriteHandleKey<MuonCombined::InDetCandidateToTagMap> m_tagMap{this,"TagMap","segmentTagMap","tag map"};
 };
 
 
diff --git a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuGirlTagTool.cxx b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuGirlTagTool.cxx
index 81cf71e9ae6f..1cdd08a8612c 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuGirlTagTool.cxx
+++ b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuGirlTagTool.cxx
@@ -50,17 +50,18 @@ namespace MuonCombined {
     return StatusCode::SUCCESS;
   }
 
-  void MuGirlTagTool::extend( const InDetCandidateCollection& inDetCandidates ) {
+  void MuGirlTagTool::extend( const InDetCandidateCollection& inDetCandidates, InDetCandidateToTagMap* tagMap ) {
+    if(!tagMap) ATH_MSG_DEBUG("We don't run this tool any more anyway");
     if (m_pMuGirlReconstruction->MuGirlReco(inDetCandidates).isFailure()) {
       ATH_MSG_ERROR("MuGirl reconstruction failed!");
     }
   }
 
-  void MuGirlTagTool::extendWithPRDs( const InDetCandidateCollection& inDetCandidates, const Muon::MdtPrepDataContainer* mdtPRDs, const Muon::CscPrepDataContainer* cscPRDs,
-				      const Muon::RpcPrepDataContainer* rpcPRDs, const Muon::TgcPrepDataContainer *tgcPRDs, const Muon::sTgcPrepDataContainer* stgcPRDs,
-				      const Muon::MMPrepDataContainer* mmPRDs ) {
+  void MuGirlTagTool::extendWithPRDs( const InDetCandidateCollection& inDetCandidates, InDetCandidateToTagMap* tagMap, 
+				      const Muon::MdtPrepDataContainer* mdtPRDs, const Muon::CscPrepDataContainer* cscPRDs, const Muon::RpcPrepDataContainer* rpcPRDs, 
+				      const Muon::TgcPrepDataContainer *tgcPRDs, const Muon::sTgcPrepDataContainer* stgcPRDs, const Muon::MMPrepDataContainer* mmPRDs ) {
     //This is just a placeholder to ensure compilation until this tool is removed from the release: it is already deprecated
-    if(mdtPRDs && cscPRDs && rpcPRDs && tgcPRDs && stgcPRDs && mmPRDs){
+    if(mdtPRDs && cscPRDs && rpcPRDs && tgcPRDs && stgcPRDs && mmPRDs && tagMap){
       if (m_pMuGirlReconstruction->MuGirlReco(inDetCandidates).isFailure()) {
 	ATH_MSG_ERROR("MuGirl reconstruction failed!");
       }
diff --git a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuGirlTagTool.h b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuGirlTagTool.h
index 3a5a54cde848..28bdb47b5c41 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuGirlTagTool.h
+++ b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuGirlTagTool.h
@@ -26,11 +26,11 @@ namespace MuonCombined {
     virtual StatusCode finalize() override;
 
     /**IMuonCombinedInDetExtensionTool interface: extend ID candidate */    
-    virtual void extend( const InDetCandidateCollection& inDetCandidates ) override;
+    virtual void extend( const InDetCandidateCollection& inDetCandidates, InDetCandidateToTagMap* tagMap ) override;
 
-    virtual void extendWithPRDs(const InDetCandidateCollection& inDetCandidates, const Muon::MdtPrepDataContainer* mdtPRDs, const Muon::CscPrepDataContainer* cscPRDs,
-				const Muon::RpcPrepDataContainer* rpdPRDs, const Muon::TgcPrepDataContainer* tgcPRDs, const Muon::sTgcPrepDataContainer* sTGCPRDs,
-                                const Muon::MMPrepDataContainer* mmPRDs) override;
+    virtual void extendWithPRDs(const InDetCandidateCollection& inDetCandidates, InDetCandidateToTagMap* tagMap, 
+				const Muon::MdtPrepDataContainer* mdtPRDs, const Muon::CscPrepDataContainer* cscPRDs, const Muon::RpcPrepDataContainer* rpdPRDs, 
+				const Muon::TgcPrepDataContainer* tgcPRDs, const Muon::sTgcPrepDataContainer* sTGCPRDs, const Muon::MMPrepDataContainer* mmPRDs) override;
 
 
   private:
diff --git a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCaloTagTool.cxx b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCaloTagTool.cxx
index 39868c8e0307..107ca3060f8e 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCaloTagTool.cxx
+++ b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCaloTagTool.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
 */
 
 //////////////////////////////////////////////////////////////////////////////
@@ -138,14 +138,15 @@ namespace MuonCombined {
   
   }
 
-  void MuonCaloTagTool::extendWithPRDs( const InDetCandidateCollection& inDetCandidates, const Muon::MdtPrepDataContainer* mdtPRDs, const Muon::CscPrepDataContainer* cscPRDs,
-					const Muon::RpcPrepDataContainer* rpcPRDs, const Muon::TgcPrepDataContainer *tgcPRDs, const Muon::sTgcPrepDataContainer* stgcPRDs,
-					const Muon::MMPrepDataContainer* mmPRDs ) {
+  void MuonCaloTagTool::extendWithPRDs( const InDetCandidateCollection& inDetCandidates, InDetCandidateToTagMap* tagMap,
+					const Muon::MdtPrepDataContainer* mdtPRDs, const Muon::CscPrepDataContainer* cscPRDs, const Muon::RpcPrepDataContainer* rpcPRDs, 
+					const Muon::TgcPrepDataContainer *tgcPRDs, const Muon::sTgcPrepDataContainer* stgcPRDs, const Muon::MMPrepDataContainer* mmPRDs ) {
     //shouldn't need this interface for this tool, I don't think
-    if(mdtPRDs && cscPRDs && rpcPRDs && tgcPRDs && stgcPRDs && mmPRDs) extend(inDetCandidates);
+    if(!mdtPRDs || !cscPRDs || !rpcPRDs || !tgcPRDs || !stgcPRDs || !mmPRDs) ATH_MSG_DEBUG("calo-tagging doesn't need PRDs");
+    extend(inDetCandidates, tagMap);
   }
 
-  void MuonCaloTagTool::extend( const InDetCandidateCollection& inDetCandidates ) {
+  void MuonCaloTagTool::extend( const InDetCandidateCollection& inDetCandidates, InDetCandidateToTagMap* tagMap ) {
     const xAOD::CaloClusterContainer* caloClusterCont=0;
     const CaloCellContainer* caloCellCont=0;
     if(m_doCaloLR){ //retrieve the xAOD::CaloClusterContainer
@@ -160,10 +161,10 @@ namespace MuonCombined {
       else if(!cells.isPresent()) ATH_MSG_DEBUG("CaloCellContainer "<<m_caloCellCont.key()<<" not present");
       else caloCellCont=cells.cptr();
     }
-    extend(inDetCandidates, caloCellCont, caloClusterCont);
+    extend(inDetCandidates, tagMap, caloCellCont, caloClusterCont);
   }
 
-  void MuonCaloTagTool::extend( const InDetCandidateCollection& inDetCandidates,
+  void MuonCaloTagTool::extend( const InDetCandidateCollection& inDetCandidates, InDetCandidateToTagMap* tagMap,
                                 const CaloCellContainer* caloCellCont,
                                 const xAOD::CaloClusterContainer* caloClusterCont) {
 
@@ -281,7 +282,7 @@ namespace MuonCombined {
       }
       
       // FIXME const-cast  changes object passed in as const
-      createMuon(const_cast<InDetCandidate&>(*idTP),  deposits, tag, likelihood);
+      createMuon(*idTP,  deposits, tag, likelihood, tagMap);
 
       // --- Count number of muons written to container 
       if ( abs(pdgId) == 13 )  m_nMuonsTagged++;
@@ -449,8 +450,8 @@ namespace MuonCombined {
   */
 
   
-  void MuonCaloTagTool::createMuon(InDetCandidate& muonCandidate,
-                                   const std::vector<DepositInCalo>& deposits, int tag, float likelihood) const {
+  void MuonCaloTagTool::createMuon(const InDetCandidate& muonCandidate,
+                                   const std::vector<DepositInCalo>& deposits, int tag, float likelihood, InDetCandidateToTagMap* tagMap) const {
     
     std::vector<DepositInCalo>::const_iterator deposit  = deposits.begin();
     std::vector<DepositInCalo>::const_iterator depositE = deposits.end();
@@ -473,7 +474,7 @@ namespace MuonCombined {
       
 //      eLoss = m_muonIsolationTool->summedCellEnergy(ptcl, m_coreDR);
 //      caloTag->set_etCore(eLoss);
-      muonCandidate.addTag(*caloTag);
+      tagMap->addEntry(&muonCandidate,caloTag);
     }
   }
 
diff --git a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCaloTagTool.h b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCaloTagTool.h
index 1337eab2451c..43365efa914f 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCaloTagTool.h
+++ b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCaloTagTool.h
@@ -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
 */
 
 #ifndef MUONCOMBINEDBASETOOLS_MUONCALOTAGTOOL_H
@@ -53,21 +53,21 @@ namespace MuonCombined {
 
     /**IMuonCombinedInDetExtensionTool interface: extend ID candidate */    
     virtual
-    void extend( const InDetCandidateCollection& inDetCandidates ) override;
+      void extend( const InDetCandidateCollection& inDetCandidates, InDetCandidateToTagMap* tagMap ) override;
 
     virtual
-    void extend( const InDetCandidateCollection& inDetCandidates,
-                 const CaloCellContainer* caloCellContainer,
-                 const xAOD::CaloClusterContainer* caloClusterContainer) override;
+      void extend( const InDetCandidateCollection& inDetCandidates, InDetCandidateToTagMap* tagMap,
+		   const CaloCellContainer* caloCellContainer,
+		   const xAOD::CaloClusterContainer* caloClusterContainer) override;
 
-    virtual void extendWithPRDs(const InDetCandidateCollection& inDetCandidates, const Muon::MdtPrepDataContainer* mdtPRDs, const Muon::CscPrepDataContainer* cscPRDs,
-				const Muon::RpcPrepDataContainer* rpdPRDs, const Muon::TgcPrepDataContainer* tgcPRDs, const Muon::sTgcPrepDataContainer* sTGCPRDs,
-                                const Muon::MMPrepDataContainer* mmPRDs) override;
+    virtual void extendWithPRDs(const InDetCandidateCollection& inDetCandidates, InDetCandidateToTagMap* tagMap, 
+				const Muon::MdtPrepDataContainer* mdtPRDs, const Muon::CscPrepDataContainer* cscPRDs, const Muon::RpcPrepDataContainer* rpdPRDs, 
+				const Muon::TgcPrepDataContainer* tgcPRDs, const Muon::sTgcPrepDataContainer* sTGCPRDs, const Muon::MMPrepDataContainer* mmPRDs) override;
 
 
   private:
     
-    void createMuon(InDetCandidate & muonCandidate, const std::vector<DepositInCalo>& deposits, int tag, float likelihood) const;
+    void createMuon(const InDetCandidate & muonCandidate, const std::vector<DepositInCalo>& deposits, int tag, float likelihood, InDetCandidateToTagMap* tagMap) const;
     const Trk::TrackParameters* getTrackParameters(const Trk::Track* trk) const;
     //bool applyEnergyIsolation(const xAOD::IParticle* muon);
     bool selectTrack(const Trk::Track* trk, const Trk::Vertex* vertex) const;
diff --git a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedDebuggerTool.h b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedDebuggerTool.h
index 3525e5d53853..027c828f38bb 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedDebuggerTool.h
+++ b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedDebuggerTool.h
@@ -37,9 +37,9 @@ namespace MuonCombined {
   public:
     MuonCombinedDebuggerTool(const std::string& type, const std::string& name, const IInterface* parent);
     ~MuonCombinedDebuggerTool(void); // destructor
-  
-    static const InterfaceID& interfaceID() {return IID_MuonCombinedDebuggerTool;}
 
+    static const InterfaceID& interfaceID() {return IID_MuonCombinedDebuggerTool;}
+  
     StatusCode initialize();
     StatusCode finalize();
 
diff --git a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedFitTagTool.cxx b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedFitTagTool.cxx
index 5bc85ebb4e71..c2c31db8950d 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedFitTagTool.cxx
+++ b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedFitTagTool.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
 */
 
 //////////////////////////////////////////////////////////////////////////////
@@ -25,6 +25,7 @@
 #include "MuonCombinedToolInterfaces/IMuonMomentumBalanceSignificance.h"
 
 #include "MuonCombinedEvent/InDetCandidate.h"
+#include "MuonCombinedEvent/InDetCandidateToTagMap.h"
 #include "MuonCombinedEvent/MuonCandidate.h"
 #include "MuonCombinedEvent/CombinedFitTag.h"
 #include "TrkToolInterfaces/ITrackScoringTool.h"
@@ -79,60 +80,60 @@ namespace MuonCombined {
   MuonCombinedFitTagTool::~MuonCombinedFitTagTool()
   {}
 
-    //<<<<<< PUBLIC MEMBER FUNCTION DEFINITIONS                             >>>>>>
-
-    StatusCode MuonCombinedFitTagTool::initialize() {
-      ATH_MSG_INFO( "Initializing MuonCombinedFitTagTool - package version " << PACKAGE_VERSION );
-
-      ATH_CHECK(m_printer.retrieve());
-      ATH_CHECK(m_tagTool.retrieve());
-      ATH_CHECK(m_trackBuilder.retrieve());
-      if(! m_outwardsBuilder.empty() ) ATH_CHECK(m_outwardsBuilder.retrieve());
-      ATH_CHECK(m_trackQuery.retrieve());
-      ATH_CHECK(m_momentumBalanceTool.retrieve());
-      if(! m_muonRecovery.empty() ) ATH_CHECK(m_muonRecovery.retrieve());
-      ATH_CHECK(m_matchQuality.retrieve());
-      ATH_CHECK(m_trackScoringTool.retrieve());
-      ATH_CHECK(m_magFieldSvc.retrieve());
-
-      if (detStore()->retrieve(m_DetID, "AtlasID").isFailure()) {
-        ATH_MSG_ERROR ("Could not get AtlasDetectorID helper" );
-        return StatusCode::FAILURE;
-      }
-
-      ATH_CHECK( m_vertexKey.initialize() );
-
-      return StatusCode::SUCCESS;
-    }
-
-    StatusCode MuonCombinedFitTagTool::finalize() {
-      return StatusCode::SUCCESS;
+  //<<<<<< PUBLIC MEMBER FUNCTION DEFINITIONS                             >>>>>>
+  
+  StatusCode MuonCombinedFitTagTool::initialize() {
+    ATH_MSG_INFO( "Initializing MuonCombinedFitTagTool - package version " << PACKAGE_VERSION );
+    
+    ATH_CHECK(m_printer.retrieve());
+    ATH_CHECK(m_tagTool.retrieve());
+    ATH_CHECK(m_trackBuilder.retrieve());
+    if(! m_outwardsBuilder.empty() ) ATH_CHECK(m_outwardsBuilder.retrieve());
+    ATH_CHECK(m_trackQuery.retrieve());
+    ATH_CHECK(m_momentumBalanceTool.retrieve());
+    if(! m_muonRecovery.empty() ) ATH_CHECK(m_muonRecovery.retrieve());
+    ATH_CHECK(m_matchQuality.retrieve());
+    ATH_CHECK(m_trackScoringTool.retrieve());
+    ATH_CHECK(m_magFieldSvc.retrieve());
+
+    if (detStore()->retrieve(m_DetID, "AtlasID").isFailure()) {
+      ATH_MSG_ERROR ("Could not get AtlasDetectorID helper" );
+      return StatusCode::FAILURE;
     }
+    
+    ATH_CHECK( m_vertexKey.initialize() );
+    
+    return StatusCode::SUCCESS;
+  }
+  
+  StatusCode MuonCombinedFitTagTool::finalize() {
+    return StatusCode::SUCCESS;
+  }
 
-    void MuonCombinedFitTagTool::combine( const MuonCandidate& muonCandidate, const std::vector<InDetCandidate*>& indetCandidates ) const {  
-
-      ATH_MSG_DEBUG("muon candidate: "<<muonCandidate.toString());
-
-      CombinedFitTag* bestTag=0;
-      InDetCandidate* bestCandidate=0;
-      std::multimap<double,InDetCandidate*> sortedInDetCandidates; //map of ID candidates by max probability of match (based on match chi2 at IP and MS entrance)
-      float probCut=.00001; //cut on max probability: below this cut, we don't attempt to form a combined track unless no combined track has yet been successfully created
-
-      // loop over ID candidates
-      for( auto& idTP : indetCandidates ){
-        double outerMatchProb = m_matchQuality->outerMatchProbability(*idTP->indetTrackParticle().track(), muonCandidate.muonSpectrometerTrack());
-        double innerMatchProb=-1;
-        if(muonCandidate.extrapolatedTrack()) innerMatchProb = m_matchQuality->innerMatchProbability(*idTP->indetTrackParticle().track(), *muonCandidate.extrapolatedTrack());
-        double maxProb=outerMatchProb; if(innerMatchProb>maxProb) maxProb=innerMatchProb;
-        sortedInDetCandidates.insert(std::pair<double,InDetCandidate*>(maxProb,idTP));
-      }
+  void MuonCombinedFitTagTool::combine( const MuonCandidate& muonCandidate, const std::vector<const InDetCandidate*>& indetCandidates, InDetCandidateToTagMap& tagMap) const {  
 
-      bool fitBadMatches=false;
+    ATH_MSG_DEBUG("muon candidate: "<<muonCandidate.toString());
 
-      std::multimap<double,InDetCandidate*>::reverse_iterator rit;
+    CombinedFitTag* bestTag=0;
+    const InDetCandidate* bestCandidate=0;
+    std::multimap<double,const InDetCandidate*> sortedInDetCandidates; //map of ID candidates by max probability of match (based on match chi2 at IP and MS entrance)
+    float probCut=.00001; //cut on max probability: below this cut, we don't attempt to form a combined track unless no combined track has yet been successfully created
 
-      //for(auto& sidTP : sortedInDetCandidates){
-      for(rit=sortedInDetCandidates.rbegin();rit!=sortedInDetCandidates.rend();++rit){ //multimap sorts from lowest to highest, so need to go through it in reverse order, sadly I don't think auto can do that yet
+    // loop over ID candidates
+    for( const auto& idTP : indetCandidates ){
+      double outerMatchProb = m_matchQuality->outerMatchProbability(*idTP->indetTrackParticle().track(), muonCandidate.muonSpectrometerTrack());
+      double innerMatchProb=-1;
+      if(muonCandidate.extrapolatedTrack()) innerMatchProb = m_matchQuality->innerMatchProbability(*idTP->indetTrackParticle().track(), *muonCandidate.extrapolatedTrack());
+      double maxProb=outerMatchProb; if(innerMatchProb>maxProb) maxProb=innerMatchProb;
+      sortedInDetCandidates.insert(std::pair<double,const InDetCandidate*>(maxProb,idTP));
+    }
+    
+    bool fitBadMatches=false;
+      
+    std::multimap<double,const InDetCandidate*>::reverse_iterator rit;
+    
+    //for(auto& sidTP : sortedInDetCandidates){
+    for(rit=sortedInDetCandidates.rbegin();rit!=sortedInDetCandidates.rend();++rit){ //multimap sorts from lowest to highest, so need to go through it in reverse order
 
       ATH_MSG_DEBUG("in det candidate prob: "<<(*rit).first);
 
@@ -147,7 +148,7 @@ namespace MuonCombined {
       if(msgLevel() >= MSG::VERBOSE) {
         ATH_MSG_VERBOSE("Doing combined fit with ID track "<<*((*rit).second->indetTrackParticle().track()));
         ATH_MSG_VERBOSE("Doing combined fit with MS track "<<muonCandidate.muonSpectrometerTrack());
-      }      
+      }
 
       // fit the combined ID-MS track
       const Trk::Track* combinedTrack = buildCombinedTrack (*((*rit).second->indetTrackParticle().track()),
@@ -237,9 +238,11 @@ namespace MuonCombined {
         }
 
       }
+      ATH_MSG_DEBUG("Final combined muon: "<<m_printer->print(bestTag->combinedTrack()));
+      ATH_MSG_DEBUG(m_printer->printStations(bestTag->combinedTrack()));
       ATH_MSG_DEBUG("Combined Muon with ID " << m_printer->print(bestCandidate->indetTrackParticle().perigeeParameters())
         << " match chi2 " << bestTag->matchChi2() << " outer match " << outerMatchChi2 );
-      bestCandidate->addTag(*bestTag);
+      tagMap.addEntry(bestCandidate,bestTag);
     }   
   }
 
diff --git a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedFitTagTool.h b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedFitTagTool.h
index 1c7295431a31..6d86c51842a9 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedFitTagTool.h
+++ b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedFitTagTool.h
@@ -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
 */
 
 #ifndef MUONCOMBINEDBASETOOLS_MUONCOMBINEDFITTAGTOOL_H
@@ -45,6 +45,7 @@ namespace MuonCombined {
   class MuonCandidate;
   class IMuonTrackTagTool;
   class CombinedFitTag;
+  class InDetCandidateToTagMap;
 
   class MuonCombinedFitTagTool: public AthAlgTool, virtual public IMuonCombinedTagTool
   {
@@ -58,7 +59,7 @@ namespace MuonCombined {
 
     /**IMuonCombinedTagTool interface: build combined  muons from a muon and a vector of indet candidates */    
     virtual 
-    void combine( const MuonCandidate& muonCandidate, const std::vector<InDetCandidate*>& indetCandidates ) const override;
+      void combine( const MuonCandidate& muonCandidate, const std::vector<const InDetCandidate*>& indetCandidates, InDetCandidateToTagMap& tagMap ) const override;
 
   private:
 
diff --git a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedStacoTagTool.cxx b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedStacoTagTool.cxx
index 26ca36f07f79..06947b750911 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedStacoTagTool.cxx
+++ b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedStacoTagTool.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
 */
 
 //////////////////////////////////////////////////////////////////////////////
@@ -14,8 +14,8 @@
 #include "MuonRecHelperTools/MuonEDMPrinterTool.h"
 #include "TrkExInterfaces/IExtrapolator.h"
 
-#include "MuonCombinedToolInterfaces/IMuonCombinedTool.h"
 #include "MuonCombinedEvent/InDetCandidate.h"
+#include "MuonCombinedEvent/InDetCandidateToTagMap.h"
 #include "MuonCombinedEvent/MuonCandidate.h"
 #include "MuonCombinedEvent/StacoTag.h"
 #include "MuonCombinedStacoTagTool.h"
@@ -55,7 +55,7 @@ namespace MuonCombined {
     return StatusCode::SUCCESS;
   }
 
-  void MuonCombinedStacoTagTool::combine( const MuonCandidate& muonCandidate, const std::vector<InDetCandidate*>& indetCandidates ) const {  
+  void MuonCombinedStacoTagTool::combine( const MuonCandidate& muonCandidate, const std::vector<const InDetCandidate*>& indetCandidates, InDetCandidateToTagMap& tagMap ) const {  
 
     // only combine if the back extrapolation was successfull
     if( !muonCandidate.extrapolatedTrack() ||
@@ -63,11 +63,11 @@ namespace MuonCombined {
 	!muonCandidate.extrapolatedTrack()->perigeeParameters()->covariance() ) return;
 
     std::unique_ptr<const Trk::Perigee> bestPerigee;
-    InDetCandidate*     bestCandidate = 0;
+    const InDetCandidate*     bestCandidate = 0;
     double              bestChi2=2e20;
 
     // loop over ID candidates
-    for( auto idTP : indetCandidates ){
+    for( const auto idTP : indetCandidates ){
       
       //skip tracklets
       if(idTP->isSiliconAssociated()) continue;
@@ -120,7 +120,7 @@ namespace MuonCombined {
       }
       ATH_MSG_DEBUG("Combined Muon with ID " << m_printer->print(*bestPerigee) << " match chi2 " << bestChi2 << " outer match " << outerMatchChi2 );
       StacoTag* tag = new StacoTag(muonCandidate,bestPerigee,bestChi2);
-      bestCandidate->addTag(*tag);
+      tagMap.addEntry(bestCandidate,tag);
     }    
   }
 
diff --git a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedStacoTagTool.h b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedStacoTagTool.h
index b3d23c5af942..feea6d941e5d 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedStacoTagTool.h
+++ b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedStacoTagTool.h
@@ -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
 */
 
 #ifndef MUONCOMBINEDBASETOOLS_MUONCOMBINEDSTACOTAGTOOL_H
@@ -29,6 +29,7 @@ namespace Trk {
 namespace MuonCombined {
   class InDetCandidate;
   class MuonCandidate;
+  class InDetCandidateToTagMap;
   class IMuonTrackTagTool;
 
   class MuonCombinedStacoTagTool: public AthAlgTool, virtual public IMuonCombinedTagTool
@@ -43,7 +44,7 @@ namespace MuonCombined {
 
     /**IMuonCombinedTagTool interface: build combined  muons from a muon and a vector of indet candidates */    
     virtual
-    void combine( const MuonCandidate& muonCandidate, const std::vector<InDetCandidate*>& indetCandidates ) const override;
+      void combine( const MuonCandidate& muonCandidate, const std::vector<const InDetCandidate*>& indetCandidates, InDetCandidateToTagMap& tagMap ) const override;
 
   private:
 
diff --git a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedTool.cxx b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedTool.cxx
index d3c9772151c0..be60144bdd48 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedTool.cxx
+++ b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedTool.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
 */
 
 //////////////////////////////////////////////////////////////////////////////
@@ -28,7 +28,6 @@ namespace MuonCombined {
     :	AthAlgTool(type, name, parent),
 	m_printer("Muon::MuonEDMPrinterTool/MuonEDMPrinterTool"),
 	m_muonCombDebugger("MuonCombined::MuonCombinedDebuggerTool/MuonCombinedDebuggerTool")
-	//m_muonCombinedTagTools("MuonCombined::MuonCombinedStacoTagTool/MuonCombinedStacoTagTool")
   {
     declareInterface<IMuonCombinedTool>(this);
     declareProperty("Printer",m_printer );
@@ -62,11 +61,15 @@ namespace MuonCombined {
     return StatusCode::SUCCESS;
   }
 
-  void MuonCombinedTool::combine( const MuonCandidateCollection& muonCandidates,  const InDetCandidateCollection& inDetCandidates ) const {
+  void MuonCombinedTool::combine( const MuonCandidateCollection& muonCandidates, const InDetCandidateCollection& inDetCandidates, std::vector<InDetCandidateToTagMap*> tagMaps) const {
    
       // check that there are tracks in both systems
     if( inDetCandidates.empty() ) return;
     if( muonCandidates.empty() )  return;
+    if(tagMaps.size()!=m_muonCombinedTagTools.size()){
+      ATH_MSG_ERROR("Number of tag maps does not match number of tag tools");
+      return;
+    }
 
     // debug tree
     if(m_runMuonCombinedDebugger) {
@@ -78,19 +81,21 @@ namespace MuonCombined {
       const Trk::Track& muonTrack = muonCandidate->extrapolatedTrack() ? *muonCandidate->extrapolatedTrack() : muonCandidate->muonSpectrometerTrack();
       ATH_MSG_DEBUG("MuonCandidate " << m_printer->print(muonTrack) << std::endl << m_printer->printStations(muonTrack) ); 
       // preselect ID candidates close to the muon
-      std::vector<InDetCandidate*> associatedIdCandidates;
+      std::vector<const InDetCandidate*> associatedIdCandidates;
       associate(*muonCandidate,inDetCandidates,associatedIdCandidates);
       if( associatedIdCandidates.empty() ) continue;
       ATH_MSG_DEBUG("Associated ID candidates " << associatedIdCandidates.size() );
       // build combined muons
-      for(auto& tool : m_muonCombinedTagTools) 
-	tool->combine(*muonCandidate,associatedIdCandidates);
-      
+      int count=0;
+      for(auto& tool : m_muonCombinedTagTools){
+	tool->combine(*muonCandidate,associatedIdCandidates,*(tagMaps.at(count)));
+	count++;
+      }
     }    
   }
 
   void MuonCombinedTool::associate( const MuonCandidate& muonCandidate, const InDetCandidateCollection& inDetCandidates,  
-				    std::vector<InDetCandidate*>& associatedIdCandidates ) const {
+				    std::vector<const InDetCandidate*>& associatedIdCandidates ) const {
 
     // define muon (eta,phi)
     double muonEta = 0.;
@@ -120,8 +125,7 @@ namespace MuonCombined {
       if (deltaEta            > m_deltaEtaPreSelection)  continue;
       if (fabs(deltaPhi)      > m_deltaPhiPreSelection)  continue;
       if (ptBal               > m_ptBalance) continue;
-      // FIXME: changing objects recorded in SG.
-      associatedIdCandidates.push_back(const_cast<InDetCandidate*>(x));
+      associatedIdCandidates.push_back(x);
     }
   }
 
diff --git a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedTool.h b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedTool.h
index 5a3aedfce2e1..ad24457cba0c 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedTool.h
+++ b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCombinedTool.h
@@ -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
 */
 
 #ifndef MUONCOMBINEDBASETOOLS_MUONCOMBINEDTOOL_H
@@ -10,6 +10,7 @@
 #include "MuonCombinedToolInterfaces/IMuonCombinedTool.h"
 #include "MuonCombinedEvent/MuonCandidateCollection.h"
 #include "MuonCombinedEvent/InDetCandidateCollection.h"
+#include "MuonCombinedEvent/InDetCandidateToTagMap.h"
 #include "MuonCombinedDebuggerTool.h"
 
 namespace Muon
@@ -31,12 +32,12 @@ namespace MuonCombined {
     StatusCode initialize();
     StatusCode finalize();
 
-    void combine( const MuonCandidateCollection& muonCandidates,  const InDetCandidateCollection& inDetCandidates ) const;
+    void combine(const MuonCandidateCollection& muonCandidates,const InDetCandidateCollection& inDetCandidates, std::vector<InDetCandidateToTagMap*> tagMaps) const;
 
   private:
 
     void associate( const MuonCandidate& muonCandidate, const InDetCandidateCollection& inDetCandidates,  
-		    std::vector<InDetCandidate*>& associatedIdCandidates ) const ;
+		    std::vector<const InDetCandidate*>& associatedIdCandidates ) const ;
 
     // helpers, managers, tools
     ToolHandle<Muon::MuonEDMPrinterTool>            m_printer;
diff --git a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCreatorTool.cxx b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCreatorTool.cxx
index c52168b67829..890994b0b72c 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCreatorTool.cxx
+++ b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCreatorTool.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
 */
 
 /////////////////////////////////////////////////////////////////////////////
@@ -187,7 +187,8 @@ namespace MuonCombined {
     return StatusCode::SUCCESS;
   }
 
-  void MuonCreatorTool::create( const MuonCandidateCollection* muonCandidates,  const InDetCandidateCollection* inDetCandidates, OutputData& outputData ) const {
+  void MuonCreatorTool::create( const MuonCandidateCollection* muonCandidates,  const InDetCandidateCollection* inDetCandidates, std::vector<const InDetCandidateToTagMap*> tagMaps, 
+				OutputData& outputData ) const {
 
     unsigned int numIdCan = inDetCandidates ? inDetCandidates->size() : 0;
     unsigned int numMuCan = muonCandidates  ? muonCandidates->size() : 0;
@@ -200,20 +201,21 @@ namespace MuonCombined {
 	  addRpcTiming(**(candidate->muonSpectrometerTrackLink()));    
     
     // Create containers for resolved candidates (always of type VIEW_ELEMENTS)
-    std::vector<const MuonCombined::InDetCandidate*> resolvedInDetCandidates;
+    InDetCandidateTagsMap resolvedInDetCandidates;
+    //std::vector<const MuonCombined::InDetCandidate*> resolvedInDetCandidates;
     std::vector<const MuonCombined::MuonCandidate*> resolvedMuonCandidates;
     
     // Resolve Overlap
-    if (!m_buildStauContainer) resolveOverlaps(inDetCandidates, muonCandidates, resolvedInDetCandidates, resolvedMuonCandidates);    
-    else selectStaus(inDetCandidates, resolvedInDetCandidates);    
+    if (!m_buildStauContainer) resolveOverlaps(inDetCandidates, muonCandidates, tagMaps, resolvedInDetCandidates, resolvedMuonCandidates);    
+    else selectStaus(inDetCandidates, resolvedInDetCandidates, tagMaps);
 
     if( inDetCandidates ) ATH_MSG_DEBUG("InDetCandidates : overlap removal " << inDetCandidates->size() << " in, " <<resolvedInDetCandidates.size() <<" out");
     if( !m_buildStauContainer && muonCandidates  ) ATH_MSG_DEBUG("MuonCandidates  : overlap removal " << muonCandidates->size() << " in, " <<resolvedMuonCandidates.size() <<" out");
 
     // Create a container for resolved candidates (always of type VIEW_ELEMENTS)
-    for( auto can : resolvedInDetCandidates ) {
+    for( InDetCandidateTags can : resolvedInDetCandidates ) {
       ATH_MSG_DEBUG("New InDetCandidate");
-      xAOD::Muon* muon = create(*can,outputData);
+      xAOD::Muon* muon = create(can,outputData);
       if( !muon ) { 
         ATH_MSG_DEBUG("no muon found");
       }else {
@@ -397,20 +399,20 @@ namespace MuonCombined {
   }
 
 
-  xAOD::Muon* MuonCreatorTool::create( const InDetCandidate& candidate, OutputData& outputData ) const {
+  xAOD::Muon* MuonCreatorTool::create( InDetCandidateTags& candidate, OutputData& outputData ) const {
 
     // no tags, no muon
-    if( candidate.combinedDataTags().empty() ) {
+    if( candidate.second.empty() ) {
       ATH_MSG_DEBUG("MuonCreatorTool::create(...) - InDetCandidate with empty combinedDataTags. Aborting. Will not create Muon.");
       return 0;
     }
     
-    if( !candidate.indetTrackParticleLink().isValid() ) {
+    if( !candidate.first->indetTrackParticleLink().isValid() ) {
       ATH_MSG_WARNING("MuonCreatorTool::create(...) : Have InDetCandidate with no valid link to an ID trackparticle. Aborting! Will not create Muon.");
       return 0;
     }
     
-    std::vector<const TagBase*> tags = candidate.combinedDataTags();
+    std::vector<const TagBase*> tags = candidate.second;
     if(tags.size()==1 && !m_buildStauContainer){
       const MuGirlLowBetaTag* muGirlLowBetaTag = dynamic_cast<const MuGirlLowBetaTag*>(tags[0]);
       if (muGirlLowBetaTag){
@@ -428,9 +430,9 @@ namespace MuonCombined {
     // now we need to sort the tags to get the best muon
     
     // set the link to the ID track particle
-    muon->setTrackParticleLink(xAOD::Muon::InnerDetectorTrackParticle, candidate.indetTrackParticleLink() );
-    ATH_MSG_DEBUG("Adding InDet Track: pt " << (*candidate.indetTrackParticleLink())->pt() 
-      << " eta " << (*candidate.indetTrackParticleLink())->eta() << " phi " << (*candidate.indetTrackParticleLink())->phi() );
+    muon->setTrackParticleLink(xAOD::Muon::InnerDetectorTrackParticle, candidate.first->indetTrackParticleLink() );
+    ATH_MSG_DEBUG("Adding InDet Track: pt " << (*candidate.first->indetTrackParticleLink())->pt() 
+      << " eta " << (*candidate.first->indetTrackParticleLink())->eta() << " phi " << (*candidate.first->indetTrackParticleLink())->phi() );
     
     ATH_MSG_DEBUG("creating Muon with " << tags.size() << " tags ");
     // loop over the tags
@@ -438,7 +440,7 @@ namespace MuonCombined {
     // Set variables to zero by calling the functions with null pointers.
     addCaloTag(*muon,0);
     addCombinedFit(*muon,0, outputData );
-    addStatisticalCombination(*muon,candidate,0, outputData );
+    addStatisticalCombination(*muon,*(candidate.first),0, outputData );
     addMuGirl(*muon,0, outputData );  
     addSegmentTag(*muon,0);
     
@@ -470,7 +472,7 @@ namespace MuonCombined {
             if( outputData.slowMuonContainer ) {
               xAOD::SlowMuon* slowMuon = new xAOD::SlowMuon();
               outputData.slowMuonContainer->push_back( slowMuon );
-            
+
 	      addMuGirlLowBeta(*muon,muGirlLowBetaTag,slowMuon, outputData ); // CHECK to see what variables are created here.
 
 	      ATH_MSG_DEBUG("slowMuon muonContainer size "<<outputData.muonContainer->size());
@@ -495,7 +497,7 @@ namespace MuonCombined {
           muon->setAuthor(tag->author());
           muon->setMuonType(tag->type());
           // Overrride type if InDet track is SiAssociated.
-          if (candidate.isSiliconAssociated() ) {
+          if (candidate.first->isSiliconAssociated() ) {
             muon->setMuonType(xAOD::Muon::SiliconAssociatedForwardMuon);
           }
           first = false;
@@ -512,7 +514,7 @@ namespace MuonCombined {
           const MuGirlTag* muGirlTag = dynamic_cast<const MuGirlTag*>(tag);
           
           addCombinedFit(*muon,cbFitTag, outputData );
-          addStatisticalCombination(*muon,candidate,stacoTag, outputData );
+          addStatisticalCombination(*muon,*(candidate.first),stacoTag, outputData );
           addMuGirl(*muon,muGirlTag, outputData );          
           if (! (cbFitTag||stacoTag||muGirlTag) ) {
             ATH_MSG_WARNING("Unknown combined tag ");
@@ -526,7 +528,7 @@ namespace MuonCombined {
           addMuGirl(*muon,muGirlTag, outputData );
           
           if (! (segTag||muGirlTag) ) {
-            ATH_MSG_WARNING("Unknown MuGirl tag ");
+            ATH_MSG_WARNING("Unknown segment-tagged tag ");
           }
         }else if( type == xAOD::Muon::CaloTagged ){
           const CaloTag* caloTag = dynamic_cast<const CaloTag*>(tag);
@@ -1010,34 +1012,7 @@ namespace MuonCombined {
         ATH_MSG_WARNING("Track doesn't have extrapolated track. Skipping");
       if (extrapolatedTrack && !extrapolatedTrack->perigeeParameters()) 
         ATH_MSG_WARNING("Track doesn't have perigee parameters on extrapolated track. Skipping");
-      //ATH_MSG_DEBUG("Set values to -999.0.");
-      //muon.setParameter( (float)-999.0, xAOD::Muon::d0_sa);
-      //muon.setParameter( (float)-999.0, xAOD::Muon::z0_sa);
-      //muon.setParameter( (float)-999.0, xAOD::Muon::phi0_sa);
-      //muon.setParameter( (float)-999.0, xAOD::Muon::theta_sa);
-      //muon.setParameter( (float)-999.0, xAOD::Muon::qOverP_sa);
-      //muon.setParameter( (float)-999.0, xAOD::Muon::Eloss_sa);
     } else {
-      //add the perigee parameters for the original extrapolated track
-      /*
-      float d0_sa=extrapolatedTrack->perigeeParameters()->parameters()[Trk::d0];
-      muon.setParameter(d0_sa, xAOD::Muon::d0_sa);
-      float z0_sa=extrapolatedTrack->perigeeParameters()->parameters()[Trk::z0];
-      muon.setParameter(z0_sa, xAOD::Muon::z0_sa);
-      float phi0_sa=extrapolatedTrack->perigeeParameters()->parameters()[Trk::phi0];
-      muon.setParameter(phi0_sa, xAOD::Muon::phi0_sa);
-      float theta_sa=extrapolatedTrack->perigeeParameters()->parameters()[Trk::theta];
-      muon.setParameter(theta_sa, xAOD::Muon::theta_sa);
-      float qOverP_sa=extrapolatedTrack->perigeeParameters()->parameters()[Trk::qOverP];
-      muon.setParameter(qOverP_sa, xAOD::Muon::qOverP_sa);
-      if(muon.author()==xAOD::Muon::MuidCo){ //only want this for combined tracks when there could have been a refit
-	const CaloEnergy* caloEnergy = m_trackQuery->caloEnergy(*extrapolatedTrack);
-	if(caloEnergy){
-	  float Eloss_sa=caloEnergy->deltaE();
-	  muon.setParameter(Eloss_sa, xAOD::Muon::Eloss_sa);
-	}
-      }
-      */
       //Now we just add the original extrapolated track itself
       //but not for SA muons, for consistency they will still have extrapolatedTrackParticle
       if(muon.muonType()!=xAOD::Muon::MuonStandAlone){
@@ -1126,51 +1101,35 @@ namespace MuonCombined {
   }
 
   void MuonCreatorTool::selectStaus( const InDetCandidateCollection* inDetCandidates,
-                                     std::vector<const MuonCombined::InDetCandidate*>& resolvedInDetCandidates) const {
-    //staus need to be kept so can go into separate xAOD staucontainer, if desired
-    std::vector< const InDetCandidate* > staus;
+                                     InDetCandidateTagsMap& resolvedInDetCandidates, 
+				     std::vector<const InDetCandidateToTagMap*> tagMaps) const {
 
     if( inDetCandidates ) {
 
       for( auto candidate : *inDetCandidates ) {
-        const InDetCandidate *can = candidate;
-        std::vector<const TagBase*> tags = can->combinedDataTags();
-        for( auto tag : tags ){
-          const MuGirlLowBetaTag* muGirlLowBetaTag = dynamic_cast<const MuGirlLowBetaTag*>(tag);
-          if( muGirlLowBetaTag) {
-            staus.push_back(candidate);	
-            ATH_MSG_DEBUG("save ID candidate stau ");
-          }
+	std::vector<const TagBase*> tags;
+	const TagBase* tag=tagMaps[0]->getTag(candidate); //in the staus case, just one tag map is present
+	const MuGirlLowBetaTag* muGirlLowBetaTag = dynamic_cast<const MuGirlLowBetaTag*>(tag);
+	if( muGirlLowBetaTag) {
+	  tags.push_back(tag);
+	  resolvedInDetCandidates.push_back(InDetCandidateTags(candidate,tags));
+	  ATH_MSG_DEBUG("save ID candidate stau ");
         }
       }
     }
     
-    //add stau candidates
-    if (!staus.empty()){
-      resolvedInDetCandidates.insert( resolvedInDetCandidates.end(), staus.begin(), staus.end() );
-      ATH_MSG_DEBUG("insert stau into resolvedInDetCandidates");
-    }
-
-    for(auto candidate : resolvedInDetCandidates) {
-      // retrieve the primary tag
-      const TagBase* primaryTag = candidate->combinedDataTags().at(0);
-      if(!primaryTag) {
-        ATH_MSG_WARNING("Unable to retrieve tag data for InDetCandidate");
-        continue;
-      }
-    }
     // print-out
     if( msgLvl(MSG::DEBUG) && inDetCandidates ){
       ATH_MSG_DEBUG("ID candidates:  " << inDetCandidates->size() << "  after stau selection " << resolvedInDetCandidates.size() );
       for( auto candidate : resolvedInDetCandidates ){
-        msg(MSG::DEBUG) << "ID candidate staus:  " << candidate->toString() << endmsg;
+        msg(MSG::DEBUG) << "ID candidate staus:  " << candidate.first->toString() << endmsg;
       }      
     }
-
   }
 
   void MuonCreatorTool::resolveOverlaps( const InDetCandidateCollection* inDetCandidates, const MuonCandidateCollection* muonCandidates, 
-					 std::vector<const MuonCombined::InDetCandidate*>& resolvedInDetCandidates, 
+					 std::vector<const InDetCandidateToTagMap*> tagMaps,
+					 InDetCandidateTagsMap& resolvedInDetCandidates, 
                                          std::vector<const MuonCombined::MuonCandidate*>& resolvedMuonCandidates) const
   {
     
@@ -1179,7 +1138,7 @@ namespace MuonCombined {
     std::set<const Trk::Track*> alreadyIncluded;
     
     // the muons only found by the calo tagger should always be kept so we can filter them out from the start
-    std::vector< const InDetCandidate* > caloMuons;
+    InDetCandidateTagsMap caloMuons;
 
     // Each InDetCandidate corresponds to a different ID track.
     // Resolve overlap among InDetCandidates for cases where different 
@@ -1188,12 +1147,16 @@ namespace MuonCombined {
 
       // first loop over ID candidates and select all candidates that have a tag
       for( auto candidate : *inDetCandidates ){
-        if( !candidate->combinedDataTags().empty() ) {
+	std::vector<const TagBase*> tags;
+	for(auto map : tagMaps){
+	  const TagBase* tag=map->getTag(candidate);
+	  if(tag) tags.push_back(tag);
+	}
+        if( !tags.empty() ) {
           // sort the tags based on quality
-          std::vector<const TagBase*>& tags = const_cast<std::vector<const TagBase*>&>(candidate->combinedDataTags());
           std::stable_sort(tags.begin(),tags.end(),SortTagBasePtr());
-          if( tags.size() == 1 && tags.front()->type() == xAOD::Muon::CaloTagged ) caloMuons.push_back(candidate);
-          else                                                                     resolvedInDetCandidates.push_back(candidate);
+          if( tags.size() == 1 && tags.front()->type() == xAOD::Muon::CaloTagged ) caloMuons.push_back(InDetCandidateTags(candidate,tags));
+	  else                                                                     resolvedInDetCandidates.push_back(InDetCandidateTags(candidate,tags));
 	  
           if( msgLvl(MSG::DEBUG) && tags.size() >= 1 ) {
             msg(MSG::DEBUG) << " InDetCandidate ";
@@ -1208,18 +1171,18 @@ namespace MuonCombined {
       if( msgLvl(MSG::DEBUG) ){
         ATH_MSG_DEBUG("ID candidates:  " << inDetCandidates->size() << "  after selection " << resolvedInDetCandidates.size() );
         for( auto candidate : resolvedInDetCandidates ){
-          msg(MSG::DEBUG) << "ID candidate:  " << candidate->toString() << endmsg;
+          msg(MSG::DEBUG) << "ID candidate:  " << candidate.first->toString() << endmsg;
         }      
       }
       
       // create a track collection for MS info, to be overlap removed
       // a dummy track for segment tagged candidates to be used in the overlap check
       TrackCollection* muonTracks = new TrackCollection(SG::VIEW_ELEMENTS);
-      std::map<const Trk::Track*, const InDetCandidate*> trackInDetCandLinks;
+      std::map<const Trk::Track*, InDetCandidateTags> trackInDetCandLinks;
 
       for(auto candidate : resolvedInDetCandidates) {
         // retrieve the primary tag
-        const TagBase* primaryTag = candidate->combinedDataTags().at(0);
+        const TagBase* primaryTag = candidate.second.at(0);
         if(!primaryTag) {
           ATH_MSG_WARNING("Unable to retrieve tag data for InDetCandidate");
           continue;
@@ -1227,7 +1190,7 @@ namespace MuonCombined {
         // check if a track is available
         if(primaryTag->primaryTrack()) {
           if( alreadyIncluded.count(primaryTag->primaryTrack()) ){
-            ATH_MSG_DEBUG("Duplicated ID candidate " << candidate->toString() );
+            ATH_MSG_DEBUG("Duplicated ID candidate " << candidate.first->toString() );
             continue;
           }
           alreadyIncluded.insert(primaryTag->primaryTrack());
@@ -1237,8 +1200,8 @@ namespace MuonCombined {
         // if not, make a dummy track out of segments
         else{
           std::vector< const Muon::MuonSegment*> segments = primaryTag->associatedSegments();
-          if( !segments.empty() && candidate->indetTrackParticle().trackLink().isValid() ){
-            Trk::Track* dummyTrack = createDummyTrack(primaryTag->associatedSegments(), *(candidate->indetTrackParticle().track()));
+          if( !segments.empty() && candidate.first->indetTrackParticle().trackLink().isValid() ){
+            Trk::Track* dummyTrack = createDummyTrack(primaryTag->associatedSegments(), *(candidate.first->indetTrackParticle().track()));
             trackInDetCandLinks[ dummyTrack ] = candidate;
             muonTracks->push_back( dummyTrack );
             muonTracksToDelete->push_back( dummyTrack );
@@ -1270,7 +1233,7 @@ namespace MuonCombined {
     if( msgLvl(MSG::DEBUG) && inDetCandidates ){
       ATH_MSG_DEBUG("ID candidates:  " << inDetCandidates->size() << "  after ambiguity solving " << resolvedInDetCandidates.size() );
       for( auto candidate : resolvedInDetCandidates ){
-        msg(MSG::DEBUG) << "ID candidate:  " << candidate->toString() << endmsg;
+        msg(MSG::DEBUG) << "ID candidate:  " << candidate.first->toString() << endmsg;
       }      
     }
     
@@ -1403,21 +1366,6 @@ namespace MuonCombined {
       return false;
     }
 
-    //set original extrapolated muon parameters to 0 if not already set (for MuGirl, segment-tagged, and calo-tagged)
-    /*
-    if(muon.author()>2 && muon.author()!=5){ //needed for muons not combined, sa, or staco, for which addMuonCandidate isn't called
-      ATH_MSG_DEBUG("set parameters to 0");
-      float val=0;
-      muon.setParameter(val, xAOD::Muon::d0_sa);
-      muon.setParameter(val, xAOD::Muon::z0_sa);
-      muon.setParameter(val, xAOD::Muon::phi0_sa);
-      muon.setParameter(val, xAOD::Muon::theta_sa);
-      muon.setParameter(val, xAOD::Muon::qOverP_sa);
-      muon.setParameter(val, xAOD::Muon::Eloss_sa);
-    }
-    */
-    //else ATH_MSG_DEBUG("found d0_sa: "<<d0test);
-    
     // add hit summary
     m_muonDressingTool->addMuonHitSummary(muon);
     
diff --git a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCreatorTool.h b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCreatorTool.h
index 543ddd6aee58..949f4126abef 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCreatorTool.h
+++ b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonCreatorTool.h
@@ -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
 */
 
 #ifndef MUONCOMBINEDBASETOOLS_MUONCREATORTOOL_H
@@ -66,6 +66,8 @@ namespace MuonCombined {
   class SegmentTag;
   class CaloTag;
 
+  typedef std::vector<InDetCandidateTags> InDetCandidateTagsMap;
+
   class MuonCreatorTool: public AthAlgTool, virtual public IMuonCreatorTool
   {
 
@@ -77,13 +79,14 @@ namespace MuonCombined {
     StatusCode finalize();
 
     /** IMuonCreatorTool interface: build muons from ID and MS candidates */    
-    void create( const MuonCandidateCollection* muonCandidates, const InDetCandidateCollection* inDetCandidates, OutputData& outputData ) const final;
+    void create( const MuonCandidateCollection* muonCandidates, const InDetCandidateCollection* inDetCandidates, std::vector<const InDetCandidateToTagMap*> tagMaps,
+		 OutputData& outputData ) const final;
 
     /** IMuonCreatorTool interface: create a muon from a muon candidate */
     xAOD::Muon* create( const MuonCandidate& candidate, OutputData& outputData ) const final;
 
     /** IMuonCreatorTool interface: create a muon from a muon candidate */
-    xAOD::Muon* create( const InDetCandidate& candidate, OutputData& outputData ) const final;
+    xAOD::Muon* create( InDetCandidateTags& candidate, OutputData& outputData ) const final;
 
   private:
     void addStatisticalCombination( xAOD::Muon& muon, const InDetCandidate& candidate, const StacoTag* tag, OutputData& outputData ) const;
@@ -115,11 +118,11 @@ namespace MuonCombined {
         Trk::SegmentCollection* muonSegmentCollection = 0 ) const ;
 
   private:
-    void resolveOverlaps( const InDetCandidateCollection* inDetCandidates, const MuonCandidateCollection* muonCandidates, 
-			  std::vector<const MuonCombined::InDetCandidate*>& resolvedInDetCandidates,
+    void resolveOverlaps( const InDetCandidateCollection* inDetCandidates, const MuonCandidateCollection* muonCandidates, std::vector<const InDetCandidateToTagMap*> tagMaps,
+			  InDetCandidateTagsMap& resolvedInDetCandidates,
                           std::vector<const MuonCombined::MuonCandidate*>& resolvedMuonCandidates) const;
     
-    void selectStaus( const InDetCandidateCollection* inDetCandidates, InDetCandidateCollection& resolvedInDetCandidates) const;
+    void selectStaus( const InDetCandidateCollection* inDetCandidates, InDetCandidateTagsMap& resolvedInDetCandidates, std::vector<const InDetCandidateToTagMap*> tagMaps) const;
 
   public:
     void selectStaus( const InDetCandidateCollection* inDetCandidates,
diff --git a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonSegmentTagTool.cxx b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonSegmentTagTool.cxx
index 6ca87d74edf4..e542a06db255 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonSegmentTagTool.cxx
+++ b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonSegmentTagTool.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
 */
 
 /////////////////////////////////////////////////////////////////////////////
@@ -164,7 +164,7 @@ namespace MuonCombined {
     return StatusCode::SUCCESS;
   }
 
-  void MuonSegmentTagTool::tag( const InDetCandidateCollection& inDetCandidates, const xAOD::MuonSegmentContainer& xaodSegments ) const {
+  void MuonSegmentTagTool::tag( const InDetCandidateCollection& inDetCandidates, const xAOD::MuonSegmentContainer& xaodSegments, InDetCandidateToTagMap* tagMap ) const {
 
     // loop over segments are extract MuonSegments + create links between segments and xAOD segments
     std::map< const Muon::MuonSegment*, ElementLink<xAOD::MuonSegmentContainer> > segmentToxAODSegmentMap;
@@ -181,10 +181,11 @@ namespace MuonCombined {
         segmentToxAODSegmentMap[mseg] = link;
       }
     }
-    tag(inDetCandidates, segments, &segmentToxAODSegmentMap);
+    tag(inDetCandidates, segments, &segmentToxAODSegmentMap, tagMap);
   }
   //todo: fix segmentToxAODSegmentMap
-  void MuonSegmentTagTool::tag( const InDetCandidateCollection& inDetCandidates, const std::vector<const Muon::MuonSegment*>& segments, SegmentMap* segmentToxAODSegmentMap ) const {
+  void MuonSegmentTagTool::tag( const InDetCandidateCollection& inDetCandidates, const std::vector<const Muon::MuonSegment*>& segments, 
+				SegmentMap* segmentToxAODSegmentMap, InDetCandidateToTagMap* tagMap ) const {
 
     std::vector<const Muon::MuonSegment*>  FilteredSegmentCollection;
     if (m_doSegmentsFilter) {
@@ -804,7 +805,7 @@ namespace MuonCombined {
         ATH_MSG_DEBUG( "make Segment Tag object for " << m_printer->print(*track) << " nr segments " << segmentsInfoTag.size() );          
         SegmentTag* tag = new SegmentTag(segmentsInfoTag);
         // FIXME const-cast changes object passed in as const
-        const_cast<InDetCandidate*>(tagCandidate)->addTag(*tag);
+	tagMap->addEntry(tagCandidate,tag);
       } 
     }   
 
diff --git a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonSegmentTagTool.h b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonSegmentTagTool.h
index ca24a014bf8d..f8f9dbe17464 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonSegmentTagTool.h
+++ b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/MuonSegmentTagTool.h
@@ -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
 */
 
 #ifndef MUONCOMBINEDBASETOOLS_MUONSEGMENTTAGTOOL_H
@@ -45,8 +45,8 @@ namespace MuonCombined {
     StatusCode finalize();
 
     /**IMuonSegmentTagTool interface: build muons from ID and MuonSegments */    
-    void tag( const InDetCandidateCollection& inDetCandidates, const xAOD::MuonSegmentContainer& segments ) const;
-    void tag( const InDetCandidateCollection& inDetCandidates, const std::vector<const Muon::MuonSegment*>& segments, SegmentMap* segmentToxAODSegmentMap ) const;
+    void tag( const InDetCandidateCollection& inDetCandidates, const xAOD::MuonSegmentContainer& segments, InDetCandidateToTagMap* tagMap ) const;
+    void tag( const InDetCandidateCollection& inDetCandidates, const std::vector<const Muon::MuonSegment*>& segments, SegmentMap* segmentToxAODSegmentMap, InDetCandidateToTagMap* tagMap ) const;
 
 
 
diff --git a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/SortInDetCandidates.h b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/SortInDetCandidates.h
index 639b434edc89..efee6d6515d4 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/SortInDetCandidates.h
+++ b/Reconstruction/MuonIdentification/MuonCombinedBaseTools/src/SortInDetCandidates.h
@@ -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
 */
 
 #ifndef MUONCOMBINED_SORTINDETCANDIDATES
@@ -17,19 +17,16 @@ namespace MuonCombined {
 
   class SortInDetCandidates {
   public:
-    bool operator()( const InDetCandidate* c1, const InDetCandidate* c2 ) const {
-      return this->operator()(*c1,*c2);
-    }
-    bool operator()( const InDetCandidate& c1, const InDetCandidate& c2 ) const {
+    bool operator()( std::pair<const InDetCandidate*,std::vector<const TagBase*> > c1, std::pair<const InDetCandidate*,std::vector<const TagBase*> > c2 ) const {
       
-      if( c1.combinedDataTags().empty() ){
-        if( c2.combinedDataTags().empty() ) return false;      
+      if( c1.second.empty() ){
+        if( c2.second.empty() ) return false;      
         return true;
       }
-      if( c2.combinedDataTags().empty() ) return false;
+      if( c2.second.empty() ) return false;
      
-      const TagBase& t1 = *c1.combinedDataTags().front();
-      const TagBase& t2 = *c2.combinedDataTags().front();
+      const TagBase& t1 = *c1.second.front();
+      const TagBase& t2 = *c2.second.front();
       // compare based on author/type
       bool s1 = t1 < t2;
       bool s2 = t2 < t1;
diff --git a/Reconstruction/MuonIdentification/MuonCombinedEvent/MuonCombinedEvent/InDetCandidate.h b/Reconstruction/MuonIdentification/MuonCombinedEvent/MuonCombinedEvent/InDetCandidate.h
index d353ea1e3402..bb20820b7610 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedEvent/MuonCombinedEvent/InDetCandidate.h
+++ b/Reconstruction/MuonIdentification/MuonCombinedEvent/MuonCombinedEvent/InDetCandidate.h
@@ -5,7 +5,6 @@
 #ifndef MUONCOMBINEDEVENT_INDETCANDIDATE_H
 #define MUONCOMBINEDEVENT_INDETCANDIDATE_H
 
-#include "MuonCombinedEvent/TagBase.h"
 #include <vector>
 #include "xAODTracking/TrackParticle.h"
 #include "xAODTracking/TrackParticleContainer.h"
@@ -14,8 +13,6 @@
 
 namespace MuonCombined {
 
-  class TagBase;
-  
   class InDetCandidate {
     
   public:
@@ -40,18 +37,6 @@ namespace MuonCombined {
     /** access TrackParticleLink */
     const ElementLink<xAOD::TrackParticleContainer>& indetTrackParticleLink() const;
     
-    /** extend InDetCandidate, takes ownership of tag object */
-    void addTag(const TagBase& tag);
-    
-    /** access tags */
-    const std::vector<const TagBase*>& combinedDataTags() const;
-
-    /** access last tag */
-    const TagBase*                     lastCombinedDataTag() const;
-
-    /** access of a given type tag */
-    const TagBase*                     lastCombinedDataTag( TagBase::Type type ) const;
-    
     //access MuonSystemExtension
     const Muon::MuonSystemExtension* getExtension() const;
 
@@ -74,9 +59,6 @@ namespace MuonCombined {
     /** cached pointer to the InDet TrackParticle */
     const xAOD::TrackParticle*   m_idTrackParticle;
 
-    /** vector of tags */
-    std::vector<const TagBase*> m_tags;
-    
     /** Was this created using a special far forward indet track*/
     bool m_siAssociated;
 
@@ -91,27 +73,6 @@ namespace MuonCombined {
 
   inline const ElementLink<xAOD::TrackParticleContainer>& InDetCandidate::indetTrackParticleLink() const { return m_idTrackParticleLink; }
 
-
-  inline void InDetCandidate::addTag(const TagBase& tag) {
-    m_tags.push_back(&tag);
-  }
-
-  inline  const std::vector<const TagBase*>& InDetCandidate::combinedDataTags() const {
-    return m_tags;
-  }
-
-  inline const TagBase* InDetCandidate::lastCombinedDataTag() const {
-    if( m_tags.empty() ) return 0;
-    return m_tags.back();
-  }
-
-  inline const TagBase* InDetCandidate::lastCombinedDataTag( TagBase::Type type) const {
-    for( auto x : m_tags ) {
-      if( x->type() == type ) return x;
-    }
-    return 0;
-  }
-
   inline bool InDetCandidate::isSiliconAssociated() const { return m_siAssociated; }
   
   inline void InDetCandidate::setSiliconAssociated( bool value ) { m_siAssociated=value; }
diff --git a/Reconstruction/MuonIdentification/MuonCombinedEvent/MuonCombinedEvent/InDetCandidateToTagMap.h b/Reconstruction/MuonIdentification/MuonCombinedEvent/MuonCombinedEvent/InDetCandidateToTagMap.h
new file mode 100644
index 000000000000..00264aedb211
--- /dev/null
+++ b/Reconstruction/MuonIdentification/MuonCombinedEvent/MuonCombinedEvent/InDetCandidateToTagMap.h
@@ -0,0 +1,36 @@
+/*
+  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef MUONCOMBINEDEVENT_INDETCANDIDATETOTAGMAP_H
+#define MUONCOMBINEDEVENT_INDETCANDIDATETOTAGMAP_H
+
+#include "MuonCombinedEvent/TagBase.h"
+#include "MuonCombinedEvent/InDetCandidate.h"
+
+#include <map>
+
+namespace MuonCombined{
+
+  class InDetCandidateToTagMap{
+  public:
+    
+    InDetCandidateToTagMap();
+    InDetCandidateToTagMap(InDetCandidateToTagMap& oldMap);
+    ~InDetCandidateToTagMap();
+    
+    void addEntry(const InDetCandidate* idcand, TagBase* tag);
+    const TagBase* getTag(const InDetCandidate* idcand) const;
+    unsigned int size() const;
+    std::map<const InDetCandidate*,TagBase*> getMap() const;
+
+  private:
+    std::map<const InDetCandidate*,TagBase*> m_tagMap;
+
+  };
+}
+
+#include "SGTools/CLASS_DEF.h"
+CLASS_DEF(MuonCombined::InDetCandidateToTagMap,68903047,1)
+
+#endif
diff --git a/Reconstruction/MuonIdentification/MuonCombinedEvent/src/InDetCandidate.cxx b/Reconstruction/MuonIdentification/MuonCombinedEvent/src/InDetCandidate.cxx
index d5b8d848f1db..9d2f1f952794 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedEvent/src/InDetCandidate.cxx
+++ b/Reconstruction/MuonIdentification/MuonCombinedEvent/src/InDetCandidate.cxx
@@ -13,16 +13,12 @@ namespace MuonCombined {
   InDetCandidate::InDetCandidate( const ElementLink<xAOD::TrackParticleContainer>& idTrackLink ) : m_idTrackParticleLink(idTrackLink), m_idTrackParticle(0),m_siAssociated(false), m_extension(0) {}
 
   InDetCandidate::~InDetCandidate() {
-    for( auto x : m_tags ) delete x;
     delete m_extension;
   }
 
   std::string InDetCandidate::toString() const {
     std::ostringstream sout;
-    sout << " pt " << indetTrackParticle().pt() << " eta " << indetTrackParticle().eta() << " phi " << indetTrackParticle().phi() 
-	 << " tags ";
-    for( auto x : combinedDataTags() ) sout << " " << x->name();
-    if( !combinedDataTags().empty() ) sout << std::endl << " primary tag " << combinedDataTags().front()->toString();
+    sout << " pt " << indetTrackParticle().pt() << " eta " << indetTrackParticle().eta() << " phi " << indetTrackParticle().phi() ;
     if (isSiliconAssociated()) sout<<std::endl << " is SiliconAssociated.";
     return sout.str();
   }
diff --git a/Reconstruction/MuonIdentification/MuonCombinedEvent/src/InDetCandidateToTagMap.cxx b/Reconstruction/MuonIdentification/MuonCombinedEvent/src/InDetCandidateToTagMap.cxx
new file mode 100644
index 000000000000..544037b1df5b
--- /dev/null
+++ b/Reconstruction/MuonIdentification/MuonCombinedEvent/src/InDetCandidateToTagMap.cxx
@@ -0,0 +1,38 @@
+/*
+  Copyright (C) 2002-2018 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "MuonCombinedEvent/InDetCandidateToTagMap.h"
+
+namespace MuonCombined{
+
+  InDetCandidateToTagMap::InDetCandidateToTagMap(){
+    m_tagMap.clear();
+  }
+
+  InDetCandidateToTagMap::InDetCandidateToTagMap(InDetCandidateToTagMap& oldMap){
+    m_tagMap=oldMap.getMap();
+  }
+  
+  InDetCandidateToTagMap::~InDetCandidateToTagMap(){
+    m_tagMap.clear();
+  }
+  
+  void InDetCandidateToTagMap::addEntry(const InDetCandidate* idcand,TagBase* tag){
+    m_tagMap.insert(std::pair<const InDetCandidate*,TagBase*>(idcand,tag));
+  }
+  
+  const TagBase* InDetCandidateToTagMap::getTag(const InDetCandidate* idcand) const{
+    auto pos=m_tagMap.find(idcand);
+    if(pos==m_tagMap.end()) return 0;
+    else return pos->second;
+  }
+  
+  unsigned int InDetCandidateToTagMap::size() const{
+    return m_tagMap.size();
+  }
+
+  std::map<const InDetCandidate*,TagBase*> InDetCandidateToTagMap::getMap() const{
+    return m_tagMap;
+  }
+}
diff --git a/Reconstruction/MuonIdentification/MuonCombinedRecExample/python/MuonCombinedAlgs.py b/Reconstruction/MuonIdentification/MuonCombinedRecExample/python/MuonCombinedAlgs.py
index 81f84e57b8f6..e3a73a979eab 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedRecExample/python/MuonCombinedAlgs.py
+++ b/Reconstruction/MuonIdentification/MuonCombinedRecExample/python/MuonCombinedAlgs.py
@@ -29,6 +29,7 @@ def MuGirlAlg(name="MuGirlAlg",**kwargs):
 def MuonCaloTagAlg(name="MuonCaloTagAlg",**kwargs):
     tools = [getPublicTool("MuonCaloTagTool")]
     kwargs.setdefault("MuonCombinedInDetExtensionTools", tools )
+    kwargs.setdefault("TagMap","caloTagMap");
     return CfgMgr.MuonCombinedInDetExtensionAlg(name,**kwargs)
 
 def MuonSegmentTagAlg( name="MuonSegmentTagAlg", **kwargs ):
@@ -39,11 +40,13 @@ def MuonInsideOutRecoAlg( name="MuonInsideOutRecoAlg", **kwargs ):
     tools = [getPublicTool("MuonInsideOutRecoTool") ]
     kwargs.setdefault("MuonCombinedInDetExtensionTools", tools )
     kwargs.setdefault("usePRDs",True)
+    kwargs.setdefault("TagMap","muGirlTagMap")
     return CfgMgr.MuonCombinedInDetExtensionAlg(name,**kwargs)
 
 def MuGirlStauAlg(name="MuGirlStauAlg",**kwargs):
     tools = [getPublicTool("MuonStauRecoTool")]
     kwargs.setdefault("MuonCombinedInDetExtensionTools", tools )
+    kwargs.setdefault("TagMap","stauTagMap")
     return CfgMgr.MuonCombinedInDetExtensionAlg(name,**kwargs)
       
 def MuonCombinedInDetCandidateAlg( name="MuonCombinedInDetCandidateAlg",**kwargs ):
@@ -76,6 +79,7 @@ def StauCreatorAlg( name="StauCreatorAlg", **kwargs ):
     kwargs.setdefault("SegmentContainerName","StauSegments")
     kwargs.setdefault("BuildSlowMuon",1)
     kwargs.setdefault("ClusterContainerName", "SlowMuonClusterCollection")
+    kwargs.setdefault("TagMaps",["stauTagMap"])
     return MuonCreatorAlg(name,**kwargs)
 
 class MuonCombinedReconstruction(ConfiguredMuonRec):
diff --git a/Reconstruction/MuonIdentification/MuonCombinedToolInterfaces/MuonCombinedToolInterfaces/IMuonCombinedInDetExtensionTool.h b/Reconstruction/MuonIdentification/MuonCombinedToolInterfaces/MuonCombinedToolInterfaces/IMuonCombinedInDetExtensionTool.h
index e1785612e9cd..c942b80487a0 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedToolInterfaces/MuonCombinedToolInterfaces/IMuonCombinedInDetExtensionTool.h
+++ b/Reconstruction/MuonIdentification/MuonCombinedToolInterfaces/MuonCombinedToolInterfaces/IMuonCombinedInDetExtensionTool.h
@@ -10,6 +10,7 @@
 
 #include "GaudiKernel/IAlgTool.h"
 #include "MuonCombinedEvent/InDetCandidateCollection.h"
+#include "MuonCombinedEvent/InDetCandidateToTagMap.h"
 #include "MuonPrepRawData/MuonPrepDataContainer.h"
 #include "MuonPrepRawData/MMPrepDataContainer.h"
 #include "MuonPrepRawData/sTgcPrepDataContainer.h"
@@ -30,12 +31,12 @@ namespace MuonCombined {
 
 
     /**IMuonCombinedInDetExtensionTool interface: build combined muons from ID candidates */    
-    virtual void extend( const InDetCandidateCollection& inDetCandidates ) = 0;
+    virtual void extend( const InDetCandidateCollection& inDetCandidates, InDetCandidateToTagMap* tagMap) = 0;
     
     /*New interface including PRDs for MuGirl segment-finding*/
-    virtual void extendWithPRDs( const InDetCandidateCollection& inDetCandidates, const Muon::MdtPrepDataContainer* mdtPRDs, const Muon::CscPrepDataContainer* cscPRDs,
-				 const Muon::RpcPrepDataContainer* rpdPRDs, const Muon::TgcPrepDataContainer* tgcPRDs, const Muon::sTgcPrepDataContainer* sTGCPRDs, 
-				 const Muon::MMPrepDataContainer* mmPRDs) =0;
+    virtual void extendWithPRDs( const InDetCandidateCollection& inDetCandidates, InDetCandidateToTagMap* tagMap,
+				 const Muon::MdtPrepDataContainer* mdtPRDs, const Muon::CscPrepDataContainer* cscPRDs, const Muon::RpcPrepDataContainer* rpdPRDs, 
+				 const Muon::TgcPrepDataContainer* tgcPRDs, const Muon::sTgcPrepDataContainer* sTGCPRDs, const Muon::MMPrepDataContainer* mmPRDs) =0;
 
   };
 
diff --git a/Reconstruction/MuonIdentification/MuonCombinedToolInterfaces/MuonCombinedToolInterfaces/IMuonCombinedTagTool.h b/Reconstruction/MuonIdentification/MuonCombinedToolInterfaces/MuonCombinedToolInterfaces/IMuonCombinedTagTool.h
index 67e6c1c07691..4bf2a44d809b 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedToolInterfaces/MuonCombinedToolInterfaces/IMuonCombinedTagTool.h
+++ b/Reconstruction/MuonIdentification/MuonCombinedToolInterfaces/MuonCombinedToolInterfaces/IMuonCombinedTagTool.h
@@ -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
 */
 
 ///////////////////////////////////////////////////////////////////
@@ -15,6 +15,7 @@
 namespace MuonCombined {
   class InDetCandidate;
   class MuonCandidate;
+  class InDetCandidateToTagMap;
 
   static const InterfaceID IID_IMuonCombinedTagTool("MuonCombined::IMuonCombinedTagTool", 1, 0);
 
@@ -30,7 +31,7 @@ namespace MuonCombined {
 
 
     /**IMuonCombinedTagTool interface: build combined  muons from a muon and a vector of indet candidates */    
-    virtual void combine( const MuonCandidate& muonCandidate, const std::vector<InDetCandidate*>& indetCandidates ) const = 0;
+    virtual void combine( const MuonCandidate& muonCandidate, const std::vector<const InDetCandidate*>& indetCandidates, InDetCandidateToTagMap& tagMap ) const = 0;
 
   };
 
diff --git a/Reconstruction/MuonIdentification/MuonCombinedToolInterfaces/MuonCombinedToolInterfaces/IMuonCombinedTool.h b/Reconstruction/MuonIdentification/MuonCombinedToolInterfaces/MuonCombinedToolInterfaces/IMuonCombinedTool.h
index 72920529d71f..8c1a5c4a377b 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedToolInterfaces/MuonCombinedToolInterfaces/IMuonCombinedTool.h
+++ b/Reconstruction/MuonIdentification/MuonCombinedToolInterfaces/MuonCombinedToolInterfaces/IMuonCombinedTool.h
@@ -11,6 +11,8 @@
 #include "GaudiKernel/IAlgTool.h"
 #include "MuonCombinedEvent/MuonCandidateCollection.h"
 #include "MuonCombinedEvent/InDetCandidateCollection.h"
+#include "MuonCombinedEvent/InDetCandidateToTagMap.h"
+#include <vector>
 
 namespace MuonCombined {
 
@@ -28,7 +30,7 @@ namespace MuonCombined {
 
 
     /**IMuonCombinedTool interface: build combined muons from ID and MS candidates */    
-    virtual void combine( const MuonCandidateCollection& muonCandidates,  const InDetCandidateCollection& inDetCandidates ) const = 0;
+    virtual void combine( const MuonCandidateCollection& muonCandidates,  const InDetCandidateCollection& inDetCandidates, std::vector<InDetCandidateToTagMap*> tagMaps ) const = 0;
 
   };
 
diff --git a/Reconstruction/MuonIdentification/MuonCombinedToolInterfaces/MuonCombinedToolInterfaces/IMuonCombinedTrigCaloTagExtensionTool.h b/Reconstruction/MuonIdentification/MuonCombinedToolInterfaces/MuonCombinedToolInterfaces/IMuonCombinedTrigCaloTagExtensionTool.h
index c4b01e7f53b0..02df646747fd 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedToolInterfaces/MuonCombinedToolInterfaces/IMuonCombinedTrigCaloTagExtensionTool.h
+++ b/Reconstruction/MuonIdentification/MuonCombinedToolInterfaces/MuonCombinedToolInterfaces/IMuonCombinedTrigCaloTagExtensionTool.h
@@ -10,6 +10,7 @@
 
 #include "GaudiKernel/IAlgTool.h"
 #include "MuonCombinedEvent/InDetCandidateCollection.h"
+#include "MuonCombinedEvent/InDetCandidateToTagMap.h"
 #include "CaloEvent/CaloCellContainer.h"
 #include "xAODCaloEvent/CaloClusterContainer.h"
 
@@ -29,7 +30,7 @@ namespace MuonCombined {
 
 
     /**IMuonCombinedTrigCaloTagExtensionTool interface: build combined muons from ID and MS candidates */    
-    virtual void extend( const InDetCandidateCollection& inDetCandidates, 
+    virtual void extend( const InDetCandidateCollection& inDetCandidates, InDetCandidateToTagMap* tagMap, 
                          const CaloCellContainer* caloCellCont = nullptr,
                          const xAOD::CaloClusterContainer* caloClusterCont = nullptr ) = 0;
   };
diff --git a/Reconstruction/MuonIdentification/MuonCombinedToolInterfaces/MuonCombinedToolInterfaces/IMuonCreatorTool.h b/Reconstruction/MuonIdentification/MuonCombinedToolInterfaces/MuonCombinedToolInterfaces/IMuonCreatorTool.h
index 504846ecc14a..a47a561ec356 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedToolInterfaces/MuonCombinedToolInterfaces/IMuonCreatorTool.h
+++ b/Reconstruction/MuonIdentification/MuonCombinedToolInterfaces/MuonCombinedToolInterfaces/IMuonCreatorTool.h
@@ -11,14 +11,18 @@
 #include "GaudiKernel/IAlgTool.h"
 #include "MuonCombinedEvent/MuonCandidateCollection.h"
 #include "MuonCombinedEvent/InDetCandidateCollection.h"
+#include "MuonCombinedEvent/InDetCandidateToTagMap.h"
 #include "xAODMuon/MuonContainer.h"
 #include "xAODMuon/SlowMuonContainer.h"
 #include "xAODTracking/TrackParticleContainer.h"
 #include "TrkTrack/TrackCollection.h"
 #include "xAODCaloEvent/CaloClusterContainer.h"
+#include <vector>
 
 namespace MuonCombined {
 
+  typedef std::pair<const InDetCandidate*,std::vector<const TagBase*> > InDetCandidateTags;
+
   static const InterfaceID IID_IMuonCreatorTool("MuonCombined::IMuonCreatorTool", 1, 0);
 
   /** @class IMuonCreatorTool
@@ -27,7 +31,7 @@ namespace MuonCombined {
       The tool is capable of writing a large number of different output formats. Whether or not certain outputs 
       are written is controled using the OutputData struct defined below. 
       If the pointer to a certain type is non-zero, the container is filled. 
-      The MuonContainer is manditory, all other output types are optional.
+      The MuonContainer is mandatory, all other output types are optional.
 
       @author Niels van Eldik
    */
@@ -81,14 +85,14 @@ namespace MuonCombined {
 
     /**IMuonCreatorTool interface: build muons from ID and MS candidates */    
 
-    virtual void create( const MuonCandidateCollection* muonCandidates, const InDetCandidateCollection* inDetCandidates,
+    virtual void create( const MuonCandidateCollection* muonCandidates, const InDetCandidateCollection* inDetCandidates, std::vector<const InDetCandidateToTagMap*> tagMaps,
     			 OutputData& outputData ) const = 0;
 
     /** create a muon from a muon candidate */
     virtual xAOD::Muon* create( const MuonCandidate& candidate, OutputData& outputData ) const = 0;
 
-    /** create a muon from a muon candidate */
-    virtual xAOD::Muon* create( const InDetCandidate& candidate, OutputData& outputData ) const = 0;
+    /** create a muon from an ID candidate */
+    virtual xAOD::Muon* create( InDetCandidateTags& candidate, OutputData& outputData) const = 0;
 
   };
 
diff --git a/Reconstruction/MuonIdentification/MuonCombinedToolInterfaces/MuonCombinedToolInterfaces/IMuonSegmentTagTool.h b/Reconstruction/MuonIdentification/MuonCombinedToolInterfaces/MuonCombinedToolInterfaces/IMuonSegmentTagTool.h
index bd8b44c12891..3fb5dae5a687 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedToolInterfaces/MuonCombinedToolInterfaces/IMuonSegmentTagTool.h
+++ b/Reconstruction/MuonIdentification/MuonCombinedToolInterfaces/MuonCombinedToolInterfaces/IMuonSegmentTagTool.h
@@ -11,6 +11,7 @@
 #include "GaudiKernel/IAlgTool.h"
 #include "MuonCombinedEvent/InDetCandidateCollection.h"
 #include "xAODMuon/MuonSegmentContainer.h"
+#include "MuonCombinedEvent/InDetCandidateToTagMap.h"
 
 namespace MuonCombined {
 
@@ -30,8 +31,9 @@ namespace MuonCombined {
 
 
     /**IMuonSegmentTagTool interface: build muons from ID and MuonSegments */    
-    virtual void tag( const InDetCandidateCollection& inDetCandidates, const xAOD::MuonSegmentContainer& segments ) const = 0;
-    virtual void tag( const InDetCandidateCollection& inDetCandidates, const std::vector<const Muon::MuonSegment*>& segments, SegmentMap* segmentToxAODSegmentMap ) const = 0;
+    virtual void tag( const InDetCandidateCollection& inDetCandidates, const xAOD::MuonSegmentContainer& segments, InDetCandidateToTagMap* tagMap ) const = 0;
+    virtual void tag( const InDetCandidateCollection& inDetCandidates, const std::vector<const Muon::MuonSegment*>& segments, 
+		      SegmentMap* segmentToxAODSegmentMap, InDetCandidateToTagMap* tagMap ) const = 0;
 
   };
 
diff --git a/Reconstruction/MuonIdentification/MuonCombinedTrackFindingTools/src/MuonInsideOutRecoTool.cxx b/Reconstruction/MuonIdentification/MuonCombinedTrackFindingTools/src/MuonInsideOutRecoTool.cxx
index ccd20c45f2a4..72e459d38c96 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedTrackFindingTools/src/MuonInsideOutRecoTool.cxx
+++ b/Reconstruction/MuonIdentification/MuonCombinedTrackFindingTools/src/MuonInsideOutRecoTool.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
 */
 
 #include "MuonInsideOutRecoTool.h"
@@ -79,26 +79,26 @@ namespace MuonCombined {
     return StatusCode::SUCCESS;
   }
 
-  void MuonInsideOutRecoTool::extend( const InDetCandidateCollection& inDetCandidates ) {
+  void MuonInsideOutRecoTool::extend( const InDetCandidateCollection& inDetCandidates, InDetCandidateToTagMap* tagMap ) {
     ATH_MSG_WARNING("This version is deprecated, please use extendWithPRDs for MuGirl");
-    extendWithPRDs(inDetCandidates,0,0,0,0,0,0);
+    extendWithPRDs(inDetCandidates,tagMap,0,0,0,0,0,0);
   }
 
-  void MuonInsideOutRecoTool::extendWithPRDs( const InDetCandidateCollection& inDetCandidates, const Muon::MdtPrepDataContainer* mdtPRDs, const Muon::CscPrepDataContainer* cscPRDs,
-					      const Muon::RpcPrepDataContainer* rpcPRDs, const Muon::TgcPrepDataContainer* tgcPRDs, const Muon::sTgcPrepDataContainer* stgcPRDs,
-					      const Muon::MMPrepDataContainer* mmPRDs ) {
+  void MuonInsideOutRecoTool::extendWithPRDs( const InDetCandidateCollection& inDetCandidates, InDetCandidateToTagMap* tagMap, 
+					      const Muon::MdtPrepDataContainer* mdtPRDs, const Muon::CscPrepDataContainer* cscPRDs, const Muon::RpcPrepDataContainer* rpcPRDs, 
+					      const Muon::TgcPrepDataContainer* tgcPRDs, const Muon::sTgcPrepDataContainer* stgcPRDs, const Muon::MMPrepDataContainer* mmPRDs ) {
     ATH_MSG_DEBUG(" extending " << inDetCandidates.size() );
 
     InDetCandidateCollection::const_iterator it = inDetCandidates.begin();
     InDetCandidateCollection::const_iterator it_end = inDetCandidates.end();
     for( ; it!=it_end;++it ){
-      handleCandidate( **it,mdtPRDs,cscPRDs,rpcPRDs,tgcPRDs,stgcPRDs,mmPRDs );
+      handleCandidate( **it,tagMap,mdtPRDs,cscPRDs,rpcPRDs,tgcPRDs,stgcPRDs,mmPRDs );
     }
   }
 
-  void MuonInsideOutRecoTool::handleCandidate( const InDetCandidate& indetCandidate, const Muon::MdtPrepDataContainer* mdtPRDs, const Muon::CscPrepDataContainer* cscPRDs,
-					       const Muon::RpcPrepDataContainer* rpcPRDs, const Muon::TgcPrepDataContainer* tgcPRDs, const Muon::sTgcPrepDataContainer* stgcPRDs,
-					       const Muon::MMPrepDataContainer* mmPRDs ) {
+  void MuonInsideOutRecoTool::handleCandidate( const InDetCandidate& indetCandidate, InDetCandidateToTagMap* tagMap, 
+					       const Muon::MdtPrepDataContainer* mdtPRDs, const Muon::CscPrepDataContainer* cscPRDs, const Muon::RpcPrepDataContainer* rpcPRDs, 
+					       const Muon::TgcPrepDataContainer* tgcPRDs, const Muon::sTgcPrepDataContainer* stgcPRDs, const Muon::MMPrepDataContainer* mmPRDs ) {
     
     if( m_ignoreSiAssocated && indetCandidate.isSiliconAssociated() ) {
       ATH_MSG_DEBUG(" skip silicon associated track for extension ");
@@ -176,7 +176,7 @@ namespace MuonCombined {
     }
 
     // add candidate to indet candidate
-    addTag(indetCandidate,*bestCandidate.first.get(),bestCandidate.second);
+    addTag(indetCandidate,tagMap,*bestCandidate.first.get(),bestCandidate.second);
   }
 
 
@@ -223,8 +223,8 @@ namespace MuonCombined {
                            std::unique_ptr<const Trk::Track>(new Trk::Track(*selectedTrack)) );
   }
 
-  void MuonInsideOutRecoTool::addTag( const InDetCandidate& indetCandidate, const Muon::MuonCandidate& candidate,  
-                                      std::unique_ptr<const Trk::Track>& selectedTrack ) const {
+  void MuonInsideOutRecoTool::addTag( const InDetCandidate& indetCandidate, InDetCandidateToTagMap* tagMap, 
+				      const Muon::MuonCandidate& candidate, std::unique_ptr<const Trk::Track>& selectedTrack ) const {
 
     const xAOD::TrackParticle& idTrackParticle = indetCandidate.indetTrackParticle();
     float bs_x = 0.;
@@ -278,8 +278,8 @@ namespace MuonCombined {
     MuGirlTag* tag = new MuGirlTag(selectedTrack.release(),segments);    
     if( standaloneRefit ) tag->setUpdatedExtrapolatedTrack(std::unique_ptr<const Trk::Track>(standaloneRefit));
 
-    // add tag to IndetCandidate
-    const_cast<InDetCandidate&>(indetCandidate).addTag(*tag);
+    // add tag to IndetCandidateToTagMap
+    tagMap->addEntry(&indetCandidate,tag);
   }
 
   bool MuonInsideOutRecoTool::getLayerData( int sector, Muon::MuonStationIndex::DetectorRegionIndex regionIndex,
diff --git a/Reconstruction/MuonIdentification/MuonCombinedTrackFindingTools/src/MuonInsideOutRecoTool.h b/Reconstruction/MuonIdentification/MuonCombinedTrackFindingTools/src/MuonInsideOutRecoTool.h
index 6678d568eb3c..a34733c607be 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedTrackFindingTools/src/MuonInsideOutRecoTool.h
+++ b/Reconstruction/MuonIdentification/MuonCombinedTrackFindingTools/src/MuonInsideOutRecoTool.h
@@ -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
 */
 
 #ifndef MUON_MUONINSIDEOUTRECOTOOL_H
@@ -56,12 +56,12 @@ namespace MuonCombined {
     static const InterfaceID& interfaceID() { return IID_MuonInsideOutRecoTool; }
 
     /**IMuonCombinedInDetExtensionTool interface: extend ID candidate with PRDs for segment-finding */   
-    virtual void extendWithPRDs( const InDetCandidateCollection& inDetCandidates, const Muon::MdtPrepDataContainer* mdtPRDs, const Muon::CscPrepDataContainer* cscPRDs,
-				 const Muon::RpcPrepDataContainer* rpdPRDs, const Muon::TgcPrepDataContainer* tgcPRDs, const Muon::sTgcPrepDataContainer* stgcPRDs,
-				 const Muon::MMPrepDataContainer* mmPRDs) override;
+    virtual void extendWithPRDs( const InDetCandidateCollection& inDetCandidates, InDetCandidateToTagMap* tagMap,
+				 const Muon::MdtPrepDataContainer* mdtPRDs, const Muon::CscPrepDataContainer* cscPRDs, const Muon::RpcPrepDataContainer* rpdPRDs, 
+				 const Muon::TgcPrepDataContainer* tgcPRDs, const Muon::sTgcPrepDataContainer* stgcPRDs, const Muon::MMPrepDataContainer* mmPRDs) override;
 
     /**IMuonCombinedInDetExtensionTool interface: deprecated*/
-    virtual void extend(const InDetCandidateCollection& inDetCandidates) override;
+    virtual void extend(const InDetCandidateCollection& inDetCandidates, InDetCandidateToTagMap* tagMap) override;
 
     /** find the best candidate for a given set of segments */
     std::pair<std::unique_ptr<const Muon::MuonCandidate>,std::unique_ptr<const Trk::Track> > 
@@ -69,13 +69,13 @@ namespace MuonCombined {
 
   private:
     /** handle a single candidate */
-    void handleCandidate( const InDetCandidate& inDetCandidate, const Muon::MdtPrepDataContainer* mdtPRDs, const Muon::CscPrepDataContainer* cscPRDs,
-			  const Muon::RpcPrepDataContainer* rpdPRDs, const Muon::TgcPrepDataContainer* tgcPRDs, const Muon::sTgcPrepDataContainer* stgcPRDs,
-			  const Muon::MMPrepDataContainer* mmPRDs );
+    void handleCandidate( const InDetCandidate& inDetCandidate, InDetCandidateToTagMap* tagMap, 
+			  const Muon::MdtPrepDataContainer* mdtPRDs, const Muon::CscPrepDataContainer* cscPRDs, const Muon::RpcPrepDataContainer* rpdPRDs, 
+			  const Muon::TgcPrepDataContainer* tgcPRDs, const Muon::sTgcPrepDataContainer* stgcPRDs, const Muon::MMPrepDataContainer* mmPRDs );
 
     /** add muon candidate to indet candidate */
-    void addTag( const InDetCandidate& indetCandidate, const Muon::MuonCandidate& candidate, 
-                 std::unique_ptr<const Trk::Track>& selectedTrack ) const;
+    void addTag( const InDetCandidate& indetCandidate, InDetCandidateToTagMap* tagMap, 
+		 const Muon::MuonCandidate& candidate, std::unique_ptr<const Trk::Track>& selectedTrack ) const;
 
     /** access data in layer */
     bool getLayerData( int sector, Muon::MuonStationIndex::DetectorRegionIndex regionIndex, Muon::MuonStationIndex::LayerIndex layerIndex, 
diff --git a/Reconstruction/MuonIdentification/MuonCombinedTrackFindingTools/src/MuonStauRecoTool.cxx b/Reconstruction/MuonIdentification/MuonCombinedTrackFindingTools/src/MuonStauRecoTool.cxx
index 4fe88ce117cc..f5b32f1823a8 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedTrackFindingTools/src/MuonStauRecoTool.cxx
+++ b/Reconstruction/MuonIdentification/MuonCombinedTrackFindingTools/src/MuonStauRecoTool.cxx
@@ -153,21 +153,21 @@ namespace MuonCombined {
     return StatusCode::SUCCESS;
   }
 
-  void MuonStauRecoTool::extendWithPRDs( const InDetCandidateCollection& inDetCandidates, const Muon::MdtPrepDataContainer* mdtPRDs, const Muon::CscPrepDataContainer* cscPRDs,
-					 const Muon::RpcPrepDataContainer* rpcPRDs, const Muon::TgcPrepDataContainer *tgcPRDs, const Muon::sTgcPrepDataContainer* stgcPRDs,
-					 const Muon::MMPrepDataContainer* mmPRDs ) {
+  void MuonStauRecoTool::extendWithPRDs( const InDetCandidateCollection& inDetCandidates, InDetCandidateToTagMap* tagMap,
+					 const Muon::MdtPrepDataContainer* mdtPRDs, const Muon::CscPrepDataContainer* cscPRDs, const Muon::RpcPrepDataContainer* rpcPRDs,
+					 const Muon::TgcPrepDataContainer *tgcPRDs, const Muon::sTgcPrepDataContainer* stgcPRDs, const Muon::MMPrepDataContainer* mmPRDs ) {
     //Maybe we'll need this later, I wouldn't be surprised if the PRDs are retrieved somewhere down the chain
     //For now it's just a placeholder though
-    if(mdtPRDs && cscPRDs && rpcPRDs && tgcPRDs && stgcPRDs && mmPRDs) extend(inDetCandidates);
+    if(mdtPRDs && cscPRDs && rpcPRDs && tgcPRDs && stgcPRDs && mmPRDs) extend(inDetCandidates, tagMap);
   }
 
-  void MuonStauRecoTool::extend( const InDetCandidateCollection& inDetCandidates ) {
+  void MuonStauRecoTool::extend( const InDetCandidateCollection& inDetCandidates, InDetCandidateToTagMap* tagMap ) {
     ATH_MSG_DEBUG(" extending " << inDetCandidates.size() );
 
     InDetCandidateCollection::const_iterator it = inDetCandidates.begin();
     InDetCandidateCollection::const_iterator it_end = inDetCandidates.end();
     for( ; it!=it_end;++it ){
-      handleCandidate( **it );
+      handleCandidate( **it, tagMap );
     }
   }
   
@@ -184,7 +184,7 @@ namespace MuonCombined {
   }
 
 
-  void MuonStauRecoTool::handleCandidate( const InDetCandidate& indetCandidate ) {
+  void MuonStauRecoTool::handleCandidate( const InDetCandidate& indetCandidate, InDetCandidateToTagMap* tagMap ) {
     
     if( m_ignoreSiAssocated && indetCandidate.isSiliconAssociated() ) {
       ATH_MSG_DEBUG(" skip silicon associated track for extension ");
@@ -299,7 +299,7 @@ namespace MuonCombined {
     /** STAGE 6
         create tag
     */
-    addTag( indetCandidate, *candidates.front() );
+    addTag( indetCandidate, *candidates.front(), tagMap );
 
   }
   
@@ -804,7 +804,7 @@ namespace MuonCombined {
     candidate.finalBetaFitResult = betaFitResult;
   }
     
-  void MuonStauRecoTool::addTag( const InDetCandidate& indetCandidate, MuonStauRecoTool::Candidate& candidate ) const {
+  void MuonStauRecoTool::addTag( const InDetCandidate& indetCandidate, MuonStauRecoTool::Candidate& candidate, InDetCandidateToTagMap* tagMap ) const {
     
     // get combined track and the segments
     const Trk::Track* combinedTrack = candidate.combinedTrack.release();
@@ -856,7 +856,7 @@ namespace MuonCombined {
 
 
     // add tag to IndetCandidate
-    const_cast<InDetCandidate&>(indetCandidate).addTag(*tag);
+    tagMap->addEntry(&indetCandidate,tag);
 
   }
 
diff --git a/Reconstruction/MuonIdentification/MuonCombinedTrackFindingTools/src/MuonStauRecoTool.h b/Reconstruction/MuonIdentification/MuonCombinedTrackFindingTools/src/MuonStauRecoTool.h
index 20be75bbb143..fda8ddd98497 100644
--- a/Reconstruction/MuonIdentification/MuonCombinedTrackFindingTools/src/MuonStauRecoTool.h
+++ b/Reconstruction/MuonIdentification/MuonCombinedTrackFindingTools/src/MuonStauRecoTool.h
@@ -152,15 +152,15 @@ namespace MuonCombined {
     virtual StatusCode finalize() override;
 
     /**IMuonCombinedInDetExtensionTool interface: extend ID candidate */   
-    virtual void extend( const InDetCandidateCollection& inDetCandidates ) override;
+    virtual void extend( const InDetCandidateCollection& inDetCandidates, InDetCandidateToTagMap* tagMap ) override;
 
-    virtual void extendWithPRDs(const InDetCandidateCollection& inDetCandidates, const Muon::MdtPrepDataContainer* mdtPRDs, const Muon::CscPrepDataContainer* cscPRDs,
-				const Muon::RpcPrepDataContainer* rpcPRDs, const Muon::TgcPrepDataContainer* tgcPRDs, const Muon::sTgcPrepDataContainer* sTGCPRDs,
-				const Muon::MMPrepDataContainer* mmPRDs) override;
+    virtual void extendWithPRDs(const InDetCandidateCollection& inDetCandidates, InDetCandidateToTagMap* tagMap, 
+				const Muon::MdtPrepDataContainer* mdtPRDs, const Muon::CscPrepDataContainer* cscPRDs, const Muon::RpcPrepDataContainer* rpcPRDs, 
+				const Muon::TgcPrepDataContainer* tgcPRDs, const Muon::sTgcPrepDataContainer* sTGCPRDs, const Muon::MMPrepDataContainer* mmPRDs) override;
 
   private:
     /** handle a single candidate */
-    void handleCandidate( const InDetCandidate& inDetCandidate );
+    void handleCandidate( const InDetCandidate& inDetCandidate, InDetCandidateToTagMap* tagMap );
 
     /** associate Hough maxima to intersection */
     void associateHoughMaxima( LayerData& layerData );
@@ -208,7 +208,7 @@ namespace MuonCombined {
     bool resolveAmbiguities( CandidateVec& candidates );
     
     /** create final tag object and add it to the inDetCandidate */
-    void addTag( const InDetCandidate& inDetCandidate, Candidate& candidate ) const;
+    void addTag( const InDetCandidate& inDetCandidate, Candidate& candidate, InDetCandidateToTagMap* tagMap ) const;
     
     /** extract time measurements from the track associated with the candidate */
     void extractTimeMeasurementsFromTrack( Candidate& candidate  );
diff --git a/Trigger/TrigAlgorithms/TrigMuSuperEF/src/TrigMuSuperEF.cxx b/Trigger/TrigAlgorithms/TrigMuSuperEF/src/TrigMuSuperEF.cxx
index b86621c69c2d..1a1f0038f0ed 100644
--- a/Trigger/TrigAlgorithms/TrigMuSuperEF/src/TrigMuSuperEF.cxx
+++ b/Trigger/TrigAlgorithms/TrigMuSuperEF/src/TrigMuSuperEF.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
 */
 
 #include <iomanip>
@@ -51,6 +51,7 @@
 #include "MuonCombinedEvent/TagBase.h"
 #include "MuonCombinedEvent/CaloTag.h"
 #include "MuonCombinedEvent/SegmentTag.h"
+#include "MuonCombinedEvent/InDetCandidateToTagMap.h"
 
 // offline reco tools
 #include "MuonCombinedToolInterfaces/IMuonCombinedTool.h"
@@ -204,7 +205,9 @@ void TrigMuSuperEF::clearRoiCache(){
   if(m_doOutsideIn && !m_combinerOnly){
     m_TrigMuonEF_saTrackTool->clearRoiCache();
   }
- 
+
+  for(auto tMap : m_tagMaps) delete tMap;
+  m_tagMaps.clear(); 
 }
 
 HLT::ErrorCode 
@@ -498,7 +501,8 @@ TrigMuSuperEF::hltExecute(const HLT::TriggerElement* inputTE, HLT::TriggerElemen
   //
   // prepare for execute
   //
-
+  for(auto tMap : m_tagMaps) delete tMap;
+  m_tagMaps.clear();
   auto muonContainerOwn = CxxUtils::make_unique<xAOD::MuonContainer>();
   m_muonContainer = muonContainerOwn.get();
   xAOD::MuonAuxContainer muonAuxContainer;
@@ -759,7 +763,9 @@ HLT::ErrorCode TrigMuSuperEF::runCaloTagOnly(const HLT::TriggerElement* inputTE,
   }
     
   //Do calotagging
-  m_caloTagTool->extend(inDetCandidates, caloCellContainer, caloClusterContainer);
+  MuonCombined::InDetCandidateToTagMap* caloTagMap=new MuonCombined::InDetCandidateToTagMap();
+  m_tagMaps.push_back(caloTagMap);
+  m_caloTagTool->extend(inDetCandidates, caloTagMap, caloCellContainer, caloClusterContainer);
 
   ATH_MSG_DEBUG("Finished CaloTag");
 
@@ -769,7 +775,7 @@ HLT::ErrorCode TrigMuSuperEF::runCaloTagOnly(const HLT::TriggerElement* inputTE,
 
   for (auto idCandidate : inDetCandidates) {
     // Get calotag and select tracks with successful tag
-    const MuonCombined::CaloTag* calotag = dynamic_cast<const MuonCombined::CaloTag*>(idCandidate->lastCombinedDataTag());
+    const MuonCombined::CaloTag* calotag = dynamic_cast<const MuonCombined::CaloTag*>(caloTagMap->getTag(idCandidate));
         
     if (calotag == nullptr) {
       ATH_MSG_DEBUG("CaloTag was not attached to InDetCandidate");
@@ -777,7 +783,13 @@ HLT::ErrorCode TrigMuSuperEF::runCaloTagOnly(const HLT::TriggerElement* inputTE,
     }
 
     MuonCombined::IMuonCreatorTool::OutputData output(*muonContainerOwn);
-    m_muonCreatorTool->create( *idCandidate, output);
+    std::vector<const MuonCombined::TagBase*> tags;
+    for(auto tmap : m_tagMaps){
+      const MuonCombined::TagBase* tag=tmap->getTag(idCandidate);
+      if(tag) tags.push_back(tag);
+    }
+    MuonCombined::InDetCandidateTags idCandTags(idCandidate,tags);
+    m_muonCreatorTool->create(idCandTags, output);
 
     //attach to output container
     ATH_MSG_DEBUG("Attaching TrackParticle to TE");
@@ -1031,7 +1043,9 @@ HLT::ErrorCode TrigMuSuperEF::runStandardChain(const HLT::TriggerElement* inputT
       ATH_MSG_DEBUG( "Executing extend()" );
       ++m_counter_TrigMuGirl.total;
       hltStatus = m_TrigMuonEF_saTrackTool->getSegments(muonRoI, m_TMEF_monVars, m_TMEF_SATimers);
-      m_muGirlTool->extend(inDetCandidates);
+      MuonCombined::InDetCandidateToTagMap* mugirlTagMap=new MuonCombined::InDetCandidateToTagMap();
+      m_tagMaps.push_back(mugirlTagMap);
+      m_muGirlTool->extend(inDetCandidates,mugirlTagMap);
       ++m_counter_TrigMuGirl.pass;//@todo fix this counter      
 
       if(m_doOutsideIn) {
@@ -1162,11 +1176,13 @@ HLT::ErrorCode TrigMuSuperEF::buildSegmentTaggedTracks(InDetCandidateCollection&
       }
     }
   }
-  m_muonSegmentTagTool->tag(inDetCandidates, segments, nullptr);
+  MuonCombined::InDetCandidateToTagMap* segmentTagMap=new MuonCombined::InDetCandidateToTagMap();
+  m_tagMaps.push_back(segmentTagMap);
+  m_muonSegmentTagTool->tag(inDetCandidates, segments, nullptr, segmentTagMap);
 
   for(auto candidate : inDetCandidates) {
-    std::vector<const MuonCombined::TagBase*> tags = candidate->combinedDataTags();
-    for(auto tag : tags) {
+    const MuonCombined::TagBase* tag=segmentTagMap->getTag(candidate);
+    if(tag){
       if( tag->type() == xAOD::Muon::SegmentTagged )
 	return HLT::OK;
     }
@@ -1180,6 +1196,11 @@ HLT::ErrorCode TrigMuSuperEF::buildCombinedTracks(const MuonCandidateCollection*
 						  TrigMuonEFCBMonVars& ,
 						  std::vector<TrigTimer*>& timers) {
 
+  MuonCombined::InDetCandidateToTagMap* muidcoTagMap=new MuonCombined::InDetCandidateToTagMap();
+  std::vector<MuonCombined::InDetCandidateToTagMap*> combinedTagMaps;
+  combinedTagMaps.push_back(muidcoTagMap);
+  m_tagMaps.push_back(muidcoTagMap);
+
   TrigTimer* trackFinderTime  = 0;
   TrigTimer* dataOutputTime = 0;
   if ( timers.size() >= 1 ) trackFinderTime = timers[0];
@@ -1190,19 +1211,11 @@ HLT::ErrorCode TrigMuSuperEF::buildCombinedTracks(const MuonCandidateCollection*
   // call the combiner
   ATH_MSG_DEBUG("Call  m_muonCombinedTool->combine, n(muon cand)=" << muonCandidates->size() << " n(ID cand)=" << inDetCandidates.size());
 
-  if(muonCandidates) m_muonCombinedTool->combine( *muonCandidates,  inDetCandidates ) ;
+  if(muonCandidates) m_muonCombinedTool->combine( *muonCandidates,  inDetCandidates, combinedTagMaps ) ;
 
   if(trackFinderTime) trackFinderTime->stop();
   if(dataOutputTime) dataOutputTime->start();
-  for(auto candidate : inDetCandidates) {
-    std::vector<const MuonCombined::TagBase*> tags = candidate->combinedDataTags();
-    for(auto tag : tags) {
-      if( tag->type() == xAOD::Muon::Combined ){
-	if(dataOutputTime) dataOutputTime->stop();
-	return HLT::OK; // found combined muon
-      }
-    }
-  }
+  if(muidcoTagMap->size()>0) return HLT::OK; //found combined muon
 
   if(dataOutputTime) dataOutputTime->stop();
   return HLT::MISSING_FEATURE; // if we got to here - no combined muon found
@@ -1333,8 +1346,16 @@ HLT::ErrorCode TrigMuSuperEF::buildMuons(const MuonCandidateCollection* muonCand
   output.extrapolatedTrackParticleContainer = extrapolatedTrackParticles;
   output.extrapolatedTrackCollection = extrapolatedTracks;
 
-  m_muonCreatorTool->create( muonCandidates, inDetCandidates, output);
-  if( m_doInsideOut ) m_stauCreatorTool->create( 0, inDetCandidates, output);
+  std::vector<const MuonCombined::InDetCandidateToTagMap*> tagMaps;
+  for(auto tmap : m_tagMaps){
+    const MuonCombined::InDetCandidateToTagMap* ctmap=new MuonCombined::InDetCandidateToTagMap(*tmap);
+    tagMaps.push_back(ctmap);
+  }
+
+  m_muonCreatorTool->create( muonCandidates, inDetCandidates, tagMaps, output);
+  if( m_doInsideOut ) m_stauCreatorTool->create( 0, inDetCandidates, tagMaps, output);
+
+  tagMaps.clear();
 
   ATH_MSG_DEBUG("N(input SA) = " << muonCandidates->size() << " N(SA from muon creator tool) = " << extrapolatedTracks->size());
 
@@ -1899,7 +1920,9 @@ HLT::ErrorCode TrigMuSuperEF::rebuildCache(const IRoiDescriptor* muonRoI, HLT::T
     ATH_MSG_DEBUG( "Executing extend()" );
     ++m_counter_TrigMuGirl.total;
     hltStatus = m_TrigMuonEF_saTrackTool->getSegments(muonRoI, m_TMEF_monVars, m_TMEF_SATimers);
-    m_muGirlTool->extend(*inDetCandidates);
+    MuonCombined::InDetCandidateToTagMap* mugirlTagMap=new MuonCombined::InDetCandidateToTagMap();
+    m_tagMaps.push_back(mugirlTagMap);
+    m_muGirlTool->extend(*inDetCandidates,mugirlTagMap);
     ++m_counter_TrigMuGirl.pass;//@todo fix this counter      
 
     if(m_doOutsideIn) {
@@ -1949,7 +1972,9 @@ void TrigMuSuperEF::runMuGirl(const ElementLinkVector<xAOD::TrackParticleContain
   buildInDetCandidates(elv_xaodidtrks, inDetCandidates);
   ATH_MSG_DEBUG( "Executing extend()" );
   ++m_counter_TrigMuGirl.total;
-  m_muGirlTool->extend(*inDetCandidates);
+  MuonCombined::InDetCandidateToTagMap* mugirlTagMap=new MuonCombined::InDetCandidateToTagMap();
+  m_tagMaps.push_back(mugirlTagMap);
+  m_muGirlTool->extend(*inDetCandidates,mugirlTagMap);
   ++m_counter_TrigMuGirl.pass;//@todo fix this counter
 }
 
diff --git a/Trigger/TrigAlgorithms/TrigMuSuperEF/src/TrigMuSuperEF.h b/Trigger/TrigAlgorithms/TrigMuSuperEF/src/TrigMuSuperEF.h
index 150c12d25d3e..818287293482 100644
--- a/Trigger/TrigAlgorithms/TrigMuSuperEF/src/TrigMuSuperEF.h
+++ b/Trigger/TrigAlgorithms/TrigMuSuperEF/src/TrigMuSuperEF.h
@@ -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
 */
 
 // Wrapper algorithm to make a smart "OR" of TrigMuonEF and TrigMuGirl
@@ -30,6 +30,7 @@
 #include "Particle/TrackParticleContainer.h"
 #include "MuonCombinedEvent/MuonCandidateCollection.h"
 #include "MuonCombinedEvent/InDetCandidateCollection.h"
+#include "MuonCombinedEvent/InDetCandidateToTagMap.h"
 
 #include "InternalCache.h"
 
@@ -184,6 +185,9 @@ class TrigMuSuperEF: public virtual HLT::FexAlgo {
   TrigRoiDescriptor* m_Roi_StillToBeAttached;
   TrigTimer* m_totalTime;
 
+  //Maps to muon tags
+  std::vector<MuonCombined::InDetCandidateToTagMap*> m_tagMaps;
+
   // Output xAOD muons
   xAOD::MuonContainer* m_muonContainer;
   //xAOD::SlowMuonContainer* m_slowMuonContainer;
-- 
GitLab