diff --git a/DataQuality/DataQualityConfigurations/CMakeLists.txt b/DataQuality/DataQualityConfigurations/CMakeLists.txt
index dcae0a350cdbe48b2a0184e61aaa170de03bc7cc..4e11aa4cc5d6bd0511d9b265642564e0b9044ac0 100644
--- a/DataQuality/DataQualityConfigurations/CMakeLists.txt
+++ b/DataQuality/DataQualityConfigurations/CMakeLists.txt
@@ -54,7 +54,7 @@ foreach( hanfile collisions_run collisions_minutes10
       ${CMAKE_CURRENT_SOURCE_DIR}/config ${configOutputFile}
       # Build binary config
       COMMAND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/atlas_build_run.sh
-      han-config-gen ${configOutputFile}
+      han-config-gen ${configOutputFile} -b true
       # Deploy binary config
       COMMAND ${CMAKE_COMMAND} -E copy
       ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${hanfile}.hcfg
diff --git a/DataQuality/DataQualityConfigurations/config/common/collisions_run.config b/DataQuality/DataQualityConfigurations/config/common/collisions_run.config
index 9da3e17599e6e20302f18274a15c31f8b2d9b23c..6205a7511aec2dd54f8b7fd97c2379ab10916dd1 100644
--- a/DataQuality/DataQualityConfigurations/config/common/collisions_run.config
+++ b/DataQuality/DataQualityConfigurations/config/common/collisions_run.config
@@ -7,6 +7,7 @@ reference CentrallyManagedReferences {
   file = data18_13TeV.00358031.express_express.merge.HIST.f961_h322._0001.1
   path = run_358031
   info = Run 358031, express_express
+  #database = collisions
   name = same_name
 }
 
@@ -15,6 +16,7 @@ reference CentrallyManagedReferences_Main {
   file = data18_13TeV.00358031.physics_Main.merge.HIST.f961_h322._0001.1
   path = run_358031
   info = Run 358031, physics_Main
+  #database = collisions
   name = same_name
 }
 
@@ -23,6 +25,7 @@ reference CentrallyManagedReferences_Trigger {
   file = data18_13TeV.00356177.express_express.merge.HIST.f956_h317._0001.1
   path = run_356177
   info = Run 356177, express_express
+  #database = collisions
   name = same_name
 }
 
@@ -31,6 +34,7 @@ reference CentrallyManagedReferences_TriggerMain {
   file = data18_13TeV.00356177.physics_Main.merge.HIST.f956_h319._0001.1
   path = run_356177
   info = Run 356177, physics_Main
+  #database = collisions
   name = same_name
 }
 
@@ -39,10 +43,10 @@ reference CentrallyManagedReferences_TriggerBphysLS {
   file = data18_13TeV.00356177.physics_BphysLS.merge.HIST.f961_h322._0001.1
   path = run_356177
   info = Run 356177, physics_BphysLS
+  #database = collisions
   name = same_name
 }
 
-
 ####################
 # Common Algorithms
 ####################
diff --git a/DataQuality/DataQualityConfigurations/config/common/cosmics_run.config b/DataQuality/DataQualityConfigurations/config/common/cosmics_run.config
index 3327a54eaed4566a8927d464c52c5187c3e71949..ea7d1442fe4c5f920bf1518415547995b522c6ce 100644
--- a/DataQuality/DataQualityConfigurations/config/common/cosmics_run.config
+++ b/DataQuality/DataQualityConfigurations/config/common/cosmics_run.config
@@ -2,11 +2,13 @@
 # References
 #######################
 
+
 reference CentrallyManagedReferences {
   location = /eos/atlas/atlascerngroupdisk/data-dqm/references/,root://eosatlas.cern.ch//eos/atlas/atlascerngroupdisk/data-dqm/references/
   file = data16_cos.00306147.express_express.merge.HIST.f738_h161._0001.1
   path = run_306147
   info = Run 306147, express
+  #database = cosmics
   name = same_name
 }
 
@@ -15,6 +17,7 @@ reference CentrallyManagedReferences_Main {
   file = data16_cos.00306147.express_express.merge.HIST.f738_h161._0001.1
   path = run_306147
   info = Run 306147, express
+  #database = cosmics
   name = same_name
 }
 
@@ -23,6 +26,7 @@ reference CentrallyManagedReferences_Trigger {
   file = data16_cos.00306147.express_express.merge.HIST.f738_h161._0001.1
   path = run_306147
   info = Run 306147, express
+  #database = cosmics
   name = same_name
 }
 
@@ -31,6 +35,7 @@ reference CentrallyManagedReferences_TriggerMain {
   file = data16_cos.00306147.express_express.merge.HIST.f738_h161._0001.1
   path = run_306147
   info = Run 306147, express
+  #database = cosmics
   name = same_name
 }
 
diff --git a/DataQuality/DataQualityConfigurations/config/common/heavyions_run.config b/DataQuality/DataQualityConfigurations/config/common/heavyions_run.config
index 51be8d8f9cec6fd2c81b7b06c43915865135d58f..df8db9207e7e8b7b60d29fa763326a81dc6959c8 100644
--- a/DataQuality/DataQualityConfigurations/config/common/heavyions_run.config
+++ b/DataQuality/DataQualityConfigurations/config/common/heavyions_run.config
@@ -7,6 +7,7 @@ reference CentrallyManagedReferences {
   file = data18_hi.00365678.express_express.merge.HIST.f1021_h331._0001.1
   path = run_365678
   info = Run 365678, express
+  #database = heavyions
   name = same_name
 }
 
@@ -15,6 +16,7 @@ reference CentrallyManagedReferences_Main {
   file = data18_hi.00365678.express_express.merge.HIST.f1021_h331._0001.1
   path = run_365678
   info = Run 365678, physics_Main
+  #database = heavyions
   name = same_name
 }
 
@@ -23,6 +25,7 @@ reference CentrallyManagedReferences_Trigger {
   file = data18_hi.00365573.express_express.merge.HIST.f1021_h331._0001.1
   path = run_365573
   info = Run 365573, express
+  #database = heavyions
   name = same_name
 }
 
@@ -31,6 +34,7 @@ reference CentrallyManagedReferences_TriggerMain {
   file = data18_hi.00365573.express_express.merge.HIST.f1021_h331._0001.1
   path = run_365573
   info = Run 365573, physics_Main
+  #database = heavyions
   name = same_name
 }
 
@@ -39,6 +43,7 @@ reference CentrallyManagedReferences_UPC {
   file = data18_hi.00365678.physics_UPC.merge.HIST.f1022_h331._0001.1
   path = run_365678
   info = Run 365678, physics_UPC
+  #database = heavyions
   name = same_name
 }
 
@@ -47,6 +52,7 @@ reference CentrallyManagedReferences_TriggerUPC {
   file = data18_hi.00365573.physics_UPC.merge.HIST.f1022_h331._0001.1
   path = run_365573
   info = Run 365573, physics_UPC
+  #database = heavyions
   name = same_name
 }
 
@@ -55,6 +61,7 @@ reference CentrallyManagedReferences_HardProbes {
   file = data18_hi.00365678.physics_HardProbes.merge.HIST.f1021_h331._0001.1
   path = run_365678
   info = Run 365678, physics_HardProbes
+  #database = heavyions
   name = same_name
 }
 
@@ -63,9 +70,11 @@ reference CentrallyManagedReferences_TriggerHardProbes {
   file = data18_hi.00365573.physics_HardProbes.merge.HIST.f1021_h331._0001.1
   path = run_365573
   info = Run 365573, physics_HardProbes
+  #database = heavyions
   name = same_name
 }
 
+
 ####################
 # Common Algorithms
 ####################
diff --git a/DataQuality/DataQualityInterfaces/CMakeLists.txt b/DataQuality/DataQualityInterfaces/CMakeLists.txt
index 9d2ecff821188fc55edaa28b3de1b3a1ff0f80b2..380a68b28a7bb6134bba071d92242003888ab372 100644
--- a/DataQuality/DataQualityInterfaces/CMakeLists.txt
+++ b/DataQuality/DataQualityInterfaces/CMakeLists.txt
@@ -9,12 +9,15 @@ atlas_subdir( DataQualityInterfaces )
 find_package( Boost COMPONENTS system regex thread filesystem )
 find_package( ROOT COMPONENTS Cint Hist RIO Tree Core MathCore pthread Graf Graf3d Gpad Html Postscript Gui GX11TTF GX11 )
 find_package( tdaq-common COMPONENTS dqm_core_io dqm_core dqm_dummy_io dqm_dummy )
+find_package( COOL COMPONENTS CoolKernel CoolApplication )
+find_package( CORAL COMPONENTS CoralBase )
+find_package( nlohmann_json )
 
 # Component(s) in the package:
 atlas_add_root_dictionary( DataQualityInterfaces
                            DataQualityInterfacesDictSource
-                           ROOT_HEADERS DataQualityInterfaces/MiniConfig.h DataQualityInterfaces/MiniConfigTreeNode.h DataQualityInterfaces/HanApp.h DataQualityInterfaces/HanConfig.h DataQualityInterfaces/HanConfigAlgLimit.h DataQualityInterfaces/HanConfigAlgPar.h DataQualityInterfaces/HanConfigParMap.h DataQualityInterfaces/HanConfigAssessor.h DataQualityInterfaces/HanConfigCompAlg.h DataQualityInterfaces/HanConfigGroup.h DataQualityInterfaces/HanConfigMetadata.h DataQualityInterfaces/ConditionsSingleton.h DataQualityInterfaces/LinkDef.h
-                           EXTERNAL_PACKAGES ROOT  Boost tdaq-common )
+                           ROOT_HEADERS DataQualityInterfaces/DatabaseConfig.h DataQualityInterfaces/MiniConfig.h DataQualityInterfaces/MiniConfigTreeNode.h DataQualityInterfaces/HanApp.h DataQualityInterfaces/HanConfig.h DataQualityInterfaces/HanConfigAlgLimit.h DataQualityInterfaces/HanConfigAlgPar.h DataQualityInterfaces/HanConfigParMap.h DataQualityInterfaces/HanConfigAssessor.h DataQualityInterfaces/HanConfigCompAlg.h DataQualityInterfaces/HanConfigGroup.h DataQualityInterfaces/HanConfigMetadata.h DataQualityInterfaces/ConditionsSingleton.h DataQualityInterfaces/LinkDef.h
+                           EXTERNAL_PACKAGES ROOT  Boost tdaq-common COOL CORAL nlohmann_json)
 
 atlas_add_library( DataQualityInterfaces
                    src/HanAlgorithmConfig.cxx
@@ -29,6 +32,7 @@ atlas_add_library( DataQualityInterfaces
                    src/HanConfigMetadata.cxx
                    src/HanOutput.cxx
                    src/MiniConfig.cxx
+                   src/DatabaseConfig.cxx
                    src/MiniConfigTreeNode.cxx
                    src/CompositeAlgorithm.cxx
                    src/HanInputRootFile.cxx
@@ -36,8 +40,8 @@ atlas_add_library( DataQualityInterfaces
                    src/ConditionsSingleton.cxx
                    ${DataQualityInterfacesDictSource}
                    PUBLIC_HEADERS DataQualityInterfaces
-                   INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ${TDAQ-COMMON_INCLUDE_DIRS}
-                   LINK_LIBRARIES ${ROOT_LIBRARIES} ${Boost_LIBRARIES} ${TDAQ-COMMON_LIBRARIES} )
+                   INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ${TDAQ-COMMON_INCLUDE_DIRS} ${CORAL_INCLUDE_DIRS} nlohmann_json::nlohmann_json ${COOL_INCLUDE_DIRS}
+                   LINK_LIBRARIES ${ROOT_LIBRARIES} ${Boost_LIBRARIES} ${TDAQ-COMMON_LIBRARIES} nlohmann_json::nlohmann_json ${CORAL_LIBRARIES} ${COOL_LIBRARIES} )
 
 atlas_add_executable( han
                       src/han.cxx
@@ -46,8 +50,8 @@ atlas_add_executable( han
 
 atlas_add_executable( han-config-gen
                       src/han_config_gen.cxx
-                      INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ${TDAQ-COMMON_INCLUDE_DIRS}
-                      LINK_LIBRARIES ${ROOT_LIBRARIES} ${Boost_LIBRARIES} ${TDAQ-COMMON_LIBRARIES} DataQualityInterfaces )
+                      INCLUDE_DIRS ${ROOT_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS} ${TDAQ-COMMON_INCLUDE_DIRS} ${CORAL_INCLUDE_DIRS}  nlohmann_json::nlohmann_json ${COOL_INCLUDE_DIRS}
+                      LINK_LIBRARIES ${ROOT_LIBRARIES} ${Boost_LIBRARIES} ${TDAQ-COMMON_LIBRARIES} DataQualityInterfaces nlohmann_json::nlohmann_json ${CORAL_LIBRARIES} ${COOL_LIBRARIES} )
 
 atlas_add_executable( han-config-print
                       src/han_config_print.cxx
diff --git a/DataQuality/DataQualityInterfaces/DataQualityInterfaces/DatabaseConfig.h b/DataQuality/DataQualityInterfaces/DataQualityInterfaces/DatabaseConfig.h
new file mode 100644
index 0000000000000000000000000000000000000000..37a7824d9c6c25f9a25f70f01b4a6edc19aaaf87
--- /dev/null
+++ b/DataQuality/DataQualityInterfaces/DataQualityInterfaces/DatabaseConfig.h
@@ -0,0 +1,43 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef dqiDatabaseConfig_h
+#define dqiDatabaseConfig_h
+
+#include <iostream>
+#include <optional>
+#include <nlohmann/json.hpp>
+#include "CoolKernel/IFolder.h"
+#include "CoolKernel/IDatabase.h"
+
+namespace dqi {
+
+class DatabaseConfig {
+
+public:
+  DatabaseConfig(std::string connectionString, long runNumber);
+  nlohmann::json GetPayload(std::string tag);
+
+  bool IsConnected() const;
+  void Disconnect();
+
+private:
+  const std::string m_connectionString;
+  const long m_runNumber;
+
+  bool m_dbConnected;
+  bool m_folderConnected;
+
+  std::unordered_map<std::string, nlohmann::json> m_jsonData;
+  cool::IFolderPtr m_folder;
+  cool::IDatabasePtr m_database;
+
+  long GetRunNumber() const;
+  nlohmann::json LoadPayload(std::string tag);
+
+  void Connect();
+};
+
+}
+#endif
diff --git a/DataQuality/DataQualityInterfaces/DataQualityInterfaces/HanConfig.h b/DataQuality/DataQualityInterfaces/DataQualityInterfaces/HanConfig.h
index 91f266872276c9a363d58439c2c8b342a8f7bd31..8c655f6fed6c2839a143b1732a636003730ed0e9 100644
--- a/DataQuality/DataQualityInterfaces/DataQualityInterfaces/HanConfig.h
+++ b/DataQuality/DataQualityInterfaces/DataQualityInterfaces/HanConfig.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef dqiHanConfig_h
@@ -16,6 +16,7 @@
 #include "DataQualityInterfaces/MiniConfigTreeNode.h"
 #include "DataQualityInterfaces/HanConfigAssessor.h"
 #include "DataQualityInterfaces/HanConfigCompAlg.h"
+#include "DataQualityInterfaces/DatabaseConfig.h"
 
 #ifndef __CINT__
 #include <boost/shared_ptr.hpp>
@@ -44,17 +45,17 @@ public:
 
   HanConfig();
   virtual ~HanConfig();
-  
-  
-  virtual void AssembleAndSave( std::string infileName, std::string outfileName );
-  
+
+
+  virtual void AssembleAndSave( std::string infileName, std::string outfileName, std::string connectionString, long runNumber, bool bulk);
+
   virtual void BuildMonitors( std::string configName, dqm_core::Input& input, HanOutput& output );
 #ifndef __CINT__
   virtual boost::shared_ptr<dqm_core::Region> BuildMonitorsNewRoot( std::string configName, dqm_core::Input& input, dqm_core::Output& output );
 #endif
   virtual void BuildConfigOutput( std::string configName, TFile* inputFile, std::string path,
                                   std::map<std::string,TSeqCollection*>* outputMap, TSeqCollection *outputList );
-  
+
   virtual TObject* GetReference( std::string& groupName, std::string& name );
   virtual const HanConfigAssessor* GetAssessor( std::string& groupName, std::string& name ) const;
 
@@ -74,19 +75,28 @@ protected:
     HanConfig::DirMap_t& m_directories;
     TMap* m_refsourcedata;
   };
-  
+
+  class RefWriter : public MiniConfigTreeNode::Writer {
+  public:
+    RefWriter( DatabaseConfig& databaseConfig_, const bool bulk);
+    virtual void Write( MiniConfigTreeNode* node);
+  protected:
+    DatabaseConfig& m_databaseConfig;
+    const bool m_bulk;
+  };
+
   class AssessmentVisitorBase : public MiniConfigTreeNode::Visitor {
   public:
     AssessmentVisitorBase( HanConfigGroup* root_, const MiniConfig& algConfig_,
                            const MiniConfig& thrConfig_, const MiniConfig& refConfig_,
                            TFile* outfile_, HanConfig::DirMap_t& directories_,
 			   TMap* refsourcedata_ );
-  
+
   protected:
-  
+
     void GetAlgorithmConfiguration( HanConfigAssessor* dqpar, const std::string& algID,
                                     std::string assessorName = "" ) const;
-    
+
     HanConfigGroup* m_root;
     const MiniConfig& m_algConfig;
     const MiniConfig& m_thrConfig;
@@ -96,10 +106,12 @@ protected:
     TMap* m_refsourcedata;
     // File cache
     mutable std::map<std::string, std::shared_ptr<TFile> > m_filecache;
+    // following is so we can skip repeated attempts to open nonexistent files
+    mutable std::unordered_set<std::string> m_badPaths;
     std::shared_ptr<TFile> GetROOTFile(std::string& fname) const;
   };
-  
-  
+
+
   class RegionVisitor : public AssessmentVisitorBase {
   public:
     RegionVisitor( HanConfigGroup* root_, const MiniConfig& algConfig_,
@@ -107,8 +119,8 @@ protected:
                    HanConfig::DirMap_t& directories_ );
     virtual void Visit( const MiniConfigTreeNode* node ) const;
   };
-  
-  
+
+
   class AssessmentVisitor : public AssessmentVisitorBase {
   public:
     AssessmentVisitor( HanConfigGroup* root_, const MiniConfig& algConfig_,
@@ -126,8 +138,8 @@ protected:
       Visit( const HanConfigAssessor* node, boost::shared_ptr<dqm_core::Region> ) const;
   protected:
     std::set<std::string>& m_regexes;
-  };  
-  
+  };
+
   class ConfigVisitor : public HanConfigAssessor::Visitor {
   public:
     ConfigVisitor( TFile* file_, dqm_core::Output* output_ );
@@ -138,7 +150,7 @@ protected:
     dqm_core::Output* m_output;
   };
 #endif
-  
+
   class CompAlgVisitor : public MiniConfigTreeNode::Visitor {
   public:
     CompAlgVisitor( TFile* outfile_ , const MiniConfig& compAlgConfig_);
@@ -147,7 +159,7 @@ protected:
     TFile* m_outfile;
     const MiniConfig& m_compAlgConfig;
   };
-  
+
   class MetadataVisitor : public MiniConfigTreeNode::Visitor {
   public:
     MetadataVisitor( TFile* outfile_ , const MiniConfig& metadataConfig_);
@@ -156,18 +168,18 @@ protected:
     TFile* m_outfile;
     const MiniConfig& m_metadataConfig;
   };
-  
+
 
   bool Initialize( std::string configName );
-  
-  
+
+
   TFile*             m_config;
 #ifndef __CINT__
   boost::shared_ptr<dqm_core::Region>  m_dqRoot;
 #endif
   HanConfigGroup*    m_top_level;
   TSeqCollection*    m_metadata;
-  
+
 //Get rid of Root macros that confuse Doxygen
 ///\cond CLASSDEF
   ClassDef( HanConfig, 0 ) // Creates a Han configuration from a MiniConfig
diff --git a/DataQuality/DataQualityInterfaces/DataQualityInterfaces/MiniConfig.h b/DataQuality/DataQualityInterfaces/DataQualityInterfaces/MiniConfig.h
index 4890ba5eda849889d1d1a5dcc3fd3f0ba6410a0a..adc71efbdf751d368668b8d1b2917013547b1548 100644
--- a/DataQuality/DataQualityInterfaces/DataQualityInterfaces/MiniConfig.h
+++ b/DataQuality/DataQualityInterfaces/DataQualityInterfaces/MiniConfig.h
@@ -27,39 +27,40 @@ class MiniConfig : public TObject {
 public:
 
   MiniConfig();
-  
+
   virtual ~MiniConfig();
-  
+
   virtual void AddKeyword( std::string keyword_ );
   virtual void AddAttributeKeyword( std::string keyword_ );
 
   virtual void SetAttribKeywordPropagateDown( bool propagateDown );
-  
+
   virtual bool ReadFile( std::string fileName );
-  
-  
+
+
   virtual std::string GetStringAttribute( std::string objName, std::string attName ) const;
-  
+
   virtual int GetIntAttribute( std::string objName, std::string attName ) const;
-  
+
   virtual float GetFloatAttribute( std::string objName, std::string attName ) const;
-  
+
   virtual void GetAttributeNames( std::string objName, std::set<std::string>& attSet ) const;
-  
+
   virtual void SendVisitor( const MiniConfigTreeNode::Visitor& visitor ) const;
-  
-  
+
+  virtual void SendWriter(MiniConfigTreeNode::Writer& writer );
+
 protected:
 
   typedef std::set<std::string>     KeySet_t;
   typedef KeySet_t::const_iterator  KeyIter_t;
-  
+
   KeySet_t             m_keywords;
   KeySet_t             m_attKeywords;
   MiniConfigTreeNode*  m_tree;
 
   bool m_propagateDown;
-  
+
 private:
 
 //Get rid of Root macros that confuse Doxygen
@@ -71,4 +72,3 @@ private:
 } // namespace dqi
 
 #endif
-
diff --git a/DataQuality/DataQualityInterfaces/DataQualityInterfaces/MiniConfigTreeNode.h b/DataQuality/DataQualityInterfaces/DataQualityInterfaces/MiniConfigTreeNode.h
index 60b7d04953b9c7d6aa9d5270619ff9b49b2369cf..79047c9010626325831a0854ef08c46bf94635dc 100644
--- a/DataQuality/DataQualityInterfaces/DataQualityInterfaces/MiniConfigTreeNode.h
+++ b/DataQuality/DataQualityInterfaces/DataQualityInterfaces/MiniConfigTreeNode.h
@@ -33,13 +33,18 @@ public:
     virtual void Visit( const MiniConfigTreeNode* node ) const = 0;
   };
 
+  class Writer {
+  public:
+    virtual ~Writer() { }
+    virtual void Write(MiniConfigTreeNode* node ) = 0;
+  };
 
   MiniConfigTreeNode( std::string name_, MiniConfigTreeNode* parent_ );
-  
+
   virtual ~MiniConfigTreeNode();
-  
+
   virtual const char* GetName() const;
-  
+
   virtual const char* GetPathName() const;
 
 
@@ -47,38 +52,40 @@ public:
   * Returns a daughter of this node, creating one if necessary.  This method only returns
   * daughters, not granddaughters.
   */
-  
+
   virtual MiniConfigTreeNode*        GetNewDaughter( std::string name_ );
-  
+
   virtual MiniConfigTreeNode*        GetDaughter( std::string name_ ) const;
-  
+
   virtual MiniConfigTreeNode*        GetParent() const;
-  
+
   virtual std::map<std::string,dqi::MiniConfigTreeNode*> GetDaughters() const;
-  
+
  /**
   * This function takes the full path name of a subnode (in UNIX directory style) and
   * returns the corresponding subnode of this node, traversing the entire subtree until it is found.
   * If the bottom of the tree is reached before the full path has been used, the last node found
   * is returned.  If any part of the path is invalid before reaching the end of the tree, 0 is returned.
   */
-  
+
   virtual const MiniConfigTreeNode*  GetNode( std::string name_ ) const;
-  
-  
+
+
   virtual void                   SetAttribute( std::string attName, std::string attValue, bool isAttribKeyword = false );
-  
+
   virtual std::string            GetAttribute( std::string attName, bool calledFromDaughter = false ) const;
 
   virtual std::string            GetAttributeLocal( std::string attName ) const;
-  
+
   virtual void                   GetAttributeNames( std::set<std::string>& attSet, bool calledFromDaughter = false ) const;
-  
+
   virtual void                   GetAttributeNamesLocal( std::set<std::string>& attSet ) const;
-  
-  
+
+
   virtual void                   Accept( const Visitor& visitor ) const;
 
+  virtual void                   Accept(Writer& writer );
+
   virtual void                   SetAttribKeywordPropagateDown( bool propagateDown );
 
   virtual bool                   GetAttribKeywordPropagateDown() const;
@@ -87,14 +94,14 @@ protected:
 
   typedef std::map<std::string,MiniConfigTreeNode*>  NodeMap_t;
   typedef NodeMap_t::const_iterator              NodeIter_t;
-  
+
   typedef std::map<std::string,std::pair<std::string,bool> >      AttMap_t;
   typedef AttMap_t::const_iterator               AttIter_t;
-  
+
   const std::string  m_name;
   mutable std::string  m_path;
   MiniConfigTreeNode*    m_parent;
-  
+
   NodeMap_t          m_daughters;
   AttMap_t           m_attributes;
 
@@ -111,4 +118,3 @@ private:
 } // namespace dqi
 
 #endif
