diff --git a/InnerDetector/InDetConditions/SCT_ConditionsData/SCT_ConditionsData/SCT_ModuleVetoCondData.h b/InnerDetector/InDetConditions/SCT_ConditionsData/SCT_ConditionsData/SCT_ModuleVetoCondData.h
new file mode 100644
index 0000000000000000000000000000000000000000..e6081013ad401ca49135ad5554746d990e8c05a1
--- /dev/null
+++ b/InnerDetector/InDetConditions/SCT_ConditionsData/SCT_ConditionsData/SCT_ModuleVetoCondData.h
@@ -0,0 +1,47 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+ * SCT_ModuleVetoCondData.h
+ * @file header file for data object
+ * @author Susumu Oda - 04/12/17
+ **/
+
+#ifndef SCT_MODULEVETOCONDDATA_H
+#define SCT_MODULEVETOCONDDATA_H
+
+#include "Identifier/Identifier.h"
+#include <set>
+
+class SCT_ModuleVetoCondData {
+public:
+  /// constructor
+  SCT_ModuleVetoCondData();
+  /// destructor
+  virtual ~SCT_ModuleVetoCondData();
+  /// set a bad wafer ID
+  bool setBadWaferId(const Identifier waferId);
+  /// check if a wafer ID is bad or not
+  bool isBadWaferId(const Identifier waferId) const; 
+  /// clear
+  void clear();
+  /// set data filled
+  void setFilled();
+  /// check the data are filled or not
+  bool filled() const;
+  /// get the number of bad wafers
+  long unsigned int size() const;
+  
+private:
+  std::set<Identifier> m_badWaferId;
+  bool m_isFilled;
+};
+
+#include "AthenaKernel/CLASS_DEF.h"
+CLASS_DEF( SCT_ModuleVetoCondData , 100510855 , 1 )
+
+#include "AthenaKernel/CondCont.h"
+CONDCONT_DEF( SCT_ModuleVetoCondData, 46782241 );
+
+#endif // SCT_MODULEVETOCONDDATA_H
diff --git a/InnerDetector/InDetConditions/SCT_ConditionsData/src/SCT_ModuleVetoCondData.cxx b/InnerDetector/InDetConditions/SCT_ConditionsData/src/SCT_ModuleVetoCondData.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..112eddb9ab9ea20506d99067a2aa2187259d27d2
--- /dev/null
+++ b/InnerDetector/InDetConditions/SCT_ConditionsData/src/SCT_ModuleVetoCondData.cxx
@@ -0,0 +1,56 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "SCT_ConditionsData/SCT_ModuleVetoCondData.h"
+
+//////////////////////////////////
+// constructor
+SCT_ModuleVetoCondData::SCT_ModuleVetoCondData():
+  m_badWaferId{},
+  m_isFilled{false}
+{
+}
+
+//////////////////////////////////
+// destructor
+SCT_ModuleVetoCondData::~SCT_ModuleVetoCondData() {
+}
+
+//////////////////////////////////
+// set a bad wafer ID
+bool SCT_ModuleVetoCondData::setBadWaferId(const Identifier waferId) {
+  return m_badWaferId.insert(waferId).second;
+}
+
+//////////////////////////////////
+// check if a wafer ID is bad or not
+bool SCT_ModuleVetoCondData::isBadWaferId(const Identifier waferId) const {
+  std::set<Identifier>::const_iterator it{m_badWaferId.find(waferId)};
+  return (it!=m_badWaferId.end());
+}
+
+//////////////////////////////////
+// clear
+void SCT_ModuleVetoCondData::clear() {
+  m_badWaferId.clear();
+  m_isFilled = false;
+}
+
+//////////////////////////////////
+// set data filled
+void SCT_ModuleVetoCondData::setFilled() {
+  m_isFilled = true;
+}
+
+//////////////////////////////////
+// check the data are filled or not
+bool SCT_ModuleVetoCondData::filled() const {
+  return m_isFilled;
+}
+
+//////////////////////////////////
+// get the number of bad wafers
+long unsigned int SCT_ModuleVetoCondData::size() const {
+  return m_badWaferId.size();
+}
diff --git a/InnerDetector/InDetConditions/SCT_ConditionsServices/share/testLinkMasking.py b/InnerDetector/InDetConditions/SCT_ConditionsServices/share/testLinkMasking.py
index dd24c29318cadb181930101008163b5cc90c5146..858c712d9b257e921a1dc26066a9db151e1323a0 100644
--- a/InnerDetector/InDetConditions/SCT_ConditionsServices/share/testLinkMasking.py
+++ b/InnerDetector/InDetConditions/SCT_ConditionsServices/share/testLinkMasking.py
@@ -67,9 +67,16 @@ conddb.addFolderSplitMC("SCT", "/SCT/DAQ/Config/ROD", "/SCT/DAQ/Config/ROD")
 conddb.addFolderSplitMC("SCT", "/SCT/DAQ/Config/Geog", "/SCT/DAQ/Config/Geog")
 conddb.addFolderSplitMC("SCT", "/SCT/DAQ/Config/RODMUR", "/SCT/DAQ/Config/RODMUR")
 conddb.addFolderSplitMC("SCT", "/SCT/DAQ/Config/MUR", "/SCT/DAQ/Config/MUR")
-conddb.addFolder("", "<dbConnection>sqlite://;schema=LinkMasking.db;dbname=CONDBR2</dbConnection>/purple/pants")
+conddb.addFolder("", "<dbConnection>sqlite://;schema=LinkMasking.db;dbname=CONDBR2</dbConnection>/purple/pants", className="CondAttrListCollection")
 # This folder can be created by SCT_ConditionsServices/python/createLinkMaskingSQLiteFile.py
 
+from IOVSvc.IOVSvcConf import CondSvc
+ServiceMgr += CondSvc()
+from AthenaCommon.AlgSequence import AthSequencer
+condSeq = AthSequencer("AthCondSeq")
+from SCT_ConditionsServices.SCT_ConditionsServicesConf import SCT_LinkMaskingCondAlg
+condSeq += SCT_LinkMaskingCondAlg("SCT_LinkMaskingCondAlg")
+
 from SCT_ConditionsServices.SCT_ConditionsServicesConf import SCT_LinkMaskingSvc
 LinkMaskingSvc = SCT_LinkMaskingSvc(name = "SCT_LinkMaskingSvc")
 ServiceMgr += LinkMaskingSvc
diff --git a/InnerDetector/InDetConditions/SCT_ConditionsServices/share/testVeto.py b/InnerDetector/InDetConditions/SCT_ConditionsServices/share/testVeto.py
index e4ea6297a6fabfdb22ca3d40b82817493441de01..f7ee3ca28df379df93e0cbc26f46e95d3ab92b65 100644
--- a/InnerDetector/InDetConditions/SCT_ConditionsServices/share/testVeto.py
+++ b/InnerDetector/InDetConditions/SCT_ConditionsServices/share/testVeto.py
@@ -8,9 +8,7 @@ from GaudiSvc.GaudiSvcConf import AuditorSvc
 ServiceMgr += AuditorSvc()
 theAuditorSvc = ServiceMgr.AuditorSvc
 theAuditorSvc.Auditors  += [ "ChronoAuditor"]
-#ChronoStatSvc = Service ( "ChronoStatSvc")
 theAuditorSvc.Auditors  += [ "MemStatAuditor" ]
-#MemStatAuditor = theAuditorSvc.auditor( "MemStatAuditor" )
 theApp.AuditAlgorithms=True
 
 
@@ -69,17 +67,26 @@ job = AlgSequence()
 IOVDbSvc = Service("IOVDbSvc")
 from IOVDbSvc.CondDB import conddb
 IOVDbSvc.GlobalTag="OFLCOND-MC16-SDR-18"
-'''
-DBname='<dbConnection>oracle://DEVDB10;schema=ATLAS_SCT_COMMCOND_DEV;dbname=ROE2;user=ATLAS_SCT_COMMCOND_DEV</dbConnection>'
-
-IOVDbSvc.Folders += [ DBname +' /SCT/Manual/BadModules']
-'''
 
 from SCT_ConditionsServices.SCT_ConditionsServicesConf import SCT_ModuleVetoSvc
 ServiceMgr +=SCT_ModuleVetoSvc()
 
 SCT_ModuleVeto=ServiceMgr.SCT_ModuleVetoSvc
-SCT_ModuleVeto.BadModuleIdentifiers=["1","2"]
+
+### Use COOL database for SCT_ModuleVetoSvc
+useDB = True # False
+if useDB:
+    SCT_ModuleVeto.BadModuleIdentifiers=["database"]
+    from IOVSvc.IOVSvcConf import CondSvc
+    ServiceMgr += CondSvc()
+    from AthenaCommon.AlgSequence import AthSequencer
+    condSeq = AthSequencer("AthCondSeq")
+    from SCT_ConditionsServices.SCT_ConditionsServicesConf import SCT_ModuleVetoCondAlg
+    condSeq += SCT_ModuleVetoCondAlg( "SCT_ModuleVetoCondAlg" )
+    conddb.addFolderWithTag("SCT_OFL", "/SCT/Manual/BadModules", "SCTManualBadModules-000-00", className="AthenaAttributeList")
+else:
+    SCT_ModuleVeto.BadModuleIdentifiers=["1", "2"]
+
 SCT_ModuleVetoSvc.OutputLevel=DEBUG
 
 from SCT_ConditionsServices.SCT_ConditionsServicesConf import SCT_ModuleVetoTestAlg
