diff --git a/DataQuality/GoodRunsListsUser/GoodRunsListsUser/DummyDumperAlg.h b/DataQuality/GoodRunsListsUser/GoodRunsListsUser/DummyDumperAlg.h
new file mode 100644
index 0000000000000000000000000000000000000000..fd56afb3ae167b86eec13701eea55852ab6926b7
--- /dev/null
+++ b/DataQuality/GoodRunsListsUser/GoodRunsListsUser/DummyDumperAlg.h
@@ -0,0 +1,50 @@
+// -*- C++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef LumiBlockComps_DummyDumperAlg_H
+#define LumiBlockComps_DummyDumperAlg_H
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "GaudiKernel/ToolHandle.h"
+
+#include <vector>
+#include <string>
+#include "TObjString.h"
+
+/////////////////////////////////////////////////////////////////////////////
+
+class ILumiBlockMetaDataTool;
+class StoreGateSvc;
+class TTree;
+class ITHistSvc;
+
+class DummyDumperAlg : public AthAlgorithm 
+{
+ public:
+  DummyDumperAlg( const std::string& name, ISvcLocator* pSvcLocator );
+  virtual ~DummyDumperAlg();
+
+  StatusCode initialize();
+  StatusCode execute();
+  StatusCode finalize();
+
+ private:
+
+  ToolHandle< ILumiBlockMetaDataTool > m_LumiBlockMetaDataTool;
+  std::vector<std::string> m_grlname;
+  std::vector<TObjString> m_grlobj;
+
+  StoreGateSvc* m_storeGate;
+  TTree* m_tree;
+
+  int m_eventCounter;
+  int m_dummyInt;
+
+  ITHistSvc* m_ths;
+};
+
+#endif // LumiBlockComps_DummyDumperAlg_H
+
diff --git a/DataQuality/GoodRunsListsUser/GoodRunsListsUser/GRLTriggerSelectorAlg.h b/DataQuality/GoodRunsListsUser/GoodRunsListsUser/GRLTriggerSelectorAlg.h
new file mode 100644
index 0000000000000000000000000000000000000000..af52e526a026fb1e250f84db0fc953c1f60081a1
--- /dev/null
+++ b/DataQuality/GoodRunsListsUser/GoodRunsListsUser/GRLTriggerSelectorAlg.h
@@ -0,0 +1,64 @@
+// -*- C++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef GoodRunsListsUser_GRLTriggerSelectorAlg_H
+#define GoodRunsListsUser_GRLTriggerSelectorAlg_H
+
+#include "GaudiKernel/ToolHandle.h"
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "GoodRunsLists/RegularFormula.h"
+
+#include <list>
+#include <string>
+#include <vector>
+#include "TString.h"
+
+/////////////////////////////////////////////////////////////////////////////
+
+class IGoodRunsListSelectorTool;
+class ITriggerRegistryTool;
+
+namespace Trig {
+  class TrigDecisionTool;
+}
+
+
+class GRLTriggerSelectorAlg : public AthAlgorithm 
+{
+ public:
+  GRLTriggerSelectorAlg( const std::string& name, ISvcLocator* pSvcLocator );
+  virtual ~GRLTriggerSelectorAlg(); 
+
+  StatusCode initialize();
+  StatusCode execute();
+  StatusCode finalize();
+
+ private:
+  ToolHandle< IGoodRunsListSelectorTool > m_GoodRunsListSelectorTool;
+  ToolHandle< ITriggerRegistryTool > m_TriggerRegistryTool;
+  ToolHandle< Trig::TrigDecisionTool > m_tdTool;
+
+  unsigned int m_prescale;
+  unsigned int m_gcounter;
+  unsigned int m_gaccept;
+  unsigned int m_tcounter;
+  unsigned int m_taccept;
+
+  std::vector<std::string> m_grlnameVec;
+  std::vector<std::string> m_brlnameVec;
+  std::string m_myname;
+
+  double* m_trigpar;
+
+  std::string  m_regexpr, m_regexprRegistrationOnly;
+  std::list<TString> m_par;
+  Root::RegularFormula m_formula;
+  bool m_applyTriggerSelection;
+
+};
+
+#endif // GoodRunsListsUser_GRLTriggerSelectorAlg_H
+
diff --git a/DataQuality/GoodRunsListsUser/GoodRunsListsUser/GoodRunsListSelectorAlg.h b/DataQuality/GoodRunsListsUser/GoodRunsListsUser/GoodRunsListSelectorAlg.h
new file mode 100644
index 0000000000000000000000000000000000000000..efea5d96309812607402db888a9bc55de8978b32
--- /dev/null
+++ b/DataQuality/GoodRunsListsUser/GoodRunsListsUser/GoodRunsListSelectorAlg.h
@@ -0,0 +1,43 @@
+// -*- C++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef GoodRunsListsUser_GoodRunsListSelectorAlg_H
+#define GoodRunsListsUser_GoodRunsListSelectorAlg_H
+
+#include "GaudiKernel/ToolHandle.h"
+#include "AthenaBaseComps/AthAlgorithm.h"
+
+#include <vector>
+#include <string>
+
+/////////////////////////////////////////////////////////////////////////////
+
+class IGoodRunsListSelectorTool;
+
+class GoodRunsListSelectorAlg : public AthAlgorithm 
+{
+ public:
+  GoodRunsListSelectorAlg( const std::string& name, ISvcLocator* pSvcLocator );
+  virtual ~GoodRunsListSelectorAlg(); 
+
+  StatusCode initialize();
+  StatusCode execute();
+  StatusCode finalize();
+
+ private:
+  ToolHandle< IGoodRunsListSelectorTool > m_GoodRunsListSelectorTool;
+
+  unsigned int m_counter;
+  unsigned int m_accept;
+  unsigned int m_prescale;
+
+  std::vector<std::string> m_grlnameVec;
+  std::vector<std::string> m_brlnameVec;
+  std::string m_myname;
+};
+
+#endif // GoodRunsListsUser_GoodRunsListSelectorAlg_H
+
diff --git a/DataQuality/GoodRunsListsUser/GoodRunsListsUser/TriggerSelectorAlg.h b/DataQuality/GoodRunsListsUser/GoodRunsListsUser/TriggerSelectorAlg.h
new file mode 100644
index 0000000000000000000000000000000000000000..c1fe5bb1878804cfd7bd844a97e8618c9c963a57
--- /dev/null
+++ b/DataQuality/GoodRunsListsUser/GoodRunsListsUser/TriggerSelectorAlg.h
@@ -0,0 +1,56 @@
+// -*- C++ -*-
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef GoodRunsListsUser_TriggerSelectorAlg_H
+#define GoodRunsListsUser_TriggerSelectorAlg_H
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+#include "GoodRunsLists/RegularFormula.h"
+#include "GaudiKernel/ToolHandle.h"
+
+#include <list>
+#include <string>
+#include "TString.h"
+
+/////////////////////////////////////////////////////////////////////////////
+
+class ITriggerRegistryTool;
+
+namespace Trig {
+  class TrigDecisionTool;
+}
+
+class TriggerSelectorAlg : public AthAlgorithm 
+{
+ public:
+  TriggerSelectorAlg( const std::string& name, ISvcLocator* pSvcLocator );
+  virtual ~TriggerSelectorAlg();
+
+  StatusCode initialize();
+  StatusCode execute();
+  StatusCode finalize();
+
+ private:
+
+  ToolHandle< Trig::TrigDecisionTool > m_tdTool;
+  ToolHandle< ITriggerRegistryTool > m_TriggerRegistryTool;
+
+  double* m_trigpar;
+
+  unsigned int m_counter;
+  unsigned int m_accept;
+  unsigned int m_prescale;
+
+  std::string  m_regexpr, m_regexprRegistrationOnly;
+  std::list<TString> m_par;
+  Root::RegularFormula m_formula;
+  bool m_applyTriggerSelection;
+
+  std::string m_myname;
+};
+
+#endif // GoodRunsListsUser_TriggerSelectorAlg_H
+
diff --git a/DataQuality/GoodRunsListsUser/README b/DataQuality/GoodRunsListsUser/README
new file mode 100644
index 0000000000000000000000000000000000000000..e5c103315e3ab7d39330e67f16791ade17f1c8a1
--- /dev/null
+++ b/DataQuality/GoodRunsListsUser/README
@@ -0,0 +1,6 @@
+Last update: 2009-10-21, by Max Baak 
+
+All good-run-list documentation at:
+-----------------------------------
+https://twiki.cern.ch/twiki/bin/view/Atlas/GoodRunsLists
+
diff --git a/DataQuality/GoodRunsListsUser/cmt/requirements b/DataQuality/GoodRunsListsUser/cmt/requirements
new file mode 100644
index 0000000000000000000000000000000000000000..3b77bb25b398539a301728964c793b1572f5d468
--- /dev/null
+++ b/DataQuality/GoodRunsListsUser/cmt/requirements
@@ -0,0 +1,30 @@
+package GoodRunsListsUser
+
+author Max Baak <mbaak@cern.ch>
+
+use AtlasPolicy       	AtlasPolicy-* 
+use AtlasROOT   	AtlasROOT-*             External
+use AthenaBaseComps 	AthenaBaseComps-*   	Control
+use GaudiInterface  	GaudiInterface-*    	External 
+use EventInfo           EventInfo-*             Event
+use GoodRunsLists       GoodRunsLists-*         DataQuality
+use LumiBlockComps      LumiBlockComps-*        LumiBlock
+use StoreGate 		StoreGate-* 		Control
+
+use TrigDecisionEvent   TrigDecisionEvent-*     Trigger/TrigEvent    # rel 15
+use TrigDecisionTool    TrigDecisionTool-*      Trigger/TrigAnalysis # rel 15
+
+## macros
+apply_tag       ROOTBasicLibs
+apply_tag       ROOTMathLibs
+
+library GoodRunsListsUser "../src/*.cxx ../src/components/*.cxx"
+apply_pattern component_library
+
+## requirements file, scripts, jobOptions and python modules
+apply_pattern declare_joboptions files="*.py"
+
+private
+#macro cppdebugflags '$(cppdebugflags_s)'
+#macro_remove componentshr_linkopts "-Wl,-s"
+
diff --git a/DataQuality/GoodRunsListsUser/run/blacklist.xml b/DataQuality/GoodRunsListsUser/run/blacklist.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3f6172bbb5934746add413e9d3c7d42f45beea93
--- /dev/null
+++ b/DataQuality/GoodRunsListsUser/run/blacklist.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<!DOCTYPE LumiRangeCollection SYSTEM "http://atlas-runquery.cern.ch/LumiRangeCollection.dtd">
+<!--This document is created by GoodRunsListWriter. Ask Max Baak for details.-->
+<LumiRangeCollection>
+  <NamedLumiRange>
+    <Name>blacklist</Name>
+    <Version>1</Version>
+    <LumiBlockCollection>
+      <Run>108175</Run>
+      <LBRange Start="840" End="845"/>
+    </LumiBlockCollection>
+  </NamedLumiRange>
+</LumiRangeCollection>
+
diff --git a/DataQuality/GoodRunsListsUser/run/grl_topmix_e.xml b/DataQuality/GoodRunsListsUser/run/grl_topmix_e.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a587a6a538f1ee66b6049e633b7e4fb7ca925068
--- /dev/null
+++ b/DataQuality/GoodRunsListsUser/run/grl_topmix_e.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!DOCTYPE LumiRangeCollection SYSTEM "http://atlas-runquery.cern.ch/LumiRangeCollection.dtd">
+<!--This document is created by GoodRunsListWriter.-->
+<LumiRangeCollection>
+  <NamedLumiRange>
+    <Name>grl_topmix_e</Name>
+    <Version>1</Version>
+    <LumiBlockCollection>
+      <Run>108175</Run>
+      <LBRange Start="806" End="806"/>
+      <LBRange Start="809" End="819"/>
+      <LBRange Start="827" End="836"/>
+      <LBRange Start="839" End="852"/>
+      <LBRange Start="855" End="867"/>
+      <LBRange Start="873" End="883"/>
+      <LBRange Start="886" End="898"/>
+      <LBRange Start="901" End="910"/>
+      <LBRange Start="917" End="929"/>
+    </LumiBlockCollection>
+  </NamedLumiRange>
+</LumiRangeCollection>
+
diff --git a/DataQuality/GoodRunsListsUser/run/grl_topmix_mu.xml b/DataQuality/GoodRunsListsUser/run/grl_topmix_mu.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3caeb8367a2ef658eb9d8b6f2a828e280760977d
--- /dev/null
+++ b/DataQuality/GoodRunsListsUser/run/grl_topmix_mu.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<!DOCTYPE LumiRangeCollection SYSTEM "http://atlas-runquery.cern.ch/LumiRangeCollection.dtd">
+<!--This document is created by GoodRunsListWriter.-->
+<LumiRangeCollection>
+  <NamedLumiRange>
+    <Name>grl_topmix_mu</Name>
+    <Version>1</Version>
+    <LumiBlockCollection>
+      <Run>108175</Run>
+      <LBRange Start="806" End="806"/>
+      <LBRange Start="813" End="821"/>
+      <LBRange Start="824" End="836"/>
+      <LBRange Start="839" End="848"/>
+      <LBRange Start="855" End="867"/>
+      <LBRange Start="875" End="883"/>
+      <LBRange Start="886" End="898"/>
+      <LBRange Start="901" End="910"/>
+      <LBRange Start="917" End="927"/>
+    </LumiBlockCollection>
+  </NamedLumiRange>
+</LumiRangeCollection>
diff --git a/DataQuality/GoodRunsListsUser/run/lumi_files/luminosity_grl_108175.806-108175.867.xml b/DataQuality/GoodRunsListsUser/run/lumi_files/luminosity_grl_108175.806-108175.867.xml
new file mode 100644
index 0000000000000000000000000000000000000000..cd48cf7d70bd45dfc277c96d0a428b7181bda8e5
--- /dev/null
+++ b/DataQuality/GoodRunsListsUser/run/lumi_files/luminosity_grl_108175.806-108175.867.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+<!DOCTYPE LumiRangeCollection SYSTEM "http://atlas-runquery.cern.ch/LumiRangeCollection.dtd">
+<!--This document is created by GoodRunsListWriter.-->
+<LumiRangeCollection>
+  <NamedLumiRange>
+    <Name>LumiBlocks_GoodDQ0</Name>
+    <Version>10</Version>
+    <Metadata Name="BadRunsList0">blacklist</Metadata>
+    <Metadata Name="Description">luminosity_Sequence0</Metadata>
+    <Metadata Name="GRLQuery">_OR_grl_topmix_mu_AND_NOT_blacklist</Metadata>
+    <Metadata Name="GoodRunsList0">grl_topmix_mu</Metadata>
+    <Metadata Name="SelectionTrigger">1</Metadata>
+    <LumiBlockCollection>
+      <Run>108175</Run>
+      <LBRange Start="806" End="806"/>
+      <LBRange Start="813" End="821"/>
+      <LBRange Start="824" End="836"/>
+      <LBRange Start="839" End="839"/>
+      <LBRange Start="846" End="848"/>
+      <LBRange Start="855" End="867"/>
+    </LumiBlockCollection>
+  </NamedLumiRange>
+  <NamedLumiRange>
+    <Name>LumiBlocks_GoodDQ1</Name>
+    <Version>10</Version>
+    <Metadata Name="Description">luminosity_Sequence1</Metadata>
+    <Metadata Name="GRLQuery">_OR_grl_topmix_e</Metadata>
+    <Metadata Name="GoodRunsList0">grl_topmix_e</Metadata>
+    <Metadata Name="SelectionTrigger">1</Metadata>
+    <LumiBlockCollection>
+      <Run>108175</Run>
+      <LBRange Start="806" End="806"/>
+      <LBRange Start="809" End="819"/>
+      <LBRange Start="827" End="836"/>
+      <LBRange Start="839" End="852"/>
+      <LBRange Start="855" End="867"/>
+    </LumiBlockCollection>
+  </NamedLumiRange>
+</LumiRangeCollection>
diff --git a/DataQuality/GoodRunsListsUser/run/lumi_files/luminosity_grl_108175.870-108175.929.xml b/DataQuality/GoodRunsListsUser/run/lumi_files/luminosity_grl_108175.870-108175.929.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f66f8ed2f1c5461b3ebb1d1848748519008175ab
--- /dev/null
+++ b/DataQuality/GoodRunsListsUser/run/lumi_files/luminosity_grl_108175.870-108175.929.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<!DOCTYPE LumiRangeCollection SYSTEM "http://atlas-runquery.cern.ch/LumiRangeCollection.dtd">
+<!--This document is created by GoodRunsListWriter.-->
+<LumiRangeCollection>
+  <NamedLumiRange>
+    <Name>LumiBlocks_GoodDQ0</Name>
+    <Version>10</Version>
+    <Metadata Name="BadRunsList0">blacklist</Metadata>
+    <Metadata Name="Description">luminosity_Sequence0</Metadata>
+    <Metadata Name="GRLQuery">_OR_grl_topmix_mu_AND_NOT_blacklist</Metadata>
+    <Metadata Name="GoodRunsList0">grl_topmix_mu</Metadata>
+    <Metadata Name="SelectionTrigger">1</Metadata>
+    <LumiBlockCollection>
+      <Run>108175</Run>
+      <LBRange Start="875" End="883"/>
+      <LBRange Start="886" End="898"/>
+      <LBRange Start="901" End="910"/>
+      <LBRange Start="917" End="927"/>
+    </LumiBlockCollection>
+  </NamedLumiRange>
+  <NamedLumiRange>
+    <Name>LumiBlocks_GoodDQ1</Name>
+    <Version>10</Version>
+    <Metadata Name="Description">luminosity_Sequence1</Metadata>
+    <Metadata Name="GRLQuery">_OR_grl_topmix_e</Metadata>
+    <Metadata Name="GoodRunsList0">grl_topmix_e</Metadata>
+    <Metadata Name="SelectionTrigger">1</Metadata>
+    <LumiBlockCollection>
+      <Run>108175</Run>
+      <LBRange Start="873" End="883"/>
+      <LBRange Start="886" End="898"/>
+      <LBRange Start="901" End="910"/>
+      <LBRange Start="917" End="929"/>
+    </LumiBlockCollection>
+  </NamedLumiRange>
+</LumiRangeCollection>
diff --git a/DataQuality/GoodRunsListsUser/run/minbias_900GeV.xml b/DataQuality/GoodRunsListsUser/run/minbias_900GeV.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9f49e5bd6fa641789aa3456a8a2244d12ed06932
--- /dev/null
+++ b/DataQuality/GoodRunsListsUser/run/minbias_900GeV.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<!DOCTYPE LumiRangeCollection SYSTEM "http://atlas-runquery.cern.ch/LumiRangeCollection.dtd">
+<!--This document is created by GoodRunsListWriter.-->
+<LumiRangeCollection>
+  <NamedLumiRange>
+    <Name>minbias_900GeV</Name>
+    <Version>10</Version>
+    <Metadata Name="Description">Example for DQ tutorial</Metadata>
+    <LumiBlockCollection>
+      <Run>142383</Run>
+      <LBRange Start="88" End="95"/>
+      <LBRange Start="116" End="123"/>
+    </LumiBlockCollection>
+  </NamedLumiRange>
+</LumiRangeCollection>
+
diff --git a/DataQuality/GoodRunsListsUser/share/GoodRunsListsUser_DQLumiExample.py b/DataQuality/GoodRunsListsUser/share/GoodRunsListsUser_DQLumiExample.py
new file mode 100644
index 0000000000000000000000000000000000000000..c926b28dd6af5c69004d907f3ce7a90b0676ef44
--- /dev/null
+++ b/DataQuality/GoodRunsListsUser/share/GoodRunsListsUser_DQLumiExample.py
@@ -0,0 +1,38 @@
+# add LumiBlockMetaDataTool to ToolSvc and configure
+from LumiBlockComps.LumiBlockCompsConf import LumiBlockMetaDataTool
+ToolSvc += LumiBlockMetaDataTool( "LumiBlockMetaDataTool" )
+LumiBlockMetaDataTool.calcLumi = True # False by default
+
+# add ToolSvc.LumiBlockMetaDataTool to MetaDataSvc
+from EventSelectorAthenaPool.EventSelectorAthenaPoolConf import MetaDataSvc
+svcMgr += MetaDataSvc( "MetaDataSvc" )
+svcMgr.MetaDataSvc.MetaDataTools += [ ToolSvc.LumiBlockMetaDataTool ]
+
+# Configure the goodrunslist selector tool
+from GoodRunsLists.GoodRunsListsConf import *
+ToolSvc += GoodRunsListSelectorTool() 
+GoodRunsListSelectorTool.GoodRunsListVec = [ '$TestArea/DataQuality/GoodRunsListsUser/run/minbias_900GeV.xml' ]
+
+## This Athena job consists of algorithms that loop over events;
+## here, the (default) top sequence is used:
+from AthenaCommon.AlgSequence import AlgSequence, AthSequencer
+job = AlgSequence()
+seq = AthSequencer("AthFilterSeq")
+
+## AthFilterSeq is always executed before the top sequence, and is configured such that
+## any follow-up sequence (eg. top sequence) is not executed in case GRLTriggerAlg1 does
+## not pass the event
+## In short, the sequence AthFilterSeq makes sure that all algs in the job sequence
+## are skipped when an event gets rejects
+from GoodRunsListsUser.GoodRunsListsUserConf import *
+seq += GRLTriggerSelectorAlg('GRLTriggerAlg1')
+seq.GRLTriggerAlg1.GoodRunsListArray = ['minbias_900GeV']        ## pick up correct name from inside xml file!
+seq.GRLTriggerAlg1.TriggerSelectionRegistration = 'L1_MBTS_1' ## set this to your favorite trigger, eg. L1_MBTS_1_1
+
+## Add the ntuple dumper to the top sequence, as usual
+## DummyDumperAlg1 is run in the top sequence, but is not executed in case GRLTriggerAlg1 rejects the event.
+job += DummyDumperAlg('DummyDumperAlg1')
+# job.DummyDumperAlg1.RootFileName = 'selection1.root'
+THistSvc.Output =  {"new DATAFILE='selection1.root' TYP='ROOT' OPT='NEW'"};
+job.DummyDumperAlg1.GRLNameVec = [ 'LumiBlocks_GoodDQ0', 'IncompleteLumiBlocks_GoodDQ0' ]
+
diff --git a/DataQuality/GoodRunsListsUser/share/GoodRunsListsUser_coolQuery.py b/DataQuality/GoodRunsListsUser/share/GoodRunsListsUser_coolQuery.py
new file mode 100644
index 0000000000000000000000000000000000000000..50bd78de1c65bfe1c0c8ce09e48a012316c81c6b
--- /dev/null
+++ b/DataQuality/GoodRunsListsUser/share/GoodRunsListsUser_coolQuery.py
@@ -0,0 +1,47 @@
+###########################################################################################
+## IMPORTANT: Configuring the goodrunslist selector tool to work from COOL
+##            does not work in combination with the LumiBlockMetaDataTool
+##            USE WITH CAUTION!
+###########################################################################################
+
+from AthenaCommon.AppMgr import ServiceMgr
+from PoolSvc.PoolSvcConf import PoolSvc
+ServiceMgr+=PoolSvc(SortReplicas=True)
+from DBReplicaSvc.DBReplicaSvcConf import DBReplicaSvc
+ServiceMgr+=DBReplicaSvc(UseCOOLSQLite=False)
+from AthenaCommon.GlobalFlags import globalflags
+globalflags.DetDescrVersion.set_Value_and_Lock('ATLAS-GEO-02-01-00')
+#globalflags.ConditionsTag.set_Value_and_Lock('OFLCOND-SIM-00-00-03')
+
+from IOVDbSvc.CondDB import conddb
+conddb.setGlobalTag('OFLCOND-SIM-00-00-03')
+include("RecExCond/AllDet_detDescr.py")
+
+include("DetectorStatus/DetStatusSvc_CondDB.py")
+conddb.addOverride('/GLOBAL/DETSTATUS/LBSUMM','DetStatusLBSumm-TopMix1')
+
+###########################################################################################
+## Configure the goodrunslist selector tool to work from COOL
+###########################################################################################
+
+from GoodRunsLists.GoodRunsListsConf import GoodRunsListSelectorTool
+from GoodRunsLists.TopMixConfig import TopMixConfig
+GoodRunsTool = GoodRunsListSelectorTool('GoodRunsTool')
+dqflagsconfig = TopMixConfig()
+GoodRunsTool.DQFlagsQueryVec = dqflagsconfig.getparseddqflags()
+GoodRunsTool.DQFlagsFromCOOL = True
+GoodRunsTool.RunRangeExpressionCOOL = '1' # 'run>=108175 || run>=10000 && run<=100000' # ala TFormula
+#GoodRunsTool.VerboseDetStatus = True
+#GoodRunsTool.OutputLevel = DEBUG
+
+###########################################################################################
+## Add GRL selector tool to pre-eventselector
+###########################################################################################
+
+## Klugde: eventselector currently needs private tool, will become public very soon!
+## Public version is used by eg. LumiBlockMetaDataTool
+## add the (private version of) grl selector tool to the eventselector
+AthenaEventLoopMgr = Service( "AthenaEventLoopMgr" )
+AthenaEventLoopMgr.PreSelectTools += [ GoodRunsTool ]
+AthenaEventLoopMgr.OutputLevel = WARNING
+
diff --git a/DataQuality/GoodRunsListsUser/share/GoodRunsListsUser_default.py b/DataQuality/GoodRunsListsUser/share/GoodRunsListsUser_default.py
new file mode 100644
index 0000000000000000000000000000000000000000..f30dc1a70cbba9cd4d54ba67b5641cfea1772e3e
--- /dev/null
+++ b/DataQuality/GoodRunsListsUser/share/GoodRunsListsUser_default.py
@@ -0,0 +1,48 @@
+## Example trigger joboptions
+#include ("AMAAthena/Trigger_jobOptions.py")
+
+###########################################################################################
+## Configure the goodrunslist selector tool to read and interpret xml files
+###########################################################################################
+
+## Configure the goodrunslist selector tool
+from GoodRunsLists.GoodRunsListsConf import *
+ToolSvc += GoodRunsListSelectorTool() 
+GoodRunsListSelectorTool.GoodRunsListVec  = [ '$TestArea/DataQuality/GoodRunsListsUser/run/grl_topmix_mu.xml' ]
+GoodRunsListSelectorTool.BlackRunsListVec = [ '$TestArea/DataQuality/GoodRunsListsUser/run/blacklist.xml' ]
+GoodRunsListSelectorTool.OutputLevel = DEBUG
+
+## GRL selector, dummy ntuple dumper
+from GoodRunsListsUser.GoodRunsListsUserConf import *
+
+###########################################################################################
+## Start of jobsequence
+###########################################################################################
+
+## This Athena job consists of algorithms that loop over events;
+## here, the (default) top sequence is used:
+from AthenaCommon.AlgSequence import AlgSequence, AthSequencer
+job = AlgSequence()
+
+###########################################################################################
+## GRLTriggerSelectorAlg uses GoodRunsListSelectorTool to determine for 
+##   each event whether to pass it, or to reject it.
+## As good- and black run lists GRLTriggerAlg1 uses: 'grl_topmix_mu' and 'blacklist', 
+##   which are the names of the good run list objects in grl_topmix_mu.xml 
+##   and blacklist.xml respectively.
+## As the dummy ntupledumper DummyDumperAlg1 runs in the top sequence, 
+##   after GRLTriggerAlg1, it is not executed in case GRLTriggerAlg1 rejects an event.
+###########################################################################################
+
+## AthFilterSeq is always executed before the top sequence, and is configured such that
+## any follow-up sequence (eg. top sequence) is not executed in case GRLTriggerAlg1 does
+## not pass the event
+seq = AthSequencer("AthFilterSeq")
+seq += GRLTriggerSelectorAlg('GRLTriggerAlg1')
+seq.GRLTriggerAlg1.GoodRunsListArray  = ['grl_topmix_mu']
+seq.GRLTriggerAlg1.BlackRunsListArray = ['blacklist']
+
+## DummyDumperAlg1 is run in the top sequence, but is not executed in case GRLTriggerAlg1 rejects the event.
+job += DummyDumperAlg('DummyDumperAlg1')
+# job.DummyDumperAlg1.RootFileName = 'selection1.root'
+THistSvc.Output =  {"new DATAFILE='selection1.root' TYP='ROOT' OPT='NEW'"};
diff --git a/DataQuality/GoodRunsListsUser/share/GoodRunsListsUser_default_data.py b/DataQuality/GoodRunsListsUser/share/GoodRunsListsUser_default_data.py
new file mode 100644
index 0000000000000000000000000000000000000000..72ed79e000cb9ef98b918f488049ecbd0a74a61e
--- /dev/null
+++ b/DataQuality/GoodRunsListsUser/share/GoodRunsListsUser_default_data.py
@@ -0,0 +1,26 @@
+# Configure the goodrunslist selector tool
+from GoodRunsLists.GoodRunsListsConf import *
+ToolSvc += GoodRunsListSelectorTool() 
+GoodRunsListSelectorTool.GoodRunsListVec = [ '$TestArea/DataQuality/GoodRunsListsUser/run/minbias_900GeV.xml' ]
+#GoodRunsListSelectorTool.OutputLevel = DEBUG
+
+## This Athena job consists of algorithms that loop over events;
+## here, the (default) top sequence is used:
+from AthenaCommon.AlgSequence import AlgSequence, AthSequencer
+job = AlgSequence()
+seq = AthSequencer("AthFilterSeq")
+
+## AthFilterSeq is always executed before the top sequence, and is configured such that
+## any follow-up sequence (eg. top sequence) is not executed in case GRLTriggerAlg1 does
+## not pass the event
+## In short, the sequence AthFilterSeq makes sure that all algs in the job sequence
+## are skipped when an event gets rejects
+from GoodRunsListsUser.GoodRunsListsUserConf import *
+seq += GRLTriggerSelectorAlg('GRLTriggerAlg1')
+seq.GRLTriggerAlg1.GoodRunsListArray = ['minbias_900GeV']        ## pick up correct name from inside xml file!
+
+## Add the ntuple dumper to the top sequence, as usual
+## DummyDumperAlg1 is run in the top sequence, but is not executed in case GRLTriggerAlg1 rejects the event.
+job += DummyDumperAlg('DummyDumperAlg1')
+# job.DummyDumperAlg1.RootFileName = 'selection1.root'
+THistSvc.Output =  {"new DATAFILE='selection1.root' TYP='ROOT' OPT='NEW'"};
diff --git a/DataQuality/GoodRunsListsUser/share/GoodRunsListsUser_jobOptions.py b/DataQuality/GoodRunsListsUser/share/GoodRunsListsUser_jobOptions.py
new file mode 100644
index 0000000000000000000000000000000000000000..4d69b57d2648750fc9654a1008b3f01262d949b3
--- /dev/null
+++ b/DataQuality/GoodRunsListsUser/share/GoodRunsListsUser_jobOptions.py
@@ -0,0 +1,53 @@
+DetDescrVersion="ATLAS-GEO-02-01-00" ## Set your geometry here
+#ConditionsTag="COMCOND-REPC-003-00" ## Set the conditions tag here;not needed for AOD
+
+##------------------------------------------------------------
+## These 4 lines are needed for actual data
+##------------------------------------------------------------
+#from AthenaCommon.GlobalFlags import GlobalFlags
+#GlobalFlags.DetGeo.set_atlas()
+#GlobalFlags.DataSource.set_data()
+#from IOVDbSvc.CondDB import conddb
+
+doTrigger = False ## Need to check
+EvtMax=-1 ## number of event to process
+
+## include your algorithm job options here
+UserAlgs=[ "GoodRunsListsUser/GoodRunsListsUser_default.py",
+	   #"GoodRunsListsUser/GoodRunsListsUser_oneSelection.py"
+           #"GoodRunsListsUser/GoodRunsListsUser_twoSelections.py",
+           #"GoodRunsListsUser/GoodRunsListsUser_preEventSelector.py",
+           #"GoodRunsListsUser/GoodRunsListsUser_coolQuery.py",
+	   #"GoodRunsListsUser/LumiBlock_LumiCalc_GRL_dumper.py",
+           #"GoodRunsListsUser/GoodRunsListsUser_DQLumiExample.py"
+         ]
+
+## the Input AOD File(s)
+from AthenaCommon.AthenaCommonFlags import athenaCommonFlags
+athenaCommonFlags.PoolAODInput = [ "/afs/cern.ch/atlas/maxidisk/d36/topmix/user.RichardHawkings.0108175.topmix_Muon.AOD.v5/user.RichardHawkings.0108175.topmix_Muon.AOD.v4._00014.pool.root",
+                                   "/afs/cern.ch/atlas/maxidisk/d36/topmix/user.RichardHawkings.0108175.topmix_Muon.AOD.v5/user.RichardHawkings.0108175.topmix_Muon.AOD.v4._00015.pool.root",
+                                 ]
+
+## Output log setting; this is for the framework in general
+## You may over-ride this in your job options for your algorithm
+OutputLevel = INFO
+
+## Read settings; for performance DPD set ESD to true
+readRDO = False
+readESD = False
+readAOD = True
+
+## Write settings; keep all of these to false.
+## Control the writing of your own n-tuple in the alg's job options
+doCBNT = False
+doWriteESD = False
+doWriteAOD = False
+doWriteTAG = False
+
+## need these two flags to turn on lumiblockmetadatatool and output metadatastore
+doDPD=True
+doFileMetaData=True
+
+## main jobOption - must always be included
+include ("RecExCommon/RecExCommon_topOptions.py")
+
diff --git a/DataQuality/GoodRunsListsUser/share/GoodRunsListsUser_jobOptions_data.py b/DataQuality/GoodRunsListsUser/share/GoodRunsListsUser_jobOptions_data.py
new file mode 100644
index 0000000000000000000000000000000000000000..1b51c0f398a9dc356909dde3b3b6bc394cc47c2e
--- /dev/null
+++ b/DataQuality/GoodRunsListsUser/share/GoodRunsListsUser_jobOptions_data.py
@@ -0,0 +1,49 @@
+DetDescrVersion="ATLAS-GEO-08-00-02" ## Set your geometry here
+#ConditionsTag="COMCOND-REPC-003-00" ## Set the conditions tag here;not needed for AOD
+
+#------------------------------------------------------------
+# These 4 lines are needed for data, not for mc
+#------------------------------------------------------------
+from AthenaCommon.GlobalFlags import GlobalFlags
+GlobalFlags.DetGeo.set_atlas()
+GlobalFlags.DataSource.set_data()
+from IOVDbSvc.CondDB import conddb
+
+doTrigger = False ## Need to check
+EvtMax=-1 ## number of event to process
+
+## include your algorithm job options here
+UserAlgs=[ 
+           "GoodRunsListsUser/GoodRunsListsUser_default_data.py"
+         ]
+
+## the Input AOD File(s)
+from AthenaCommon.AthenaCommonFlags import athenaCommonFlags
+athenaCommonFlags.PoolAODInput = [
+				   "/afs/cern.ch/atlas/maxidisk/d36/data09_900GeV/data09_900GeV.00142383.physics_MinBias.merge.AOD.r988_p62_tid102217_00/AOD.102217._000003.pool.root.1",
+				   "/afs/cern.ch/atlas/maxidisk/d36/data09_900GeV/data09_900GeV.00142383.physics_MinBias.merge.AOD.r988_p62_tid102217_00/AOD.102217._000006.pool.root.1",
+				 ]
+
+## Output log setting; this is for the framework in general
+## You may over-ride this in your job options for your algorithm
+OutputLevel = INFO
+
+## Read settings; for performance DPD set ESD to true
+readRDO = False
+readESD = False
+readAOD = True
+
+## Write settings; keep all of these to false.
+## Control the writing of your own n-tuple in the alg's job options
+doCBNT = False
+doWriteESD = False
+doWriteAOD = False
+doWriteTAG = False
+
+## need these two flags to turn on lumiblockmetadatatool and output metadatastore
+doDPD=True
+doFileMetaData=True
+
+## main jobOption - must always be included
+include ("RecExCommon/RecExCommon_topOptions.py")
+
diff --git a/DataQuality/GoodRunsListsUser/share/GoodRunsListsUser_oneSelection.py b/DataQuality/GoodRunsListsUser/share/GoodRunsListsUser_oneSelection.py
new file mode 100644
index 0000000000000000000000000000000000000000..a8d6d11c1c9bbfeb71b44b621f5a30476ee44753
--- /dev/null
+++ b/DataQuality/GoodRunsListsUser/share/GoodRunsListsUser_oneSelection.py
@@ -0,0 +1,46 @@
+## Example trigger joboptions
+#include ("AMAAthena/Trigger_jobOptions.py")
+
+###########################################################################################
+## Configure the goodrunslist selector tool to read and interpret xml files
+###########################################################################################
+
+## Configure the goodrunslist selector tool
+from GoodRunsLists.GoodRunsListsConf import *
+ToolSvc += GoodRunsListSelectorTool() 
+GoodRunsListSelectorTool.GoodRunsListVec  = [ 'grl_topmix_mu.xml' ]
+GoodRunsListSelectorTool.BlackRunsListVec = [ 'blacklist.xml' ]
+#GoodRunsListSelectorTool.OutputLevel = DEBUG
+
+## GRL selector, dummy ntuple dumper
+from GoodRunsListsUser.GoodRunsListsUserConf import *
+
+###########################################################################################
+## Start of jobsequence
+###########################################################################################
+
+## This Athena job consists of algorithms that loop over events;
+## here, the (default) top sequence is used:
+from AthenaCommon.AlgSequence import AlgSequence, AthSequencer
+job = AlgSequence()
+
+###########################################################################################
+## GRLTriggerSelectorAlg uses GoodRunsListSelectorTool to determine for 
+##   each event whether to pass it, or to reject it.
+## As good- and black run lists GRLTriggerAlg1 uses: 'grl_topmix_mu' and 'blacklist', 
+##   which are the names of the good run list objects in grl_topmix_mu.xml 
+##   and blacklist.xml respectively.
+## As the dummy ntupledumper DummyDumperAlg1 runs in sequence ModSequence1, 
+##   after GRLTriggerAlg1, it is not executed in case GRLTriggerAlg1 rejects an event.
+###########################################################################################
+
+## Sequence 1
+job += AthSequencer("ModSequence1")
+job.ModSequence1 += GRLTriggerSelectorAlg('GRLTriggerAlg1')
+job.ModSequence1 += DummyDumperAlg('DummyDumperAlg1')
+
+job.ModSequence1.GRLTriggerAlg1.GoodRunsListArray  = ['grl_topmix_mu']
+job.ModSequence1.GRLTriggerAlg1.BlackRunsListArray = ['blacklist']
+
+# job.ModSequence1.DummyDumperAlg1.RootFileName = 'selection1.root'
+THistSvc.Output =  {"new DATAFILE='selection1.root' TYP='ROOT' OPT='NEW'"};
diff --git a/DataQuality/GoodRunsListsUser/share/GoodRunsListsUser_preEventSelector.py b/DataQuality/GoodRunsListsUser/share/GoodRunsListsUser_preEventSelector.py
new file mode 100644
index 0000000000000000000000000000000000000000..de98b25ae8843273469b911a0d33655e7f996c5c
--- /dev/null
+++ b/DataQuality/GoodRunsListsUser/share/GoodRunsListsUser_preEventSelector.py
@@ -0,0 +1,32 @@
+###########################################################################################
+## IMPORTANT: Configuring the goodrunslist selector as preevent selector tool
+##            does currently not work in combination with the LumiBlockMetaDataTool
+##            USE WITH CAUTION!
+###########################################################################################
+
+###########################################################################################
+## Configure the goodrunslist selector tool
+###########################################################################################
+
+from GoodRunsLists.GoodRunsListsConf import *
+GoodRunsTool = GoodRunsListSelectorTool('GoodRunsTool')
+GoodRunsTool.GoodRunsListVec  = [ 'grl_topmix_mu.xml', 'grl_topmix_e.xml' ]
+GoodRunsTool.BlackRunsListVec = [ 'blacklist.xml' ]
+GoodRunsTool.RejectBlackRunsInEventSelector = True  ## False by default
+GoodRunsTool.EventSelectorMode = True
+#GoodRunsTool.OutputLevel = DEBUG
+
+###########################################################################################
+## Add GRL selector tool to pre-eventselector
+###########################################################################################
+
+## Klugde: eventselector currently needs private tool, will become public very soon!
+## Public version is used by eg. LumiBlockMetaDataTool
+## add the (private version of) grl selector tool to the eventselector
+AthenaEventLoopMgr = Service( "AthenaEventLoopMgr" )
+AthenaEventLoopMgr.PreSelectTools += [ GoodRunsTool ]
+#AthenaEventLoopMgr.OutputLevel = WARNING
+
+from AthenaCommon.AppMgr import ServiceMgr
+ServiceMgr += AthenaEventLoopMgr
+
diff --git a/DataQuality/GoodRunsListsUser/share/GoodRunsListsUser_twoSelections.py b/DataQuality/GoodRunsListsUser/share/GoodRunsListsUser_twoSelections.py
new file mode 100644
index 0000000000000000000000000000000000000000..5dd81c7ed41324fef8a0a3098e9f1bfb6961c677
--- /dev/null
+++ b/DataQuality/GoodRunsListsUser/share/GoodRunsListsUser_twoSelections.py
@@ -0,0 +1,54 @@
+## Example trigger joboptions
+#include ("AMAAthena/Trigger_jobOptions.py")
+
+###########################################################################################
+## Configure the goodrunslist selector tool to read and interpret xml files
+###########################################################################################
+
+## Configure the goodrunslist selector tool
+from GoodRunsLists.GoodRunsListsConf import *
+ToolSvc += GoodRunsListSelectorTool() 
+GoodRunsListSelectorTool.GoodRunsListVec  = [ 'grl_topmix_mu.xml', 'grl_topmix_e.xml' ]
+GoodRunsListSelectorTool.BlackRunsListVec = [ 'blacklist.xml' ]
+#GoodRunsListSelectorTool.OutputLevel = DEBUG
+
+## GRL selector, dummy ntuple dumper
+from GoodRunsListsUser.GoodRunsListsUserConf import *
+
+###########################################################################################
+## Start of jobsequence
+###########################################################################################
+
+## This Athena job consists of algorithms that loop over events;
+## here, the (default) top sequence is used:
+from AthenaCommon.AlgSequence import AlgSequence, AthSequencer
+job = AlgSequence()
+
+###########################################################################################
+## GRLTriggerSelectorAlg uses GoodRunsListSelectorTool to determine for 
+##   each event whether to pass it, or to reject it.
+## As good- and black run lists GRLTriggerAlg1 uses: 'grl_topmix_mu' and 'blacklist', 
+##   which are the names of the good run list objects in grl_topmix_mu.xml 
+##   and blacklist.xml respectively. 
+## GRLTriggerAlg2 uses 'grl_topmix_e', coming from grl_topmix_e.xml
+## As the dummy ntupledumper DummyDumperAlg1 runs in sequence ModSequence1, 
+##   after GRLTriggerAlg1, it is not executed in case GRLTriggerAlg1 rejects an event.
+##   Same story for GRLTriggerAlg2 and DummyDumperAlg2, running in ModSequence2
+###########################################################################################
+
+## Selection 1
+job += AthSequencer("ModSequence1")
+job.ModSequence1 += GRLTriggerSelectorAlg('GRLTriggerAlg1')
+job.ModSequence1.GRLTriggerAlg1.GoodRunsListArray  = ['grl_topmix_mu']
+job.ModSequence1.GRLTriggerAlg1.BlackRunsListArray = ['blacklist']
+job.ModSequence1 += DummyDumperAlg('DummyDumperAlg1')
+# job.ModSequence1.DummyDumperAlg1.RootFileName = 'selection1.root'
+THistSvc.Output =  {"new DATAFILE='selection1.root' TYP='ROOT' OPT='NEW'"};
+
+## Selection 2
+job += AthSequencer("ModSequence2")
+job.ModSequence2 += GRLTriggerSelectorAlg('GRLTriggerAlg2')
+job.ModSequence2.GRLTriggerAlg2.GoodRunsListArray  = ['grl_topmix_e']
+job.ModSequence2 += DummyDumperAlg('DummyDumperAlg2')
+# job.ModSequence2.DummyDumperAlg2.RootFileName = 'selection2.root'
+THistSvc.Output =  {"new DATAFILE='selection2.root' TYP='ROOT' OPT='NEW'"};
diff --git a/DataQuality/GoodRunsListsUser/share/LumiBlock_LumiCalc_GRL_dumper.py b/DataQuality/GoodRunsListsUser/share/LumiBlock_LumiCalc_GRL_dumper.py
new file mode 100644
index 0000000000000000000000000000000000000000..9f4827b6cc8b81806cb4e153630da52ce0cd32d1
--- /dev/null
+++ b/DataQuality/GoodRunsListsUser/share/LumiBlock_LumiCalc_GRL_dumper.py
@@ -0,0 +1,43 @@
+# add LumiBlockMetaDataTool to ToolSvc and configure
+from LumiBlockComps.LumiBlockCompsConf import LumiBlockMetaDataTool
+ToolSvc += LumiBlockMetaDataTool( "LumiBlockMetaDataTool" )
+LumiBlockMetaDataTool.calcLumi = True # False by default
+
+# add ToolSvc.LumiBlockMetaDataTool to MetaDataSvc
+from EventSelectorAthenaPool.EventSelectorAthenaPoolConf import MetaDataSvc
+svcMgr += MetaDataSvc( "MetaDataSvc" )
+svcMgr.MetaDataSvc.MetaDataTools += [ ToolSvc.LumiBlockMetaDataTool ]
+
+# Configure the goodrunslist selector tool
+from GoodRunsLists.GoodRunsListsConf import *
+ToolSvc += GoodRunsListSelectorTool() 
+GoodRunsListSelectorTool.GoodRunsListVec = [ 'grl_topmix_mu.xml', 'grl_topmix_e.xml' ]
+GoodRunsListSelectorTool.BlackRunsListVec = [ 'blacklist.xml' ]
+
+## This Athena job consists of algorithms that loop over events;
+## here, the (default) top sequence is used:
+from AthenaCommon.AlgSequence import AlgSequence, AthSequencer
+job = AlgSequence()
+job += AthSequencer("ModSequence1")
+
+## GRL selector, dummy ntuple dumper
+from GoodRunsListsUser.GoodRunsListsUserConf import *
+job.ModSequence1 += GRLTriggerSelectorAlg('GRLTriggerAlg1')
+job.ModSequence1.GRLTriggerAlg1.GoodRunsListArray = ['grl_topmix_mu']
+job.ModSequence1.GRLTriggerAlg1.BlackRunsListArray = ['blacklist']
+job.ModSequence1.GRLTriggerAlg1.TriggerSelectionRegistration = 'EF_mu20'
+
+job.ModSequence1 += DummyDumperAlg('DummyDumperAlg1')
+# job.ModSequence1.DummyDumperAlg1.RootFileName = 'selection1.root'
+THistSvc.Output =  {"new DATAFILE='selection1.root' TYP='ROOT' OPT='NEW'"};
+job.ModSequence1.DummyDumperAlg1.GRLNameVec = [ 'LumiBlocks_GoodDQ0', 'IncompleteLumiBlocks_GoodDQ0' ]
+
+# add LumiCalcSvc to ServiceMgr and configure
+from LumiBlockComps.LumiBlockCompsConf import LumiCalcSvc
+LumiCalcSvc = LumiCalcSvc()
+LumiCalcSvc.Triggers = ["EF_mu20"]
+LumiCalcSvc.UseMC = True
+LumiCalcSvc.LBCollNames = ["LumiBlocks_GoodDQ0", "IncompleteLumiBlocks_GoodDQ0", "LumiBlocks", "IncompleteLumiBlocks"]
+LumiCalcSvc.Verbose = False
+svcMgr += LumiCalcSvc
+
diff --git a/DataQuality/GoodRunsListsUser/share/LumiCalc_twoFinalStates.py b/DataQuality/GoodRunsListsUser/share/LumiCalc_twoFinalStates.py
new file mode 100644
index 0000000000000000000000000000000000000000..9a155f3911ac72afc1212b3e6e877bfac4089dd5
--- /dev/null
+++ b/DataQuality/GoodRunsListsUser/share/LumiCalc_twoFinalStates.py
@@ -0,0 +1,104 @@
+########################################
+# Job to run RecExCommon, schedule
+# LumiBlockMetaDataTool and LumiCalcSvc
+# but don't write out any AOD outputfile
+
+########################################
+
+include ("AMAAthena/Trigger_jobOptions.py")
+
+########################################
+
+# the Input AOD File
+from AthenaCommon.AthenaCommonFlags import athenaCommonFlags
+athenaCommonFlags.PoolAODInput = [ "/afs/cern.ch/user/r/radbal/scratch0/data/TopMix/user.RichardHawkings.0108175.topmix_Muon.AOD.v4._00057.pool.root" ]
+
+# the EvtMax
+if not vars().has_key('EvtMax'): EvtMax = -1
+athenaCommonFlags.EvtMax=EvtMax
+
+# Configure the goodrunslist selector tool
+from GoodRunsLists.GoodRunsListsConf import *
+ToolSvc += TriggerRegistryTool()
+ToolSvc += GoodRunsListSelectorTool() 
+GoodRunsListSelectorTool.GoodRunsListVec = [ 'grl1.xml', 'grl2.xml', 'grl3.xml' ]
+GoodRunsListSelectorTool.BlackRunsListVec = [ 'blacklist1.xml' ]
+#GoodRunsListSelectorTool.OutputLevel = DEBUG
+
+# add LumiBlockMetaDataTool and configure
+from GoodRunsListsUser.GoodRunsListsUserConf import DummyDumperAlg
+from LumiBlockComps.LumiBlockCompsConf import LumiBlockMetaDataTool
+ToolSvc += LumiBlockMetaDataTool( "LumiBlockMetaDataTool" )
+LumiBlockMetaDataTool.calcLumi = True # False by default
+#LumiBlockMetaDataTool.storeXMLFiles = False # default is True
+#LumiBlockMetaDataTool.applyDQCuts = False # default is True
+#LumiBlockMetaDataTool.OutputLevel = DEBUG
+
+# add LumiCalcSvc and configure
+from LumiBlockComps.LumiBlockCompsConf import LumiCalcSvc
+LumiCalcSvc = LumiCalcSvc()
+LumiCalcSvc.UseMC = True
+LumiCalcSvc.LBCollNames = ["LumiBlocks", "IncompleteLumiBlocks"]
+LumiCalcSvc.Triggers = ["EF_mu20"]
+LumiCalcSvc.Verbose = False
+svcMgr += LumiCalcSvc
+
+## This Athena job consists of algorithms that loop over events;
+## here, the (default) top sequence is used:
+from AthenaCommon.AlgSequence import AlgSequence, AthSequencer
+job = AlgSequence()
+job += AthSequencer("ModSequence1")
+job += AthSequencer("ModSequence2")
+
+## GRL selector
+job.ModSequence1 += GRLTriggerSelectorAlg('GRLTriggerAlg1')
+job.ModSequence1.GRLTriggerAlg1.GoodRunsListArray = ['grl1']
+job.ModSequence1.GRLTriggerAlg1.BlackRunsListArray = ['blacklist1']
+job.ModSequence1.GRLTriggerAlg1.TriggerSelection = 'EF_mu20'
+#job.ModSequence1.GRLTriggerAlg1.OutputLevel = DEBUG
+
+job.ModSequence1 += DummyDumperAlg('DummyDumperAlg1')
+# job.ModSequence1.DummyDumperAlg1.RootFileName = 'file1.root'
+THistSvc.Output =  {"new DATAFILE='file1.root' TYP='ROOT' OPT='NEW'"};
+job.ModSequence1.DummyDumperAlg1.GRLNameVec = [ 'LumiBlocks_GoodDQ0', 'IncompleteLumiBlocks_GoodDQ0' ]
+
+## GRL selector
+job.ModSequence2 += GRLTriggerSelectorAlg('GRLTriggerAlg2')
+job.ModSequence2.GRLTriggerAlg2.GoodRunsListArray = ['grl2','grl3']
+job.ModSequence2.GRLTriggerAlg2.TriggerSelection = 'EF_e20_loose_passEF || EF_e20_loose'
+#job.ModSequence2.GRLTriggerAlg2.OutputLevel = DEBUG
+
+job.ModSequence2 += DummyDumperAlg('DummyDumperAlg2')
+# job.ModSequence2.DummyDumperAlg2.RootFileName = 'file2.root'
+THistSvc.Output =  {"new DATAFILE='file2.root' TYP='ROOT' OPT='NEW'"};
+job.ModSequence2.DummyDumperAlg2.GRLNameVec = [ 'LumiBlocks_GoodDQ1', 'IncompleteLumiBlocks_GoodDQ1' ]
+
+# Either use aodtoaod.py as it is
+#include ("RecExCommon/aodtoaod.py")
+
+# Or work directly on RecExCommon_topOptions.py
+# turn OFF most flags for RecExCommon, no output files
+doCBNT=False
+doWriteRDO=False
+doWriteESD=False
+doWriteAOD=False
+doAOD=False
+doWriteTAG=False 
+readAOD=True
+
+# turn ON these 2 flags
+doDPD=True
+doFileMetaData=True
+
+# execute RecExCommon
+include ("RecExCommon/RecExCommon_topOptions.py")
+
+# reduce POOL verbosity
+os.environ['POOL_OUTMSG_LEVEL'] = 'WARNING'
+os.environ['CORAL_MSGLEVEL'] = 'WARNING'
+
+# This is need for PANDA Grid job
+#xfile = open('dummy.txt','w')
+#xfile.write('a')
+#xfile.close()
+
diff --git a/DataQuality/GoodRunsListsUser/src/DummyDumperAlg.cxx b/DataQuality/GoodRunsListsUser/src/DummyDumperAlg.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..aa3b57d31c4a050b43b9a6242e1af9dc04ff353c
--- /dev/null
+++ b/DataQuality/GoodRunsListsUser/src/DummyDumperAlg.cxx
@@ -0,0 +1,147 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+
+#include "GoodRunsListsUser/DummyDumperAlg.h"
+#include "LumiBlockComps/ILumiBlockMetaDataTool.h"
+
+#include "EventInfo/EventInfo.h"
+#include "EventInfo/EventID.h"
+#include "StoreGate/StoreGate.h"
+
+#include "GaudiKernel/ITHistSvc.h"
+
+#include <TList.h>
+#include "TTree.h"
+
+DummyDumperAlg::DummyDumperAlg(const std::string& name, ISvcLocator* pSvcLocator) 
+ : AthAlgorithm(name, pSvcLocator)
+ , m_LumiBlockMetaDataTool("LumiBlockMetaDataTool")
+ , m_storeGate(0)
+ , m_tree(0)
+ , m_eventCounter(0)
+ , m_dummyInt(0)
+{
+  declareProperty( "GRLNameVec", m_grlname );
+}
+
+
+DummyDumperAlg::~DummyDumperAlg()
+{
+  /// For some reason deleting the tree results in a crash.
+  /// Double deletion somewhere?
+  //if (m_tree!=0) { delete m_tree; m_tree=0; }
+}
+
+
+StatusCode DummyDumperAlg::initialize() 
+{
+  ATH_MSG_DEBUG ("initialize()");
+
+  MsgStream log (msgSvc(), name());
+
+  if (service("THistSvc",m_ths).isFailure())
+  {
+    log << MSG::ERROR << "Couldn't get THistSvc" << endmsg;
+    return StatusCode::FAILURE;
+  }
+
+  /// Retrieve the LBMD tool using the ToolHandles
+  if ( m_LumiBlockMetaDataTool.retrieve().isFailure() ) {
+    ATH_MSG_FATAL 
+      (m_LumiBlockMetaDataTool.propertyName() << ": Failed to retrieve tool "
+       << m_LumiBlockMetaDataTool.type());
+    return StatusCode::FAILURE;
+  } else {
+    ATH_MSG_DEBUG
+      (m_LumiBlockMetaDataTool.propertyName() << ": Retrieved tool " 
+       << m_LumiBlockMetaDataTool.type());
+  }
+
+  /// get StoreGateSvc interface
+  if( service("StoreGateSvc", m_storeGate).isFailure() ) {
+    ATH_MSG_ERROR ("Cannot get StoreGateSvc.");
+    return StatusCode::FAILURE;
+  }
+
+  // make tree
+  m_tree = new TTree("tree","tree");
+  if (m_ths->regTree (m_tree->GetName(), m_tree).isFailure())
+  {
+    log << MSG::ERROR << "Couldn't register " << m_tree->GetName() << endmsg;
+    return StatusCode::FAILURE;
+  }
+
+  (void) m_tree->Branch("eventNumber",&m_dummyInt,"eventNumber/I");
+  (void) m_tree->Branch("runNumber",&m_dummyInt,"runNumber/I");
+  (void) m_tree->Branch("lumiBlock",&m_dummyInt,"lumiBlock/I");
+  (void) m_tree->Branch("timeStamp",&m_dummyInt,"timeStamp/I");
+
+  ATH_MSG_DEBUG ("initialize() successful");
+
+  return StatusCode::SUCCESS;
+}
+
+
+StatusCode 
+DummyDumperAlg::execute() 
+{
+  ATH_MSG_DEBUG ("execute()");
+
+  m_eventCounter++;
+
+  // get event number here ...
+  int eventNumber(0);
+  int runNumber(0);
+  int lumiBlock(0);
+  int timeStamp(0);
+
+  // retrieve event info
+  const EventInfo*  p_evt = 0;
+  StatusCode status = m_storeGate->retrieve(p_evt);
+
+  if(status.isSuccess() && p_evt!=0) {
+    eventNumber = p_evt->event_ID()->event_number();
+    runNumber = p_evt->event_ID()->run_number();
+    lumiBlock = p_evt->event_ID()->lumi_block();
+    timeStamp = p_evt->event_ID()->time_stamp();
+    ATH_MSG_DEBUG ("Got run number = " << runNumber << ", event number = " << eventNumber);
+  } else {
+    ATH_MSG_WARNING ("Unable to retrieve EventInfo from StoreGate. Return failure.");
+    return status;
+  }
+
+  // fill the dummy tree
+  m_tree->SetBranchAddress( "eventNumber", &eventNumber ); 
+  m_tree->SetBranchAddress( "runNumber", &runNumber ); 
+  m_tree->SetBranchAddress( "lumiBlock", &lumiBlock ); 
+  m_tree->SetBranchAddress( "timeStamp", &timeStamp ); 
+
+  m_tree->Fill();
+
+  ATH_MSG_DEBUG ("execute() successful");
+
+  return StatusCode::SUCCESS;
+}
+
+
+StatusCode DummyDumperAlg::finalize() 
+{
+  ATH_MSG_DEBUG ("finalize()");
+
+  // add grl strings to tree
+  std::vector<std::string>::const_iterator itr=m_grlname.begin();
+  for (; itr!=m_grlname.end(); ++itr) {
+    const TString grlstring = m_LumiBlockMetaDataTool->getGRLString( *itr );
+    if (grlstring.IsNull()) continue;
+    m_grlobj.push_back( TObjString( grlstring ) );
+    m_tree->GetUserInfo()->Add( &(*m_grlobj.rbegin()) );  
+  }
+
+  ATH_MSG_DEBUG ("finalize() successful");
+
+  return StatusCode::SUCCESS;
+}
+
+
diff --git a/DataQuality/GoodRunsListsUser/src/GRLTriggerSelectorAlg.cxx b/DataQuality/GoodRunsListsUser/src/GRLTriggerSelectorAlg.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..dd21fcacaeb4ec9522feff0d6a402595fc6c35fb
--- /dev/null
+++ b/DataQuality/GoodRunsListsUser/src/GRLTriggerSelectorAlg.cxx
@@ -0,0 +1,203 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+
+#include "GoodRunsListsUser/GRLTriggerSelectorAlg.h"
+#include "GoodRunsLists/IGoodRunsListSelectorTool.h"
+#include "GoodRunsLists/ITriggerRegistryTool.h"
+
+#include "GoodRunsLists/TMsgLogger.h"
+#include "TrigDecisionTool/TrigDecisionTool.h" // rel 15
+#include "TrigDecisionEvent/TrigDecision.h" // rel 15
+#include "TROOT.h"
+
+GRLTriggerSelectorAlg::GRLTriggerSelectorAlg(const std::string& name, ISvcLocator* pSvcLocator) 
+ : AthAlgorithm(name, pSvcLocator)
+ , m_GoodRunsListSelectorTool("GoodRunsListSelectorTool")
+ , m_TriggerRegistryTool("TriggerRegistryTool")
+ , m_gcounter(0)
+ , m_gaccept(0)
+ , m_tcounter(0)
+ , m_taccept(0)
+ , m_trigpar(0)
+ , m_applyTriggerSelection(false)
+{
+  declareProperty( "GoodRunsListArray", m_grlnameVec );
+  declareProperty( "BlackRunsListArray", m_brlnameVec );
+  declareProperty( "TriggerSelection", m_regexpr );
+  declareProperty( "TriggerSelectionRegistration", m_regexprRegistrationOnly );
+  declareProperty( "CounterPrescale", m_prescale = 1000 );
+}
+
+
+GRLTriggerSelectorAlg::~GRLTriggerSelectorAlg()
+{ 
+  // cleanup
+  if (m_trigpar!=0) { delete[] m_trigpar; m_trigpar=0; }
+} 
+
+
+StatusCode GRLTriggerSelectorAlg::initialize() 
+{
+  ATH_MSG_DEBUG ("initialize()");
+
+  Root::TMsgLogger::SetMinLevel(static_cast<Root::TMsgLevel>(outputLevel()));
+
+  /// construct registration name
+  {
+    std::ostringstream tmp;
+    tmp << "Sequence" << m_GoodRunsListSelectorTool->getGRLSelectorRegistry().size();
+    m_myname = tmp.str();
+  };
+
+  /////////////////////////////////////
+
+  /// Retrieve the GoodRunsListSelector tool using the ToolHandles
+  if ( m_GoodRunsListSelectorTool.retrieve().isFailure() ) {
+    ATH_MSG_FATAL 
+      (m_GoodRunsListSelectorTool.propertyName() << ": Failed to retrieve tool "
+       << m_GoodRunsListSelectorTool.type());
+    return StatusCode::FAILURE;
+  } else {
+    ATH_MSG_DEBUG
+      (m_GoodRunsListSelectorTool.propertyName() << ": Retrieved tool " 
+       << m_GoodRunsListSelectorTool.type());
+  }
+
+  /// register the GRL selector for later use in lumiblockmetadata tool. 
+  ATH_MSG_INFO ("initialize() :: Now registering this GRL Selector with unique name <" << m_myname << ">.");
+  bool regOk = m_GoodRunsListSelectorTool->registerGRLSelector(m_myname,m_grlnameVec,m_brlnameVec);
+  if (!regOk) {
+    ATH_MSG_ERROR ("initialize() :: Failure to register this GRL Selector with name <" << m_myname << ">. Return failure.");
+    return StatusCode::FAILURE;
+  }
+
+  /////////////////////////////////////
+
+  /// determine correct trigger selection expression
+  if (!m_regexprRegistrationOnly.empty() && m_regexpr.empty()) {
+    m_regexpr = m_regexprRegistrationOnly;
+    m_applyTriggerSelection = false;
+  } else if (m_regexprRegistrationOnly.empty() && !m_regexpr.empty()) {
+    m_applyTriggerSelection = true;
+  } else if (!m_regexprRegistrationOnly.empty() && !m_regexpr.empty()) {
+    ATH_MSG_WARNING ("initialize() :: Both TriggerSelectionRegistration and TriggerSelection are set. Ignoring TriggerSelectionRegistration.");
+    m_regexprRegistrationOnly = "";
+    m_applyTriggerSelection = true;
+  } else { // default in case nothing is set, pass through mode
+    m_regexpr = "1";
+    m_applyTriggerSelection = false;
+  }
+
+  if (!m_applyTriggerSelection)
+    ATH_MSG_INFO ("initialize() :: Trigger selection set to pass-through mode.");
+
+  /// Retrieve the TriggerRegistry tool using the ToolHandles
+  if ( m_TriggerRegistryTool.retrieve().isFailure() ) {
+    ATH_MSG_FATAL
+      (m_TriggerRegistryTool.propertyName() << ": Failed to retrieve tool "
+       << m_TriggerRegistryTool.type());
+    return StatusCode::FAILURE;
+  } else {
+    ATH_MSG_DEBUG
+      (m_TriggerRegistryTool.propertyName() << ": Retrieved tool " 
+       << m_TriggerRegistryTool.type());
+  }
+
+  int formOk = m_formula.setFormula(m_regexpr.c_str()) ;
+
+  if ( 0!=formOk ) {
+    ATH_MSG_ERROR ("Cannot parse regular expression : " << m_regexpr << " . Return Failure.");
+    return StatusCode::FAILURE;
+  }
+
+  // get trigger names from formula 
+  m_par = m_formula.getParNames();
+  m_trigpar = new double[m_formula.getNPars()];
+
+  /// register the trigger selector for later use in lumicalcsvc. 
+  ATH_MSG_INFO ("initialize() :: Now registering this Trigger Selector with unique name <" << m_myname << ">.");
+  regOk = m_TriggerRegistryTool->registerTriggerSelector(m_myname,m_regexpr,m_par);
+  if (!regOk) {
+    ATH_MSG_ERROR ("initialize() :: Failure to register this Trigger Selector with name <" << m_myname << ">. Return failure.");
+    return StatusCode::FAILURE;
+  }
+
+  /////////////////////////////////////
+
+  ATH_MSG_DEBUG ("initialize() successful");
+
+  return StatusCode::SUCCESS;
+}
+
+
+StatusCode 
+GRLTriggerSelectorAlg::execute() 
+{
+  ATH_MSG_DEBUG ("execute()");
+
+  /////////////////////////////////////
+
+  if (m_gcounter % m_prescale == 0) 
+    ATH_MSG_INFO ("Now processing event passing GRL selection : " << m_gcounter);
+  m_gcounter++ ;
+
+  bool statusOk = m_GoodRunsListSelectorTool->passThisRunLB(m_grlnameVec,m_brlnameVec);
+  this->setFilterPassed (statusOk); // This skips the execution of following algs for this event
+  if (statusOk) ++m_gaccept;
+  else { return StatusCode::SUCCESS; }
+
+  /////////////////////////////////////
+
+  if (m_applyTriggerSelection) { 
+    if( m_tdTool.retrieve().isFailure()) {
+      ATH_MSG_ERROR ("Could not retrieve TrigDecisionTool. Return Failure.");
+      return StatusCode::FAILURE;
+    } else {
+      ATH_MSG_DEBUG ("Successfully retrieved TrigDecisionTool.");
+    }
+  }
+
+  if (m_tcounter % m_prescale == 0)
+    ATH_MSG_INFO ("Now processing event passing Trigger selection : " << m_tcounter);
+  m_tcounter++ ;
+
+  // Filling trigger map
+  std::list<TString>::iterator tnItr = m_par.begin() ;
+  for (unsigned int i=0; tnItr!=m_par.end(); ++tnItr, ++i) {
+    bool isPassed(true);
+    if (m_applyTriggerSelection) { isPassed = m_tdTool->isPassed(tnItr->Data()); }
+    m_trigpar[i] = static_cast<double>(isPassed);
+    ATH_MSG_DEBUG ("Trigger name : " << *tnItr << " = " << m_trigpar[i]);
+  }
+
+  // evaluate trigger regular expression
+  double dummy(0);
+  bool pass(true);
+  if (m_applyTriggerSelection) pass = static_cast<bool>(m_formula.EvalPar(&dummy,m_trigpar));
+  this->setFilterPassed (pass);  // skip execution of following algs for this event
+  if (pass) ++m_taccept;
+
+  /////////////////////////////////////
+
+  ATH_MSG_DEBUG ("Event accepted? " << pass);
+
+  ATH_MSG_DEBUG ("execute() successful");
+
+  return StatusCode::SUCCESS;
+}
+
+
+StatusCode GRLTriggerSelectorAlg::finalize() 
+{
+  ATH_MSG_DEBUG ("finalize()");
+
+  ATH_MSG_INFO ("GRL     : Processed " << m_gcounter << " events, accepted " << m_gaccept << " events.");
+  ATH_MSG_INFO ("Trigger : Processed " << m_tcounter << " events, accepted " << m_taccept << " events.");
+
+  ATH_MSG_DEBUG ("finalize() successful");
+
+  return StatusCode::SUCCESS;
+}
+
diff --git a/DataQuality/GoodRunsListsUser/src/GoodRunsListSelectorAlg.cxx b/DataQuality/GoodRunsListsUser/src/GoodRunsListSelectorAlg.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..1ed378b53ec8b84df1d87bc52478dbc1410f573a
--- /dev/null
+++ b/DataQuality/GoodRunsListsUser/src/GoodRunsListSelectorAlg.cxx
@@ -0,0 +1,97 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+
+#include "GoodRunsListsUser/GoodRunsListSelectorAlg.h"
+#include "GoodRunsLists/IGoodRunsListSelectorTool.h"
+#include "GoodRunsLists/TMsgLogger.h"
+#include "TROOT.h"
+
+GoodRunsListSelectorAlg::GoodRunsListSelectorAlg(const std::string& name, ISvcLocator* pSvcLocator) 
+ : AthAlgorithm(name, pSvcLocator)
+ , m_GoodRunsListSelectorTool("GoodRunsListSelectorTool")
+ , m_counter(0)
+ , m_accept(0)
+{
+  declareProperty( "GoodRunsListArray", m_grlnameVec );
+  declareProperty( "BlackRunsListArray", m_brlnameVec );
+  declareProperty( "CounterPrescale", m_prescale = 1000);
+}
+
+
+GoodRunsListSelectorAlg::~GoodRunsListSelectorAlg()
+{ 
+} 
+
+
+StatusCode GoodRunsListSelectorAlg::initialize() 
+{
+  ATH_MSG_DEBUG ("initialize()");
+
+  Root::TMsgLogger::SetMinLevel(static_cast<Root::TMsgLevel>(outputLevel()));
+
+  /// Retrieve the GoodRunsListSelector tool using the ToolHandles
+  if ( m_GoodRunsListSelectorTool.retrieve().isFailure() ) {
+    ATH_MSG_FATAL 
+      (m_GoodRunsListSelectorTool.propertyName() << ": Failed to retrieve tool "
+       << m_GoodRunsListSelectorTool.type());
+    return StatusCode::FAILURE;
+  } else {
+    ATH_MSG_DEBUG
+      (m_GoodRunsListSelectorTool.propertyName() << ": Retrieved tool " 
+       << m_GoodRunsListSelectorTool.type());
+  }
+
+  /// construct registration name
+  {
+    std::ostringstream tmp;
+    tmp << "Sequence" << m_GoodRunsListSelectorTool->getGRLSelectorRegistry().size();
+    m_myname = tmp.str();
+  };
+
+  /// register the GRL selector for later use in lumiblockmetadata tool. 
+  ATH_MSG_INFO ("initialize() :: Now registering this GRL Selector with unique name <" << m_myname << ">.");
+  bool regOk = m_GoodRunsListSelectorTool->registerGRLSelector(m_myname,m_grlnameVec,m_brlnameVec);
+  if (!regOk) {
+    ATH_MSG_ERROR ("initialize() :: Failure to register this GRL Selector with name <" << m_myname << ">. Return failure.");
+    return StatusCode::FAILURE;
+  }
+
+  ATH_MSG_DEBUG ("initialize() successful");
+
+  return StatusCode::SUCCESS;
+}
+
+
+StatusCode 
+GoodRunsListSelectorAlg::execute() 
+{
+  ATH_MSG_DEBUG ("execute()");
+
+  if (m_counter % m_prescale == 0) 
+    ATH_MSG_INFO ("Now processing event : " << m_counter);
+  m_counter++ ;
+
+  bool statusOk = m_GoodRunsListSelectorTool->passThisRunLB(m_grlnameVec,m_brlnameVec);
+  this->setFilterPassed (statusOk); // This skips the execution of following algs for this event
+  if (statusOk) ++m_accept;
+
+  ATH_MSG_DEBUG ("execute() successful");
+
+  return StatusCode::SUCCESS;
+}
+
+
+StatusCode GoodRunsListSelectorAlg::finalize() 
+{
+  ATH_MSG_DEBUG ("finalize()");
+
+  ATH_MSG_INFO ("Processed " << m_counter << " events, accepted " << m_accept << " events.");
+
+  ATH_MSG_DEBUG ("finalize() successful");
+
+  return StatusCode::SUCCESS;
+}
+
+
diff --git a/DataQuality/GoodRunsListsUser/src/TriggerSelectorAlg.cxx b/DataQuality/GoodRunsListsUser/src/TriggerSelectorAlg.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..248f384b46824a22e391e28dcf4da73a4e6e9013
--- /dev/null
+++ b/DataQuality/GoodRunsListsUser/src/TriggerSelectorAlg.cxx
@@ -0,0 +1,157 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+
+#include "GoodRunsListsUser/TriggerSelectorAlg.h"
+#include "GoodRunsLists/ITriggerRegistryTool.h"
+#include "GoodRunsLists/TMsgLogger.h"
+
+#include "TrigDecisionTool/TrigDecisionTool.h" // rel 15
+#include "TrigDecisionEvent/TrigDecision.h" // rel 15
+
+#include "TROOT.h"
+
+TriggerSelectorAlg::TriggerSelectorAlg(const std::string& name, ISvcLocator* pSvcLocator) 
+ : AthAlgorithm(name, pSvcLocator)
+ , m_TriggerRegistryTool("TriggerRegistryTool")
+ , m_trigpar(0)
+ , m_counter(0)
+ , m_accept(0)
+ , m_applyTriggerSelection(false)
+{
+  declareProperty( "TriggerSelection", m_regexpr );
+  declareProperty( "TriggerSelectionRegistration", m_regexprRegistrationOnly );
+  declareProperty( "CounterPrescale", m_prescale = 1000 );
+}
+
+
+TriggerSelectorAlg::~TriggerSelectorAlg()
+{
+  // cleanup
+  if (m_trigpar!=0) { delete[] m_trigpar; m_trigpar=0; }
+}
+
+
+StatusCode TriggerSelectorAlg::initialize() 
+{
+  ATH_MSG_DEBUG ("initialize()");
+
+  Root::TMsgLogger::SetMinLevel(static_cast<Root::TMsgLevel>(outputLevel()));
+
+  /// determine correct trigger selection expression
+  if (!m_regexprRegistrationOnly.empty() && m_regexpr.empty()) {
+    m_regexpr = m_regexprRegistrationOnly;
+    m_applyTriggerSelection = false;
+  } else if (m_regexprRegistrationOnly.empty() && !m_regexpr.empty()) {
+    m_applyTriggerSelection = true;
+  } else if (!m_regexprRegistrationOnly.empty() && !m_regexpr.empty()) {
+    ATH_MSG_WARNING ("initialize() :: Both TriggerSelectionRegistration and TriggerSelection are set. Ignoring TriggerSelectionRegistration.");
+    m_regexprRegistrationOnly = "";
+    m_applyTriggerSelection = true;
+  } else { // default in case nothing is set, pass through mode
+    m_regexpr = "1";
+    m_applyTriggerSelection = false;
+  }
+
+  if (!m_applyTriggerSelection)
+    ATH_MSG_INFO ("initialize() :: Trigger selection set to pass-through mode.");
+
+  /// Retrieve the TriggerRegistry tool using the ToolHandles
+  if ( m_TriggerRegistryTool.retrieve().isFailure() ) {
+    ATH_MSG_FATAL 
+      (m_TriggerRegistryTool.propertyName() << ": Failed to retrieve tool "
+       << m_TriggerRegistryTool.type());
+    return StatusCode::FAILURE;
+  } else {
+    ATH_MSG_DEBUG
+      (m_TriggerRegistryTool.propertyName() << ": Retrieved tool " 
+       << m_TriggerRegistryTool.type());
+  }
+
+  int formOk = m_formula.setFormula(m_regexpr.c_str()) ;
+
+  if ( 0!=formOk ) {
+    ATH_MSG_ERROR ("Cannot parse regular expression : " << m_regexpr << " . Return Failure.");
+    return StatusCode::FAILURE;
+  }
+
+  // get trigger names from formula 
+  m_par = m_formula.getParNames();
+  m_trigpar = new double[m_formula.getNPars()];
+
+  /// construct registration name
+  {
+    std::ostringstream tmp;
+    tmp << "Sequence" << m_TriggerRegistryTool->getTriggerSelectorRegistry().size();
+    m_myname = tmp.str();
+  };
+
+  /// register the trigger selector for later use in lumicalcsvc. 
+  ATH_MSG_INFO ("initialize() :: Now registering this Trigger Selector with unique name <" << m_myname << ">.");
+  bool regOk = m_TriggerRegistryTool->registerTriggerSelector(m_myname,m_regexpr,m_par);
+  if (!regOk) {
+    ATH_MSG_ERROR ("initialize() :: Failure to register this Trigger Selector with name <" << m_myname << ">. Return failure.");
+    return StatusCode::FAILURE;
+  }
+
+  ATH_MSG_DEBUG ("initialize() successful");
+
+  return StatusCode::SUCCESS;
+}
+
+
+StatusCode 
+TriggerSelectorAlg::execute() 
+{
+  ATH_MSG_DEBUG ("execute()");
+
+  if (m_applyTriggerSelection) {
+    if( m_tdTool.retrieve().isFailure()) {
+      ATH_MSG_ERROR ("Could not retrieve TrigDecisionTool. Return Failure.");
+      return StatusCode::FAILURE;
+    } else {
+      ATH_MSG_DEBUG ("Successfully retrieved TrigDecisionTool.");
+    }
+  }
+
+  if (m_counter % m_prescale == 0)
+    ATH_MSG_INFO ("Now processing event : " << m_counter);
+  m_counter++ ;
+
+  // Filling trigger map
+  std::list<TString>::iterator tnItr = m_par.begin() ;
+  for (unsigned int i=0; tnItr!=m_par.end(); ++tnItr, ++i) {
+    bool isPassed(true);
+    if (m_applyTriggerSelection) isPassed = m_tdTool->isPassed(tnItr->Data());
+    m_trigpar[i] = static_cast<double>(isPassed);
+    ATH_MSG_DEBUG ("Trigger name : " << *tnItr << " = " << m_trigpar[i]);
+  }
+
+  // evaluate trigger regular expression
+  double dummy(0);
+  bool pass(true);
+  if (m_applyTriggerSelection) pass = static_cast<bool>(m_formula.EvalPar(&dummy,m_trigpar));
+  this->setFilterPassed (pass);  // skip execution of following algs for this event
+  if (pass) ++m_accept;
+
+  ATH_MSG_DEBUG ("Event accepted? " << pass);
+
+  ATH_MSG_DEBUG ("execute() successful");
+
+  return StatusCode::SUCCESS;
+}
+
+
+StatusCode TriggerSelectorAlg::finalize() 
+{
+  ATH_MSG_DEBUG ("finalize()");
+
+  ATH_MSG_INFO ("Processed " << m_counter << " events, accepted " << m_accept << " events.");
+
+  ATH_MSG_DEBUG ("finalize() successful");
+
+  return StatusCode::SUCCESS;
+}
+
+
diff --git a/DataQuality/GoodRunsListsUser/src/components/GoodRunsListsUser_entries.cxx b/DataQuality/GoodRunsListsUser/src/components/GoodRunsListsUser_entries.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..4eae3c17e5b6bd2c7a15538fe950c23a19af5b8a
--- /dev/null
+++ b/DataQuality/GoodRunsListsUser/src/components/GoodRunsListsUser_entries.cxx
@@ -0,0 +1,18 @@
+#include "GoodRunsListsUser/DummyDumperAlg.h"
+#include "GoodRunsListsUser/TriggerSelectorAlg.h"
+#include "GoodRunsListsUser/GoodRunsListSelectorAlg.h"
+#include "GoodRunsListsUser/GRLTriggerSelectorAlg.h"
+#include "GaudiKernel/DeclareFactoryEntries.h"
+
+DECLARE_ALGORITHM_FACTORY( DummyDumperAlg )
+DECLARE_ALGORITHM_FACTORY( TriggerSelectorAlg )
+DECLARE_ALGORITHM_FACTORY( GoodRunsListSelectorAlg )
+DECLARE_ALGORITHM_FACTORY( GRLTriggerSelectorAlg )
+
+DECLARE_FACTORY_ENTRIES( GoodRunsListsUser ) {
+    DECLARE_ALGORITHM( DummyDumperAlg )
+    DECLARE_ALGORITHM( TriggerSelectorAlg )
+    DECLARE_ALGORITHM( GoodRunsListSelectorAlg )
+    DECLARE_ALGORITHM( GRLTriggerSelectorAlg )
+}
+
diff --git a/DataQuality/GoodRunsListsUser/src/components/GoodRunsListsUser_load.cxx b/DataQuality/GoodRunsListsUser/src/components/GoodRunsListsUser_load.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..9b9d393fcfae209be299e45b3901f1771efc3499
--- /dev/null
+++ b/DataQuality/GoodRunsListsUser/src/components/GoodRunsListsUser_load.cxx
@@ -0,0 +1,4 @@
+#include "GaudiKernel/LoadFactoryEntries.h"
+
+LOAD_FACTORY_ENTRIES(GoodRunsListsUser)
+