-
diff --git a/DataQuality/DataQualityInterfaces/src/DatabaseConfig.cxx b/DataQuality/DataQualityInterfaces/src/DatabaseConfig.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..c2950099fecc81cd58947a59debe488130f8c0c7
--- /dev/null
+++ b/DataQuality/DataQualityInterfaces/src/DatabaseConfig.cxx
@@ -0,0 +1,110 @@
+/*
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include <iostream>
+#include <nlohmann/json.hpp>
+
+#include "CoolApplication/DatabaseSvcFactory.h"
+#include "CoolKernel/IDatabase.h"
+#include "CoolKernel/IDatabaseSvc.h"
+#include "CoolKernel/IObject.h"
+#include "CoolKernel/IFolder.h"
+#include "CoolKernel/IObject.h"
+
+#include "DataQualityInterfaces/DatabaseConfig.h"
+#include <array>
+
+namespace dqi {
+
+DatabaseConfig::
+DatabaseConfig(std::string connectionString, long runNumber)
+  : m_connectionString(connectionString)
+  , m_runNumber((runNumber << 32) + 1)
+  , m_dbConnected(false)
+  , m_folderConnected(false)
+{
+}
+
+void
+DatabaseConfig::
+Disconnect()
+{
+    if(m_dbConnected) {
+      m_database->closeDatabase();
+      m_dbConnected = false;
+      m_folderConnected = false;
+    }
+}
+
+void
+DatabaseConfig::
+Connect()
+{
+  try {
+    cool::IDatabaseSvc& dbSvc = cool::DatabaseSvcFactory::databaseService();
+    m_database = dbSvc.openDatabase(m_connectionString, true);
+
+  } catch (std::exception& e) {
+    std::cerr << "Unable to open database -> " << e.what() << '\n';
+    return;
+  }
+  m_dbConnected = true;
+  try {
+    m_folder= m_database->getFolder("/GLOBAL/DQM/REFERENCES");
+
+  } catch (std::exception& e) {
+    std::cerr << "Unable loading folder for this tag/run-> " << e.what() << '\n';
+    return;
+  }
+  m_folderConnected = true;
+}
+
+nlohmann::json
+DatabaseConfig::
+GetPayload(std::string tag)
+{
+  if(!m_dbConnected && !m_folderConnected) {
+    Connect();
+  }
+  if(m_jsonData.find(tag) == m_jsonData.end()) {
+    return LoadPayload(tag);
+  }
+  return m_jsonData.at(tag);
+}
+
+nlohmann::json
+DatabaseConfig::
+LoadPayload(std::string tag)
+{
+  nlohmann::json jsonData;
+  if(m_dbConnected && m_folderConnected) {
+    try {
+      cool::IObjectPtr object = m_folder->findObject(GetRunNumber(), 1, tag);
+
+      std::string data = object->payloadValue("jsonData");
+      jsonData = nlohmann::json::parse(data);
+      m_jsonData[tag] = jsonData;
+
+    } catch (std::exception& e) {
+      std::cerr << "Error: Failed loading payload for this tag/run-> " << e.what() << '\n';
+    }
+  }
+  return jsonData;
+}
+
+bool
+DatabaseConfig::
+IsConnected() const
+{
+  return m_dbConnected && m_folderConnected;
+}
+
+long
+DatabaseConfig::
+GetRunNumber() const
+{
+  return m_runNumber;
+}
+
+}
diff --git a/DataQuality/DataQualityInterfaces/src/HanConfig.cxx b/DataQuality/DataQualityInterfaces/src/HanConfig.cxx
index 3c2addf9f96dfd757faa5b0e0ef0992f7ed928f3..72c01c3b545b209a9a1362c3e82211eebc5876f4 100644
--- a/DataQuality/DataQualityInterfaces/src/HanConfig.cxx
+++ b/DataQuality/DataQualityInterfaces/src/HanConfig.cxx
@@ -42,6 +42,7 @@
 #include "DataQualityInterfaces/HanOutput.h"
 #include "DataQualityInterfaces/MiniConfig.h"
 #include "DataQualityInterfaces/HanUtils.h"
+#include "DataQualityInterfaces/DatabaseConfig.h"
 #include <boost/regex.hpp>
 #include <boost/algorithm/string/case_conv.hpp>
 #include <boost/algorithm/string/split.hpp>
@@ -81,12 +82,12 @@ HanConfig::
 
 void
 HanConfig::
-AssembleAndSave( std::string infileName, std::string outfileName )
+AssembleAndSave( std::string infileName, std::string outfileName, std::string connectionString, long runNumber, bool bulk)
 {
   std::unique_ptr< TFile > outfile( TFile::Open( outfileName.c_str(),
                                                  "RECREATE" ) );
   DirMap_t directories;
-  
+
   // Collect reference histograms and copy to config file
   MiniConfig refconfig;
   refconfig.AddKeyword("reference");
@@ -94,13 +95,18 @@ AssembleAndSave( std::string infileName, std::string outfileName )
   TMap refsourcedata;
   RefVisitor refvisitor( outfile.get(), directories, &refsourcedata );
   refconfig.SendVisitor( refvisitor );
-  
+
+  DatabaseConfig databaseConfig(connectionString, runNumber);
+  RefWriter refwriter(databaseConfig, bulk);
+  refconfig.SendWriter( refwriter );
+  databaseConfig.Disconnect();
+
   // Collect threshold definitions
   MiniConfig thrconfig;
   thrconfig.AddKeyword("thresholds");
   thrconfig.AddAttributeKeyword("limits");
   thrconfig.ReadFile(infileName);
-  
+
   // Collect algorithm definitions
   MiniConfig algconfig;
   algconfig.AddKeyword("algorithm");
@@ -110,21 +116,21 @@ AssembleAndSave( std::string infileName, std::string outfileName )
   MiniConfig regconfig;
   regconfig.AddKeyword("output");
   regconfig.ReadFile(infileName);
-  
+
   // Collect histogram definitions
   MiniConfig histconfig;
   histconfig.AddKeyword("dir");
   histconfig.AddAttributeKeyword("hist");
   histconfig.SetAttribKeywordPropagateDown(false);
   histconfig.ReadFile(infileName);
-  
+
   // Collect and write composite-algorithm definitions
   MiniConfig compalgconfig;
   compalgconfig.AddKeyword("compositealgorithm");
   compalgconfig.ReadFile(infileName);
   CompAlgVisitor compalgvisitor(outfile.get(), compalgconfig);
   compalgconfig.SendVisitor(compalgvisitor);
-  
+
   MiniConfig metadataconfig;
   metadataconfig.AddKeyword("metadata");
   metadataconfig.ReadFile(infileName);
@@ -137,11 +143,11 @@ AssembleAndSave( std::string infileName, std::string outfileName )
 
   RegionVisitor regvisitor( root.get(), algconfig, thrconfig, refconfig, directories );
   regconfig.SendVisitor( regvisitor );
-  
-  AssessmentVisitor histvisitor( root.get(), algconfig, thrconfig, refconfig, outfile.get(), 
-				 directories, &refsourcedata );  
+
+  AssessmentVisitor histvisitor( root.get(), algconfig, thrconfig, refconfig, outfile.get(),
+				 directories, &refsourcedata );
   histconfig.SendVisitor( histvisitor );
-  
+
   outfile->WriteTObject(&refsourcedata, "refsourcedata");
   outfile->cd();
   root->Write();
@@ -157,9 +163,9 @@ BuildMonitors( std::string configName, dqm_core::Input& input, HanOutput& output
   if( !isInitialized ) {
     return;
   }
-  
+
   m_dqRoot = BuildMonitorsNewRoot( configName, input, output );
-  
+
   output.setConfig( this );
 }
 
@@ -171,7 +177,7 @@ BuildMonitorsNewRoot( std::string configName, dqm_core::Input& input, dqm_core::
   if( !isInitialized ) {
     return boost::shared_ptr<dqm_core::Region>();
   }
-  
+
   std::string algName( m_top_level->GetAlgName() );
   std::string algLibName( m_top_level->GetAlgLibName() );
   if( algLibName != "" ) {
@@ -184,7 +190,7 @@ BuildMonitorsNewRoot( std::string configName, dqm_core::Input& input, dqm_core::
   }
   dqm_core::RegionConfig regc( algName, 1.0 );
   boost::shared_ptr<dqm_core::Region> retval(dqm_core::Region::createRootRegion( "top_level", input, output, regc ));
-  
+
   ConfigVisitor confvisitor( m_config, &output );
   m_top_level->Accept( confvisitor, retval );
   return retval;
@@ -199,21 +205,21 @@ BuildConfigOutput( std::string configName, TFile* inputFile, std::string path,
   if( !isInitialized ) {
     return;
   }
-  
+
   if( inputFile == 0 ) {
     return;
   }
-  
+
   TDirectory* basedir(0);
   if( path != "" ) {
     std::string pathForSearch = path;
     pathForSearch += "/dummyName";
     basedir = ChangeInputDir( inputFile, pathForSearch );
   }
-  
+
   if( basedir == 0 )
     basedir = inputFile;
-  
+
   TIter mdIter(m_metadata);
   TSeqCollection* mdList = newTList("HanMetadata_");
   HanConfigMetadata* md(0);
@@ -222,7 +228,7 @@ BuildConfigOutput( std::string configName, TFile* inputFile, std::string path,
   }
   TSeqCollection* top_level_list = m_top_level->GetList(basedir,*outputMap);
   top_level_list->Add( mdList );
-  outputList->Add( top_level_list );  
+  outputList->Add( top_level_list );
 }
 
 
@@ -233,7 +239,7 @@ GetReference( std::string& groupName, std::string& name )
   /*  if( m_top_level == 0 ) {
     return 0;
   }
-  
+
   HanConfigGroup* parent = m_top_level->GetNode(groupName);
   if( parent == 0 ) {
     parent = m_top_level;
@@ -251,13 +257,15 @@ GetReference( std::string& groupName, std::string& name )
 	return ref;
     }
   }
-  
+
   return 0;
 }
 
-std::string 
+std::string
 SplitReference(std::string refPath, std::string refName )
 {
+  // this will never be run in a multithread environment
+  static std::unordered_set<std::string> badPaths;
   //Split comma sepated inputs into individual file names
   std::string delimiter = ",";
   std::vector<std::string> refFileList;
@@ -275,15 +283,17 @@ SplitReference(std::string refPath, std::string refName )
     std::string fileName=refFileList.at(i)+refName;
     size_t first = fileName.find_first_not_of(" ");
     fileName.erase(0, first);
+    if (badPaths.find(fileName) != badPaths.end()) continue;
     if (gROOT->GetListOfFiles()->FindObject(fileName.c_str()) ) {
       return fileName;
-    } 
+    }
     else {
       if(TFile::Open(fileName.c_str())){
 	return fileName;
       }
       else{
-	std::cerr << "Unable to open " << fileName << ", trying next reference file" << std::endl;
+        badPaths.insert(fileName);
+	std::cerr << "Unable to open " << fileName << ", trying next reference file option" << std::endl;
       }
     }
   }
@@ -298,20 +308,20 @@ GetAssessor( std::string& groupName, std::string& name ) const
   if( m_top_level == 0 ) {
     return 0;
   }
-  
+
   HanConfigGroup* parent = m_top_level->GetNode(groupName);
   if( parent == 0 ) {
     parent = m_top_level;
   }
-  
+
   const HanConfigAssessor& a = parent->GetAssessor(name);
 
   return new HanConfigAssessor(a);
-} 
+}
 
 void
 HanConfig::
-GetRegexList(std::set<std::string>& regexlist) 
+GetRegexList(std::set<std::string>& regexlist)
 {
   RegexVisitor rv(regexlist);
   m_top_level->Accept(rv, boost::shared_ptr<dqm_core::Region>());
@@ -368,10 +378,39 @@ Visit( const MiniConfigTreeNode* node ) const
     if (! m_refsourcedata->FindObject(fileName.c_str())) {
       m_refsourcedata->Add(fnameostr, refInfo != "" ? new TObjString(refInfo.c_str())
 			   : new TObjString("Reference"));
-    }  
+    }
   }
 }
 
+HanConfig::RefWriter::
+RefWriter( DatabaseConfig& databaseConfig_, const bool bulk)
+  : m_databaseConfig(databaseConfig_),
+    m_bulk(bulk)
+{
+}
+
+
+void
+HanConfig::RefWriter::
+Write( MiniConfigTreeNode* node )
+{
+  std::string database = node->GetAttribute("database");
+
+  if(database != "") {
+    database += (m_bulk ? "-physics-UPD4" : "-express-UPD1");
+    nlohmann::json jsonPayload = m_databaseConfig.GetPayload(database);
+    std::string reference = node->GetName();
+
+    if(jsonPayload.find(reference) != jsonPayload.end()) {
+      nlohmann::json referenceJson = jsonPayload[reference];
+      for (nlohmann::json::iterator it = referenceJson.begin(); it != referenceJson.end(); ++it) {
+        node->SetAttribute(it.key(), it.value(), false);
+      }
+    } else {
+      std::cerr << "Unable to find reference definition in database: " << reference << '\n';
+    }
+   }
+}
 
 HanConfig::AssessmentVisitorBase::
 AssessmentVisitorBase( HanConfigGroup* root_, const MiniConfig& algConfig_,
@@ -396,12 +435,16 @@ GetROOTFile( std::string& fname ) const
   if (it != end(m_filecache)) {
     return it->second;
   } else {
+    if (m_badPaths.find(fname) != m_badPaths.end()) {
+      return std::shared_ptr<TFile>(nullptr);
+    }
     std::shared_ptr<TFile> thisptr(TFile::Open(fname.c_str()));
     if (thisptr.get()) {
       return ( m_filecache[fname] = thisptr );
      } else {
+       m_badPaths.insert(fname);
       return thisptr;
-    }	  
+    }
   }
 }
 
@@ -426,7 +469,7 @@ float AttribToFloat(const MiniConfigTreeNode* node, const std::string attrib,
 
 void
 HanConfig::AssessmentVisitorBase::
-GetAlgorithmConfiguration( HanConfigAssessor* dqpar, const std::string& algID, 
+GetAlgorithmConfiguration( HanConfigAssessor* dqpar, const std::string& algID,
                            std::string assessorName ) const
 {
   // bool hasName(false);
@@ -479,7 +522,7 @@ GetAlgorithmConfiguration( HanConfigAssessor* dqpar, const std::string& algID,
       // for each condition ...
       for(size_t t=0;t<condPairs.size();t++){
 	std::string refID=condPairs.at(t).second;
-	std::string cond=condPairs.at(t).first;	
+	std::string cond=condPairs.at(t).first;
 	std::vector<std::string> refIDVec;
 	TObjArray *toarray(0);
 	bool isMultiRef(false);
@@ -532,13 +575,13 @@ GetAlgorithmConfiguration( HanConfigAssessor* dqpar, const std::string& algID,
 	      m_outfile->cd(); //we are writing to the / folder of file
 	      TObject* obj;
 	      obj = key->ReadObj();
-	      if (isMultiRef) { 
+	      if (isMultiRef) {
 		TObject* cobj = obj->Clone();
 		TH1* hobj = dynamic_cast<TH1*>(cobj);
 		if (hobj) {
 		  hobj->SetName(thisRefID.c_str());
 		}
-		toarray->Add(cobj); 
+		toarray->Add(cobj);
 		delete obj;
 	      } else {
 		std::string algRefUniqueName=algRefFile+":/"+absAlgRefName;
@@ -586,8 +629,8 @@ GetAlgorithmConfiguration( HanConfigAssessor* dqpar, const std::string& algID,
 	      }
 	    }
 	  }
-	} 
-	    
+	}
+
 	if (isMultiRef) {
 	  std::string algRefUniqueName=cond+"_multiple:/"+absAlgRefName;
 	  newRefId=CS.getNewReferenceName(algRefUniqueName,true);
@@ -608,9 +651,9 @@ GetAlgorithmConfiguration( HanConfigAssessor* dqpar, const std::string& algID,
 	    std::cerr<<"Warning New reference id is empty for refId=\""
 		     <<refID<<"\", cond=\""<<cond<<"\", assessorName= \""
 		     <<assessorName<<"\""<<std::endl;
-		     } 
+		     }
 	} */