@@ -91,4 +98,5 @@ import AthenaCommon.AtlasUnixGeneratorJob
 
 
 ServiceMgr.EventSelector.RunNumber  = 300000 # MC16c 2017 run number
+ServiceMgr.EventSelector.InitialTimeStamp  = 1500000000 # MC16c 2017 time stamp
 theApp.EvtMax                   = 1
diff --git a/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_LinkMaskingCondAlg.cxx b/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_LinkMaskingCondAlg.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..ba7cf4c1c28346eb85a7194cffdf1a2c09df553f
--- /dev/null
+++ b/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_LinkMaskingCondAlg.cxx
@@ -0,0 +1,104 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "SCT_LinkMaskingCondAlg.h"
+
+#include "GaudiKernel/EventIDRange.h"
+
+SCT_LinkMaskingCondAlg::SCT_LinkMaskingCondAlg(const std::string& name, ISvcLocator* pSvcLocator)
+  : ::AthAlgorithm(name, pSvcLocator)
+  , m_readKey{"/purple/pants"}
+  // This folder can be created by SCT_ConditionsServices/python/createLinkMaskingSQLiteFile.py
+  , m_writeKey{"SCT_LinkMaskingCondData"}
+  , m_condSvc{"CondSvc", name}
+{
+  declareProperty("ReadKey", m_readKey, "Key of input (raw) bad wafer conditions folder");
+  declareProperty("WriteKey", m_writeKey, "Key of output (derived) bad wafer conditions folder");
+}
+
+SCT_LinkMaskingCondAlg::~SCT_LinkMaskingCondAlg() {
+}
+
+StatusCode SCT_LinkMaskingCondAlg::initialize() {
+  ATH_MSG_DEBUG("initialize " << name());
+
+  // CondSvc
+  ATH_CHECK(m_condSvc.retrieve());
+
+  // Read Cond Handle
+  ATH_CHECK(m_readKey.initialize());
+  // Write Cond Handles
+  ATH_CHECK(m_writeKey.initialize());
+  if(m_condSvc->regHandle(this, m_writeKey).isFailure()) {
+    ATH_MSG_FATAL("unable to register WriteCondHandle " << m_writeKey.fullKey() << " with CondSvc");
+    return StatusCode::FAILURE;
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode SCT_LinkMaskingCondAlg::execute() {
+  ATH_MSG_DEBUG("execute " << name());
+
+  // Write Cond Handle
+  SG::WriteCondHandle<SCT_ModuleVetoCondData> writeHandle{m_writeKey};
+  // Do we have a valid Write Cond Handle for current time?
+  if (writeHandle.isValid()) {
+    // in theory this should never be called in MT
+    writeHandle.updateStore();
+    ATH_MSG_DEBUG("CondHandle " << writeHandle.fullKey() << " is already valid."
+                  << ". In theory this should not be called, but may happen"
+                  << " if multiple concurrent events are being processed out of order."
+                  << " Forcing update of Store contents");
+    return StatusCode::SUCCESS; 
+  }
+
+  // Read Cond Handle
+  SG::ReadCondHandle<CondAttrListCollection> readHandle{m_readKey};
+  const CondAttrListCollection* readCdo{*readHandle}; 
+  if (readCdo==nullptr) {
+    ATH_MSG_FATAL("Null pointer to the read conditions object");
+    return StatusCode::FAILURE;
+  }
+  // Get the validitiy range
+  EventIDRange rangeW;
+  if (not readHandle.range(rangeW)) {
+    ATH_MSG_FATAL("Failed to retrieve validity range for " << readHandle.key());
+    return StatusCode::FAILURE;
+  }
+  ATH_MSG_INFO("Size of AthenaAttributeList " << readHandle.fullKey() << " readCdo->size()= " << readCdo->size());
+  ATH_MSG_INFO("Range of input is " << rangeW);
+  
+  // Construct the output Cond Object and fill it in
+  SCT_ModuleVetoCondData* writeCdo{new SCT_ModuleVetoCondData()};
+
+  // Read bad wafer info
+  CondAttrListCollection::const_iterator linkItr{readCdo->begin()};
+  CondAttrListCollection::const_iterator linkEnd{readCdo->end()};
+  for (;linkItr != linkEnd; ++linkItr) {
+    //A CondAttrListCollection is a map of ChanNum and AttributeList
+    Identifier waferId{(*linkItr).first};
+    CondAttrListCollection::AttributeList payload{(*linkItr).second};
+    bool lastProbedState{payload[0].data<bool>()};
+    if (not lastProbedState) writeCdo->setBadWaferId(waferId);
+    ATH_MSG_INFO("LINK " << waferId << " (" << waferId.get_identifier32().get_compact() << " in 32 bit): " << lastProbedState);
+  }
+  if (writeCdo->size()!=0) writeCdo->setFilled();
+
+  // Record the output cond object
+  if (writeHandle.record(rangeW, writeCdo).isFailure()) {
+    ATH_MSG_FATAL("Could not record SCT_ModuleVetoCondData " << writeHandle.key() 
+                  << " with EventRange " << rangeW
+                  << " into Conditions Store");
+    return StatusCode::FAILURE;
+  }
+  ATH_MSG_INFO("recorded new CDO " << writeHandle.key() << " with range " << rangeW << " into Conditions Store");
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode SCT_LinkMaskingCondAlg::finalize() {
+  ATH_MSG_DEBUG("finalize " << name());
+  return StatusCode::SUCCESS;
+}
diff --git a/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_LinkMaskingCondAlg.h b/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_LinkMaskingCondAlg.h
new file mode 100644
index 0000000000000000000000000000000000000000..26a6d6f70eb0d75363a0c7737c501368905f636d
--- /dev/null
+++ b/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_LinkMaskingCondAlg.h
@@ -0,0 +1,36 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/ 
+
+#ifndef SCT_LINKMASKINGCONDALG
+#define SCT_LINKMASKINGCONDALG
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+
+#include "StoreGate/ReadCondHandleKey.h"
+#include "AthenaPoolUtilities/CondAttrListCollection.h"
+
+#include "StoreGate/WriteCondHandleKey.h"
+#include "SCT_ConditionsData/SCT_ModuleVetoCondData.h"
+
+#include "GaudiKernel/ICondSvc.h"
+
+#include "GaudiKernel/Property.h"
+
+class SCT_LinkMaskingCondAlg : public AthAlgorithm 
+{  
+ public:
+  SCT_LinkMaskingCondAlg(const std::string& name, ISvcLocator* pSvcLocator);
+  ~SCT_LinkMaskingCondAlg();
+  StatusCode initialize();
+  StatusCode execute();
+  StatusCode finalize();
+
+ private:
+  SG::ReadCondHandleKey<CondAttrListCollection> m_readKey;
+  SG::WriteCondHandleKey<SCT_ModuleVetoCondData> m_writeKey;
+
+  ServiceHandle<ICondSvc> m_condSvc;
+};
+
+#endif // SCT_LINKMASKINGCONDALG
diff --git a/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_LinkMaskingSvc.cxx b/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_LinkMaskingSvc.cxx
index 3da66379f590697bdc9e1d587ab84f91138124eb..cc275ff3e812dabafc835e3f51be73e2b4353047 100644
--- a/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_LinkMaskingSvc.cxx
+++ b/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_LinkMaskingSvc.cxx
@@ -14,16 +14,15 @@
 #include "Identifier/IdentifierHash.h"
 #include "InDetIdentifier/SCT_ID.h"
 
-// Static folder name
-static const std::string coolLinkFolderName{"/purple/pants"};
-// This folder can be created by SCT_ConditionsServices/python/createLinkMaskingSQLiteFile.py 
-
 // Constructor
 SCT_LinkMaskingSvc::SCT_LinkMaskingSvc(const std::string& name, ISvcLocator* pSvcLocator) : 
   AthService(name, pSvcLocator),
-  m_filled{false},
   m_detStore{"DetectorStore", name},
-  m_sctHelper{nullptr}
+  m_sctHelper{nullptr},
+  m_mutex{},
+  m_cache{},
+  m_condData{},
+  m_condKey{"SCT_LinkMaskingCondData"}
 { 
   // nop
 }
@@ -44,11 +43,8 @@ StatusCode SCT_LinkMaskingSvc::initialize() {
     return StatusCode::FAILURE;
   }
 
-  // Register callbacks for folders 
-  if (m_detStore->regFcn(&SCT_LinkMaskingSvc::fillData, this, m_dataLink, coolLinkFolderName).isFailure()) {
-    ATH_MSG_FATAL("Failed to register callback");
-    return StatusCode::FAILURE;
-  }
+  // Read Cond Handle
+  CHECK(m_condKey.initialize());
 
   return StatusCode::SUCCESS;
 }
@@ -61,7 +57,7 @@ StatusCode SCT_LinkMaskingSvc::finalize() {
 
 // Query interfaces.
 StatusCode SCT_LinkMaskingSvc::queryInterface(const InterfaceID& riid, void** ppvInterface) {
-  if ( ISCT_ConditionsSvc::interfaceID().versionMatch(riid) ) {
+  if (ISCT_ConditionsSvc::interfaceID().versionMatch(riid)) {
     *ppvInterface = dynamic_cast<ISCT_ConditionsSvc*>(this);
   } else {
     // Interface is not directly available : try out a base class
@@ -80,10 +76,13 @@ bool SCT_LinkMaskingSvc::canReportAbout(InDetConditions::Hierarchy h) {
 bool SCT_LinkMaskingSvc::isGood(const Identifier& elementId, InDetConditions::Hierarchy h) {
   if (not canReportAbout(h)) return true;
 
-  bool result{true};
-  result = (m_maskedLinkIds.find(elementId) == m_maskedLinkIds.end());
+  const EventContext& ctx{Gaudi::Hive::currentContext()};
+  const SCT_ModuleVetoCondData* condData{getCondData(ctx)};
+  // If database cannot be retrieved, all wafer IDs are good.
+  if (condData==nullptr) return true;
 
-  return result;
+  // Return the result of database
+  return (not condData->isBadWaferId(elementId));
 }
 
 // Is a wafer with this IdentifierHash good?
@@ -92,59 +91,29 @@ bool SCT_LinkMaskingSvc::isGood(const IdentifierHash& hashId) {
   return isGood(elementId);
 }
 
-// Callback funtion (with arguments required by IovDbSvc) to fill channel, module and link info
-StatusCode SCT_LinkMaskingSvc::fillData(int& /*i*/, std::list<std::string>& /*l*/) {
-  // Clear previous information at callback
-  m_maskedLinkIds.clear();
-
-  // Get link folder
-  if (retrieveFolder(m_dataLink, coolLinkFolderName).isFailure()) {
-    ATH_MSG_FATAL("Could not fill masked link data");
-    return StatusCode::FAILURE;
-  } else {
-    ATH_MSG_INFO("fillChannelData: IOV callback resulted in a link CondAttrListCollection of size " << m_dataLink->size());
-  }
-
-  CondAttrListCollection::const_iterator linkItr{m_dataLink->begin()};
-  CondAttrListCollection::const_iterator linkEnd{m_dataLink->end()};
-  for (;linkItr != linkEnd; ++linkItr) {
-    //A CondAttrListCollection is a map of ChanNum and AttributeList
-    Identifier waferId{(*linkItr).first};
-    CondAttrListCollection::AttributeList payload{(*linkItr).second};
-    bool lastProbedState{payload[0].data<bool>()};
-    if (not lastProbedState) m_maskedLinkIds.insert(waferId);
-    ATH_MSG_INFO("LINK " << waferId << ": " << lastProbedState);
-  }
-
-  m_filled = (m_maskedLinkIds.size() != 0);
-
-  const long unsigned int totalMasked{m_maskedLinkIds.size()};
-  ATH_MSG_INFO("Total number of masked links is " << totalMasked);
-
-  return StatusCode::SUCCESS;
-}
-
 // Is the information filled?
 bool SCT_LinkMaskingSvc::filled() const {
-  return m_filled;
+  const EventContext& ctx{Gaudi::Hive::currentContext()};
+  const SCT_ModuleVetoCondData* condData{getCondData(ctx)};
+  return (condData!=nullptr);
 }
 
-// Get a DB folder
-StatusCode SCT_LinkMaskingSvc::retrieveFolder(const DataHandle<CondAttrListCollection>& pDataVec, const std::string& folderName) {
-  if (not m_detStore) {
-    ATH_MSG_FATAL("The detector store pointer is NULL");
-    return StatusCode::FAILURE;
+const SCT_ModuleVetoCondData*
+SCT_LinkMaskingSvc::getCondData(const EventContext& ctx) const {
+  static const EventContext::ContextEvt_t invalidValue{EventContext::INVALID_CONTEXT_EVT};
+  EventContext::ContextID_t slot{ctx.slot()};
+  EventContext::ContextEvt_t evt{ctx.evt()};
+  std::lock_guard<std::mutex> lock{m_mutex};
+  if (slot>=m_cache.size()) {
+    m_cache.resize(slot+1, invalidValue); // Store invalid values in order to go to the next IF statement.
   }
-
-  if (m_detStore->retrieve(pDataVec, folderName).isFailure()) {
-    ATH_MSG_FATAL("Could not retrieve AttrListCollection for " << folderName);
-    return StatusCode::FAILURE;
+  if (m_cache[slot]!=evt) {
+    SG::ReadCondHandle<SCT_ModuleVetoCondData> condData{m_condKey};
+    if (not condData.isValid()) {
+      ATH_MSG_ERROR("Failed to get " << m_condKey.key());
+    }
+    m_condData.set(*condData);
+    m_cache[slot] = evt;
   }
-
-  if (0 == pDataVec->size()) {
-    ATH_MSG_FATAL("This folder's data set appears to be empty: " << folderName);
-    return StatusCode::FAILURE;
-  }
-
-  return StatusCode::SUCCESS;
+  return m_condData.get();
 }
diff --git a/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_LinkMaskingSvc.h b/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_LinkMaskingSvc.h
index 635699766fcbd162b5fa3e81f0e7986739da9515..762203d73546bc14beaa32fa1952831f0513d716 100644
--- a/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_LinkMaskingSvc.h
+++ b/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_LinkMaskingSvc.h
@@ -14,19 +14,21 @@
 // STL includes
 #include <string>
 #include <set>
-#include <list>
-#include <utility>
+#include <vector>
+#include <mutex>
 
 // Gaudi includes
 #include "GaudiKernel/ServiceHandle.h"
+#include "GaudiKernel/EventContext.h"
+#include "GaudiKernel/ContextSpecificPtr.h"
 
 // Athena includes
 #include "AthenaBaseComps/AthService.h"
 #include "AthenaPoolUtilities/CondAttrListCollection.h"
 #include "Identifier/Identifier.h"
 #include "InDetConditionsSummaryService/InDetHierarchy.h"
+#include "SCT_ConditionsData/SCT_ModuleVetoCondData.h"
 #include "SCT_ConditionsServices/ISCT_ConditionsSvc.h"
-#include "StoreGate/DataHandle.h"
 
 // Forward declarations
 template <class TYPE> class SvcFactory;
@@ -68,7 +70,7 @@ public:
   virtual StatusCode                    fillData() { return StatusCode::FAILURE; }
   
   /**Fill data from an IOVDbSvc callback*/
-  virtual StatusCode                    fillData(int& i, std::list<std::string>& l);
+  virtual StatusCode                    fillData(int& /*i*/, std::list<std::string>& /*l*/) { return StatusCode::SUCCESS; };
   
   /**Are the data available?*/
   virtual bool                          filled() const;
@@ -77,17 +79,24 @@ public:
   virtual bool                          canFillDuringInitialize() { return false; }
   
 private:
-  std::set<Identifier>                     m_maskedLinkIds;                 //!< Set of masked link identifiers 
-  bool                                     m_filled;                        //!< Had the data been filled?
-  ServiceHandle<StoreGateSvc>              m_detStore;                      //!< Handle on the detector store
-  const DataHandle<CondAttrListCollection> m_dataLink;                      //!< Handle for link info from DB
-  const SCT_ID*                            m_sctHelper;                     //!< ID helper for SCT
+  SCT_ModuleVetoCondData                   m_data;      //!< Set of masked link identifiers
+  ServiceHandle<StoreGateSvc>              m_detStore;  //!< Handle on the detector store
+  const SCT_ID*                            m_sctHelper; //!< ID helper for SCT
 
-  /** Retreive a given folder from the DB*/
-  StatusCode                            retrieveFolder(const DataHandle<CondAttrListCollection> &pDataVec, const std::string & folderName);
+  // Mutex to protect the contents.
+  mutable std::mutex m_mutex;
+  // Cache to store events for slots
+  mutable std::vector<EventContext::ContextEvt_t> m_cache;
+  // Pointer of SCT_ModuleVetoCondData
+  mutable Gaudi::Hive::ContextSpecificPtr<const SCT_ModuleVetoCondData> m_condData;
+  // ReadCondHandleKey
+  SG::ReadCondHandleKey<SCT_ModuleVetoCondData> m_condKey;
+  // Provides SCT_ModuleVetoCondData pointer
+  const SCT_ModuleVetoCondData* getCondData(const EventContext& ctx) const;
+  
 };
 
-inline const InterfaceID& SCT_LinkMaskingSvc::interfaceID(){
+inline const InterfaceID& SCT_LinkMaskingSvc::interfaceID() {
   return ISCT_ConditionsSvc::interfaceID(); 
 }
 
diff --git a/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_LinkMaskingTestAlg.cxx b/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_LinkMaskingTestAlg.cxx
index 8057b32b06a8fbd2a1e1655c5e814875eec49923..a82efd0f179c346715b9cf540c7f7d29fc549e4f 100644
--- a/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_LinkMaskingTestAlg.cxx
+++ b/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_LinkMaskingTestAlg.cxx
@@ -12,37 +12,32 @@
  **/
 
 #include "SCT_LinkMaskingTestAlg.h"
-#include "InDetConditionsSummaryService/InDetHierarchy.h"
-#include "SCT_ConditionsServices/ISCT_ConditionsSvc.h"
 
 //Gaudi includes
 #include "GaudiKernel/StatusCode.h"
 
 //Athena includes
 #include "Identifier/Identifier.h"
+#include "InDetConditionsSummaryService/InDetHierarchy.h"
+#include "SCT_ConditionsServices/ISCT_ConditionsSvc.h"
 
-//local includes
-#include "SCT_LinkMaskingSvc.h"
-
-SCT_LinkMaskingTestAlg::SCT_LinkMaskingTestAlg(const std::string& name, ISvcLocator* pSvcLocator ) : 
-  AthAlgorithm( name, pSvcLocator ),
-  m_linkMaskingSvc("SCT_LinkMaskingSvc", name)
-{
-  declareProperty("LinkMaskingSvc",                   m_linkMaskingSvc);
+SCT_LinkMaskingTestAlg::SCT_LinkMaskingTestAlg(const std::string& name, ISvcLocator* pSvcLocator) : 
+  AthAlgorithm(name, pSvcLocator),
+  m_linkMaskingSvc("SCT_LinkMaskingSvc", name) {
+  declareProperty("LinkMaskingSvc", m_linkMaskingSvc);
 }
 
-SCT_LinkMaskingTestAlg::~SCT_LinkMaskingTestAlg()
-{ 
-  msg(MSG::INFO) << "Calling destructor" << endmsg;
+SCT_LinkMaskingTestAlg::~SCT_LinkMaskingTestAlg() { 
+  ATH_MSG_INFO("Calling destructor");
 }
 
 //Initialize
-StatusCode SCT_LinkMaskingTestAlg::initialize(){
-  msg(MSG::INFO)<< "Calling initialize" << endmsg;
+StatusCode SCT_LinkMaskingTestAlg::initialize() {
+  ATH_MSG_INFO("Calling initialize");
   
   // Retrieve link masking service
   if (m_linkMaskingSvc.retrieve().isFailure()) {
-    msg(MSG::ERROR)<<"Could not retrieve the link masking service"<<endmsg;
+    ATH_MSG_FATAL("Could not retrieve the link masking service");
     return StatusCode::FAILURE;
   }
 
@@ -50,18 +45,18 @@ StatusCode SCT_LinkMaskingTestAlg::initialize(){
 }
 
 //Execute
-StatusCode SCT_LinkMaskingTestAlg::execute(){
+StatusCode SCT_LinkMaskingTestAlg::execute() {
 
-  msg(MSG::INFO) << "Wafer 167786496 is " << (m_linkMaskingSvc->isGood(Identifier(167786496)) ? "not masked":"masked") << endmsg;
-  msg(MSG::INFO) << "Wafer 167787520 is " << (m_linkMaskingSvc->isGood(Identifier(167787520)) ? "not masked":"masked") << endmsg;
+  ATH_MSG_INFO("Wafer 167772160 is " << (m_linkMaskingSvc->isGood(Identifier{167772160}) ? "not masked" : "masked"));
+  ATH_MSG_INFO("Wafer 167773184 is " << (m_linkMaskingSvc->isGood(Identifier{167773184}) ? "not masked" : "masked"));
+  ATH_MSG_INFO("Wafer 167786496 is " << (m_linkMaskingSvc->isGood(Identifier{167786496}) ? "not masked" : "masked"));
+  ATH_MSG_INFO("Wafer 167787520 is " << (m_linkMaskingSvc->isGood(Identifier{167787520}) ? "not masked" : "masked"));
 
   return StatusCode::SUCCESS;
 }
 
-
 //Finalize
-StatusCode SCT_LinkMaskingTestAlg::finalize(){
-  StatusCode sc(StatusCode::SUCCESS);
-  msg(MSG::INFO)<< "Calling finalize" << endmsg;
-  return sc;
+StatusCode SCT_LinkMaskingTestAlg::finalize() {
+  ATH_MSG_INFO("Calling finalize");
+  return StatusCode::SUCCESS;
 }
diff --git a/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_LinkMaskingTestAlg.h b/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_LinkMaskingTestAlg.h
index 07971fe2be3a5267f5504ff3f0df7ef2fbc984d2..6b0aef868f5987dfc7e982fe289c008a3eb0ea0b 100644
--- a/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_LinkMaskingTestAlg.h
+++ b/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_LinkMaskingTestAlg.h
@@ -31,7 +31,7 @@ class ISCT_ConditionsSvc;
 ///Example class to show calling the SCT_LinkMaskingSvc
 class SCT_LinkMaskingTestAlg : public AthAlgorithm {
  public:
-  SCT_LinkMaskingTestAlg(const std::string &name,ISvcLocator *pSvcLocator) ;
+  SCT_LinkMaskingTestAlg(const std::string& name, ISvcLocator* pSvcLocator);
  ~SCT_LinkMaskingTestAlg();
 
   StatusCode initialize();
@@ -42,4 +42,4 @@ class SCT_LinkMaskingTestAlg : public AthAlgorithm {
   ServiceHandle<ISCT_ConditionsSvc> m_linkMaskingSvc;
 }; 
 
-#endif
+#endif // SCT_LinkMaskingTestAlg_H
diff --git a/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_ModuleVetoCondAlg.cxx b/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_ModuleVetoCondAlg.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..6e6e9350cf6c2c5c3e1a7e2cd30096827dc1c538
--- /dev/null
+++ b/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_ModuleVetoCondAlg.cxx
@@ -0,0 +1,110 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "SCT_ModuleVetoCondAlg.h"
+
+#include "GaudiKernel/EventIDRange.h"
+
+template <class T> 
+static std::vector<T> 
+string2Vector(const std::string& s) {
+  std::vector<T> v;
+  std::istringstream inputStream{s};
+  std::istream_iterator<T> vecRead{inputStream};
+  std::istream_iterator<T> endOfString; //relies on default constructor to produce eof
+  std::copy(vecRead,endOfString, std::back_inserter(v));// DOESN'T ALLOW NON-WHITESPACE DELIMITER !
+  return v;
+}
+
+SCT_ModuleVetoCondAlg::SCT_ModuleVetoCondAlg(const std::string& name, ISvcLocator* pSvcLocator)
+  : ::AthAlgorithm(name, pSvcLocator)
+  , m_readKey{"/SCT/Manual/BadModules"}
+  , m_writeKey{"SCT_ModuleVetoCondData"}
+  , m_condSvc{"CondSvc", name}
+{
+  declareProperty("ReadKey", m_readKey, "Key of input (raw) bad module conditions folder");
+  declareProperty("WriteKey", m_writeKey, "Key of output (derived) bad module conditions folder");
+}
+
+SCT_ModuleVetoCondAlg::~SCT_ModuleVetoCondAlg() {
+}
+
+StatusCode SCT_ModuleVetoCondAlg::initialize() {
+  ATH_MSG_DEBUG("initialize " << name());
+
+  // CondSvc
+  ATH_CHECK(m_condSvc.retrieve());
+
+  // Read Cond Handle
+  ATH_CHECK(m_readKey.initialize());
+  // Write Cond Handles
+  ATH_CHECK(m_writeKey.initialize());
+  if(m_condSvc->regHandle(this, m_writeKey).isFailure()) {
+    ATH_MSG_FATAL("unable to register WriteCondHandle " << m_writeKey.fullKey() << " with CondSvc");
+    return StatusCode::FAILURE;
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode SCT_ModuleVetoCondAlg::execute() {
+  ATH_MSG_DEBUG("execute " << name());
+
+  // Write Cond Handle
+  SG::WriteCondHandle<SCT_ModuleVetoCondData> writeHandle{m_writeKey};
+  // Do we have a valid Write Cond Handle for current time?
+  if (writeHandle.isValid()) {
+    // in theory this should never be called in MT
+    writeHandle.updateStore();
+    ATH_MSG_DEBUG("CondHandle " << writeHandle.fullKey() << " is already valid."
+                  << ". In theory this should not be called, but may happen"
+                  << " if multiple concurrent events are being processed out of order."
+                  << " Forcing update of Store contents");
+    return StatusCode::SUCCESS; 
+  }
+
+  // Read Cond Handle
+  SG::ReadCondHandle<AthenaAttributeList> readHandle{m_readKey};
+  const AthenaAttributeList* readCdo{*readHandle}; 
+  if (readCdo==nullptr) {
+    ATH_MSG_FATAL("Null pointer to the read conditions object");
+    return StatusCode::FAILURE;
+  }
+  // Get the validitiy range
+  EventIDRange rangeW;
+  if (not readHandle.range(rangeW)) {
+    ATH_MSG_FATAL("Failed to retrieve validity range for " << readHandle.key());
+    return StatusCode::FAILURE;
+  }
+  ATH_MSG_INFO("Size of AthenaAttributeList " << readHandle.fullKey() << " readCdo->size()= " << readCdo->size());
+  ATH_MSG_INFO("Range of input is " << rangeW);
+  
+  // Construct the output Cond Object and fill it in
+  SCT_ModuleVetoCondData* writeCdo{new SCT_ModuleVetoCondData()};
+
+  // Read bad wafer info
+  std::string badModuleString{(*readCdo)["ModuleList"].data<std::string>()};
+  std::vector<int> v{string2Vector<int>(badModuleString)};
+  int numberInDb{static_cast<int>(v.size())};
+  ATH_MSG_INFO(numberInDb << " elements were declared bad in the database.");
+  for (std::vector<int>::const_iterator i{v.begin()}; i!=v.end(); ++i) {
+    writeCdo->setBadWaferId(Identifier{*i});
+  }
+
+  // Record the output cond object
+  if (writeHandle.record(rangeW, writeCdo).isFailure()) {
+    ATH_MSG_FATAL("Could not record SCT_ModuleVetoCondData " << writeHandle.key() 
+                  << " with EventRange " << rangeW
+                  << " into Conditions Store");
+    return StatusCode::FAILURE;
+  }
+  ATH_MSG_INFO("recorded new CDO " << writeHandle.key() << " with range " << rangeW << " into Conditions Store");
+
+  return StatusCode::SUCCESS;
+}
+
+StatusCode SCT_ModuleVetoCondAlg::finalize() {
+  ATH_MSG_DEBUG("finalize " << name());
+  return StatusCode::SUCCESS;
+}
diff --git a/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_ModuleVetoCondAlg.h b/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_ModuleVetoCondAlg.h
new file mode 100644
index 0000000000000000000000000000000000000000..5c2c634d524ec10888b28523ba7a016c164ac0cc
--- /dev/null
+++ b/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_ModuleVetoCondAlg.h
@@ -0,0 +1,36 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/ 
+
+#ifndef SCT_MODULEVETOCONDALG
+#define SCT_MODULEVETOCONDALG
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+
+#include "StoreGate/ReadCondHandleKey.h"
+#include "AthenaPoolUtilities/AthenaAttributeList.h"
+
+#include "StoreGate/WriteCondHandleKey.h"
+#include "SCT_ConditionsData/SCT_ModuleVetoCondData.h"
+
+#include "GaudiKernel/ICondSvc.h"
+
+#include "GaudiKernel/Property.h"
+
+class SCT_ModuleVetoCondAlg : public AthAlgorithm 
+{  
+ public:
+  SCT_ModuleVetoCondAlg(const std::string& name, ISvcLocator* pSvcLocator);
+  ~SCT_ModuleVetoCondAlg();
+  StatusCode initialize();
+  StatusCode execute();
+  StatusCode finalize();
+
+ private:
+  SG::ReadCondHandleKey<AthenaAttributeList> m_readKey;
+  SG::WriteCondHandleKey<SCT_ModuleVetoCondData> m_writeKey;
+
+  ServiceHandle<ICondSvc> m_condSvc;
+};
+
+#endif // SCT_MODULEVETOCONDALG
diff --git a/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_ModuleVetoSvc.cxx b/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_ModuleVetoSvc.cxx
index 380026e660ae9542fa1b08363bf715f1d5b92ebf..27939ff11af7789c885e29072fdec1ba6b9023c6 100644
--- a/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_ModuleVetoSvc.cxx
+++ b/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_ModuleVetoSvc.cxx
@@ -9,45 +9,35 @@
  **/
 
 #include "SCT_ModuleVetoSvc.h"
+
 //STL includes
-#include <vector>
-#include <list>
 #include <algorithm>
-#include <sstream>
 #include <iterator>
 
 //Gaudi includes
 #include "GaudiKernel/StatusCode.h"
 
+//Athena includes
 #include "Identifier/IdentifierHash.h"
-
 #include "InDetIdentifier/SCT_ID.h"
 
-static const std::string databaseSignature("database");
-static const std::string coolFolderName("/SCT/Manual/BadModules"); //a single-channel folder in the DB
-
-template <class T> 
-static std::vector<T> 
-string2Vector(const std::string & s){
-  std::vector<T> v;
-  std::istringstream inputStream(s);
-  std::istream_iterator<T> vecRead(inputStream);
-  std::istream_iterator<T> endOfString; //relies on default constructor to produce eof
-  std::copy(vecRead,endOfString,std::back_inserter(v));// DOESN'T ALLOW NON-WHITESPACE DELIMITER !
-  return v;
-}
+static const std::string databaseSignature{"database"};
 
 // Constructor
-SCT_ModuleVetoSvc::SCT_ModuleVetoSvc( const std::string& name, ISvcLocator* pSvcLocator ) :
+SCT_ModuleVetoSvc::SCT_ModuleVetoSvc(const std::string& name, ISvcLocator* pSvcLocator) :
   AthService(name, pSvcLocator),
-  m_filled{false},
+  m_localCondData{},
   m_pHelper{nullptr},
   m_useDatabase{false},
   m_maskLayers{false},
   m_maskSide{-1},
-  m_detStore("DetectorStore",name)
+  m_detStore{"DetectorStore", name},
+  m_mutex{},
+  m_cache{},
+  m_condData{},
+  m_condKey{"SCT_ModuleVetoCondData"}
   {
-    declareProperty("BadModuleIdentifiers",m_badElements);
+    declareProperty("BadModuleIdentifiers", m_badElements);
     declareProperty("MaskLayers",  m_maskLayers, "Mask full layers/disks in overlay" ); 
     declareProperty("MaskSide",  m_maskSide, "Mask full modules (-1), innwe (0) or outer (1) sides" );  
     declareProperty("LayersToMask", m_layersToMask, "Which barrel layers to mask out, goes from 0 to N-1"); 
@@ -56,59 +46,57 @@ SCT_ModuleVetoSvc::SCT_ModuleVetoSvc( const std::string& name, ISvcLocator* pSvc
 
 //Initialize
 StatusCode 
-SCT_ModuleVetoSvc::initialize(){
-  StatusCode sc{StatusCode::SUCCESS};
-
-  if(m_maskLayers &&  !m_layersToMask.size() && !m_disksToMask.size()) {
-    ATH_MSG_DEBUG( "Layer/Disk masking enabled, but no layer/disk specified!" );
+SCT_ModuleVetoSvc::initialize() {
+  if (m_maskLayers and !m_layersToMask.size() and !m_disksToMask.size()) {
+    ATH_MSG_INFO("Layer/Disk masking enabled, but no layer/disk specified!");
     m_maskLayers = false;
   }
   
-  if(!m_maskLayers &&  (m_layersToMask.size() || m_disksToMask.size())) {
-    ATH_MSG_DEBUG( "Layer/Disk to mask specified, but masking is disabled!" );
+  if (!m_maskLayers and (m_layersToMask.size() or m_disksToMask.size())) {
+    ATH_MSG_INFO("Layer/Disk to mask specified, but masking is disabled!");
   } 
 
-  if(!m_maskLayers &&  m_maskSide!=-1) {
-    ATH_MSG_DEBUG( "Layer/Disk side to mask specified, but masking is disabled!" );
+  if (!m_maskLayers and m_maskSide!=-1) {
+    ATH_MSG_INFO("Layer/Disk side to mask specified, but masking is disabled!");
   } 
   
-  if(m_maskLayers &&  m_disksToMask.size() && (std::find(m_disksToMask.begin(), m_disksToMask.end(),0)!=m_disksToMask.end())) {
-    ATH_MSG_WARNING( "0th Disk not defined (-N to N) - check your setup!" );
+  if (m_maskLayers and m_disksToMask.size() and (std::find(m_disksToMask.begin(), m_disksToMask.end(),0)!=m_disksToMask.end())) {
+    ATH_MSG_WARNING("0th Disk not defined (-N to N) - check your setup!");
   }   
 
-  if(m_detStore->retrieve(m_pHelper,"SCT_ID").isFailure()) {
-    ATH_MSG_ERROR("SCT helper failed to retrieve");
+  if (m_detStore->retrieve(m_pHelper, "SCT_ID").isFailure()) {
+    ATH_MSG_FATAL("SCT helper failed to retrieve");
     return StatusCode::FAILURE;
   } else {
     ATH_MSG_INFO("Successfully retrieved SCT_ID helper");
   }
 
-  m_useDatabase=(std::find(m_badElements.value().begin(),m_badElements.value().end(),databaseSignature) != m_badElements.value().end());
-  if(not m_useDatabase) {
-    if(fillData().isFailure()) {
-      ATH_MSG_ERROR("Failed to fill data");
+  // If "database" is found in m_badElements, COOL database is used.
+  m_useDatabase=(std::find(m_badElements.value().begin(), m_badElements.value().end(), databaseSignature) != m_badElements.value().end());
+  ATH_MSG_INFO("m_useDatabase is " << m_useDatabase);
+
+  if (not m_useDatabase) {
+    if (fillData().isFailure()) {
+      ATH_MSG_FATAL("Failed to fill data");
       return StatusCode::FAILURE;
     }
   } else {
-    if(m_detStore->regFcn(&SCT_ModuleVetoSvc::fillData,this,m_dbList,coolFolderName).isFailure()) {
-      ATH_MSG_ERROR("Failed to register callback");
-      return StatusCode::FAILURE;
-    }
+    // Read Cond Handle
+    CHECK(m_condKey.initialize());
   }
-  //
-  const std::string databaseUseString{m_useDatabase?"":"not "};
+
+  const std::string databaseUseString{m_useDatabase ? "" : "not "};
   ATH_MSG_INFO("Initialized veto service with data, "
-               <<(m_badElements.value().size() - int(m_useDatabase))
-               <<" elements declared bad. Database will "<<databaseUseString<<"be used.");
- 
-  return sc;
+               << (m_badElements.value().size() - static_cast<long unsigned int>(m_useDatabase))
+               << " elements declared bad. Database will " << databaseUseString << "be used.");
+
+  return StatusCode::SUCCESS;
 }
 
 //Finalize
 StatusCode
 SCT_ModuleVetoSvc::finalize() {
-  StatusCode sc{StatusCode::SUCCESS};
-  return sc;
+  return StatusCode::SUCCESS;
 }
 
 // From s.binet
@@ -119,7 +107,7 @@ SCT_ModuleVetoSvc::finalize() {
 // N.B. Don't forget to release the interface after use!!!
 StatusCode 
 SCT_ModuleVetoSvc::queryInterface(const InterfaceID& riid, void** ppvInterface) {
-  if(ISCT_ConditionsSvc::interfaceID().versionMatch(riid)) {
+  if (ISCT_ConditionsSvc::interfaceID().versionMatch(riid)) {
     *ppvInterface = dynamic_cast<ISCT_ConditionsSvc*>(this);
   } else {
     // Interface is not directly available : try out a base class
@@ -131,80 +119,117 @@ SCT_ModuleVetoSvc::queryInterface(const InterfaceID& riid, void** ppvInterface)
 
 bool 
 SCT_ModuleVetoSvc::canReportAbout(InDetConditions::Hierarchy h) {
-  return ((h==InDetConditions::DEFAULT) or (h==InDetConditions::SCT_SIDE) );
+  return ((h==InDetConditions::DEFAULT) or (h==InDetConditions::SCT_SIDE));
 }
 
 bool 
-SCT_ModuleVetoSvc::isGood(const Identifier & elementId, InDetConditions::Hierarchy h) {
-  if(not canReportAbout(h)) return true;
-  bool result{m_badIds.find(elementId) == m_badIds.end()};
-  return result;
+SCT_ModuleVetoSvc::isGood(const Identifier& elementId, InDetConditions::Hierarchy h) {
+  if (not canReportAbout(h)) return true;
+
+  // Bad wafer in properties
+  if (m_localCondData.isBadWaferId(elementId)) return false;
+  // If database is not used, all wafer IDs here should be good.
+  if (not m_useDatabase) return true;
+
+  const EventContext& ctx{Gaudi::Hive::currentContext()};
+  const SCT_ModuleVetoCondData* condData{getCondData(ctx)};
+  // If database cannot be retrieved, all wafer IDs are good.
+  if (condData==nullptr) return true;
+
+  // Return the result of database
+  return (not condData->isBadWaferId(elementId));
 }
 
 bool 
-SCT_ModuleVetoSvc::isGood(const IdentifierHash & hashId) {
+SCT_ModuleVetoSvc::isGood(const IdentifierHash& hashId) {
   Identifier elementId{m_pHelper->wafer_id(hashId)};
   return isGood(elementId);
 }
 
 StatusCode 
 SCT_ModuleVetoSvc::fillData() {
+  // Reset SCT_ModuleVetoCondData
+  m_localCondData.clear();
+
+  // Fill data based on properties
   StatusCode sc{StatusCode::SUCCESS};
-  if((m_badElements.value().size() - int(m_useDatabase)) == 0 && !m_maskLayers) {
+  if ((m_badElements.value().size() - static_cast<int>(m_useDatabase)) == 0 and !m_maskLayers) {
     ATH_MSG_INFO("No bad modules in job options.");
     return sc;
   } 
+
   bool success{true};
   std::vector<std::string>::const_iterator pId{m_badElements.value().begin()};
   std::vector<std::string>::const_iterator last{m_badElements.value().end()};
-  for(;pId not_eq last;++pId) {
+  for(; pId not_eq last;++pId) {
     unsigned long long idToWrite{static_cast<unsigned long long>(atoll(pId->c_str()))};
-    if(*pId != databaseSignature) success &= m_badIds.insert(Identifier(idToWrite)).second;
+    if (*pId != databaseSignature) success &= m_localCondData.setBadWaferId(Identifier(idToWrite));
   }
 
-  if(m_maskLayers) {
-    ATH_MSG_INFO("Masking "<<m_layersToMask.size()<<" SCT Layers");
-    ATH_MSG_INFO("Masking "<<m_disksToMask.size()<<" SCT Disks");
-    for(unsigned int i{0}; i < m_pHelper->wafer_hash_max(); i++){
+  if (m_maskLayers) {
+    ATH_MSG_INFO("Masking " << m_layersToMask.size() << " SCT Layers");
+    ATH_MSG_INFO("Masking " << m_disksToMask.size() << " SCT Disks");
+    for(unsigned int i{0}; i < m_pHelper->wafer_hash_max(); i++) {
       Identifier mID{m_pHelper->wafer_id(i)};
-      if(
-         (m_pHelper->barrel_ec(mID) == 0 && (m_maskSide==-1 || m_pHelper->side(mID)==m_maskSide) && (std::find(m_layersToMask.begin(), m_layersToMask.end(), m_pHelper->layer_disk(mID)) != m_layersToMask.end())) ||
-         (m_pHelper->barrel_ec(mID) == 2  && (m_maskSide==-1 || m_pHelper->side(mID)==m_maskSide) && (std::find(m_disksToMask.begin(), m_disksToMask.end(), (m_pHelper->layer_disk(mID) + 1)) != m_disksToMask.end())) ||
-         (m_pHelper->barrel_ec(mID) == -2 && (m_maskSide==-1 || m_pHelper->side(mID)==m_maskSide) && (std::find(m_disksToMask.begin(), m_disksToMask.end(), -1*(m_pHelper->layer_disk(mID) + 1)) != m_disksToMask.end()))
-         ) {
-        ATH_MSG_DEBUG("Masking ID Hash"<<i);
-        m_badIds.insert(mID);
+      int bec{m_pHelper->barrel_ec(mID)};
+      int side{m_pHelper->side(mID)};
+      int layer_disk{m_pHelper->layer_disk(mID)};
+
+      if ((bec ==  0 and (m_maskSide==-1 or side==m_maskSide) and (std::find(m_layersToMask.begin(), m_layersToMask.end(),    layer_disk     ) != m_layersToMask.end())) or
+          (bec ==  2 and (m_maskSide==-1 or side==m_maskSide) and (std::find(m_disksToMask.begin(),  m_disksToMask.end(),    (layer_disk + 1)) != m_disksToMask.end()))  or
+          (bec == -2 and (m_maskSide==-1 or side==m_maskSide) and (std::find(m_disksToMask.begin(),  m_disksToMask.end(), -1*(layer_disk + 1)) != m_disksToMask.end()))) {
+        ATH_MSG_DEBUG("Masking ID Hash " << i);
+        m_localCondData.setBadWaferId(mID);
       }
     }
   }
   
-  m_filled=true;
+  ATH_MSG_INFO(m_localCondData.size() << " bad wafers are defined via properties.");
+
+  m_localCondData.setFilled();
   ATH_MSG_DEBUG("Successfully filled bad SCT identifiers list");
-  return success?sc:(StatusCode::FAILURE);
+  return (success ? sc : StatusCode::FAILURE);
 }
 
 StatusCode 
-SCT_ModuleVetoSvc::fillData(int& /*i*/ , std::list<std::string>& /*folderList*/) {
-  StatusCode sc{fillData()};
-  if(sc.isFailure()) return StatusCode::FAILURE;
-  if(m_detStore->retrieve(m_dbList,coolFolderName).isFailure()) return StatusCode::FAILURE;
-  std::string badModuleString{m_dbList[0]["ModuleList"].data<std::string>()};
-  std::vector<int> v{string2Vector<int>(badModuleString)};
-  int numberInDb{static_cast<int>(v.size())};
-  ATH_MSG_INFO(numberInDb<<" elements were declared bad in the database.");
-  for(std::vector<int>::const_iterator i(v.begin());i!=v.end();++i) {
-    m_badIds.insert(Identifier(*i));
-  }
-  return sc;
+SCT_ModuleVetoSvc::fillData(int& /*i*/, std::list<std::string>& /*folderList*/) {
+  return StatusCode::SUCCESS;
 }
 
 bool 
 SCT_ModuleVetoSvc::canFillDuringInitialize() {
-  return (not m_useDatabase);// can only fill during intialize if we don't use the database
+  return (not m_useDatabase); // can only fill during intialize if we don't use the database
 }
 
 bool
 SCT_ModuleVetoSvc::filled() const {
-  //code
-  return m_filled;
+  // If bad wafer IDs from properties are not filled, not filled.
+  if (not m_localCondData.filled()) return false;
+  // If database is not used, filled is returned.
+  if (not m_useDatabase) return true;
+
+  // If database is used, null pointer means not filled.
+  const EventContext& ctx{Gaudi::Hive::currentContext()};
+  const SCT_ModuleVetoCondData* condData{getCondData(ctx)};
+  return (condData!=nullptr);
+}
+
+const SCT_ModuleVetoCondData*
+SCT_ModuleVetoSvc::getCondData(const EventContext& ctx) const {
+  static const EventContext::ContextEvt_t invalidValue{EventContext::INVALID_CONTEXT_EVT};
+  EventContext::ContextID_t slot{ctx.slot()};
+  EventContext::ContextEvt_t evt{ctx.evt()};
+  std::lock_guard<std::mutex> lock{m_mutex};
+  if (slot>=m_cache.size()) {
+    m_cache.resize(slot+1, invalidValue); // Store invalid values in order to go to the next IF statement.
+  }
+  if (m_cache[slot]!=evt) {
+    SG::ReadCondHandle<SCT_ModuleVetoCondData> condData{m_condKey};
+    if (not condData.isValid()) {
+      ATH_MSG_ERROR("Failed to get " << m_condKey.key());
+    }
+    m_condData.set(*condData);
+    m_cache[slot] = evt;
+  }
+  return m_condData.get();
 }
diff --git a/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_ModuleVetoSvc.h b/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_ModuleVetoSvc.h
index 94ffd70adb68db71baf664d26ddc595b99101476..a678d93ff96edfee43215b2027e393cc22a81d7f 100644
--- a/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_ModuleVetoSvc.h
+++ b/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_ModuleVetoSvc.h
@@ -6,27 +6,31 @@
  * @file SCT_ModuleVetoSvc.h
  * header file for service allowing one to declare modules as bad
  * @author shaun.roe@cern.ch
-**/
+ **/
 
 #ifndef SCT_ModuleVetoSvc_h
 #define SCT_ModuleVetoSvc_h
+
 //STL includes
 #include <string>
 #include <set>
+#include <vector>
+#include <mutex>
+
+//Interface include
+#include "SCT_ConditionsServices/ISCT_ConditionsSvc.h"
 
 //Gaudi includes
-#include "AthenaBaseComps/AthService.h"
 #include "GaudiKernel/ServiceHandle.h"
-#include "StoreGate/DataHandle.h"
-#include "StoreGate/StoreGateSvc.h"
+#include "GaudiKernel/EventContext.h"
+#include "GaudiKernel/ContextSpecificPtr.h"
 
 //Athena includes
+#include "AthenaBaseComps/AthService.h"
 #include "Identifier/Identifier.h"
-#include "AthenaPoolUtilities/AthenaAttributeList.h"
-
-//local includes
 #include "InDetConditionsSummaryService/InDetHierarchy.h"
-#include "SCT_ConditionsServices/ISCT_ConditionsSvc.h"
+#include "SCT_ConditionsData/SCT_ModuleVetoCondData.h"
+#include "StoreGate/StoreGateSvc.h"
 
 //forward declarations
 template <class TYPE> class SvcFactory;
@@ -34,41 +38,39 @@ class ISvcLocator;
 class IdentifierHash;
 class SCT_ID;
 class StatusCode;
-//class Identifier; < not fwd declared, used in a vector so need storage size
-
 
 /**
  * @class SCT_ModuleVetoSvc
  * Service allowing one to manually declare detector elements as 'bad' in the joboptions file
-**/
-class SCT_ModuleVetoSvc: virtual public ISCT_ConditionsSvc, public AthService{
+ **/
+class SCT_ModuleVetoSvc: virtual public ISCT_ConditionsSvc, public AthService {
   friend class SvcFactory<SCT_ModuleVetoSvc>;
-public:
+ public:
   //@name Service methods
   //@{
-  SCT_ModuleVetoSvc( const std::string & name, ISvcLocator* svc);
+  SCT_ModuleVetoSvc(const std::string & name, ISvcLocator* svc);
   virtual ~SCT_ModuleVetoSvc(){}
   virtual StatusCode initialize();
   virtual StatusCode finalize();
-  virtual StatusCode queryInterface( const InterfaceID& riid, void** ppvInterface );
-  static const InterfaceID & interfaceID();
+  virtual StatusCode queryInterface(const InterfaceID& riid, void** ppvInterface);
+  static const InterfaceID& interfaceID();
   //@}
   
   ///Can the service report about the given component? (chip, module...)
   virtual bool canReportAbout(InDetConditions::Hierarchy h);
   
   ///Is the detector element good?
-  virtual bool isGood(const Identifier & elementId, InDetConditions::Hierarchy h=InDetConditions::DEFAULT);
+  virtual bool isGood(const Identifier& elementId, InDetConditions::Hierarchy h=InDetConditions::DEFAULT);
   
   ///is it good?, using wafer hash
-  virtual bool isGood(const IdentifierHash & hashId);
+  virtual bool isGood(const IdentifierHash& hashId);
 
   
   ///Manually get the data in the structure before proceding
   virtual StatusCode fillData();
   
   //I'm going to fill this from job options, but these may pecify the database is to be used
-  virtual StatusCode fillData(int& /*i*/ , std::list<std::string>& /*l*/);
+  virtual StatusCode fillData(int& /*i*/, std::list<std::string>& /*l*/);
   
   ///Are the data available?
   virtual bool filled() const;
@@ -76,22 +78,34 @@ public:
   ///Can the data be filled during the initialize phase?
   virtual bool canFillDuringInitialize();
   
-private:
+ private:
   StringArrayProperty m_badElements; //list of bad detector elements (= module sides)
-  std::set<Identifier> m_badIds;
-  bool m_filled;
+  //  std::set<Identifier> m_badIds;
+  //  bool m_filled;
+  SCT_ModuleVetoCondData m_localCondData;
   const SCT_ID * m_pHelper;
   bool m_useDatabase;
   bool m_maskLayers;
   int m_maskSide;
   std::vector<int> m_layersToMask; 
   std::vector<int> m_disksToMask; 
-  const DataHandle<AthenaAttributeList>   m_dbList;// implies single channel folder used
   ServiceHandle<StoreGateSvc> m_detStore;
+
+  // Mutex to protect the contents.
+  mutable std::mutex m_mutex;
+  // Cache to store events for slots
+  mutable std::vector<EventContext::ContextEvt_t> m_cache;
+  // Pointer of SCT_ModuleVetoCondData
+  mutable Gaudi::Hive::ContextSpecificPtr<const SCT_ModuleVetoCondData> m_condData;
+  // ReadCondHandleKey
+  SG::ReadCondHandleKey<SCT_ModuleVetoCondData> m_condKey;
+  // Provides SCT_ModuleVetoCondData pointer
+  const SCT_ModuleVetoCondData* getCondData(const EventContext& ctx) const;
+  
 };
 
-inline const InterfaceID & SCT_ModuleVetoSvc::interfaceID(){
+inline const InterfaceID& SCT_ModuleVetoSvc::interfaceID() {
   return ISCT_ConditionsSvc::interfaceID(); 
 }
 
-#endif
+#endif // SCT_ModuleVetoSvc_h
diff --git a/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_ModuleVetoTestAlg.cxx b/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_ModuleVetoTestAlg.cxx
index 35aadada91b59690b0d8789c44ea582c4029f29c..bf2ce6b3df591e8e22d9b828d9a5d800a0d03c95 100644
--- a/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_ModuleVetoTestAlg.cxx
+++ b/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_ModuleVetoTestAlg.cxx
@@ -23,58 +23,69 @@
 //local includes
 #include "SCT_ModuleVetoSvc.h"
 
-SCT_ModuleVetoTestAlg::SCT_ModuleVetoTestAlg( 
-                         const std::string& name, 
-                         ISvcLocator* pSvcLocator ) : 
-                         AthAlgorithm( name, pSvcLocator ), m_pModuleVetoSvc("SCT_ModuleVetoSvc",name){
-                           //nop
+SCT_ModuleVetoTestAlg::SCT_ModuleVetoTestAlg(const std::string& name, ISvcLocator* pSvcLocator) : 
+  AthAlgorithm(name, pSvcLocator), 
+  m_pModuleVetoSvc("SCT_ModuleVetoSvc", name) {
+  //nop
 }
 
 SCT_ModuleVetoTestAlg::~SCT_ModuleVetoTestAlg()
 { 
-  msg(MSG::INFO) << "Calling destructor" << endmsg;
+  ATH_MSG_INFO("Calling destructor");
 }
 
 //Initialize
 StatusCode 
-SCT_ModuleVetoTestAlg::initialize(){
-  StatusCode sc(StatusCode::SUCCESS);
-  msg(MSG::INFO) << "Calling initialize" << endmsg;
+SCT_ModuleVetoTestAlg::initialize() {
+  StatusCode sc{StatusCode::SUCCESS};
+  ATH_MSG_INFO("Calling initialize");
   sc = m_pModuleVetoSvc.retrieve();
   if (StatusCode::SUCCESS not_eq sc) {
-    msg(MSG::ERROR)<<"Could not retrieve the veto service"<<endmsg;
+    ATH_MSG_ERROR("Could not retrieve the veto service");
   }
   return sc;
 }
 
 //Execute
 StatusCode 
-SCT_ModuleVetoTestAlg::execute(){
+SCT_ModuleVetoTestAlg::execute() {
   //This method is only used to test the summary service, and only used within this package,
   // so the INFO level messages have no impact on performance of these services when used by clients
-  StatusCode sc(StatusCode::SUCCESS);
-  msg(MSG::INFO) << "Calling execute" << endmsg;
-  msg(MSG::INFO) <<"Dummy call to module id 0: module is "<<endmsg;
-  bool result=m_pModuleVetoSvc->isGood(Identifier(0));
-  msg(MSG::INFO) << (result?"good":"bad") << endmsg;
-  msg(MSG::INFO) <<"Dummy call to module id 1: module is "<<endmsg;
-  result=m_pModuleVetoSvc->isGood(Identifier(1));
-  msg(MSG::INFO) << (result?"good":"bad") << endmsg;
-  msg(MSG::INFO) << "Using Identifier Hash method: with number 2137 "<<endmsg;
-  result=m_pModuleVetoSvc->isGood(IdentifierHash(2137));
-  msg(MSG::INFO) << (result?"good":"bad") << endmsg;
-  msg(MSG::INFO) <<"Dummy call to module id 3: module is "<<endmsg;
-  result=m_pModuleVetoSvc->isGood(Identifier(3));
-   msg(MSG::INFO) << (result?"good":"bad") << endmsg;
-  return sc;
+
+  ATH_MSG_INFO("Calling execute");
+
+  ATH_MSG_INFO("Dummy call to module id 0: module is ");
+  bool result{m_pModuleVetoSvc->isGood(Identifier{0})};
+  ATH_MSG_INFO((result ? "good" : "bad"));
+
+  ATH_MSG_INFO("Dummy call to module id 1:  module is ");
+  result=m_pModuleVetoSvc->isGood(Identifier{1});
+  ATH_MSG_INFO((result ? "good" : "bad"));
+
+  ATH_MSG_INFO("Dummy call to module id 2:  module is ");
+  result=m_pModuleVetoSvc->isGood(Identifier{2});
+  ATH_MSG_INFO((result ? "good" : "bad"));
+
+  ATH_MSG_INFO("Dummy call to module id 3:  module is ");
+  result=m_pModuleVetoSvc->isGood(Identifier{3});
+  ATH_MSG_INFO((result ? "good" : "bad"));
+
+  ATH_MSG_INFO("Dummy call to module id 151040000:  module is ");
+  result=m_pModuleVetoSvc->isGood(Identifier{151040000});
+  ATH_MSG_INFO((result ? "good" : "bad"));
+
+  ATH_MSG_INFO("Using Identifier Hash method:  with number 2137 ");
+  result=m_pModuleVetoSvc->isGood(IdentifierHash{2137});
+  ATH_MSG_INFO((result ? "good" : "bad"));
+
+  return StatusCode::SUCCESS;
 }
 
 
 //Finalize
 StatusCode
-SCT_ModuleVetoTestAlg::finalize(){
-  StatusCode sc(StatusCode::SUCCESS);
-  MsgStream log(msgSvc(),name());
-  log << MSG::INFO << "Calling finalize" << endmsg;
-  return sc;
+SCT_ModuleVetoTestAlg::finalize() {
+  ATH_MSG_INFO("Calling finalize");
+
+  return StatusCode::SUCCESS;
 }
diff --git a/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_SensorsTestAlg.cxx b/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_SensorsTestAlg.cxx
index f141612c5ada43c7b1f9021cd21045a2c44eb0c7..8385edac8a0d01c02bcae4e17982d906bcc0d3fa 100644
--- a/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_SensorsTestAlg.cxx
+++ b/InnerDetector/InDetConditions/SCT_ConditionsServices/src/SCT_SensorsTestAlg.cxx
@@ -31,8 +31,7 @@
 
 using namespace std;
 
-SCT_SensorsTestAlg::SCT_SensorsTestAlg( 
-                                       const std::string& name, 
+SCT_SensorsTestAlg::SCT_SensorsTestAlg(const std::string& name, 
                                        ISvcLocator* pSvcLocator ) : 
   AthAlgorithm( name, pSvcLocator ), m_SensorsSvc("SCT_SensorsSvc",name){
   //nop
diff --git a/InnerDetector/InDetConditions/SCT_ConditionsServices/src/components/SCT_ConditionsServices_entries.cxx b/InnerDetector/InDetConditions/SCT_ConditionsServices/src/components/SCT_ConditionsServices_entries.cxx
index be4a4f4273a0c108dc891e72452db9b2d3656e0c..512ff70d554213b4f5d886056f85ad4b9d34c4d0 100644
--- a/InnerDetector/InDetConditions/SCT_ConditionsServices/src/components/SCT_ConditionsServices_entries.cxx
+++ b/InnerDetector/InDetConditions/SCT_ConditionsServices/src/components/SCT_ConditionsServices_entries.cxx
@@ -1,9 +1,11 @@
 #include "../SCT_ConditionsSummarySvc.h"
-#include "../SCT_ModuleVetoSvc.h"
+#include "../SCT_ConditionsSummaryTestAlg.h"
+
 #include "../SCT_StripVetoSvc.h"
 
+#include "../SCT_ModuleVetoSvc.h"
+#include "../SCT_ModuleVetoCondAlg.h"
 #include "../SCT_ModuleVetoTestAlg.h"
-#include "../SCT_ConditionsSummaryTestAlg.h"
 
 #include "../SCT_DCSConditionsSvc.h"
 #include "../SCT_DCSConditionsHVCondAlg.h"
@@ -39,6 +41,7 @@
 #include "../SCT_ReadoutTestAlg.h"
 
 #include "../SCT_LinkMaskingSvc.h"
+#include "../SCT_LinkMaskingCondAlg.h"
 #include "../SCT_LinkMaskingTestAlg.h"
 
 #include "../SCT_TdaqEnabledSvc.h"
@@ -64,7 +67,6 @@
 #include "../SCT_ElectricFieldTool.h"
 
 #include "../SCT_RODVetoSvc.h"
-
 #include "../SCT_RODVetoTestAlg.h"
 
 //specific to rod veto testing:
@@ -72,6 +74,7 @@
 DECLARE_COMPONENT( SCT_RODVetoTestAlg )
 DECLARE_COMPONENT( SCT_RODVetoSvc )
 
+DECLARE_COMPONENT( SCT_ModuleVetoCondAlg )
 DECLARE_COMPONENT( SCT_ModuleVetoTestAlg )
 DECLARE_COMPONENT( SCT_ConditionsSummaryTestAlg )
 DECLARE_COMPONENT( SCT_CachedSummaryTestAlg )
@@ -88,6 +91,7 @@ DECLARE_COMPONENT( SCT_ReadCalibChipNoiseCondAlg )
 DECLARE_COMPONENT( SCT_SiliconConditionsTestAlg )
 DECLARE_COMPONENT( SCT_ReadoutTestAlg )
 DECLARE_COMPONENT( SCT_ReadCalibDataCondAlg )
+DECLARE_COMPONENT( SCT_LinkMaskingCondAlg )
 DECLARE_COMPONENT( SCT_LinkMaskingTestAlg )
 DECLARE_COMPONENT( SCT_ConfigurationConditionsTestAlg )
 DECLARE_COMPONENT( SCT_ConfigurationCondAlg )