-	
+
 	if(!cond.empty()){
 	  newRefString<<cond<<":"<<newRefId<<";";
 	}else{
@@ -618,7 +661,7 @@ GetAlgorithmConfiguration( HanConfigAssessor* dqpar, const std::string& algID,
 	}
       }
       dqpar->SetAlgRefName((newRefString.str()));
-			       
+
 //       std::string algRefName( m_refConfig.GetStringAttribute(refID,"name") );
 //       std::string algRefPath( m_refConfig.GetStringAttribute(refID,"path") );
 //       std::string absAlgRefName("");
@@ -676,15 +719,15 @@ Visit( const MiniConfigTreeNode* node ) const
   const MiniConfigTreeNode* parent = node->GetParent();
   if( parent == 0 )
     return;
-  
+
   const MiniConfigTreeNode* grandparent = parent->GetParent();
   auto alloc = std::make_unique<HanConfigGroup>();
   HanConfigGroup* reg = (grandparent==0) ? m_root : alloc.get();
-  
+
   std::string regName( node->GetName() );
   reg->SetName( regName );
   reg->SetPathName( node->GetPathName() );
-  
+
   std::string algID( node->GetAttribute("algorithm") );
   if( algID != "" ) {
     GetAlgorithmConfiguration( reg, algID );
@@ -715,7 +758,7 @@ RegexVisitor( std::set<std::string>& regexes_ )
 {
 }
 
-boost::shared_ptr<dqm_core::Node> 
+boost::shared_ptr<dqm_core::Node>
 HanConfig::RegexVisitor::
 Visit( const HanConfigAssessor* node, boost::shared_ptr<dqm_core::Region> ) const
 {
@@ -752,18 +795,18 @@ Visit( const MiniConfigTreeNode* node ) const
     const MiniConfigTreeNode* histNode = node->GetDaughter( *h );
     if( histNode == 0 )
       continue;
-    
+
     algID = histNode->GetAttribute("algorithm");
     regID = histNode->GetAttribute("output");
-    
+
     if( algID == "" ) {
       std::cerr << "No \"algorithm\" defined for " << histNode->GetPathName() << "\n";
       continue;
     }
-    
+
     if( regID == "" )
       regID = "top_level";
-    
+
     std::string strNodeName(histNode->GetName());
     std::string strHistName, strFullHistName;
     std::string::size_type atsign = strNodeName.find("@");
@@ -778,10 +821,10 @@ Visit( const MiniConfigTreeNode* node ) const
 
     if( strHistName == "all_in_dir" )
       continue;
-    
+
     if( defined.find(histNode->GetPathName()) != defined.end() )
       continue;
-    
+
     HanConfigAssessor dqpar;
     dqpar.SetName( histNode->GetPathName() );
 
@@ -790,16 +833,16 @@ Visit( const MiniConfigTreeNode* node ) const
     if (regexflag == "1" || regexflag == "true" || regexflag == "yes") {
     	dqpar.SetIsRegex(true);
     }
-    
+
     if (histNode->GetAttribute("weight") != "") {
       std::ostringstream err;
       err << "Weight attribute not a floating point type for " << histNode->GetPathName() << "; setting to zero";
       dqpar.SetWeight(AttribToFloat(histNode, "weight",
 				    err.str()));
     }
-        
+
     GetAlgorithmConfiguration( &dqpar, algID, strFullHistName );
-   
+
     std::set<std::string> histAtt2;
     histNode->GetAttributeNames( histAtt2 );
     std::set<std::string>::const_iterator histAttEnd2 = histAtt2.end();
@@ -818,7 +861,7 @@ Visit( const MiniConfigTreeNode* node ) const
     HanConfigParMap parMap;
     parMap.SetName("inputname"); parMap.SetValue( strFullHistName );
     dqpar.AddAnnotation(parMap);
-       
+
     HanConfigGroup* dqreg = m_root->GetNode( regID );
     dqreg = (dqreg==0) ? m_root : dqreg;
     if( dqreg != 0 ) {
@@ -826,12 +869,12 @@ Visit( const MiniConfigTreeNode* node ) const
     }
     defined.insert( strFullHistName );
   }
-  
+
   for( std::set<std::string>::const_iterator h = histAtt.begin(); h != histAttEnd; ++h ) {
     const MiniConfigTreeNode* histNode = node->GetDaughter( *h );
     if( histNode == 0 )
       continue;
-    
+
     algID = histNode->GetAttribute("algorithm");
     regID = histNode->GetAttribute("output");
 
@@ -839,7 +882,7 @@ Visit( const MiniConfigTreeNode* node ) const
       std::cerr << "No \"algorithm\" defined for " << histNode->GetPathName() << "\n";
       continue;
     }
-    
+
     if( regID == "" )
       regID = "top_level";
 
@@ -858,7 +901,7 @@ Visit( const MiniConfigTreeNode* node ) const
     }
 
     if( strHistName == "all_in_dir" ) {
-	
+
       std::string regexflag(histNode->GetAttribute("regex"));
       if (histNode->GetAttribute("regex") != "") {
       	std::cerr << "WARNING: all_in_dir and regex are incompatible; ignoring regex flag for " << histNode->GetPathName()
@@ -875,18 +918,18 @@ Visit( const MiniConfigTreeNode* node ) const
         std::cerr << "WARNING: No \"file\" defined for " << histNode->GetPathName() << "\n";
         continue;
       }
-      
+
       std::string refPath( m_refConfig.GetStringAttribute(refID,"path") );
-      
+
       std::string objPath("");
       std::string absObjPath("");
-      
+
       refFile = SplitReference( m_refConfig.GetStringAttribute(refID,"location"), refFile);
       std::shared_ptr<TFile> infile( GetROOTFile(refFile) );
       TDirectory* basedir(0);
       TDirectory* dir(0);
       TKey* key;
-      
+
       if( refPath != "" ) {
         //std::cout << "Searching under path \"" << refPath << "\" for " << "\"" << histNode->GetPathName() << "\"\n";
         absObjPath += refPath;
@@ -899,10 +942,10 @@ Visit( const MiniConfigTreeNode* node ) const
           continue;
         }
       }
-      
+
       if( basedir == 0 )
         basedir = infile.get();
-      
+
       std::string allPathName( histNode->GetPathName() );
       std::string::size_type i = allPathName.find_last_of('/');
       if( i != std::string::npos ) {
@@ -911,13 +954,13 @@ Visit( const MiniConfigTreeNode* node ) const
         absObjPath += std::string( allPathName, 0, i );
         absObjPath += "/";
       }
-      
+
       dir = ChangeInputDir( basedir, histNode->GetPathName() );
       if( dir == 0 ) {
         std::cerr << "INFO: Cannot find path \"" << absObjPath << "\" in reference file\n";
         continue;
       }
-      
+
       TIter next( dir->GetListOfKeys() );
       std::string objName;
       std::string absObjName;
@@ -931,21 +974,21 @@ Visit( const MiniConfigTreeNode* node ) const
         TEfficiency* tmpe = dynamic_cast<TEfficiency*>(tmpobj);
         if( tmph == 0 && tmpg == 0 && tmpe == 0 )
           continue;
-        
+
         objName = objPath;
         objName += std::string( tmpobj->GetName() );
         absObjName = absObjPath;
         absObjName += std::string( tmpobj->GetName() );
         delete tmpobj;
-        
+
         if( defined.find(objName) != defined.end() ||
 	    localdefined.find(objName) != localdefined.end() )
           continue;
-        
+
         TKey* test = getObjKey( infile.get(), absObjName );
         if( test == 0 )
           continue;
-        
+
         HanConfigAssessor dqpar;
         dqpar.SetName( objName + extension );
         GetAlgorithmConfiguration( &dqpar, algID, objName );
@@ -983,7 +1026,7 @@ Visit( const MiniConfigTreeNode* node ) const
         }
         localdefined.insert( objName );
       }
-      
+
       continue;
     }
   }
@@ -1013,7 +1056,7 @@ Visit( const HanConfigAssessor* node, boost::shared_ptr<dqm_core::Region> dqPare
       //std::cout << "Can't load library " << algLibName << ". Continuing regardless ..." << std::endl;
     }
   }
-  
+
   if( gnode != 0 ) {
     dqm_core::RegionConfig regc( algName, node->GetWeight() );
     std::string regName( gnode->GetPathName() );
@@ -1021,10 +1064,10 @@ Visit( const HanConfigAssessor* node, boost::shared_ptr<dqm_core::Region> dqPare
     m_output->addListener(regName, dqParent.get());
     return reg;
   }
-  
+
   std::string inputData( node->GetHistPath() );
   HanAlgorithmConfig* algConfig = new HanAlgorithmConfig( *node, m_file );
-  dqm_core::ParameterConfig parc( inputData, algName, node->GetWeight(), 
+  dqm_core::ParameterConfig parc( inputData, algName, node->GetWeight(),
 				  std::shared_ptr<HanAlgorithmConfig>(algConfig), node->GetIsRegex() );
   boost::shared_ptr<dqm_core::Node> par(dqParent->addParameter( node->GetName(), parc ));
   m_output->addListener(node->GetName(), dqParent.get());
@@ -1046,11 +1089,11 @@ Visit( const MiniConfigTreeNode* node ) const
 {
   m_outfile->cd();
   std::map<std::string,MiniConfigTreeNode*> daughters = node->GetDaughters();
-  std::map<std::string,MiniConfigTreeNode*>::const_iterator nodeiterEnd = daughters.end();  
+  std::map<std::string,MiniConfigTreeNode*>::const_iterator nodeiterEnd = daughters.end();
   for( std::map<std::string,MiniConfigTreeNode*>::const_iterator iter = daughters.begin(); iter != nodeiterEnd; ++iter ) {
     std::string compAlgID = iter->second->GetName();
     std::string compAlgKey = iter->first;
-    
+
     HanConfigCompAlg* compAlg = new HanConfigCompAlg();
     std::set<std::string> compAlgAtt;
     m_compAlgConfig.GetAttributeNames(compAlgID, compAlgAtt);
@@ -1062,7 +1105,7 @@ Visit( const MiniConfigTreeNode* node ) const
         std::string subAlgs( m_compAlgConfig.GetStringAttribute(compAlgID,"subalgs") );
         std::string::size_type pos = subAlgs.find(',');
         for(int size=subAlgs.size(), sizeOld=-8;
-    	    size != sizeOld; 
+    	    size != sizeOld;
     	    subAlgs.erase(0, pos+1), pos = subAlgs.find(","),sizeOld=size, size=subAlgs.size()) {
             //std::cout << "  --> adding component algorithm: " <<  subAlgs.substr(0,pos) << std::endl;
             compAlg->AddAlg( subAlgs.substr(0,pos));
@@ -1072,7 +1115,7 @@ Visit( const MiniConfigTreeNode* node ) const
         std::string libs( m_compAlgConfig.GetStringAttribute(compAlgID,"libnames") );
         std::string::size_type pos = libs.find(',');
         for(int size=libs.size(), sizeOld=-8;
-    	    size != sizeOld; 
+    	    size != sizeOld;
     	    libs.erase(0, pos+1), pos = libs.find(","),sizeOld=size, size=libs.size()) {
             //std::cout << "  --> using library: " <<  libs.substr(0,pos) << std::endl;
             compAlg->AddLib( libs.substr(0,pos));
@@ -1082,7 +1125,7 @@ Visit( const MiniConfigTreeNode* node ) const
     compAlg->Write();
   }
 }
-  
+
 HanConfig::MetadataVisitor::
 MetadataVisitor(TFile* outfile_, const MiniConfig& metadataConfig_)
   : m_outfile(outfile_)
@@ -1108,9 +1151,9 @@ Visit( const MiniConfigTreeNode* node ) const
       m_outfile->cd();
     }
   }
-    
+
   std::map<std::string,MiniConfigTreeNode*> daughters = node->GetDaughters();
-  std::map<std::string,MiniConfigTreeNode*>::const_iterator nodeiterEnd = daughters.end();  
+  std::map<std::string,MiniConfigTreeNode*>::const_iterator nodeiterEnd = daughters.end();
   for( std::map<std::string,MiniConfigTreeNode*>::const_iterator iter = daughters.begin(); iter != nodeiterEnd; ++iter ) {
     std::string metadataID = iter->second->GetName();
 
@@ -1127,14 +1170,14 @@ Visit( const MiniConfigTreeNode* node ) const
     delete metadata;
   }
 }
-   
+
 
 bool
 HanConfig::
 Initialize( std::string configName )
 {
   if( m_config == 0 || m_top_level == 0 ) {
-    
+
     delete m_config;
     delete m_top_level;
     if (m_metadata) {
@@ -1154,7 +1197,7 @@ Initialize( std::string configName )
     } else {
       std::cerr << "Can't retrieve reference source info" << std::endl;
     }
-    
+
     TIter nextKey( m_config->GetListOfKeys() );
     TKey* compAlgKey(0);
     while( (compAlgKey = dynamic_cast<TKey*>( nextKey() )) != 0 ) {
@@ -1166,7 +1209,7 @@ Initialize( std::string configName )
       }
       delete obj;
     }
-    
+
     TKey* key(0);
 
     m_metadata = newTList("HanMetadata");
@@ -1198,7 +1241,7 @@ Initialize( std::string configName )
       return false;
     }
   }
-  
+
   return true;
 }
 
@@ -1235,7 +1278,7 @@ ChangeInputDir( TDirectory* dir, std::string path )
     }
     return ChangeInputDir( dir, pName );
   }
-  
+
   return dir;
 }
 
@@ -1246,7 +1289,7 @@ ChangeOutputDir( TFile* file, std::string path, DirMap_t& directories )
 {
 	if( file == 0 )
 		return 0;
-	
+
   std::string::size_type i = path.find_last_of('/');
   if( i != std::string::npos ) {
     std::string subPath( path, 0, i );
@@ -1272,9 +1315,8 @@ ChangeOutputDir( TFile* file, std::string path, DirMap_t& directories )
       return dir;
     }
   }
-	
+
   return file;
 }
 
 } // namespace dqi
-
diff --git a/DataQuality/DataQualityInterfaces/src/MiniConfig.cxx b/DataQuality/DataQualityInterfaces/src/MiniConfig.cxx
index 684a503402986f614c7399382679faab443d3fea..af8bf1bb5f7f1bc8a5c842e7c6d4e4c502d29f49 100644
--- a/DataQuality/DataQualityInterfaces/src/MiniConfig.cxx
+++ b/DataQuality/DataQualityInterfaces/src/MiniConfig.cxx
@@ -9,6 +9,7 @@
 #include <fstream>
 #include <iostream>
 #include <sstream>
+#include <optional>
 //#include <algorithm>
 
 #include "boost/algorithm/string/case_conv.hpp"
@@ -74,19 +75,19 @@ MiniConfig::
 ReadFile( std::string fileName )
 {
   bool success(true);
-  
+
   delete m_tree;
   m_tree = new MiniConfigTreeNode( "global", 0 );
   m_tree->SetAttribKeywordPropagateDown( m_propagateDown );
   MiniConfigTreeNode* node = m_tree;
-  
+
   std::ifstream file( fileName.c_str() );
   if( !file ) {
     std::cerr << "MiniConfig::ReadFile(): "
               << "cannot read from file: " << fileName << "\n";
     return false;
   }
-  
+
   std::string line;
   char c;
   std::string key;
@@ -96,31 +97,31 @@ ReadFile( std::string fileName )
   std::string val;
   int skipCount(0);
   int lineNumber = 0;
-  
+
   while( getline(file,line) ) {
     ++lineNumber;
     std::istringstream linestream(line);
     c = 0;
-    
+
     while( linestream.get(c) ) {
       // ignore leading whitespace
       if( !isspace(c) ) {
         break;
       }
     }
-    
+
     // ignore empty lines
     if( c == 0 || isspace(c) ) {
       continue;
     }
-    
+
     // ignore comments
     if( c == '#' ) {
       continue;
     }
-    
+
     linestream.putback(c);
-    
+
     // check for: }
     linestream >> sep;
     if( !linestream ) {
@@ -144,10 +145,10 @@ ReadFile( std::string fileName )
       }
       continue;
     }
-    
+
     // check for: <att> = <val>
     att = sep;
-    linestream >> sep;    
+    linestream >> sep;
     if( !linestream ) {
       std::cerr << "MiniConfig::ReadFile(): "
                 << "badly formatted line: \"" << line << "\", line number " << lineNumber << "\n";
@@ -165,11 +166,11 @@ ReadFile( std::string fileName )
         continue;
       }
       if( skipCount == 0 ) {
-	node->SetAttribute( att, val, false );
+        node->SetAttribute( att, val, false );
       }
       continue;
     }
-    
+
     // check for: keyword <identifier> {
     key = att;
     const std::string& lokey = boost::algorithm::to_lower_copy(key);
@@ -183,7 +184,7 @@ ReadFile( std::string fileName )
       continue;
     }
     if( sep == "{" ) {
-      if( m_keywords.find(key) != m_keywords.end() 
+      if( m_keywords.find(key) != m_keywords.end()
 	  || m_keywords.find(lokey) != m_keywords.end() ) {
         node = node->GetNewDaughter( id );
       }
@@ -197,12 +198,12 @@ ReadFile( std::string fileName )
       }
       continue;
     }
-    
+
     std::cerr << "MiniConfig::ReadFile(): "
               << "badly formatted line: \"" << line << "\", line number " << lineNumber << "\n";
     success = false;
   }
-  
+
   return success;
 }
 
@@ -216,7 +217,7 @@ GetStringAttribute( std::string objName, std::string attName ) const
               << "not configured (no file has been read)\n";
     return std::string("");
   }
-  
+
   const MiniConfigTreeNode* node = m_tree->GetNode( objName );
   if( node == 0 ) {
     std::cerr << "MiniConfig::GetStringAttribute(): "
@@ -236,14 +237,14 @@ GetIntAttribute( std::string objName, std::string attName ) const
               << "not configured (no file has been read)\n";
     return 0;
   }
-  
+
   const MiniConfigTreeNode* node = m_tree->GetNode( objName );
   if( node == 0 ) {
     std::cerr << "MiniConfig::GetIntAttribute(): "
               << "\"" << objName << "\" does not exist\n";
     return 0;
   }
-  
+
   int val;
   std::string valstring = node->GetAttribute( attName );
   std::istringstream valstream(valstring);
@@ -253,7 +254,7 @@ GetIntAttribute( std::string objName, std::string attName ) const
               << "\"" << attName << "\" not an integer type\n";
     return 0;
   }
-  
+
   return val;
 }
 
@@ -267,14 +268,14 @@ GetFloatAttribute( std::string objName, std::string attName ) const
               << "not configured (no file has been read)\n";
     return 0;
   }
-  
+
   const MiniConfigTreeNode* node = m_tree->GetNode( objName );
   if( node == 0 ) {
     std::cerr << "MiniConfig::GetFloatAttribute(): "
               << "\"" << objName << "\" does not exist\n";
     return 0;
   }
-  
+
   float val;
   std::string valstring = node->GetAttribute( attName );
   std::istringstream valstream(valstring);
@@ -284,7 +285,7 @@ GetFloatAttribute( std::string objName, std::string attName ) const
               << ": \"" << attName << "\" not a floating-point type\n";
     return 0;
   }
-  
+
   return val;
 }
 
@@ -294,20 +295,20 @@ MiniConfig::
 GetAttributeNames( std::string objName, std::set<std::string>& attSet ) const
 {
   attSet.clear();
-  
+
   if( m_tree == 0 ) {
     std::cerr << "MiniConfig::GetAttributeNames(): "
               << "not configured (no file has been read)\n";
     return;
   }
-  
+
   const MiniConfigTreeNode* node = m_tree->GetNode( objName );
   if( node == 0 ) {
     std::cerr << "MiniConfig::GetAttributeNames(): "
               << "\"" << objName << "\" does not exist\n";
     return;
   }
-  
+
   node->GetAttributeNames( attSet );
 }
 
@@ -324,6 +325,17 @@ SendVisitor( const MiniConfigTreeNode::Visitor& visitor ) const
   }
 }
 
+void
+MiniConfig::
+SendWriter(MiniConfigTreeNode::Writer& writer)
+{
+  if( m_tree == 0 ) {
+    std::cerr << "MiniConfig::SendWriter(): "
+              << "not configured (no file has been read)\n";
+  } else {
+    m_tree->Accept(writer);
+  }
+}
 
-} // namespace dqi
 
+} // namespace dqi
diff --git a/DataQuality/DataQualityInterfaces/src/MiniConfigTreeNode.cxx b/DataQuality/DataQualityInterfaces/src/MiniConfigTreeNode.cxx
index 7e552b61976546a65fc7ed7d90c5f5a4fc57d659..f19819762ba2c787db823b350229a4a613b4f2ef 100644
--- a/DataQuality/DataQualityInterfaces/src/MiniConfigTreeNode.cxx
+++ b/DataQuality/DataQualityInterfaces/src/MiniConfigTreeNode.cxx
@@ -74,7 +74,7 @@ GetNewDaughter( std::string name_ )
   if( i != m_daughters.end() ) {
     return i->second;
   }
-  
+
   MiniConfigTreeNode* node = new MiniConfigTreeNode( name_, this );
   node->SetAttribKeywordPropagateDown(this->m_propagateDown);
   NodeMap_t::value_type nodeVal( name_, node );
@@ -103,7 +103,7 @@ GetParent() const
 }
 
 
-std::map<std::string,MiniConfigTreeNode*> 
+std::map<std::string,MiniConfigTreeNode*>
 MiniConfigTreeNode::
 GetDaughters() const
 {
@@ -117,7 +117,7 @@ GetNode( std::string name_ ) const
   if( m_daughters.size() == 0 ) {
     return this;
   }
-  
+
   std::string::size_type k = name_.find_first_of('/');
   if( k != std::string::npos ) {
     std::string dName( name_, 0, k );
@@ -132,7 +132,7 @@ GetNode( std::string name_ ) const
     }
     return GetNode( pName );
   }
-  
+
   NodeIter_t i = m_daughters.find( name_ );
   if( i == m_daughters.end() ) {
     return this;
@@ -167,7 +167,7 @@ GetAttribute( std::string attName, bool calledFromDaughter ) const
   return i->second.first;
 }
 
-// Like GetAttributes, but only returns attributes of *this* node, 
+// Like GetAttributes, but only returns attributes of *this* node,
 // not inherited ones
 std::string
 MiniConfigTreeNode::
@@ -225,6 +225,18 @@ Accept( const Visitor& visitor ) const
   }
 }
 
+void
+MiniConfigTreeNode::
+Accept(Writer& writer )
+{
+  writer.Write(this);
+  NodeIter_t daugEnd = m_daughters.end();
+  for( NodeIter_t i = m_daughters.begin(); i != daugEnd; ++i ) {
+    MiniConfigTreeNode* node = i->second;
+    node->Accept(writer);
+  }
+}
+
 void
 MiniConfigTreeNode::
 SetAttribKeywordPropagateDown( bool propagateDown )
@@ -240,4 +252,3 @@ GetAttribKeywordPropagateDown() const
 }
 
 } // namespace dqi
-
diff --git a/DataQuality/DataQualityInterfaces/src/han_config_gen.cxx b/DataQuality/DataQualityInterfaces/src/han_config_gen.cxx
index 06250c8199a5c96a5a96ba74e50b0e75ad5dece3..5a569247e132b212797850a1ef128ea129622184 100644
--- a/DataQuality/DataQualityInterfaces/src/han_config_gen.cxx
+++ b/DataQuality/DataQualityInterfaces/src/han_config_gen.cxx
@@ -1,9 +1,9 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
 */
 
 /**
- * $Id: han_config_gen.cxx,v 1.3 2009-02-09 15:19:59 ponyisi Exp $
+ * $Id: han_config_gen.cxx,v 1.3 2009-02-09 15:19:59 ponyisi $
  */
 
 #include <iostream>
@@ -20,6 +20,11 @@ void usage( const std::string& command_name, int exit_code );
 class CmdLineArgs {
 public:
   CmdLineArgs( int argc, char *argv[] );
+
+  
+  std::string m_connectionString =  "sqlite://;schema=/afs/cern.ch/user/a/atlasdqm/dqmdisk1/cherrypy-devel/RefDB.db;dbname=REFDB";
+  long m_runNumber = 2147483646;
+  bool m_bulk = false; 
   
   std::string command;
   std::string mconfig;
@@ -45,7 +50,7 @@ int main( int argc, char *argv[] )
   outfileName += ".hcfg";
   
   dqi::HanConfig config;
-  config.AssembleAndSave( infileName, outfileName );
+  config.AssembleAndSave( infileName, outfileName, arg.m_connectionString, arg.m_runNumber, arg.m_bulk);
   return 0;
 }
 
@@ -60,11 +65,44 @@ CmdLineArgs::
 CmdLineArgs( int argc, char *argv[] )
 {
   command = argv[0];
-  if( argc > 3 ) usage( command, 1 );
+  if( argc > 10 ) usage( command, 1 );
   if( argc < 2 ) usage( command, 0 );
   
   mconfig = argv[1];
-  if(argc==3)conds=argv[2];
+  
+  if(argc >= 3) {
+    int ic = 2;
+    while(ic < argc) {
+      int ir = argc - ic;
+      std::string par0 = argv[ic];
+      if(par0 == "-c") {
+      	if(ir > 1) {
+      	  m_connectionString = argv[ic + 1];
+          std::cout << "Setting DB connection string to " << m_connectionString << std::endl;
+	        ++ic;
+	      }
+      } else if(par0 == "-r") {
+	      if(ir > 1) {
+	        try {
+	          m_runNumber = std::stol(argv[ic + 1]);
+            std::cout << "Setting run number to " << m_runNumber << std::endl;
+	          ++ic;
+	        } catch(std::exception& e) {
+	          std::cout << "Error with input arguments, specified run " << argv[ic+1] << " not a long" << '\n';
+	        }
+	      }
+      } else if(par0 == "-b") {
+	      if(ir > 1) {
+	        m_bulk = (strcmp(argv[ic+1], "true") == 0);
+          std::cout << "Setting bulk processing mode to " << (m_bulk ? "true" : "false") << std::endl;
+	        ++ic;
+	      }
+      } else {
+	      conds = argv[ic];
+      }
+      ++ic;
+    }
+  }
 }