From a57afe9e6a545087bcc21122e0e51dff0f448373 Mon Sep 17 00:00:00 2001
From: Markus Frank <Markus.Frank@cern.ch>
Date: Mon, 5 Dec 2016 22:07:31 +0100
Subject: [PATCH] First version of conditions and alignments

---
 DDCond/include/DDCond/ConditionsDataLoader.h  |  10 +-
 DDCond/include/DDCond/ConditionsSlice.h       |  28 ++-
 DDCond/src/ConditionsSlice.cpp                |  26 +-
 DDCond/src/plugins/ConditionsMultiLoader.cpp  |   5 +-
 DDCond/src/plugins/ConditionsPlugins.cpp      |   5 +
 DDCond/src/plugins/ConditionsUserPool.cpp     |  97 ++++----
 DDCond/src/plugins/ConditionsXmlLoader.cpp    |   5 +-
 DDCore/include/DD4hep/AlignedVolumePrinter.h  |   3 +
 DDCore/include/DD4hep/AlignmentsPrinter.h     |  11 +-
 DDCore/include/DD4hep/ConditionsPrinter.h     |   4 +
 DDCore/include/DD4hep/Printout.h              |   3 +
 DDCore/src/AlignedVolumePrinter.cpp           |  10 +-
 DDCore/src/AlignmentsPrinter.cpp              | 118 ++++-----
 DDCore/src/ConditionsPrinter.cpp              |  18 +-
 DDCore/src/Primitives.cpp                     | 184 +++++++-------
 DDCore/src/Printout.cpp                       |   7 +-
 DDDB/include/DDDB/DDDBConditionPrinter.h      |  49 ++--
 DDDB/include/DDDB/DDDBConditionsLoader.h      |   5 +-
 DDDB/src/CondDB2DDDB.cpp                      |   3 +-
 DDDB/src/DDDBAlignmentTest.cpp                | 107 +++++++--
 DDDB/src/DDDBAlignmentUpdateCall.cpp          |   2 +-
 DDDB/src/DDDBConditionPrinter.cpp             |  71 ++++--
 DDDB/src/DDDBConditionsLoader.cpp             | 101 +++++---
 DDDB/src/DDDBDerivedCondTest.cpp              | 173 ++++++++++----
 DDDB/src/DDDBPlugins.cpp                      | 226 +++++++++++-------
 DDG4/src/Geant4Random.cpp                     |   6 +-
 examples/AlignDet/CMakeLists.txt              |  28 ++-
 .../AlignDet/src/AlignmentExampleObjects.cpp  |   2 +-
 .../src/AlignmentExample_read_xml.cpp         |  21 +-
 .../AlignDet/src/AlignmentExample_stress.cpp  |   4 +-
 examples/Conditions/CMakeLists.txt            |  44 +++-
 .../src/ConditionExample_populate.cpp         |  14 +-
 .../src/ConditionExample_stress.cpp           |   4 +-
 .../src/ConditionExample_stress2.cpp          |   4 +-
 examples/DDDB/CMakeLists.txt                  |  48 ++--
 examples/DDDB/scripts/run_dddb.sh             |  19 +-
 36 files changed, 934 insertions(+), 531 deletions(-)

diff --git a/DDCond/include/DDCond/ConditionsDataLoader.h b/DDCond/include/DDCond/ConditionsDataLoader.h
index 3a2dd8b2d..b8c76aa0a 100644
--- a/DDCond/include/DDCond/ConditionsDataLoader.h
+++ b/DDCond/include/DDCond/ConditionsDataLoader.h
@@ -50,8 +50,9 @@ namespace DD4hep {
       typedef Condition::iov_type         iov_type;
       typedef Condition::key_type         key_type;
 
-      typedef std::vector<std::pair<key_type,ConditionsSlice::Entry*> > EntryVector;
-      
+      typedef std::map<key_type,Condition>                              LoadedItems;
+      typedef std::vector<std::pair<key_type,ConditionsSlice::Entry*> > RequiredItems;
+
     protected:
       /// Reference to main detector description object
       LCDD&             m_lcdd;
@@ -82,9 +83,8 @@ namespace DD4hep {
                                  const iov_type&  req_validity,
                                  RangeConditions& conditions) = 0;
       virtual size_t load_many(  const iov_type&  req_validity,
-                                 EntryVector&     work,
-                                 EntryVector&     loaded,
-                                 EntryVector&     missing,
+                                 RequiredItems&   work,
+                                 LoadedItems&     loaded,
                                  iov_type&        combined_validity) = 0;
     };
   }        /* End namespace Conditions         */
diff --git a/DDCond/include/DDCond/ConditionsSlice.h b/DDCond/include/DDCond/ConditionsSlice.h
index 0093d775b..ec7a88536 100644
--- a/DDCond/include/DDCond/ConditionsSlice.h
+++ b/DDCond/include/DDCond/ConditionsSlice.h
@@ -52,6 +52,7 @@ namespace DD4hep {
      */
     class ConditionsSlice  {
     public:
+
       /// Base class for data loading information.
       /**
        *   Must be specialized to fit the needs of the concrete ConditionsDataLoader object.
@@ -63,7 +64,32 @@ namespace DD4hep {
       struct Info {
         /// Default destructor. 
         virtual ~Info();
+        virtual const std::type_info& type() const = 0;
+        virtual const void*           ptr()  const = 0;
+        template<typename T> T*       data() const {  return (T*)ptr(); }
       };
+
+      /// Concrete class for data loading information.
+      /**
+       *   \author  M.Frank
+       *   \version 1.0
+       *   \date    31/03/2016
+       */
+      template <typename T> struct LoadInfo : public Info {
+        T info;
+        LoadInfo()           = default;
+        LoadInfo(const T& i) : info(i) {}
+        virtual ~LoadInfo()  = default;
+        LoadInfo& operator=(const LoadInfo& copy) {
+          if ( &copy != this ) info = copy.info;
+          return *this;
+        }
+        virtual const std::type_info& type() const { return typeid(T); }
+        virtual const void*           ptr() const  { return &info;     }
+      };
+      template <typename T> static LoadInfo<T> loadInfo(const T& t)
+      { return LoadInfo<T>(t);                                         }
+      
       /// Slice entry class. Describes all information to load a condition.
       /**
        *   \author  M.Frank
@@ -80,7 +106,6 @@ namespace DD4hep {
       protected:
       public:
         ConditionKey          key;
-        Condition             condition;
         ConditionDependency*  dependency = 0;
         Condition::mask_type  mask       = 0;
         Info*                 loadinfo   = 0;
@@ -118,6 +143,7 @@ namespace DD4hep {
           : Entry(k, this), T(d)       { }
         virtual ~ConditionsLoaderEntry() = default;
         virtual Entry* clone()   { return new ConditionsLoaderEntry(*this); }
+        virtual const void* data() const {  return (T*)this;  }
       };
       
       typedef Condition::key_type                key_type;
diff --git a/DDCond/src/ConditionsSlice.cpp b/DDCond/src/ConditionsSlice.cpp
index 5b1bfc8cb..6782f902c 100644
--- a/DDCond/src/ConditionsSlice.cpp
+++ b/DDCond/src/ConditionsSlice.cpp
@@ -24,14 +24,14 @@ ConditionsSlice::Info::~Info()  {
 
 /// Copy constructor (special!)
 ConditionsSlice::Entry::Entry(const Entry& copy, Info* l)
-  : key(copy.key), condition(0), loadinfo(l)
+  : key(copy.key), loadinfo(l)
 {
   if ( copy.dependency ) dependency = copy.dependency->addRef();
 }
 
 /// Initializing constructor
 ConditionsSlice::Entry::Entry(const ConditionKey& k, Info* l)
-  : key(k), condition(0), loadinfo(l)
+  : key(k), loadinfo(l)
 {
 }
 
@@ -78,8 +78,8 @@ void ConditionsSlice::clear()   {
 
 /// Clear the conditions access and the user pool.
 void ConditionsSlice::reset()   {
-  for(const auto& e : m_conditions ) e.second->condition = 0;
-  for(const auto& e : m_derived ) e.second->condition = 0;
+  //for(const auto& e : m_conditions ) e.second->condition = 0;
+  //for(const auto& e : m_derived ) e.second->condition = 0;
   if ( pool().get() ) pool()->clear();
   m_iov.reset();
 }
@@ -121,18 +121,24 @@ bool ConditionsSlice::insert_condition(Entry* entry)   {
 namespace  {
   
   struct SliceOper  : public ConditionsSelect  {
-    struct LoadInfo : public ConditionsSlice::Info {
-      std::string info;
-      LoadInfo(const std::string& i) : info(i) {}
-      virtual ~LoadInfo() {}
-    };
     ConditionsSlice* slice;
     SliceOper(ConditionsSlice* s) : slice(s) {}
     void operator()(const ConditionsIOVPool::Elements::value_type& v)    {
       v.second->select_all(*this);
     }
     bool operator()(Condition::Object* c)  const  {
-      slice->insert(ConditionKey(c->name,c->hash),LoadInfo(c->name));
+      if ( 0 == (c->flags&Condition::DERIVED) )   {
+        slice->insert(ConditionKey(c->name,c->hash),ConditionsSlice::loadInfo(c->address));
+        return true;
+      }
+      //DD4hep::printout(DD4hep::INFO,"Slice","++ Ignore dependent condition: %s",c->name.c_str());
+#if 0
+      const ConditionsSlice::ConditionsProxy& cc=slice->conditions();
+      auto i = cc.find(c->hash);
+      const ConditionsSlice::LoadInfo<std::string>* info =
+        (const ConditionsSlice::LoadInfo<std::string>*)(*i).second->loadinfo;
+      std::string* address = info->data<std::string>();
+#endif      
       return true;
     }
     /// Return number of conditions selected
diff --git a/DDCond/src/plugins/ConditionsMultiLoader.cpp b/DDCond/src/plugins/ConditionsMultiLoader.cpp
index 76dd9ce0b..48fc55081 100644
--- a/DDCond/src/plugins/ConditionsMultiLoader.cpp
+++ b/DDCond/src/plugins/ConditionsMultiLoader.cpp
@@ -57,9 +57,8 @@ namespace DD4hep {
                                  RangeConditions& conditions);
       /// Optimized update using conditions slice data
       virtual size_t load_many(  const iov_type& /* req_validity */,
-                                 EntryVector&    /* work         */,
-                                 EntryVector&    /* loaded       */,
-                                 EntryVector&    /* missing      */,
+                                 RequiredItems&  /* work         */,
+                                 LoadedItems&    /* loaded       */,
                                  iov_type&       /* conditions_validity */)
       {
         except("ConditionsLoader","+++ update: Invalid call!");
diff --git a/DDCond/src/plugins/ConditionsPlugins.cpp b/DDCond/src/plugins/ConditionsPlugins.cpp
index 102deb1c6..2e1c787f0 100644
--- a/DDCond/src/plugins/ConditionsPlugins.cpp
+++ b/DDCond/src/plugins/ConditionsPlugins.cpp
@@ -393,6 +393,7 @@ DECLARE_APPLY(DD4hep_ConditionsClean,ddcond_clean_conditions)
 template <typename PRINTER>
 static void* create_printer(Geometry::LCDD& lcdd, int argc,char** argv)  {
   typedef typename PRINTER::pool_type pool_t;
+  PrintLevel print_level = INFO;
   string prefix = "", name = "";
   int    flags = 0, have_pool = 0, arg_error = false;
   for(int i=0; i<argc && argv[i]; ++i)  {
@@ -404,6 +405,8 @@ static void* create_printer(Geometry::LCDD& lcdd, int argc,char** argv)  {
       flags = ::atol(argv[++i]);
     else if ( 0 == ::strncmp("-pool",argv[i],5) )
       have_pool = 1;
+    else if ( 0 == ::strncmp("-print",argv[i],5) )
+      print_level = DD4hep::printLevel(argv[++i]);
     else
       arg_error = true;
   }
@@ -418,12 +421,14 @@ static void* create_printer(Geometry::LCDD& lcdd, int argc,char** argv)  {
       "     -flags  <number>         Printout processing flags.                      \n"
       "     -pool                    Attach conditions user pool from                \n"
       "                              PluginTester instance attached to LCDD.       \n\n"
+      "     -print                   Printout level for the printer object.          \n"
       "\tArguments given: " << arguments(argc,argv) << endl << flush;
     ::exit(EINVAL);
   }
   DetElement world = lcdd.world();
   printout(INFO,"Printer","World=%s [%p]",world.path().c_str(),world.ptr());
   PRINTER* p = (flags) ? new PRINTER(prefix,flags) : new PRINTER(prefix);
+  p->printLevel = print_level;
   if ( have_pool != 0 )  {
     PluginTester* test = lcdd.extension<PluginTester>();
     pool_t* pool = test->extension<pool_t>("ConditionsTestUserPool");
diff --git a/DDCond/src/plugins/ConditionsUserPool.cpp b/DDCond/src/plugins/ConditionsUserPool.cpp
index 3d05bc650..296c77509 100644
--- a/DDCond/src/plugins/ConditionsUserPool.cpp
+++ b/DDCond/src/plugins/ConditionsUserPool.cpp
@@ -139,18 +139,6 @@ namespace {
   template <typename T> MapSelector<T> mapSelector(T& container)
   {  return MapSelector<T>(container);   }
 
-  template <typename T> struct MapInserter {
-    T& m;
-    MapInserter(T& o) : m(o) {}
-    void operator()(Condition& c)  {
-      Condition::Object* o = c.ptr();
-      m.insert(make_pair(o->hash,o));
-    }
-    void operator()(ConditionsSlice::Entry* e)  { (*this)(e->condition);  }
-  };
-  template <typename T> MapInserter<T> mapInsert(T& container)
-  {  return MapInserter<T>(container);   }
-
   template <typename T> struct Inserter {
     T& m;
     IOV* iov;
@@ -160,21 +148,7 @@ namespace {
       m.insert(make_pair(o->hash,o));
       if ( iov ) iov->iov_intersection(o->iov->key());
     }
-    void operator()(ConditionsSlice::Entry* e)  { (*this)(e->condition);  }
-    void operator()(const pair<Condition::key_type,ConditionsSlice::Entry*>& e)
-    { (*this)(e.second->condition);  }
-  };
-  template <typename T> struct Updater {
-    T& m;
-    IOV* iov;
-    Updater(T& o, IOV* i=0) : m(o), iov(i) {}
-    void operator()(Condition& c)  {
-      Condition::Object* o = c.ptr();
-      typename T::iterator i=m.find(o->hash);
-      (*i).second = o;
-      if ( iov ) iov->iov_intersection(o->iov->key());
-    }
-    void operator()(ConditionsSlice::Entry* e)  { (*this)(e->condition);  }
+    void operator()(const pair<Condition::key_type,Condition>& e) { (*this)(e.second);  }
   };
 }
 
@@ -336,10 +310,18 @@ size_t ConditionsMappedUserPool<MAPPING>::compute(const Dependencies& deps,
 
 typedef ConditionsSlice::Entry SliceEntry;
 namespace {
-  bool _compare(const pair<Condition::key_type,void*>& a,const pair<Condition::key_type,void*>& b)
-  { return a.first < b.first; }
+  struct COMP {
+    typedef pair<Condition::key_type,SliceEntry*> Slice;
+    typedef pair<Condition::key_type,Condition>   Cond;
+    bool operator()(const Slice& a,const Cond& b) const
+    { return a.first < b.first; }
+    bool operator()(const Cond& a,const Slice& b) const
+    { return a.first < b.first; }
+  };
+  //bool _compare(const pair<const Condition::key_type,void*>& a,const pair<const Condition::key_type,void*>& b)
+  //{ return a.first < b.first; }
   pair<Condition::key_type,ConditionDependency*> _to_dep(pair<Condition::key_type,SliceEntry*>& e)
-  { return make_pair(e.first,e.second->dependency); }
+  { return make_pair(e.second->key.hash,e.second->dependency); }
 }
 
 template<typename MAPPING> UserPool::Result
@@ -347,54 +329,67 @@ ConditionsMappedUserPool<MAPPING>::prepare_VSN_1(const IOV&              require
                                                  ConditionsSlice&        slice,
                                                  void*                   user_param)
 {
-  typedef vector<pair<key_type,SliceEntry*> > _Missing;
-  Result result;
-  IOV pool_iov(required.iovType);
-  size_t len = m_conditions.size();
+  //typedef std::set<pair<Condition::key_type,SliceEntry*> > _Missing;
+  typedef std::vector<pair<Condition::key_type,SliceEntry*> > _Missing;
+  //typedef ConditionsDataLoader::RequiredItems _Missing;
   const auto& slice_cond = slice.conditions();
   const auto& slice_calc = slice.derived();
+  IOV pool_iov(required.iovType);
+  Result result;
 
   m_conditions.clear();
   pool_iov.reset().invert();
   m_iovPool->select(required, Operators::mapConditionsSelect(m_conditions), pool_iov);
   m_iov = pool_iov;
-  _Missing cond_missing(len+slice_cond.size()), calc_missing(len+slice_calc.size());
-  _Missing::iterator cond_last = set_difference(slice_cond.begin(),   slice_cond.end(),
-                                                m_conditions.begin(), m_conditions.end(),
-                                                cond_missing.begin(), _compare); 
-  int num_cond_miss = int(cond_last-cond_missing.begin());
+  _Missing cond_missing(slice_cond.size()+m_conditions.size());
+  _Missing calc_missing(slice_calc.size()+m_conditions.size());
+
+  _Missing::iterator last_cond = set_difference(begin(slice_cond),   end(slice_cond),
+                                                begin(m_conditions), end(m_conditions),
+                                                begin(cond_missing), COMP());
+  int num_cond_miss = int(last_cond-begin(cond_missing));
   printout(num_cond_miss==0 ? DEBUG : INFO,"UserPool",
            "Found %ld missing conditions out of %ld conditions.",
            num_cond_miss, m_conditions.size());
-
-  _Missing::iterator calc_last = set_difference(slice_calc.begin(),   slice_calc.end(),
-                                                m_conditions.begin(), m_conditions.end(),
-                                                calc_missing.begin(), _compare);
-  int num_calc_miss = int(calc_last-calc_missing.begin());
+  _Missing::iterator last_calc = set_difference(begin(slice_calc),   end(slice_calc),
+                                                begin(m_conditions), end(m_conditions),
+                                                begin(calc_missing), COMP());
+  int num_calc_miss = int(last_calc-begin(calc_missing));
   printout(num_cond_miss==0 ? DEBUG : INFO,"UserPool",
            "Found %ld missing derived conditions out of %ld conditions.",
-           int(calc_last-calc_missing.begin()), m_conditions.size());
+           num_calc_miss, m_conditions.size());
 
   result.selected = m_conditions.size();
   result.missing  = num_cond_miss+num_calc_miss;
   //
   // Now we load the missing conditions from the conditions loader
   //
-  if ( int(cond_last-cond_missing.begin())>0 )  {
-    vector<pair<key_type,SliceEntry*> > loaded, missing;
-    size_t updates = m_loader->load_many(required, cond_missing, loaded, missing, pool_iov);
+  if ( num_cond_miss > 0 )  {
+    ConditionsDataLoader::LoadedItems loaded;
+    size_t updates = m_loader->load_many(required, cond_missing, loaded, pool_iov);
+    // Need to compute the intersection: All missing entries are required....
+    _Missing load_missing(cond_missing.size()+loaded.size());
+    // Note: cond_missing is already sorted (doc of 'set_difference'). No need to re-sort....
+    _Missing::iterator load_last = set_difference(begin(cond_missing), end(cond_missing),
+                                                  begin(loaded), end(loaded),
+                                                  begin(load_missing), COMP());
+    int num_load_miss = int(load_last-begin(load_missing));
+    printout(num_load_miss==0 ? DEBUG : ERROR,"UserPool",
+             "Found %ld out of %d conditions, which CANNOT be loaded...",
+             num_load_miss, int(loaded.size()));
+
     for_each(loaded.begin(),loaded.end(),Inserter<MAPPING>(m_conditions,&m_iov));
     result.loaded    = updates;
     result.missing  -= updates;
-    if ( !missing.empty() )  {
+    if ( cond_missing.size() != loaded.size() )  {
       // ERROR!
     }
   }
   //
   // Now we update the already existing dependencies, which have expired
   //
-  if ( int(calc_last-calc_missing.begin()) > 0 )  {
-    ConditionsDependencyCollection deps(calc_missing.begin(), calc_last, _to_dep);
+  if ( num_calc_miss > 0 )  {
+    ConditionsDependencyCollection deps(calc_missing.begin(), last_calc, _to_dep);
     ConditionsDependencyHandler handler(m_manager, *this, deps, user_param);
     for(auto i=begin(deps); i != end(deps); ++i)   {
       const ConditionDependency* d = (*i).second.get();
diff --git a/DDCond/src/plugins/ConditionsXmlLoader.cpp b/DDCond/src/plugins/ConditionsXmlLoader.cpp
index 8c7ffaf6e..31b758eed 100644
--- a/DDCond/src/plugins/ConditionsXmlLoader.cpp
+++ b/DDCond/src/plugins/ConditionsXmlLoader.cpp
@@ -53,9 +53,8 @@ namespace DD4hep {
                                  RangeConditions& conditions);
       /// Optimized update using conditions slice data
       virtual size_t load_many(  const iov_type& /* req_validity */,
-                                 EntryVector&    /* work         */,
-                                 EntryVector&    /* loaded       */,
-                                 EntryVector&    /* missing      */,
+                                 RequiredItems&  /* work         */,
+                                 LoadedItems&    /* loaded       */,
                                  iov_type&       /* conditions_validity */)
       {
         except("ConditionsLoader","+++ update: Invalid call!");
diff --git a/DDCore/include/DD4hep/AlignedVolumePrinter.h b/DDCore/include/DD4hep/AlignedVolumePrinter.h
index 70b9706b6..9557a68fe 100644
--- a/DDCore/include/DD4hep/AlignedVolumePrinter.h
+++ b/DDCore/include/DD4hep/AlignedVolumePrinter.h
@@ -14,6 +14,7 @@
 #define DD4HEP_DDCORE_ALIGNEDVOLUMEPRINTER_H
 
 // Framework includes
+#include "DD4hep/Printout.h"
 #include "DD4hep/AlignmentsProcessor.h"
 
 /// Namespace for the AIDA detector description toolkit
@@ -39,6 +40,8 @@ namespace DD4hep {
       std::string   name;
       /// Printout prefix
       std::string   prefix;
+      /// Printout level
+      PrintLevel    printLevel;
     protected:
       /// Printout processing and customization flag
       int           m_flag;
diff --git a/DDCore/include/DD4hep/AlignmentsPrinter.h b/DDCore/include/DD4hep/AlignmentsPrinter.h
index cabf92a78..aced8404d 100644
--- a/DDCore/include/DD4hep/AlignmentsPrinter.h
+++ b/DDCore/include/DD4hep/AlignmentsPrinter.h
@@ -14,6 +14,7 @@
 #define DD4HEP_DDCORE_ALIGNMENTSPRINTER_H
 
 // Framework includes
+#include "DD4hep/Printout.h"
 #include "DD4hep/AlignmentsProcessor.h"
 
 /// Namespace for the AIDA detector description toolkit
@@ -39,6 +40,8 @@ namespace DD4hep {
       std::string   name;
       /// Printout prefix
       std::string   prefix;
+      /// Printout level
+      PrintLevel    printLevel;
     protected:
       /// Printout processing and customization flag
       int           m_flag;
@@ -63,16 +66,16 @@ namespace DD4hep {
     };
 
     /// Default printout of an alignment entry
-    void printAlignment(const std::string& prefix, Alignment alignment);
+    void printAlignment(PrintLevel prt_level, const std::string& prefix, Alignment alignment);
 
     /// Default printout of a container entry
-    void printContainer(const std::string& prefix, Container container, UserPool* pool);
+    void printContainer(PrintLevel prt_level, const std::string& prefix, Container container, UserPool* pool);
 
     /// Default printout of a detector element entry
-    void printElement(const std::string& prefix, DetElement element, UserPool* pool);
+    void printElement(PrintLevel prt_level, const std::string& prefix, DetElement element, UserPool* pool);
 
     /// PrintElement placement with/without alignment applied
-    void printElementPlacement(const std::string& prefix, DetElement detector, UserPool* pool);
+    void printElementPlacement(PrintLevel prt_level, const std::string& prefix, DetElement detector, UserPool* pool);
 
   }    /* End namespace Alignments           */
 }      /* End namespace DD4hep               */
diff --git a/DDCore/include/DD4hep/ConditionsPrinter.h b/DDCore/include/DD4hep/ConditionsPrinter.h
index 5ba9d6e40..4276d8d53 100644
--- a/DDCore/include/DD4hep/ConditionsPrinter.h
+++ b/DDCore/include/DD4hep/ConditionsPrinter.h
@@ -14,6 +14,7 @@
 #define DD4HEP_DDCORE_CONDITIONSPRINTER_H
 
 // Framework includes
+#include "DD4hep/Printout.h"
 #include "DD4hep/ConditionsProcessor.h"
 
 /// Namespace for the AIDA detector description toolkit
@@ -39,6 +40,9 @@ namespace DD4hep {
       std::string   name;
       /// Printout prefix
       std::string   prefix;
+      /// Printout level
+      PrintLevel    printLevel;
+
     protected:
       /// Printout processing and customization flag
       int           m_flag;
diff --git a/DDCore/include/DD4hep/Printout.h b/DDCore/include/DD4hep/Printout.h
index 85b236933..4820af4aa 100644
--- a/DDCore/include/DD4hep/Printout.h
+++ b/DDCore/include/DD4hep/Printout.h
@@ -234,6 +234,9 @@ namespace DD4hep {
   /// Translate the printer level from string to value
   PrintLevel printLevel(const std::string& value);
 
+  /// Check if this print level would result in some output
+  bool isActivePrintLevel(int severity);
+
   /// Helper class template to implement ASCII object dumps
   /** @class Printer Conversions.h  DD4hep/compact/Conversions.h
    *
diff --git a/DDCore/src/AlignedVolumePrinter.cpp b/DDCore/src/AlignedVolumePrinter.cpp
index 498b6db78..bc2180fd1 100644
--- a/DDCore/src/AlignedVolumePrinter.cpp
+++ b/DDCore/src/AlignedVolumePrinter.cpp
@@ -21,30 +21,30 @@ using namespace DD4hep::Alignments;
 
 /// Initializing constructor
 AlignedVolumePrinter::AlignedVolumePrinter(const string& pref, int flg)
-  : AlignmentsProcessor(0), name("Alignment"), prefix(pref), m_flag(flg)
+  : AlignmentsProcessor(0), name("Alignment"), prefix(pref), printLevel(INFO), m_flag(flg)
 {
 }
 
 /// Initializing constructor
 AlignedVolumePrinter::AlignedVolumePrinter(UserPool* p, const std::string& pref,int flg)
-  : AlignmentsProcessor(p), name("Alignment"), prefix(pref), m_flag(flg)
+  : AlignmentsProcessor(p), name("Alignment"), prefix(pref), printLevel(INFO), m_flag(flg)
 {
 }
 
 /// Callback to output alignments information
 int AlignedVolumePrinter::operator()(Alignment a)    {
-  printAlignment(name, a);
+  printAlignment(printLevel, name, a);
   return 1;
 }
 
 /// Container callback for object processing
 int AlignedVolumePrinter::operator()(Container container)   {
-  printContainer(name, container, m_pool);
+  printContainer(printLevel, name, container, m_pool);
   return 1;
 }
 
 /// Callback to output alignments information of an entire DetElement
 int AlignedVolumePrinter::processElement(DetElement de)  {
-  printElementPlacement(name, de, m_pool);
+  printElementPlacement(printLevel, name, de, m_pool);
   return 1;
 }
diff --git a/DDCore/src/AlignmentsPrinter.cpp b/DDCore/src/AlignmentsPrinter.cpp
index a7b538536..8146b3ad2 100644
--- a/DDCore/src/AlignmentsPrinter.cpp
+++ b/DDCore/src/AlignmentsPrinter.cpp
@@ -27,37 +27,37 @@ using namespace DD4hep::Alignments;
 
 /// Initializing constructor
 AlignmentsPrinter::AlignmentsPrinter(const string& pref, int flg)
-  : AlignmentsProcessor(0), name("Alignment"), prefix(pref), m_flag(flg)
+  : AlignmentsProcessor(0), name("Alignment"), prefix(pref), printLevel(INFO), m_flag(flg)
 {
 }
 
 /// Initializing constructor
 AlignmentsPrinter::AlignmentsPrinter(UserPool* p, const std::string& pref,int flg)
-  : AlignmentsProcessor(p), name("Alignment"), prefix(pref), m_flag(flg)
+  : AlignmentsProcessor(p), name("Alignment"), prefix(pref), printLevel(INFO), m_flag(flg)
 {
 }
 
 /// Callback to output alignments information
 int AlignmentsPrinter::operator()(Alignment a)    {
-  printAlignment(name, a);
+  printAlignment(printLevel, name, a);
   return 1;
 }
 
 /// Container callback for object processing
 int AlignmentsPrinter::operator()(Container container)   {
-  printContainer(name, container, m_pool);
+  printContainer(printLevel, name, container, m_pool);
   return 1;
 }
 
 /// Callback to output alignments information of an entire DetElement
 int AlignmentsPrinter::processElement(DetElement de)  {
-  printElement(name, de, m_pool);
+  printElement(printLevel, name, de, m_pool);
   return 1;
 }
 
 
 /// Default printout of an alignment entry
-void DD4hep::Alignments::printAlignment(const string& prefix, Alignment a)   {
+void DD4hep::Alignments::printAlignment(PrintLevel lvl, const string& prefix, Alignment a)   {
   if ( a.isValid() )   {
     Alignment::Object* ptr = a.ptr();
     const Alignment::Data& data = a.data();
@@ -65,29 +65,31 @@ void DD4hep::Alignments::printAlignment(const string& prefix, Alignment a)   {
     const Delta& D = data.delta;
     string new_prefix = prefix;
     new_prefix.assign(prefix.length(),' ');
-    printout(INFO,prefix,"++ %s \tPath:%s [%p] Typ:%s",
+    printout(lvl,prefix,"++ %s \tPath:%s [%p] Typ:%s",
              new_prefix.c_str(), cond.name(), a.ptr(),
              typeName(typeid(*ptr)).c_str());
-    printout(INFO,prefix,"++ %s \tData:(%11s-%8s-%5s)",
+    printout(lvl,prefix,"++ %s \tData:(%11s-%8s-%5s)",
              new_prefix.c_str(), 
              D.hasTranslation() ? "Translation" : "",
              D.hasRotation() ? "Rotation" : "",
              D.hasPivot() ? "Pivot" : "");
-    printf("WorldTrafo: "); data.worldTrafo.Print();
-    printf("DetTrafo:   "); data.detectorTrafo.Print();
+    if ( isActivePrintLevel(lvl) )  {
+      printf("WorldTrafo: "); data.worldTrafo.Print();
+      printf("DetTrafo:   "); data.detectorTrafo.Print();
+    }
   }
 }
 
 /// Default printout of an container entry
-void DD4hep::Alignments::printContainer(const string& prefix, Container container, UserPool* pool)   {
+void DD4hep::Alignments::printContainer(PrintLevel prt_level, const string& prefix, Container container, UserPool* pool)   {
   string tag = prefix+"Cont";
   if ( pool )  {
     for(const auto& k : container.keys() )  {
       try {
         Alignment align = container.get(k.first,*pool);
-        printout(INFO,tag,"++ %s Alignment [%16llX] -> [%16llX] %s",
+        printout(prt_level,tag,"++ %s Alignment [%16llX] -> [%16llX] %s",
                  prefix.c_str(), k.first, k.second.first, k.second.second.c_str());
-        printAlignment(prefix,align);
+        printAlignment(prt_level, prefix,align);
       }
       catch(...)  {
         printout(ERROR,tag,"++ %s %s [%16llX] -> [%16llX]",
@@ -100,15 +102,15 @@ void DD4hep::Alignments::printContainer(const string& prefix, Container containe
 }
 
 /// Default printout of a detector element entry
-void DD4hep::Alignments::printElement(const string& prefix, DetElement de, UserPool* pool)   {
+void DD4hep::Alignments::printElement(PrintLevel prt_level, const string& prefix, DetElement de, UserPool* pool)   {
   string tag = prefix+"Element";
   if ( de.isValid() )  {
     if ( pool )  {
       DetAlign  a(de);
       Container c = a.alignments();
-      printout(INFO,tag,"++ Alignments of DE %s [%d entries]",
+      printout(prt_level,tag,"++ Alignments of DE %s [%d entries]",
                de.path().c_str(), int(c.keys().size()));
-      printContainer(prefix, c, pool);
+      printContainer(prt_level, prefix, c, pool);
       return;
     }
     except(tag,"Cannot process DetElement alignments from '%s' without valid user-pool",de.name());
@@ -142,7 +144,9 @@ static string _transformPoint2Detector(const Alignment::Data& data, const Positi
   return text;
 }
 
-static void printAlignmentEx(const string& prefix, const string& opt, DetElement de, Alignment alignment)  {
+static void printAlignmentEx(PrintLevel lvl, const string& prefix,
+                             const string& opt, DetElement de, Alignment alignment)
+{
   using Geometry::Box;
   DetAlign      a(de);
   const string& tag = prefix;
@@ -162,7 +166,7 @@ static void printAlignmentEx(const string& prefix, const string& opt, DetElement
   Position p8(-bbox.x(),-bbox.y(),-bbox.z());
 
   if ( align_cond.isValid() )  {
-    printout(INFO,tag,"++ %s DATA: (%11s-%8s-%5s) %p IOV:%s", opt.c_str(), 
+    printout(lvl,tag,"++ %s DATA: (%11s-%8s-%5s) %p IOV:%s", opt.c_str(), 
              align_delta.hasTranslation() ? "Translation" : "",
              align_delta.hasRotation() ? "Rotation" : "",
              align_delta.hasPivot() ? "Pivot" : "",
@@ -170,7 +174,7 @@ static void printAlignmentEx(const string& prefix, const string& opt, DetElement
              align_cond.iov().str().c_str());
   }
   else  {
-    printout(INFO,tag,"++ %s DATA: (%11s-%8s-%5s) %p", opt.c_str(), 
+    printout(lvl,tag,"++ %s DATA: (%11s-%8s-%5s) %p", opt.c_str(), 
              align_delta.hasTranslation() ? "Translation" : "",
              align_delta.hasRotation() ? "Rotation" : "",
              align_delta.hasPivot() ? "Pivot" : "",
@@ -179,46 +183,49 @@ static void printAlignmentEx(const string& prefix, const string& opt, DetElement
   if ( align_delta.hasTranslation() )  {
     stringstream str;
     Utils::toStream(align_delta.translation, str);
-    printout(INFO,tag,"++ %s DELTA Translation: %s", opt.c_str(), replace_all(str.str(),"\n","").c_str());
+    printout(lvl,tag,"++ %s DELTA Translation: %s",
+             opt.c_str(), replace_all(str.str(),"\n","").c_str());
   }
   if ( align_delta.hasPivot() )  {
     stringstream str;
     Utils::toStream(align_delta.pivot, str);
     string res = replace_all(str.str(),"\n","");
     res = "( "+replace_all(res,"  "," , ")+" )";
-    printout(INFO,tag,"++ %s DELTA Pivot:       %s", opt.c_str(), res.c_str());
+    printout(lvl,tag,"++ %s DELTA Pivot:       %s", opt.c_str(), res.c_str());
   }
   if ( align_delta.hasRotation() )  {
     stringstream str;
     Utils::toStream(align_delta.rotation, str);
-    printout(INFO,tag,"++ %s DELTA Rotation:    %s", opt.c_str(), replace_all(str.str(),"\n","").c_str());
+    printout(lvl,tag,"++ %s DELTA Rotation:    %s", opt.c_str(), replace_all(str.str(),"\n","").c_str());
   }
-  printf("%s %s WorldTrafo (to %s): ",opt.c_str(), tag.c_str(), de.world().path().c_str());
-  align_data.worldTrafo.Print();
-  printf("%s %s DetTrafo (to %s): ",opt.c_str(), tag.c_str(), par.c_str());
-  align_data.detectorTrafo.Print();
-
-  printout(INFO,tag,"++ %s: P1(x,y,z) %s", opt.c_str(), _transformPoint2World(align_data, p1).c_str());
-  printout(INFO,tag,"++ %s: P2(x,y,z) %s", opt.c_str(), _transformPoint2World(align_data, p2).c_str());
-  printout(INFO,tag,"++ %s: P3(x,y,z) %s", opt.c_str(), _transformPoint2World(align_data, p3).c_str());
-  printout(INFO,tag,"++ %s: P4(x,y,z) %s", opt.c_str(), _transformPoint2World(align_data, p4).c_str());
-  printout(INFO,tag,"++ %s: P5(x,y,z) %s", opt.c_str(), _transformPoint2World(align_data, p5).c_str());
-  printout(INFO,tag,"++ %s: P6(x,y,z) %s", opt.c_str(), _transformPoint2World(align_data, p6).c_str());
-  printout(INFO,tag,"++ %s: P7(x,y,z) %s", opt.c_str(), _transformPoint2World(align_data, p7).c_str());
-  printout(INFO,tag,"++ %s: P8(x,y,z) %s", opt.c_str(), _transformPoint2World(align_data, p8).c_str());
+  if ( isActivePrintLevel(lvl) )  {
+    printf("%s %s WorldTrafo (to %s): ",opt.c_str(), tag.c_str(), de.world().path().c_str());
+    align_data.worldTrafo.Print();
+    printf("%s %s DetTrafo (to %s): ",opt.c_str(), tag.c_str(), par.c_str());
+    align_data.detectorTrafo.Print();
+  }
+  printout(PrintLevel(lvl-1),tag,"++ %s: P1(x,y,z) %s", opt.c_str(), _transformPoint2World(align_data, p1).c_str());
+  printout(PrintLevel(lvl-1),tag,"++ %s: P2(x,y,z) %s", opt.c_str(), _transformPoint2World(align_data, p2).c_str());
+  printout(PrintLevel(lvl-1),tag,"++ %s: P3(x,y,z) %s", opt.c_str(), _transformPoint2World(align_data, p3).c_str());
+  printout(PrintLevel(lvl-1),tag,"++ %s: P4(x,y,z) %s", opt.c_str(), _transformPoint2World(align_data, p4).c_str());
+  printout(PrintLevel(lvl-1),tag,"++ %s: P5(x,y,z) %s", opt.c_str(), _transformPoint2World(align_data, p5).c_str());
+  printout(PrintLevel(lvl-1),tag,"++ %s: P6(x,y,z) %s", opt.c_str(), _transformPoint2World(align_data, p6).c_str());
+  printout(PrintLevel(lvl-1),tag,"++ %s: P7(x,y,z) %s", opt.c_str(), _transformPoint2World(align_data, p7).c_str());
+  printout(PrintLevel(lvl-1),tag,"++ %s: P8(x,y,z) %s", opt.c_str(), _transformPoint2World(align_data, p8).c_str());
 
-  printout(INFO,tag,"++ %s: P1(x,y,z) %s", opt.c_str(), _transformPoint2Detector(align_data, p1).c_str());
-  printout(INFO,tag,"++ %s: P2(x,y,z) %s", opt.c_str(), _transformPoint2Detector(align_data, p2).c_str());
-  printout(INFO,tag,"++ %s: P3(x,y,z) %s", opt.c_str(), _transformPoint2Detector(align_data, p3).c_str());
-  printout(INFO,tag,"++ %s: P4(x,y,z) %s", opt.c_str(), _transformPoint2Detector(align_data, p4).c_str());
-  printout(INFO,tag,"++ %s: P5(x,y,z) %s", opt.c_str(), _transformPoint2Detector(align_data, p5).c_str());
-  printout(INFO,tag,"++ %s: P6(x,y,z) %s", opt.c_str(), _transformPoint2Detector(align_data, p6).c_str());
-  printout(INFO,tag,"++ %s: P7(x,y,z) %s", opt.c_str(), _transformPoint2Detector(align_data, p7).c_str());
-  printout(INFO,tag,"++ %s: P8(x,y,z) %s", opt.c_str(), _transformPoint2Detector(align_data, p8).c_str());
+  printout(PrintLevel(lvl-1),tag,"++ %s: P1(x,y,z) %s", opt.c_str(), _transformPoint2Detector(align_data, p1).c_str());
+  printout(PrintLevel(lvl-1),tag,"++ %s: P2(x,y,z) %s", opt.c_str(), _transformPoint2Detector(align_data, p2).c_str());
+  printout(PrintLevel(lvl-1),tag,"++ %s: P3(x,y,z) %s", opt.c_str(), _transformPoint2Detector(align_data, p3).c_str());
+  printout(PrintLevel(lvl-1),tag,"++ %s: P4(x,y,z) %s", opt.c_str(), _transformPoint2Detector(align_data, p4).c_str());
+  printout(PrintLevel(lvl-1),tag,"++ %s: P5(x,y,z) %s", opt.c_str(), _transformPoint2Detector(align_data, p5).c_str());
+  printout(PrintLevel(lvl-1),tag,"++ %s: P6(x,y,z) %s", opt.c_str(), _transformPoint2Detector(align_data, p6).c_str());
+  printout(PrintLevel(lvl-1),tag,"++ %s: P7(x,y,z) %s", opt.c_str(), _transformPoint2Detector(align_data, p7).c_str());
+  printout(PrintLevel(lvl-1),tag,"++ %s: P8(x,y,z) %s", opt.c_str(), _transformPoint2Detector(align_data, p8).c_str());
 }
 
 /// PrintElement placement with/without alignment applied
-void DD4hep::Alignments::printElementPlacement(const string& prefix, DetElement de, UserPool* pool)   {
+void DD4hep::Alignments::printElementPlacement(PrintLevel lvl, const string& prefix, DetElement de, UserPool* pool)
+{
   using Geometry::Box;
   using Geometry::Solid;
   using Geometry::Volume;
@@ -233,11 +240,12 @@ void DD4hep::Alignments::printElementPlacement(const string& prefix, DetElement
       Box bbox = de.placement().volume().solid();
       ::memset(text,'=',sizeof(text));
       text[sizeof(text)-1] = 0;
-      printout(INFO,tag,text);
-      printout(INFO,tag,"++ Alignments of DE %s [%d entries]",
+      printout(lvl, tag, text);
+      printout(lvl, tag, "++ Alignments of DE %s [%d entries]",
                de.path().c_str(), int(container.keys().size()));
-      printout(INFO,tag,"++ Volume: %s  BBox: x=%7.3f y=%7.3f z=%7.3f",bbox.type(),bbox.x(),bbox.y(),bbox.z());
-      printAlignmentEx(tag,"NOMINAL",de,nominal);
+      printout(lvl, tag, "++ Volume: %s  BBox: x=%7.3f y=%7.3f z=%7.3f",
+               bbox.type(), bbox.x(), bbox.y(), bbox.z());
+      printAlignmentEx(lvl, tag, "NOMINAL", de, nominal);
 
       for(const auto& k : container.keys() )  {
         try {
@@ -245,25 +253,25 @@ void DD4hep::Alignments::printElementPlacement(const string& prefix, DetElement
           const Alignment::Data& align_data = align.data();
           Conditions::Condition  align_cond = align_data.condition;
           if ( k.first != k.second.first )  {
-            printout(INFO,tag,"++ Alignment %p [%16llX] -> [%16llX] %s (SYNONYM) ignored.",
+            printout(lvl, tag, "++ Alignment %p [%16llX] -> [%16llX] %s (SYNONYM) ignored.",
                      a.ptr(), k.first, k.second.first, k.second.second.c_str());
             continue;
           }
-          printout(INFO,tag,"++ Alignment %p [%16llX] -> [%16llX] %s",
+          printout(lvl, tag, "++ Alignment %p [%16llX] -> [%16llX] %s",
                    a.ptr(), k.first, k.second.first, k.second.second.c_str());
           if ( k.second.second != align_cond.name() )  {
-            printout(INFO,prefix,"++ \tPath:%s [%p]", align_cond.name(), a.ptr());
+            printout(lvl, prefix, "++ \tPath:%s [%p]", align_cond.name(), a.ptr());
           }
-          printAlignmentEx(tag,"ALIGNMENT",de,align);
+          printAlignmentEx(lvl, tag, "ALIGNMENT", de, align);
         }
         catch(...)  {
-          printout(ERROR,tag,"++ %s %s [%16llX] -> [%16llX]",
+          printout(ERROR, tag, "++ %s %s [%16llX] -> [%16llX]",
                    prefix.c_str(), "FAILED Alignment:", k.first, k.second.first);
         }
       }
       return;
     }
-    except(tag,"Cannot process DetElement alignments from '%s' without valid user-pool",de.name());
+    except(tag, "Cannot process DetElement alignments from '%s' without valid user-pool", de.name());
   }
-  except(tag,"Cannot process alignments of an invalid detector element");
+  except(tag, "Cannot process alignments of an invalid detector element");
 }
diff --git a/DDCore/src/ConditionsPrinter.cpp b/DDCore/src/ConditionsPrinter.cpp
index 122065f8c..fb15637eb 100644
--- a/DDCore/src/ConditionsPrinter.cpp
+++ b/DDCore/src/ConditionsPrinter.cpp
@@ -22,13 +22,13 @@ using namespace DD4hep::Conditions;
 
 /// Initializing constructor
 ConditionsPrinter::ConditionsPrinter(UserPool* p, const std::string& pref, int flg)
-  : ConditionsProcessor(p), name("Condition"), prefix(pref), m_flag(flg)
+  : ConditionsProcessor(p), name("Condition"), prefix(pref), printLevel(INFO), m_flag(flg)
 {
 }
 
 /// Initializing constructor
 ConditionsPrinter::ConditionsPrinter(const std::string& pref, int flg)
-  : ConditionsProcessor(0), name("Condition"), prefix(pref), m_flag(flg)
+  : ConditionsProcessor(0), name("Condition"), prefix(pref), printLevel(INFO), m_flag(flg)
 {
 }
 
@@ -37,17 +37,19 @@ int ConditionsPrinter::operator()(Condition cond)    {
   if ( cond.isValid() )   {
     std::string repr = cond.str(m_flag);
     if ( repr.length() > 100 )
-      printout(INFO,name,"++ %s%s", prefix.c_str(), repr.c_str());
+      printout(this->printLevel,name,
+               "++ %s%s", prefix.c_str(), repr.c_str());
     else
-      printout(INFO,name,"++ %s%s [%p]", prefix.c_str(), repr.c_str(), cond.ptr());
+      printout(this->printLevel,name,"++ %s%s [%p]",
+               prefix.c_str(), repr.c_str(), cond.ptr());
     const OpaqueData& data = cond.data();
     std::string values = data.str();
     if ( values.length() > 132 ) values = values.substr(0,130)+"...";
     std::string new_prefix = prefix;
     new_prefix.assign(prefix.length(),' ');
-    printout(INFO,name,"++ %s \tPath:%s Key:%16llX Type:%s",
+    printout(this->printLevel,name,"++ %s \tPath:%s Key:%16llX Type:%s",
              new_prefix.c_str(), cond.name(), cond.key(), data.dataType().c_str());
-    printout(INFO,name,"++ %s \tData:%s", new_prefix.c_str(), values.c_str());
+    printout(this->printLevel,name,"++ %s \tData:%s", new_prefix.c_str(), values.c_str());
   }
   return 1;
 }
@@ -55,14 +57,14 @@ int ConditionsPrinter::operator()(Condition cond)    {
 /// Container callback for object processing
 int ConditionsPrinter::operator()(Container container)   {
   if ( m_pool )  {
-    printout(INFO,name,"++ Conditions of DE %s [%d entries]",
+    printout(this->printLevel,name,"++ Conditions of DE %s [%d entries]",
              container->detector.path().c_str(), int(container.keys().size()));
     for(const auto& k : container.keys() )  {
       Condition c = container.get(k.first,*m_pool);
       std::string nam = c.name();
       std::string cn = nam.substr(nam.find('#')+1);
       Condition::key_type key = ConditionKey::hashCode(cn);
-      printout(INFO,name,"++ %s %s %s [%16llX] -> %s [%16llX]",
+      printout(this->printLevel,name,"++ %s %s %s [%16llX] -> %s [%16llX]",
                prefix.c_str(), "Condition:", cn.c_str(), key==k.first ? key : k.first,
                c.name(), k.second.first);
       (*this)(c);
diff --git a/DDCore/src/Primitives.cpp b/DDCore/src/Primitives.cpp
index e6c2c6c9a..4637e3c95 100644
--- a/DDCore/src/Primitives.cpp
+++ b/DDCore/src/Primitives.cpp
@@ -17,6 +17,9 @@
 #include "DD4hep/Printout.h"
 
 // C/C++ include files
+#include <algorithm>
+#include <functional>
+#include <numeric>
 #include <stdexcept>
 #include <cstdint>
 #include <cstring>
@@ -29,113 +32,130 @@ typedef abi::__class_type_info class_t;
 using   abi::__dynamic_cast;
 #endif
 #endif
+
+/// Local Utilities
+namespace {
+
+#if 0
 //-----------------------------------------------------------------------------
 // MurmurHash2, 64-bit versions, by Austin Appleby
-
+//
 // The same caveats as 32-bit MurmurHash2 apply here - beware of alignment 
 // and endian-ness issues if used across multiple platforms.
-static inline uint64_t murmur_hash_64 ( const void * key, int len)  {
+  inline uint64_t murmur_hash_64 ( const void * key, int len)  {
 #define seed 0xFEEDBABE
-  typedef unsigned long long int uint64;
+    typedef unsigned long long int uint64;
+
 #if INTPTR_MAX == INT32_MAX
-	const unsigned int * data = (const unsigned int *)key;
-	const unsigned int m = 0x5bd1e995;
-	const int r = 24;
-
-	unsigned int h1 = seed ^ len;
-	unsigned int h2 = 0;
-
-	while(len >= 8)
-	{
-		unsigned int k1 = *data++;
-		k1 *= m; k1 ^= k1 >> r; k1 *= m;
-		h1 *= m; h1 ^= k1;
-		len -= 4;
-
-		unsigned int k2 = *data++;
-		k2 *= m; k2 ^= k2 >> r; k2 *= m;
-		h2 *= m; h2 ^= k2;
-		len -= 4;
-	}
-
-	if(len >= 4)
-	{
-		unsigned int k1 = *data++;
-		k1 *= m; k1 ^= k1 >> r; k1 *= m;
-		h1 *= m; h1 ^= k1;
-		len -= 4;
-	}
-
-	switch(len)
-	{
-	case 3: h2 ^= ((unsigned char*)data)[2] << 16;
-	case 2: h2 ^= ((unsigned char*)data)[1] << 8;
-	case 1: h2 ^= ((unsigned char*)data)[0];
-    h2 *= m;
-	};
-
-	h1 ^= h2 >> 18; h1 *= m;
-	h2 ^= h1 >> 22; h2 *= m;
-	h1 ^= h2 >> 17; h1 *= m;
-	h2 ^= h1 >> 19; h2 *= m;
-
-	uint64 h = h1;
-
-	h = (h << 32) | h2;
+    const unsigned int * data = (const unsigned int *)key;
+    const unsigned int m = 0x5bd1e995;
+    const int r = 24;
+
+    unsigned int h1 = seed ^ len;
+    unsigned int h2 = 0;
+
+    while(len >= 8)
+    {
+      unsigned int k1 = *data++;
+      k1 *= m; k1 ^= k1 >> r; k1 *= m;
+      h1 *= m; h1 ^= k1;
+      len -= 4;
+
+      unsigned int k2 = *data++;
+      k2 *= m; k2 ^= k2 >> r; k2 *= m;
+      h2 *= m; h2 ^= k2;
+      len -= 4;
+    }
+
+    if(len >= 4)
+    {
+      unsigned int k1 = *data++;
+      k1 *= m; k1 ^= k1 >> r; k1 *= m;
+      h1 *= m; h1 ^= k1;
+      len -= 4;
+    }
+
+    switch(len)
+    {
+    case 3: h2 ^= ((unsigned char*)data)[2] << 16;
+    case 2: h2 ^= ((unsigned char*)data)[1] << 8;
+    case 1: h2 ^= ((unsigned char*)data)[0];
+      h2 *= m;
+    };
+
+    h1 ^= h2 >> 18; h1 *= m;
+    h2 ^= h1 >> 22; h2 *= m;
+    h1 ^= h2 >> 17; h1 *= m;
+    h2 ^= h1 >> 19; h2 *= m;
+
+    uint64 h = h1;
+
+    h = (h << 32) | h2;
 #elif INTPTR_MAX == INT64_MAX
-	const uint64* data = (const uint64*)key;
-	const uint64 m = 0xc6a4a7935bd1e995;
-	const int r = 47;
+    const uint64* data = (const uint64*)key;
+    const uint64 m = 0xc6a4a7935bd1e995;
+    const int r = 47;
 
-	uint64 h = seed ^ (len * m);
+    uint64 h = seed ^ (len * m);
 
-	const uint64 * end = data + (len/8);
+    const uint64 * end = data + (len/8);
 
-	while(data != end)
-	{
-		uint64 k = *data++;
+    while(data != end)
+    {
+      uint64 k = *data++;
 
-		k *= m; 
-		k ^= k >> r; 
-		k *= m; 
+      k *= m; 
+      k ^= k >> r; 
+      k *= m; 
 		
-		h ^= k;
-		h *= m; 
-	}
-
-	const unsigned char * data2 = (const unsigned char*)data;
-
-	switch(len & 7)
-	{
-	case 7: h ^= uint64(data2[6]) << 48;
-	case 6: h ^= uint64(data2[5]) << 40;
-	case 5: h ^= uint64(data2[4]) << 32;
-	case 4: h ^= uint64(data2[3]) << 24;
-	case 3: h ^= uint64(data2[2]) << 16;
-	case 2: h ^= uint64(data2[1]) << 8;
-	case 1: h ^= uint64(data2[0]);
-    h *= m;
-	};
+      h ^= k;
+      h *= m; 
+    }
+
+    const unsigned char * data2 = (const unsigned char*)data;
+
+    switch(len & 7)
+    {
+    case 7: h ^= uint64(data2[6]) << 48;
+    case 6: h ^= uint64(data2[5]) << 40;
+    case 5: h ^= uint64(data2[4]) << 32;
+    case 4: h ^= uint64(data2[3]) << 24;
+    case 3: h ^= uint64(data2[2]) << 16;
+    case 2: h ^= uint64(data2[1]) << 8;
+    case 1: h ^= uint64(data2[0]);
+      h *= m;
+    };
  
-	h ^= h >> r;
-	h *= m;
-	h ^= h >> r;
+    h ^= h >> r;
+    h *= m;
+    h ^= h >> r;
 
 #else
 #error "Environment not 32 or 64-bit."
+#endif
+    return h;
+  }
 #endif
 
-	return h;
+  struct FNV1a_64 {
+    static const unsigned long long int hashinit = 14695981039346656037ull;
+    static constexpr unsigned long long int doByte(unsigned long long int hash,unsigned char val)
+    { return (hash ^ val) * 1099511628211ull; }
+  };
 }
 
-
 /// We need it so often: one-at-time 64 bit hash function
 unsigned long long int DD4hep::hash64(const char* key)   {
-  return murmur_hash_64(key, strlen(key));
+  //return murmur_hash_64(key, strlen(key));
+  unsigned char* str = (unsigned char*)key;
+  unsigned long long int hash = FNV1a_64::hashinit;
+  for ( ; *str; ++str) hash = FNV1a_64::doByte(hash, *str);
+  return hash;
 }
 
 unsigned long long int DD4hep::hash64(const std::string& key)  {
-  return murmur_hash_64(key.data(), key.length());
+  //return murmur_hash_64(key.data(), key.length());
+  return std::accumulate(begin(key),end(key),FNV1a_64::hashinit,FNV1a_64::doByte);
 }
 
 long int DD4hep::makeTime(int year, int month, int day,
diff --git a/DDCore/src/Printout.cpp b/DDCore/src/Printout.cpp
index 8310a17d1..7ad0ab0d4 100644
--- a/DDCore/src/Printout.cpp
+++ b/DDCore/src/Printout.cpp
@@ -326,7 +326,7 @@ DD4hep::PrintLevel DD4hep::printLevel()  {
 
 /// Translate the printer level from string to value
 DD4hep::PrintLevel DD4hep::printLevel(const char* value)  {
-  if ( !value ) except("Printout","Invalid printlevel requested");
+  if ( !value ) except("Printout","Invalid printlevel requested [EINVAL: Null-pointer argument]");
   // Explicit values
   if ( strcmp(value,"NOLOG")   == 0 ) return DD4hep::NOLOG;
   if ( strcmp(value,"VERBOSE") == 0 ) return DD4hep::VERBOSE;
@@ -354,6 +354,11 @@ DD4hep::PrintLevel DD4hep::printLevel(const std::string& value)  {
   return printLevel(value.c_str());
 }
 
+/// Check if this print level would result in some output
+bool DD4hep::isActivePrintLevel(int severity)   {
+  return severity >= print_lvl;
+}
+
 /// Set new printout format for the 3 fields: source-level-message. All 3 are strings
 string DD4hep::setPrintFormat(const string& new_format) {
   string old = print_fmt;
diff --git a/DDDB/include/DDDB/DDDBConditionPrinter.h b/DDDB/include/DDDB/DDDBConditionPrinter.h
index 2041c8d40..4876adbca 100644
--- a/DDDB/include/DDDB/DDDBConditionPrinter.h
+++ b/DDDB/include/DDDB/DDDBConditionPrinter.h
@@ -20,6 +20,7 @@
 #define DD4HEP_DDDB_DDDBCONDITIONPRINTER_H
 
 // Framework includes
+#include "DD4hep/Printout.h"
 #include "DD4hep/ConditionsData.h"
 #include "DD4hep/ConditionsProcessor.h"
 
@@ -50,42 +51,60 @@ namespace DD4hep {
        *   \ingroup DD4HEP_DDDB
        */
       class ParamPrinter {
+        
       protected:
-        /// Printout prefix
-        std::string& m_prefix;
+        /// Parent object
+        ConditionPrinter* m_parent = 0;
       public:
-        /// Default constructor
-        ParamPrinter() = default;
         /// Copy constructor
         ParamPrinter(const ParamPrinter& copy) = default;
         /// Initializing constructor
-        ParamPrinter(std::string& prefix);
+        ParamPrinter(ConditionPrinter* p);
         /// Default destructor
         virtual ~ParamPrinter() = default;
         /// Assignment operator
         ParamPrinter& operator=(const ParamPrinter& copy) = default;
-
-        /// Set prefix for prinouts
-        void setPrefix(const std::string& value)  {  m_prefix = value; }
-        /// Access prefix value
-        const std::string& prefix() const         {   return m_prefix; }
         /// Callback to output conditions information
         virtual void operator()(const Conditions::AbstractMap::Params::value_type& obj)  const;
       };
 
     protected:
-      std::string m_prefix;
-      ParamPrinter* m_print;
-      int    m_flag;
+      friend class ParamPrinter;
+      
+      /// Sub-printer
+      ParamPrinter* m_print = 0;
+      /// Printout prefix
+      std::string   m_prefix;
+      /// Flags to steer output processing
+      int           m_flag = 0;
+      /// Printout level
+      PrintLevel    m_printLevel = INFO;
 
+      /// Counter: number of parameters
+      size_t        m_numParam = 0;
+      /// Counter: number of conditions
+      size_t        m_numCondition = 0;
+      /// Counter: number of empty conditions
+      size_t        m_numEmptyCondition = 0;
+      
     public:
       typedef Conditions::Condition Condition;
       typedef Conditions::Container Container;
-
+      /// No default constructor
+      ConditionPrinter() = delete;
+      /// No copy constructor
+      ConditionPrinter(const ConditionPrinter& copy) = delete;
       /// Initializing constructor
-      ConditionPrinter(const std::string& prefix="", 
+      ConditionPrinter(const std::string& prefix, 
                        int flag=Condition::NO_NAME|Condition::WITH_IOV|Condition::WITH_ADDRESS,
                        ParamPrinter* prt=0);
+      /// Default destructor
+      virtual ~ConditionPrinter();
+      
+      /// Set printout level for prinouts
+      void setPrintLevel(PrintLevel lvl);
+      /// Access the prefix value
+      const std::string& prefix() const         { return m_prefix;   }
       /// Set prefix for prinouts
       void setPrefix(const std::string& value)  {  m_prefix = value; }
       /// Callback to output conditions information
diff --git a/DDDB/include/DDDB/DDDBConditionsLoader.h b/DDDB/include/DDDB/DDDBConditionsLoader.h
index ddc21c1ce..098a7280a 100644
--- a/DDDB/include/DDDB/DDDBConditionsLoader.h
+++ b/DDDB/include/DDDB/DDDBConditionsLoader.h
@@ -88,9 +88,8 @@ namespace DD4hep {
                                  RangeConditions& conditions);
       /// Optimized update using conditions slice data
       virtual size_t load_many(  const iov_type& req_validity,
-                                 EntryVector&    work,
-                                 EntryVector&    loaded,
-                                 EntryVector&    missing,
+                                 RequiredItems&  work,
+                                 LoadedItems&    loaded,
                                  iov_type&       conditions_validity);
 
       /// ConditionsListener overload: onRegister new condition
diff --git a/DDDB/src/CondDB2DDDB.cpp b/DDDB/src/CondDB2DDDB.cpp
index 8f9c001d6..7c156f535 100644
--- a/DDDB/src/CondDB2DDDB.cpp
+++ b/DDDB/src/CondDB2DDDB.cpp
@@ -590,12 +590,11 @@ namespace DD4hep {
       if ( !_find(id, context->geo->conditions) )  {
         Catalog*   catalog = _option<Catalog>();
         Document*  doc     = context->locals.xml_doc;
-
         string     path    = object_path(context,name);
         static int num_param=0, num_vector=0, num_map=0, num_spec=0, num_align=0;
 
         Condition cond(path,"DDDB");
-        cond->address  = id;
+        cond->address  = doc->name+"@"+id;
         cond->value    = path; // doc->name;
         cond->validity = "";
         cond->hash     = Conditions::ConditionKey::hashCode(cond->value);
diff --git a/DDDB/src/DDDBAlignmentTest.cpp b/DDDB/src/DDDBAlignmentTest.cpp
index fd46ef24d..329f68872 100644
--- a/DDDB/src/DDDBAlignmentTest.cpp
+++ b/DDDB/src/DDDBAlignmentTest.cpp
@@ -19,6 +19,7 @@
 
 // Framework includes
 #include "DD4hep/LCDD.h"
+#include "DD4hep/Path.h"
 #include "DD4hep/DetAlign.h"
 #include "DD4hep/Printout.h"
 #include "DD4hep/Factories.h"
@@ -50,14 +51,19 @@ namespace  {
     ConditionUpdateCall* updateCall;
     LCDD&                lcdd;
     string               m_name;
-
+    PrintLevel           m_level = INFO;
+    long                 m_installCount = 0;
+    long                 m_accessCount = 0;
+    
     /// Initializing constructor
-    AlignmentSelector(LCDD& l) : lcdd(l), m_name("Selector")   {
+    AlignmentSelector(LCDD& l, PrintLevel p) : lcdd(l), m_name("DDDBAlignments"), m_level(p)   {
       // The alignment update call can be re-used over and over. It has not state.
       updateCall = new DDDB::DDDBAlignmentUpdateCall();
     }
     /// Default destructor
     virtual ~AlignmentSelector()   {
+      printout(INFO,m_name,"++ Installed alignment calls:     %ld", m_installCount);
+      printout(INFO,m_name,"++ Number of accessed alignments: %ld", m_accessCount);
       releasePtr(updateCall);
     }
     /// Recursive alignment collector
@@ -85,17 +91,22 @@ namespace  {
             b->detector = de;
             b.add(ConditionKey(cond->value));
             am.adoptDependency(b.release());
+            ++m_installCount;
           }
           else  {
             ::sprintf(fmt,"%03d %%-%ds %%-20s -> %%s",level+1,2*level+3);
-            printout(INFO,m_name,fmt,"","Alignment:    ", 
+            printout(m_level,m_name,fmt,"","Alignment:    ", 
                      !cond.isValid() ? (cat->condition+"  !!!UNRESOLVED!!!").c_str() : cat->condition.c_str());
           }
         }
       }
+      catch(const exception& e)  {
+        ::sprintf(fmt,"%03d %%-%ds %%s: %%-20s  Exception: %%s",level+1,2*level+3);
+        printout(INFO,m_name, fmt, "", de.path().c_str(), "[NO CATALOG availible]", e.what());
+      }
       catch(...)  {
-        ::sprintf(fmt,"%03d %%-%ds %%s%%-20s -> %%s",level+1,2*level+3);
-        printout(INFO,m_name, fmt, "", de.path().c_str(), "NO CATALOG availible!", "");
+        ::sprintf(fmt,"%03d %%-%ds %%s: %%-20s",level+1,2*level+3);
+        printout(INFO,m_name, fmt, "", de.path().c_str(), "[NO CATALOG availible]");
       }
       const DetElement::Children& c = de.children();
       for (DetElement::Children::const_iterator i = c.begin(); i != c.end(); ++i)
@@ -117,13 +128,14 @@ namespace  {
                             long time)
     {
       const IOVType* iovType = conds.iovType("epoch");
-      IOV  iov(iovType, IOV::Key(time,time));
+      IOV  iov(iovType, time);
       slice.adopt(createSlice(conds,*iovType));
-      ConditionsManager::Result res = conds.prepare(iov, *slice);
-      printout(INFO,"Conditions",
-               "+++ ConditionsUpdate: Total of %ld conditions (S:%ld,L:%ld,C:%ld,M:%ld) ... IOV:%s",
-               res.total(), res.selected, res.loaded, res.computed, res.missing, iov.str().c_str());
-      align.compute(*(slice->pool()));
+      ConditionsManager::Result cres = conds.prepare(iov, *slice);
+      AlignmentsManager::Result ares = align.compute(*(slice->pool()));
+      printout(INFO,"DDDBAlign",
+               "++ AlignmentManager: %ld conditions (S:%ld,L:%ld,C:%ld,M:%ld) (A:%ld,M:%ld) for IOV:%-12s",
+               cres.total(), cres.selected, cres.loaded, cres.computed, cres.missing, 
+               ares.computed, ares.missing, iov.str().c_str());
       return 1;
     }
     /// Access dependent alignment conditions from DetElement object using global and local keys
@@ -131,6 +143,7 @@ namespace  {
       typedef ConditionsDependencyCollection Deps;
       dd4hep_ptr<ConditionsSlice> slice;
       int ret = computeDependencies(slice, conds, align, time);
+
       if ( ret == 1 )  {
         const Deps& deps = align.knownDependencies();
         int count = 0;
@@ -144,23 +157,25 @@ namespace  {
             {
               Alignments::Alignment    a = c.get(k.hash,p);
               const Alignments::Delta& D = a.data().delta;
-              printout(INFO,"Alignment","++ [%16llX] (%11s-%8s-%5s) Cond:%p '%s'", k.hash,
+              printout(m_level,"Alignment","++ [%16llX] (%11s-%8s-%5s) Cond:%p '%s'", k.hash,
                        D.hasTranslation() ? "Translation" : "",
                        D.hasRotation() ? "Rotation" : "",
                        D.hasPivot() ? "Pivot" : "",
                        a.data().hasCondition() ? a.data().condition.ptr() : 0,
                        k.name.c_str());
               ++count;
+              ++m_accessCount;
             }
             {
               Alignments::Alignment    a = c.get("Alignment",p);
               const Alignments::Delta& D = a.data().delta;
-              printout(INFO,"Alignment","++ [%16llX] (%11s-%8s-%5s) Cond:%p 'Alignment'", k.hash,
+              printout(m_level,"Alignment","++ [%16llX] (%11s-%8s-%5s) Cond:%p 'Alignment'", k.hash,
                        D.hasTranslation() ? "Translation" : "",
                        D.hasRotation() ? "Rotation" : "",
                        D.hasPivot() ? "Pivot" : "",
                        a.data().hasCondition() ? a.data().condition.ptr() : 0);
               ++count;
+              ++m_accessCount;              
             }
           }
         }
@@ -169,24 +184,45 @@ namespace  {
       return ret;
     }
   };
-  //========================================================================
-  long make_time(int argc, char** argv) {
-    return argc>0 ? makeTime(argv[0],"%d-%m-%Y %H:%M:%S") : makeTime(2016,4,1,12);
-  }
 }
 
 //==========================================================================
 namespace  {
-  /// Plugin function:
-  /// Load dependent alignment conditions according to time stamps.
+
+  /// Plugin function: Load dependent alignment conditions according to time stamps.
   long dddb_derived_alignments(LCDD& lcdd, int argc, char** argv) {
-    long time = make_time(argc, argv);
-    AlignmentSelector selec(lcdd);
+    int turns = 1;
+    PrintLevel level = INFO;
+    long time = makeTime(2016,4,1,12);
+    
+    for(int i=0; i<argc; ++i)  {
+      if ( ::strcmp(argv[i],"-time")==0 )  {
+        time = makeTime(argv[++i],"%d-%m-%Y %H:%M:%S");
+        printout(level,"DDDB","Setting event time in %s to %s [%ld]",
+                 Path(__FILE__).filename().c_str(), argv[i-1], time);
+      }
+      else if ( ::strcmp(argv[i],"-print")==0 )  {
+        level = DD4hep::printLevel(argv[++i]);
+        printout(level,"DDDB","Setting print level in %s to %s [%d]",
+                 Path(__FILE__).filename().c_str(), argv[i-1], level);
+      }
+      else if ( ::strcmp(argv[i],"-turns")==0 )  {
+        turns = ::atol(argv[++i]);
+      }
+      else if ( ::strcmp(argv[i],"--help")==0 )      {
+        printout(level,"Plugin-Help","Usage: DDDB_DerivedAlignmentsTest --opt [--opt]        ");
+        printout(level,"Plugin-Help","  -time  <string>     Set event time Format: \"%%d-%%m-%%Y %%H:%%M:%%S\"");
+        printout(level,"Plugin-Help","  -print <value>      Printlevel for output      ");
+        printout(level,"Plugin-Help","  -help               Print this help message    ");
+        ::exit(EINVAL);
+      }
+    }
+    AlignmentSelector selec(lcdd, level);
     AlignmentsManager align(AlignmentsManager::from(lcdd));
     ConditionsManager conds(ConditionsManager::from(lcdd));
     int ret = selec.collect(conds,align,time);
     if ( ret == 1 )  {
-      for(int i=0; i<10; ++i)  {  {
+      for(int i=0; i<turns; ++i)  {  {
           long ti = time + i*3600;
           dd4hep_ptr<ConditionsSlice> slice;
           ret = selec.computeDependencies(slice,conds,align,ti);
@@ -202,11 +238,30 @@ DECLARE_APPLY(DDDB_DerivedAlignmentsTest,dddb_derived_alignments)
 //==========================================================================
 
 namespace  {
-  /// Plugin function:
-  /// Access dependent alignment conditions from DetElement object using global and local keys
+  /// Plugin function: Access dependent alignment conditions from DetElement object using global and local keys
   long dddb_access_alignments(LCDD& lcdd, int argc, char** argv) {
-    long time = make_time(argc, argv);
-    AlignmentSelector selec(lcdd);
+    PrintLevel level = INFO;
+    long time = makeTime(2016,4,1,12);
+    for(int i=0; i<argc; ++i)  {
+      if ( ::strcmp(argv[i],"-time")==0 )  {
+        time = makeTime(argv[++i],"%d-%m-%Y %H:%M:%S");
+        printout(level,"DDDB","Setting event time in %s to %s [%ld]",
+                 Path(__FILE__).filename().c_str(), argv[i-1], time);
+      }
+      else if ( ::strcmp(argv[i],"-print")==0 )  {
+        level = DD4hep::printLevel(argv[++i]);
+        printout(level,"DDDB","Setting print level in %s to %s [%d]",
+                 Path(__FILE__).filename().c_str(), argv[i-1], level);
+      }
+      else if ( ::strcmp(argv[i],"--help")==0 )      {
+        printout(level,"Plugin-Help","Usage: DDDB_AlignmentsAccessTest --opt [--opt]        ");
+        printout(level,"Plugin-Help","  -time  <string>     Set event time Format: \"%%d-%%m-%%Y %%H:%%M:%%S\"");
+        printout(level,"Plugin-Help","  -print <value>      Printlevel for output      ");
+        printout(level,"Plugin-Help","  -help               Print this help message    ");
+        ::exit(EINVAL);
+      }
+    }
+    AlignmentSelector selec(lcdd,level);
     AlignmentsManager align(AlignmentsManager::from(lcdd));
     ConditionsManager conds(ConditionsManager::from(lcdd));
     int ret = selec.collect(conds,align,time);
diff --git a/DDDB/src/DDDBAlignmentUpdateCall.cpp b/DDDB/src/DDDBAlignmentUpdateCall.cpp
index 0ce36179f..e69fbc425 100644
--- a/DDDB/src/DDDBAlignmentUpdateCall.cpp
+++ b/DDDB/src/DDDBAlignmentUpdateCall.cpp
@@ -49,6 +49,6 @@ DDDB::DDDBAlignmentUpdateCall::operator()(const ConditionKey& key, const UpdateC
   data.detector = det;
   printout(INFO,"AlignmentUpdate","++ Failed to access alignment-Delta from %s",
            cond->value.c_str());
-  ConditionPrinter()(cond);
+  ConditionPrinter("AlignmentUpdate")(cond);
   return target;
 }
diff --git a/DDDB/src/DDDBConditionPrinter.cpp b/DDDB/src/DDDBConditionPrinter.cpp
index 550df60e8..f2a598dfb 100644
--- a/DDDB/src/DDDBConditionPrinter.cpp
+++ b/DDDB/src/DDDBConditionPrinter.cpp
@@ -31,12 +31,13 @@ using Conditions::AbstractMap;
 using Conditions::Condition;
 
 /// Initializing constructor
-ConditionPrinter::ParamPrinter::ParamPrinter(string& p)  : m_prefix(p)  {
+ConditionPrinter::ParamPrinter::ParamPrinter(ConditionPrinter* p)  : m_parent(p)  {
 }
 
 /// Callback to output conditions information
 void ConditionPrinter::ParamPrinter::operator()(const AbstractMap::Params::value_type& obj)  const {
   const std::type_info& type = obj.second.typeInfo();
+  ++m_parent->m_numParam;
   if ( type == typeid(string) )  {
     string value = obj.second.get<string>().c_str();
     size_t len = value.length();
@@ -44,16 +45,16 @@ void ConditionPrinter::ParamPrinter::operator()(const AbstractMap::Params::value
       value.erase(100);
       value += "...";
     }
-    printout(INFO,"Condition","++ %s\t-> Param: %-16s %-8s -> %s",
-             m_prefix.c_str(),
+    printout(m_parent->m_printLevel,"Condition","++ %s\t-> Param: %-16s %-8s -> %s",
+             m_parent->m_prefix.c_str(),
              obj.first.c_str(), 
              obj.second.dataType().c_str(), 
-             value.c_str());	
+             value.c_str());
   }
   else if ( type == typeid(AbstractMap) )  {
     const AbstractMap& d= obj.second.get<AbstractMap>();
-    printout(INFO,"Condition","++ %s\t-> [%s] CL:%d %-8s -> %s",
-             m_prefix.c_str(),
+    printout(m_parent->m_printLevel,"Condition","++ %s\t-> [%s] CL:%d %-8s -> %s",
+             m_parent->m_prefix.c_str(),
              obj.first.c_str(), d.classID,
              obj.second.dataType().c_str(), 
              obj.second.str().c_str());	
@@ -65,8 +66,8 @@ void ConditionPrinter::ParamPrinter::operator()(const AbstractMap::Params::value
       value.erase(100);
       value += "...";
     }
-    printout(INFO,"Condition","++ %s\t-> [%s] %-8s -> %s",
-             m_prefix.c_str(),
+    printout(m_parent->m_printLevel,"Condition","++ %s\t-> [%s] %-8s -> %s",
+             m_parent->m_prefix.c_str(),
              obj.first.c_str(),
              obj.second.dataType().c_str(), 
              value.c_str());	
@@ -75,31 +76,44 @@ void ConditionPrinter::ParamPrinter::operator()(const AbstractMap::Params::value
 
 /// Initializing constructor
 ConditionPrinter::ConditionPrinter(const string& prefix, int flg, ParamPrinter* prt)
-  : ConditionsProcessor(0), m_prefix(prefix), m_print(prt), m_flag(flg)
+  : ConditionsProcessor(0), m_print(prt), m_prefix(prefix), m_flag(flg)
 {
 }
 
+/// Default destructor
+ConditionPrinter::~ConditionPrinter()   {
+  printout(INFO,"Condition","++ %s +++++++++++++ Printout summary:", m_prefix.c_str());
+  printout(INFO,"Condition","++ %s Number of conditions:       %8ld  [  dto. empty:%ld]",
+           m_prefix.c_str(), m_numCondition, m_numEmptyCondition);
+  printout(INFO,"Condition","++ %s Total Number of parameters: %8ld  [%7.3f Parameters/Condition]",
+           m_prefix.c_str(), m_numParam, double(m_numParam)/std::max(double(m_numCondition),1e0));
+}
+
+/// Set printout level for prinouts
+void ConditionPrinter::setPrintLevel(PrintLevel lvl)   {
+  m_printLevel = lvl;
+}
+
 /// Callback to output conditions information
 int ConditionPrinter::operator()(Condition cond)    {
   if ( cond.isValid() )   {
-    printout(INFO,"Condition","++ %s%s",m_prefix.c_str(),cond.str(m_flag).c_str());
+    printout(m_printLevel,"Condition","++ %s%s",m_prefix.c_str(),cond.str(m_flag).c_str());
     const AbstractMap& data = cond.get<AbstractMap>();
-    string new_prefix = m_prefix;
-    new_prefix.assign(m_prefix.length(),' ');
-    printout(INFO,"Condition","++ %s Path:%s Class:%d [%s]",
+    printout(m_printLevel,"Condition","++ %s Path:%s Class:%d [%s]",
              m_prefix.c_str(),
              cond.name(),
              data.classID, 
              cond.data().dataType().c_str());
+    ++m_numCondition;
     if ( !data.params.empty() )  {
-      if ( m_print )  {
-        const string& tmp = m_print->prefix();
-        m_print->setPrefix(new_prefix);
-        for_each(data.params.begin(), data.params.end(),*m_print);
-        m_print->setPrefix(tmp);
-        return 1;
-      }
-      for_each(data.params.begin(), data.params.end(),ParamPrinter(new_prefix));
+      const string tmp = m_prefix;
+      m_prefix.assign(tmp.length(),' ');
+      if ( !m_print ) m_print = new ParamPrinter(this);
+      for_each(data.params.begin(), data.params.end(),*m_print);
+      m_prefix = tmp;
+    }
+    else  {
+      ++m_numEmptyCondition;
     }
   }
   return 1;
@@ -107,17 +121,22 @@ int ConditionPrinter::operator()(Condition cond)    {
 
 /// Plugin function
 static void* create_dddb_conditions_printer(Geometry::LCDD& /* lcdd */, int argc, char** argv)  {
-  string prefix = "";
-  int    flags = 0;
+  int        flags = 0;
+  string     prefix = "";
+  PrintLevel prtLevel = INFO;
   for(int i=0; i<argc && argv[i]; ++i)  {
-    if ( 0 == ::strncmp("-prefix",argv[i],4) )
+    if ( 0 == ::strncmp("-prefix",argv[i],6) )
       prefix = argv[++i];
-    else if ( 0 == ::strncmp("-flags",argv[i],2) )
+    else if ( 0 == ::strncmp("-flags",argv[i],6) )
       flags = ::atol(argv[++i]);
+    else if ( 0 == ::strncmp("-printlevel",argv[i],6) )
+      prtLevel = DD4hep::printLevel(argv[++i]);
   }
-  DetElement::Processor* proc = flags
+  DDDB::ConditionPrinter* printer = flags
     ? new DDDB::ConditionPrinter(prefix,flags)
     : new DDDB::ConditionPrinter(prefix);
+  printer->setPrintLevel(prtLevel);
+  DetElement::Processor* proc = printer;
   return proc;
 }
 DECLARE_LCDD_CONSTRUCTOR(DDDB_ConditionsPrinter,create_dddb_conditions_printer)
diff --git a/DDDB/src/DDDBConditionsLoader.cpp b/DDDB/src/DDDBConditionsLoader.cpp
index 9ea7af5c7..d6e982afb 100644
--- a/DDDB/src/DDDBConditionsLoader.cpp
+++ b/DDDB/src/DDDBConditionsLoader.cpp
@@ -28,6 +28,7 @@
 #include "DD4hep/Factories.h"
 #include "DD4hep/Operators.h"
 #include "DD4hep/ConditionsData.h"
+#include "DD4hep/ConditionDerived.h"
 #include "DD4hep/objects/ConditionsInterna.h"
 #include "DDCond/ConditionsManagerObject.h"
 
@@ -41,6 +42,7 @@ using DD4hep::Geometry::LCDD;
 using DD4hep::Conditions::Condition;
 using DD4hep::Conditions::AbstractMap;
 using DD4hep::Conditions::RangeConditions;
+using DD4hep::Conditions::ConditionsSlice;
 typedef DD4hep::Conditions::RangeConditions RC;
 
 namespace {
@@ -49,14 +51,21 @@ namespace {
     REPLACE=2,
     NONE
   };
+  typedef DD4hep::Conditions::ConditionsDataLoader::RequiredItems Entries;
+  typedef DD4hep::Conditions::ConditionsDataLoader::LoadedItems   Loaded;
   struct CallArgs  {
     CMD                        cmd;
     Condition::key_type        key;
     Condition::iov_type&       iov;
-    RC&                        rc;
+    RC*                        rc;
+    Entries*                   work;
+    Loaded*                    loaded;
     CallArgs(CMD c, Condition::key_type k, Condition::iov_type& i, RC& r)
-      : cmd(c), key(k), iov(i), rc(r) {}
+      : cmd(c), key(k), iov(i), rc(&r), work(0), loaded(0) {}
+    CallArgs(CMD c, Condition::key_type k, Condition::iov_type& i, Entries& w, Loaded& l)
+      : cmd(c), key(k), iov(i), rc(0), work(&w), loaded(&l) {}
   };
+
   void* create_loader(LCDD& lcdd, int argc, char** argv)   {
     using DD4hep::Conditions::ConditionsManager;
     using DD4hep::Conditions::ConditionsManagerObject;
@@ -226,23 +235,21 @@ size_t DDDBConditionsLoader::update(const iov_type& req_validity,
     const Document*       doc = data.option<Document>();
     loadDocument(local_reader, doc->id, doc->name);
   }
-  m_mgr->callOnRegister(call,false);  
+  m_mgr->callOnRegister(call,false);
   return 0;
 }
 #endif
 
 /// Optimized update using conditions slice data
-size_t DDDBConditionsLoader::load_many(const iov_type& /* req_validity */,
-                                    EntryVector&    /* work         */,
-                                    EntryVector&    /* loaded       */,
-                                    EntryVector&    /* missing      */,
-                                    iov_type&       /* conditions_validity*/)
+size_t DDDBConditionsLoader::load_many(const iov_type& req_validity,
+                                       RequiredItems&  work,
+                                       LoadedItems&    loaded,
+                                       iov_type&       conditions_validity)
 {
-#if 0
-  CallArgs arg(REPLACE, 0, conditions_validity, conditions);
+  CallArgs arg(REPLACE, 0, conditions_validity, work, loaded);
   pair<ConditionsListener*,void*> call(this,&arg);
-  map<string,Condition::Object*> urls;
   DDDBReaderContext  local;
+  map<std::string,std::string>   urls;
 
   local.event_time  = req_validity.keyData.first;
   local.valid_since = 0;
@@ -252,26 +259,35 @@ size_t DDDBConditionsLoader::load_many(const iov_type& /* req_validity */,
   XML::UriContextReader local_reader(m_resolver, &local);
 
   /// First collect all required URIs
-  for(RC::const_iterator i=conditions.begin(); i!=conditions.end(); ++i)  {
-    Condition::Object* c = (*i).ptr();
-    size_t idx = c->address.find('#');
-    string url = (idx == string::npos) ? c->address : c->address.substr(0,idx);
-#if 0
-    printout(INFO,"DDDB","++ Need to update: %-40s [%16llX] --> %s",
-             c->name.c_str(), c->hash, url.c_str());
-#endif
-    urls.insert(make_pair(url,c));
+  for(const auto& i : work )  {
+    ConditionsSlice::Entry* e = i.second;
+    if ( e->dependency )  {
+      printout(INFO,"DDDB","++ CANNOT update derived: %-40s [%16llX]",
+               e->dependency->target.name.c_str(), e->dependency->target.hash);
+      continue;
+    }
+    std::string* address = e->loadinfo->data<std::string>();
+    if ( !address )  {
+      printout(INFO,"DDDB","++ CANNOT update condition: %-40s [%16llX]",
+               e->key.name.c_str(), e->key.hash);
+      continue;
+    }
+    size_t idx     = address->find('@');
+    string doc_nam = address->substr(0,idx);
+    string doc_url = address->substr(idx+1);
+    if ( (idx=doc_url.find('#')) != string::npos )
+      doc_url = doc_url.substr(0,idx);
+    //printout(DEBUG,"DDDB","++ Need to update: %-40s [%16llX] --> %s",
+    //         e->key.name.c_str(), e->key.hash, doc_url.c_str());
+    urls.insert(make_pair(doc_url,doc_nam));
   }
   /// Now load them. In the callbacks we can check if we got all required conditions
-  for(map<string,Condition::Object*>::const_iterator j=urls.begin(); j!=urls.end(); ++j)  {
-    Condition            cond = (*j).second;
-    const AbstractMap&   data = cond.get<AbstractMap>();
-    const Document*       doc = data.option<Document>();
-    loadDocument(local_reader, doc->id, doc->name);
+  for(const auto& url : urls )  {
+    loadDocument(local_reader, url.first, url.second);
+    // loadDocument(local_reader, doc->id, doc->name);
   }
   m_mgr->callOnRegister(call,false);
-#endif
-  except("ConditionsLoader","+++ update: Invalid call!");
+  //except("ConditionsLoader","+++ update: Invalid call!");
   return 0;
 }
 
@@ -282,22 +298,29 @@ void DDDBConditionsLoader::onRegisterCondition(Condition cond, void* param)  {
   if ( param )   {
     CallArgs* arg = (CallArgs*)param;
     Condition::Object* c = cond.ptr();
-    RC& r = arg->rc;
-    if ( arg->cmd == REPLACE )  {
-      RC::iterator i=std::find_if(r.begin(),r.end(),byName(cond));
-      if ( i != r.end() ) {
-        (*i) = cond;
-        printout(DEBUG,"DDDB","++ Got  MATCH: %-40s [%16llX] --> %s.",
+    if ( arg->rc )  {
+      RC& r = *arg->rc;
+      if ( arg->cmd == REPLACE )  {
+        RC::iterator i=std::find_if(r.begin(),r.end(),byName(cond));
+        if ( i != r.end() ) {
+          (*i) = cond;
+          printout(DEBUG,"DDDB","++ Got  MATCH: %-40s [%16llX] --> %s.",
+                   c->name.c_str(), c->hash, c->address.c_str());
+          arg->iov.iov_intersection(cond.iov());
+          return;
+        }
+        printout(INFO,"DDDB","++ Got update: %-40s [%16llX] --> %s.",
                  c->name.c_str(), c->hash, c->address.c_str());
+      }
+      else if ( arg->cmd == INSERT && arg->key == c->hash )   {
         arg->iov.iov_intersection(cond.iov());
-        return;
+        r.insert(r.end(),cond);
       }
-      printout(INFO,"DDDB","++ Got update: %-40s [%16llX] --> %s.",
-               c->name.c_str(), c->hash, c->address.c_str());
     }
-    else if ( arg->cmd == INSERT && arg->key == c->hash )   {
-      arg->iov.iov_intersection(cond.iov());
-      r.insert(r.end(),cond);
+    else  {
+      key_type     key    = cond.key();
+      LoadedItems& loaded = *arg->loaded;
+      loaded.insert(make_pair(key,cond));
     }
   }
 }
diff --git a/DDDB/src/DDDBDerivedCondTest.cpp b/DDDB/src/DDDBDerivedCondTest.cpp
index a9870b035..47dfaebee 100644
--- a/DDDB/src/DDDBDerivedCondTest.cpp
+++ b/DDDB/src/DDDBDerivedCondTest.cpp
@@ -19,6 +19,7 @@
 
 // Framework includes
 #include "DD4hep/LCDD.h"
+#include "DD4hep/Path.h"
 #include "DD4hep/Plugins.h"
 #include "DD4hep/Printout.h"
 #include "DD4hep/Factories.h"
@@ -47,6 +48,12 @@ using Geometry::DetElement;
 /// Anonymous namespace for plugins
 namespace  {
 
+  /// Helper containing shared typedefs
+  /**
+   *  \author  M.Frank
+   *  \version 1.0
+   *  \ingroup DD4HEP_CONDITIONS
+   */
   class DataTypes  {
   public:
     typedef AbstractMap                      Map;
@@ -57,6 +64,29 @@ namespace  {
     typedef DDDB::ConditionPrinter           _Printer;
   };
 
+  /// Helper containing shared context
+  /**
+   *  \author  M.Frank
+   *  \version 1.0
+   *  \ingroup DD4HEP_CONDITIONS
+   */
+  struct CallContext {
+    long              numCall1 = 0;
+    long              numCall2 = 0;
+    long              numCall3 = 0;
+    long              numFail1 = 0;
+    long              numFail2 = 0;
+    long              numFail3 = 0;
+    long              numBuild1 = 0;
+    long              numBuild2 = 0;
+    long              numBuild3 = 0;
+    long              numAlignments = 0;
+    long              numNoCatalogs = 0;
+    PrintLevel        level = INFO;
+    DDDB::ConditionPrinter printer;
+    CallContext() : printer("") {}
+  };
+  
   /// Specialized conditions update callback for alignments
   /**
    *  Used by clients to update a condition.
@@ -67,25 +97,30 @@ namespace  {
    */
   class ConditionUpdate1 : public ConditionUpdateCall, public DataTypes  {
   public:
-    ConditionUpdate1()          {    }
+    CallContext& context;
+    ConditionUpdate1(CallContext& c) : context(c)  {
+      ++context.numCall1;
+    }
     virtual ~ConditionUpdate1() {    }
     /// Interface to client Callback in order to update the condition
-    virtual Condition operator()(const ConditionKey& key, const Context& context)  {
-      printout(INFO,"ConditionUpdate1","++ Building dependent condition: %s",key.name.c_str());
+    virtual Condition operator()(const ConditionKey& key, const Context& ctxt)  {
+      printout(context.level,"ConditionUpdate1","++ Building dependent condition: %s",key.name.c_str());
       Condition    target(key.name,"Alignment");
       Data&        data  = target.bind<Data>();
-      Condition    cond0 = context.condition(0);
+      Condition    cond0 = ctxt.condition(0);
       const Map&   src0  = cond0.get<Map>();
       const Param& par0  = src0.firstParam().second;
       if ( par0.typeInfo() == typeid(Delta) )  {
         const Delta& delta = src0.first<Delta>();
         data.delta         = delta;
         data.flag          = Data::HAVE_NONE;
+        ++context.numBuild1;
       }
       else  {
-        printout(INFO,"ConditionUpdate1","++ Failed to access Delta from %s",
+        ++context.numFail1;
+        printout(context.level,"ConditionUpdate1","++ Failed to access Delta from %s",
                  cond0->value.c_str());
-        _Printer()(cond0);
+        context.printer(cond0);
       }
       //data.condition   = target;
       return target;
@@ -101,28 +136,33 @@ namespace  {
    */
   class ConditionUpdate2 : public ConditionUpdateCall, public DataTypes  {
   public:
-    ConditionUpdate2()          {    }
+    CallContext& context;
+    ConditionUpdate2(CallContext& c) : context(c)  {
+      ++context.numCall2;
+    }
     virtual ~ConditionUpdate2() {    }
     /// Interface to client Callback in order to update the condition
-    virtual Condition operator()(const ConditionKey& key, const Context& context)  {
-      printout(INFO,"ConditionUpdate2","++ Building dependent condition: %s",key.name.c_str());
+    virtual Condition operator()(const ConditionKey& key, const Context& ctxt)  {
+      printout(context.level,"ConditionUpdate2","++ Building dependent condition: %s",key.name.c_str());
       Condition     target(key.name,"Alignment");
       Data&         data  = target.bind<Data>();
-      Condition     cond0 = context.condition(0);
+      Condition     cond0 = ctxt.condition(0);
       const Map&    src0  = cond0.get<Map>();      
       const Param&  par0  = src0.firstParam().second;
 
       if ( par0.typeInfo() == typeid(Delta) )  {
         const Delta& delta0 = src0.first<Delta>();
-        const Data&  delta1 = context.get<Data>(1);
+        const Data&  delta1 = ctxt.get<Data>(1);
         data.delta          = delta0;
         data.delta          = delta1.delta;
         data.flag           = Data::HAVE_NONE;
+        ++context.numBuild2;
       }
       else  {
-        printout(INFO,"ConditionUpdate2","++ Failed to access Delta from %s",
+        ++context.numFail2;
+        printout(context.level,"ConditionUpdate2","++ Failed to access Delta from %s",
                  cond0->value.c_str());
-        _Printer()(cond0);
+        context.printer(cond0);
       }
       //data.condition   = target;
       return target;
@@ -138,30 +178,35 @@ namespace  {
    */
   class ConditionUpdate3 : public ConditionUpdateCall, public DataTypes  {
   public:
-    ConditionUpdate3()          {    }
+    CallContext& context;
+    ConditionUpdate3(CallContext& c) : context(c)  {
+      ++context.numCall3;
+    }
     virtual ~ConditionUpdate3() {    }
     /// Interface to client Callback in order to update the condition
-    virtual Condition operator()(const ConditionKey& key, const Context& context)  {
-      printout(INFO,"ConditionUpdate3","++ Building dependent condition: %s",key.name.c_str());
+    virtual Condition operator()(const ConditionKey& key, const Context& ctxt)  {
+      printout(context.level,"ConditionUpdate3","++ Building dependent condition: %s",key.name.c_str());
       Condition    target(key.name,"Alignment");
       Data&        data  = target.bind<Data>();
-      Condition    cond0 = context.condition(0);
+      Condition    cond0 = ctxt.condition(0);
       const Map&   src0  = cond0.get<Map>();
       const Param& par0  = src0.firstParam().second;
 
       if ( par0.typeInfo() == typeid(Delta) )  {
         const Delta& delta0 = src0.first<Delta>();
-        const Data&  delta1 = context.get<Data>(1);
-        const Data&  delta2 = context.get<Data>(2);
+        const Data&  delta1 = ctxt.get<Data>(1);
+        const Data&  delta2 = ctxt.get<Data>(2);
         data.delta          = delta0;
         data.delta          = delta1.delta;
         data.delta          = delta2.delta;
         data.flag           = Data::HAVE_NONE;
+        ++context.numBuild3;
       }
       else  {
-        printout(INFO,"ConditionUpdate2","++ Failed to access Delta from %s",
+        ++context.numFail3;
+        printout(context.level,"ConditionUpdate2","++ Failed to access Delta from %s",
                  cond0->value.c_str());
-        _Printer()(cond0);
+        context.printer(cond0);
       }
       //data.condition = target;
       return target;
@@ -182,18 +227,37 @@ namespace  {
     RangeConditions   m_allConditions;
     Dependencies      m_allDependencies;
     ConditionsManager m_manager;
-    struct Counters {
-      size_t numAlignments;
-      size_t numNoCatalogs;
-      void reset() { numAlignments=numNoCatalogs=0; }
-    } m_counters;
-
+    PrintLevel        m_level;
+    CallContext       m_context;
+    
+    /// Default constructor
+    ConditionsSelector() = delete;
     /// Initializing constructor
-    ConditionsSelector(ConditionsAccess mgr) : m_manager(mgr) {
+    ConditionsSelector(ConditionsAccess mgr, PrintLevel lvl)
+      : m_manager(mgr), m_level(lvl)
+    {
+      m_context.level = lvl;
       Operators::collectAllConditions(mgr, m_allConditions);
     }
-
+    /// Default destructor
     virtual ~ConditionsSelector()   {
+      printout(INFO,"Conditions","+++ Total number of conditions:   %ld", m_allConditions.size());
+      printout(INFO,"Conditions","+++ Total number of dependencies: %ld", m_allDependencies.size());
+      printout(INFO,"Conditions","+++ Number of Type1 instances:    %ld", m_context.numCall1);
+      printout(INFO,"Conditions","+++ Number of Type1 callbacks:    %ld", m_context.numBuild1);
+      printout(INFO,"Conditions","+++ Number of Type1 failures:     %ld", m_context.numFail1);
+      printout(INFO,"Conditions","+++ Number of Type2 instances:    %ld", m_context.numCall2);
+      printout(INFO,"Conditions","+++ Number of Type2 callbacks:    %ld", m_context.numBuild2);
+      printout(INFO,"Conditions","+++ Number of Type2 failures:     %ld", m_context.numFail2);
+      printout(INFO,"Conditions","+++ Number of Type3 instances:    %ld", m_context.numCall3);
+      printout(INFO,"Conditions","+++ Number of Type3 callbacks:    %ld", m_context.numBuild3);
+      printout(INFO,"Conditions","+++ Number of Type3 failures:     %ld", m_context.numFail3);
+      printout(INFO,"Conditions","+++ Total Number of instances:    %ld",
+               m_context.numCall1+m_context.numCall2+m_context.numCall3);
+      printout(INFO,"Conditions","+++ Total Number of callbacks:    %ld",
+               m_context.numBuild1+m_context.numBuild2+m_context.numBuild3);
+      printout(INFO,"Conditions","+++ Total Number of failures:     %ld",
+               m_context.numFail1+m_context.numFail2+m_context.numFail3);
       m_allDependencies.clear();
     }
 
@@ -221,29 +285,29 @@ namespace  {
     long collectDependencies(DetElement de, int level)  {
       char fmt[64], text[256];
       DDDB::Catalog* cat = 0;
-      DDDB::ConditionPrinter prt;
+      string pref = m_context.printer.prefix();
       const DetElement::Children& c = de.children();
 
       ::snprintf(fmt,sizeof(fmt),"%%-%ds-> ",2*level+5);
       ::snprintf(text,sizeof(text),fmt,"");
-      prt.setPrefix(text);
+      m_context.printer.setPrefix(text);
 
       try  {
         ::sprintf(fmt,"%03d %%-%ds Detector: %%s #Dau:%%d VolID:%%p",level+1,2*level+1);
-        printout(INFO,m_name,fmt,"",de.path().c_str(),int(c.size()),(void*)de.volumeID());
+        printout(m_level,m_name,fmt,"",de.path().c_str(),int(c.size()),(void*)de.volumeID());
         cat = de.extension<DDDB::Catalog>();
-        ::sprintf(fmt,"%03d %%-%ds %%-20s -> %%s",level+1,2*level+3);
+        ::sprintf(fmt,"%03d %%-%ds %%-20s -> %%s", level+1, 2*level+3);
         if ( !cat->condition.empty() )  {
           RangeConditions rc = findCond(cat->condition);
-          printout(INFO,m_name,fmt,"","Alignment:    ", 
+          printout(m_level,m_name,fmt,"","Alignment:    ", 
                    rc.empty() ? (cat->condition+"  !!!UNRESOLVED!!!").c_str() : cat->condition.c_str());
           if ( !rc.empty() )   {
             ConditionKey target1(cat->condition+"/derived_1");
             ConditionKey target2(cat->condition+"/derived_2");
             ConditionKey target3(cat->condition+"/derived_3");
-            DependencyBuilder build_1(target1, new ConditionUpdate1());
-            DependencyBuilder build_2(target2, new ConditionUpdate2());
-            DependencyBuilder build_3(target3, new ConditionUpdate3());
+            DependencyBuilder build_1(target1, new ConditionUpdate1(m_context));
+            DependencyBuilder build_2(target2, new ConditionUpdate2(m_context));
+            DependencyBuilder build_3(target3, new ConditionUpdate3(m_context));
 
             build_1->detector = de;
             build_2->detector = de;
@@ -264,14 +328,15 @@ namespace  {
             m_allDependencies.insert(build_2.release());
             m_allDependencies.insert(build_3.release());
           }
-          ++m_counters.numAlignments;
+          ++m_context.numAlignments;
         }
       }
       catch(...)  {
         ::sprintf(fmt,"%03d %%-%ds %%s%%-20s -> %%s",level+1,2*level+3);
-        printout(INFO,m_name, fmt, "", de.path().c_str(), "NO CATALOG availible!", "");
-        ++m_counters.numNoCatalogs;
+        printout(m_level,m_name, fmt, "", de.path().c_str(), "NO CATALOG availible!", "");
+        ++m_context.numNoCatalogs;
       }
+      m_context.printer.setPrefix(pref);
       for (DetElement::Children::const_iterator i = c.begin(); i != c.end(); ++i)
         collectDependencies((*i).second,level+1);
       return 1;
@@ -284,7 +349,7 @@ namespace  {
       IOV  iov(iovType, IOV::Key(time,time));
       slice->insert(deps);
       m_manager.prepare(iov, *slice);
-      printout(INFO,"Conditions",
+      printout(m_level,"Conditions",
                "+++ ConditionsUpdate: Updated %ld conditions... IOV:%s",
                long(slice->pool()->size()), iov.str().c_str());
       slice->pool()->clear();
@@ -296,9 +361,29 @@ namespace  {
   /// Plugin function
   /// Load, compute and access derived conditions
   long dddb_derived_alignments(LCDD& lcdd, int argc, char** argv) {
-    long time = argc>0 ? makeTime(argv[0],"%d-%m-%Y %H:%M:%S") : makeTime(2016,4,1,12);
-    ConditionsManager manager = ConditionsManager::from(lcdd);
-    ConditionsSelector selector(manager);
+    PrintLevel level = INFO;
+    long time = makeTime(2016,4,1,12);
+    for(int i=0; i<argc; ++i)  {
+      if ( ::strcmp(argv[i],"-time")==0 )  {
+        time = makeTime(argv[++i],"%d-%m-%Y %H:%M:%S");
+        printout(level,"DDDB","Setting event time in %s to %s [%ld]",
+                 Path(__FILE__).filename().c_str(), argv[i-1], time);
+      }
+      else if ( ::strcmp(argv[i],"-print")==0 )  {
+        level = DD4hep::printLevel(argv[++i]);
+        printout(level,"DDDB","Setting print level in %s to %s [%d]",
+                 Path(__FILE__).filename().c_str(), argv[i-1], level);
+      }
+      else if ( ::strcmp(argv[i],"--help")==0 )      {
+        printout(level,"Plugin-Help","Usage: DDDB_DerivedCondTest --opt [--opt]        ");
+        printout(level,"Plugin-Help","  -time  <string>     Set event time Format: \"%%d-%%m-%%Y %%H:%%M:%%S\"");
+        printout(level,"Plugin-Help","  -print <value>      Printlevel for output      ");
+        printout(level,"Plugin-Help","  -help               Print this help message    ");
+        ::exit(EINVAL);
+      }
+    }
+
+    ConditionsSelector selector(ConditionsManager::from(lcdd), level);
     int ret = selector.collectDependencies(lcdd.world(), 0);
     if ( ret == 1 )  {
       ret = selector.computeDependencies(time);
diff --git a/DDDB/src/DDDBPlugins.cpp b/DDDB/src/DDDBPlugins.cpp
index 338eda3e2..1ef1d605b 100644
--- a/DDDB/src/DDDBPlugins.cpp
+++ b/DDDB/src/DDDBPlugins.cpp
@@ -22,6 +22,7 @@
 #include "DD4hep/Plugins.h"
 #include "DD4hep/Printout.h"
 #include "DD4hep/Factories.h"
+#include "DD4hep/DetAlign.h"
 #include "DD4hep/DetConditions.h"
 #include "DD4hep/ConditionsData.h"
 #include "DD4hep/objects/DetectorInterna.h"
@@ -34,14 +35,40 @@ using namespace std;
 using namespace DD4hep;
 using DD4hep::Geometry::LCDD;
 
+/// Anonymous namespace for plugins
+namespace {
+  PrintLevel s_PrintLevel = INFO;
+}
+
+/// Plugin function
+static long dddb_plugin_print_level(LCDD& /* lcdd */, int argc, char** argv) {
+  for(int i=0; i<argc; ++i)  {
+    if ( ::strcmp(argv[i],"--print")==0 )  {
+      s_PrintLevel = DD4hep::printLevel(argv[++i]);
+      printout(INFO,"DDDB","Setting print level for %s to %s [%d]",__FILE__,argv[i-1],s_PrintLevel);
+      return 1;
+    }
+  }
+  return 0;
+}
+DECLARE_APPLY(DDDB_PluginLevel,dddb_plugin_print_level)
+
 /// Plugin function
 static long dddb_dump_conditions(LCDD& lcdd, int , char** ) {
-  const void* args[] = { "-processor", "DDDB_ConditionsPrinter", "-prefix", "DDDB", "-end-processor", 0};
-  lcdd.apply("DD4hep_ConditionsDump", 5, (char**)args);
+  const void* args[] = { "-processor", "DDDB_ConditionsPrinter", "-prefix", "DDDB", "-printlevel", "INFO", "-end-processor", 0};
+  lcdd.apply("DD4hep_ConditionsDump", 7, (char**)args);
   return 1;
 }
 DECLARE_APPLY(DDDB_ConditionsDump,dddb_dump_conditions)
 //==========================================================================
+/// Plugin function
+static long dddb_dump_conditions_summary(LCDD& lcdd, int , char** ) {
+  const void* args[] = { "-processor", "DDDB_ConditionsPrinter", "-prefix", "DDDB", "-printlevel", "DEBUG", "-end-processor", 0};
+  lcdd.apply("DD4hep_ConditionsDump", 7, (char**)args);
+  return 1;
+}
+DECLARE_APPLY(DDDB_ConditionsSummary,dddb_dump_conditions_summary)
+//==========================================================================
 
 
 /// Anonymous namespace for plugins
@@ -108,7 +135,7 @@ namespace {
    *  @version 1.0
    *  @date    01/04/2014
    */
-  template <int flag> long dump_detelement_tree(LCDD& lcdd, int argc, char** argv) {
+  long dump_det_tree(LCDD& lcdd, int flag, int argc, char** argv) {
 
     using Conditions::RangeConditions;
     using Conditions::AbstractMap;
@@ -118,13 +145,6 @@ namespace {
     using DDDB::ConditionPrinter;
     using DDDB::Catalog;
 
-    struct Counters {
-      long totConditions;
-      long numConditions;
-      long numAlignments;
-      long numNoCatalogs;
-      void reset() { totConditions=numConditions=numAlignments=numNoCatalogs=0; }
-    };
 
     /// Callback object to print selective information
     /**
@@ -132,52 +152,69 @@ namespace {
      *  @version 1.0
      *  @date    01/04/2014
      */
-    struct Actor {
+    struct DumpActor {
+      struct Counters {
+        long totConditions;
+        long numConditions;
+        long numAlignments;
+        long numDetElements;
+        long numDetAlignmentKeys;
+        long numDetConditionKeys;
+        long numNoCatalogs;
+        long numDetPlacements;
+        void reset() {
+          totConditions=numConditions=numAlignments=numNoCatalogs=0;
+          numDetElements=numDetConditionKeys=numDetAlignmentKeys=0;
+          numDetPlacements=0;
+        }
+      };
+
       /// Container with all known conditions
       vector<pair<int,Condition> >  m_allConditions;
-      Counters        m_counters;
-      bool            m_sensitivesOnly;
-      bool            m_dumpConditions;
-      string          m_name;
-      LCDD&           m_lcdd;
-      IOV             m_iov;
+      ConditionPrinter m_printer;
+      ConditionPrinter m_condPrinter;
+      ConditionPrinter m_alignPrinter;
+      Counters         m_counters;
+      int              m_flag;
+      bool             m_sensitivesOnly;
+      bool             m_dumpConditions;
+      string           m_name;
+      LCDD&            m_lcdd;
+      IOV              m_iov;
 
       /// Standard constructor
-      Actor(LCDD& l, bool sens, bool dmp) : m_sensitivesOnly(sens), m_dumpConditions(dmp), m_lcdd(l), m_iov(0) {}
+      DumpActor(LCDD& l, int flg, bool sens, bool dmp)
+        : m_printer("DDDBDetectors"), m_condPrinter("DDDBConditions"), m_alignPrinter("DDDBAlignments"),
+          m_flag(flg), m_sensitivesOnly(sens), m_dumpConditions(dmp), m_lcdd(l), m_iov(0)
+      {
+        m_printer.setPrintLevel(s_PrintLevel);
+        m_condPrinter.setPrintLevel(s_PrintLevel);
+        m_alignPrinter.setPrintLevel(s_PrintLevel);
+      }
 
       /// Standard destructor
-      ~Actor()  {
-        if ( flag > 1 )  {
-          printout(INFO,m_name,"++ Number of DetElements without catalog: %8ld",m_counters.numNoCatalogs);
-          printout(INFO,m_name,"++ Number of attached alignments:         %8ld",m_counters.numAlignments);
-          if ( flag > 2 )  {
-            printout(INFO,m_name,"++ Number of attached conditions:         %8ld",m_counters.numConditions);
-            printout(INFO,m_name,"++ Total number of conditions:            %8ld",m_counters.totConditions);
+      ~DumpActor()  {
+        printout(INFO,m_name,"++ DDDB: Number of DetElements in the geometry: %8ld",m_counters.numDetElements);
+        printout(INFO,m_name,"++ DDDB: Number of DetElement placements:       %8ld",m_counters.numDetPlacements);
+        printout(INFO,m_name,"++ DDDB: Number of DetElement condition keys:   %8ld",m_counters.numDetConditionKeys);
+        printout(INFO,m_name,"++ DDDB: Number of DetElement alignment keys:   %8ld",m_counters.numDetAlignmentKeys);
+        if ( m_flag > 1 )  {
+          printout(INFO,m_name,"++ DDDB: Number of DetElements without catalog: %8ld",m_counters.numNoCatalogs);
+          printout(INFO,m_name,"++ DDDB: Number of attached conditions:         %8ld",m_counters.numConditions);
+          printout(INFO,m_name,"++ DDDB: Number of attached alignments:         %8ld",m_counters.numAlignments);
+          if ( m_flag > 2 )  {
+            printout(INFO,m_name,"++ DDDB: Total number of conditions:            %8ld",m_counters.totConditions);
           }
         }
-#if 0
-        printout(INFO,m_name,"**************** DDDB Detector dump: Conditions Usage ***************************");
-        for(const auto& ic : m_allConditions )  {
-          Condition cond = ic.second;
-          const AbstractMap& data = cond.get<AbstractMap>();
-          const DDDB::Document* doc = data.option<DDDB::Document>();
-          if ( doc ) 
-            printout(INFO,m_name,"++ Usage: %d Cond: %s/%s  -> %s [%16llX]",
-                     ic.first, doc->name.c_str(), cond->name.c_str(), cond->value.c_str(), cond->hash);
-          else
-            printout(INFO,m_name,"++ Usage: %d Cond: ---/%s  -> %s [%16llX]",
-                     ic.first, cond->name.c_str(), cond->value.c_str(), cond->hash);
-        }
-#endif
         printout(INFO,m_name,"*********************************************************************************");
       }
 
       /// Initialization
-      Actor& init()  {
+      DumpActor& init()  {
         m_counters.reset();
         m_allConditions.clear();
 
-        if ( flag >= 3 )   {
+        if ( m_flag >= 3 )   {
           RangeConditions rc;
           Conditions::Operators::collectAllConditions(m_lcdd, rc);
           m_iov.reset().invert();
@@ -189,9 +226,8 @@ namespace {
           }
           m_iov.set(m_iov.keyData.first);
           if ( m_dumpConditions )   {
-            DDDB::ConditionPrinter prt;
             printout(INFO,m_name,"**************** DDDB Detector dump: ALL Conditions *****************************");
-            for(Condition cond : rc ) prt(cond);
+            for(Condition cond : rc ) m_printer(cond);
             printout(INFO,m_name,"*********************************************************************************");
           }
         }
@@ -224,19 +260,30 @@ namespace {
       }
       /// __________________________________________________________________________________
       void printDetElement(int level, DetElement de,
-                           ConditionPrinter& prt,
                            bool with_placement=false,
                            bool with_keys=false,
                            bool with_values=false)
       {
         char fmt[128];
         const DetElement::Children& c = de.children();
+        ++m_counters.numDetElements;
         ::sprintf(fmt,"%03d %%-%ds Detector: %%s #Dau:%%d VolID:%%p Place:%%p",level+1,2*level+1);
-        printout(INFO, m_name, fmt, "", de.path().c_str(), int(c.size()),
+        printout(s_PrintLevel, m_name, fmt, "", de.path().c_str(), int(c.size()),
                  (void*)de.volumeID(), (void*)de.placement().ptr());
+        if ( de.placement().isValid() ) {
+          ++m_counters.numDetPlacements;
+        }
+        if ( de.hasConditions() )  {
+          Conditions::DetConditions dc(de);
+          m_counters.numDetConditionKeys += dc.conditions().numKeys();
+        }
+        if ( de.hasAlignments() )  {
+          Alignments::DetAlign da(de);
+          m_counters.numDetAlignmentKeys += da.alignments().numKeys();
+        }
         if ( with_placement )  {
           ::sprintf(fmt,"%03d %%-%ds Placement: %%s",level+1,2*level+3);
-          printout(INFO,m_name,fmt,"",de.placementPath().c_str());
+          printout(s_PrintLevel,m_name,fmt,"",de.placementPath().c_str());
         }
         if ( (with_keys || with_values) && de.hasConditions() )  {
           Conditions::DetConditions dc(de);
@@ -244,101 +291,105 @@ namespace {
           ::sprintf(fmt,"%03d %%-%ds Key: %%16llX -> %%16llX -> %%s",level+1,2*level+3);
           for(const auto& i : cont->keys )  {
             if ( with_keys )   {
-              printout(INFO,m_name,fmt,"",i.first,i.second.first, i.second.second.c_str());
+              printout(s_PrintLevel,m_name,fmt,"",i.first,i.second.first, i.second.second.c_str());
             }
             if ( with_values )   {
               Condition::key_type key = i.second.first;
               Condition cond = dc.get(key, m_iov);
-              prt(cond);
+              m_printer(cond);
             }
           }
         }
       }
       /// __________________________________________________________________________________
-      void printConditionInfo(int level, Catalog* cat, ConditionPrinter& prt, bool with_elements=false)   {
+      void printConditionInfo(int level, Catalog* cat, bool with_elements=false)   {
         if ( cat && !cat->conditioninfo.empty() )   {
           char fmt[128];
+          ++m_counters.numConditions;
           ::sprintf(fmt,"%03d %%-%ds Cond:%%-20s -> %%s",level+1,2*level+3);
           for(const auto& i : cat->conditioninfo )  {
             const string& cond_name = i.second;
-            ++m_counters.numConditions;
             if ( with_elements )  {
               RangeConditions rc = findCond(cond_name);
-              printout(INFO,m_name,fmt,"",i.first.c_str(), 
+              printout(s_PrintLevel,m_name,fmt,"",i.first.c_str(), 
                        rc.empty() ? (cond_name+"  !!!UNRESOLVED!!!").c_str() : cond_name.c_str());
-              for(Condition cond : rc ) prt(cond);
+              for(Condition cond : rc ) m_condPrinter(cond);
               continue;
             }
-            printout(INFO,m_name,fmt,"",i.first.c_str(),cond_name.c_str());
+            printout(s_PrintLevel,m_name,fmt,"",i.first.c_str(),cond_name.c_str());
           }
         }
       }
       /// __________________________________________________________________________________
-      void printAlignment(int level, Catalog* cat, ConditionPrinter& prt, bool with_values=false)   {
+      void printAlignment(int level, Catalog* cat, bool with_values=false)   {
         if ( cat && !cat->condition.empty() )  {
           char fmt[128];
           ::sprintf(fmt,"%03d %%-%ds %%-20s -> %%s",level+1,2*level+3);
           ++m_counters.numAlignments;
           if ( with_values )  {
             RangeConditions rc = findCond(cat->condition);
-            printout(INFO,m_name,fmt,"","Alignment:", 
+            printout(s_PrintLevel,m_name,fmt,"","Alignment:", 
                      rc.empty() ? (cat->condition+"  !!!UNRESOLVED!!!").c_str() : cat->condition.c_str());
             for(const auto& i : rc)
-              prt(i);
+              m_printer(i);
             return;
           }
-          printout(INFO,m_name,fmt,"","Alignment:",cat->condition.c_str());
+          printout(s_PrintLevel,m_name,fmt,"","Alignment:",cat->condition.c_str());
         }
       }
       /// __________________________________________________________________________________
       long dump(DetElement de, int level)  {
         char fmt[64], text[512];
         Catalog* cat = 0;
-        ConditionPrinter prt;
         const DetElement::Children& c = de.children();
         ::snprintf(fmt,sizeof(fmt),"%%-%ds-> ",2*level+5);
         ::snprintf(text,sizeof(text),fmt,"");
-        prt.setPrefix(text);
+        m_printer.setPrefix(text);
         try  {
           if ( !m_sensitivesOnly || 0 != de.volumeID() )  {
-            switch(flag)  {
+            switch(m_flag)  {
             case 0:
-              printDetElement(level, de, prt, false, false);
+              printDetElement(level, de, false, false);
               break;
             case 1:
-              printDetElement(level, de, prt, false, false);
+              printDetElement(level, de, false, false);
               cat = de.extension<Catalog>();
-              printAlignment(level, cat, prt, false);
-              printConditionInfo(level, cat, prt, false);
+              printAlignment(level, cat, false);
+              printConditionInfo(level, cat, false);
               break;
             case 2:
-              printDetElement(level, de, prt, true, true);
+              printDetElement(level, de, true, true);
               cat = de.extension<Catalog>();
-              printAlignment(level, cat, prt, false);
-              printConditionInfo(level, cat, prt, false);
+              printAlignment(level, cat, false);
+              printConditionInfo(level, cat, false);
               break;
             case 3:
-              printDetElement(level, de, prt, false, false);
+              printDetElement(level, de, false, false);
               cat = de.extension<Catalog>();
-              printAlignment(level, cat, prt, true);
+              printAlignment(level, cat, true);
               break;
             case 4:
-              printDetElement(level, de, prt, true, true);
+              printDetElement(level, de, true, true);
               cat = de.extension<Catalog>();
-              printAlignment(level, cat, prt, true);
-              printConditionInfo(level, cat, prt, true);
+              printAlignment(level, cat, true);
+              printConditionInfo(level, cat, true);
               break;
             case 5:
-              printDetElement(level, de, prt, true, true, true);
+              printDetElement(level, de, true, true, true);
               break;
             default:
               break;
             }
           }
         }
+        catch(const exception& e)  {
+          ::sprintf(fmt,"%03d %%-%ds Exception from: %%s %%-20s %%s",level+1,2*level+3);
+          printout(INFO, m_name, fmt, "", de.path().c_str(), "[NO CATALOG availible]",e.what());
+          ++m_counters.numNoCatalogs;
+        }
         catch(...)  {
-          ::sprintf(fmt,"%03d %%-%ds %%s%%-20s -> %%s",level+1,2*level+3);
-          printout(INFO,m_name, fmt, "", de.path().c_str(), "NO CATALOG availible!", "");
+          ::sprintf(fmt,"%03d %%-%ds Exception from: %%s %%-20s",level+1,2*level+3);
+          printout(INFO, m_name, fmt, "", de.path().c_str(), "[NO CATALOG availible]");
           ++m_counters.numNoCatalogs;
         }
         for (const auto& i : c)
@@ -346,20 +397,24 @@ namespace {
         return 1;
       }
     };
-
     bool dump_sensitive_only = false, dump_all_cond = false;
     for(int i=0; i<argc; ++i)  {
-      if ( ::strcmp(argv[i],"--sensitive")==0 ) { dump_sensitive_only = true; }
-      if ( ::strcmp(argv[i],"--dump")==0      ) { dump_all_cond = true;       }
-      if ( ::strcmp(argv[i],"--help")==0 ) {
-        printout(INFO,"Plugin-Help","Usage: DDDBDetectorDump --opt [--opt]");
-        printout(INFO,"Plugin-Help","  --sensitive          Only use sensitive elements");
-        printout(INFO,"Plugin-Help","  --dump               Print conditions inventory");
-        printout(INFO,"Plugin-Help","  --help               Print this help message");
+      if ( ::strcmp(argv[i],"-sensitive")==0 )   { dump_sensitive_only = true; }
+      else if ( ::strcmp(argv[i],"-dump")==0 )   { dump_all_cond = true;       }
+      else if ( ::strcmp(argv[i],"-print")==0 )  {
+        s_PrintLevel = DD4hep::printLevel(argv[++i]);
+        printout(INFO,"DDDB","Setting print level for %s to %s [%d]",__FILE__,argv[i-1],s_PrintLevel);
+      }
+      else if ( ::strcmp(argv[i],"--help")==0 )      {
+        printout(INFO,"Plugin-Help","Usage: DDDBDetectorDump --opt [--opt]            ");
+        printout(INFO,"Plugin-Help","  -sensitive          Only use sensitive elements");
+        printout(INFO,"Plugin-Help","  -dump               Print conditions inventory ");
+        printout(INFO,"Plugin-Help","  -print <value>      Printlevel for output      ");
+        printout(INFO,"Plugin-Help","  -help               Print this help message    ");
         return 0;
       }
     }
-    Actor actor(lcdd, dump_sensitive_only, dump_all_cond);
+    DumpActor actor(lcdd, flag, dump_sensitive_only, dump_all_cond);
     actor.m_name = "DDDBDetectorDump";
     if ( flag == 1 )
       actor.m_name = "DDDBDetVolumeDump";
@@ -374,6 +429,9 @@ namespace {
     printout(INFO,actor.m_name,"**************** DDDB Detector dump *****************************");
     return actor.init().dump(lcdd.world(), 0);
   }
+  
+  template <int flag> long dump_detelement_tree(LCDD& lcdd, int argc, char** argv)
+  {  return dump_det_tree(lcdd,flag,argc,argv);    }
 } /* End anonymous namespace  */
 
 DECLARE_APPLY(DDDB_DetectorDump,dump_detelement_tree<0>)
diff --git a/DDG4/src/Geant4Random.cpp b/DDG4/src/Geant4Random.cpp
index f8945bf9e..a2b207087 100644
--- a/DDG4/src/Geant4Random.cpp
+++ b/DDG4/src/Geant4Random.cpp
@@ -60,7 +60,11 @@ namespace    {
       m_generator->setSeed((long)seed);
     }
     /// Single shot random number creation
-    virtual Double_t Rndm(Int_t=0)  {
+    virtual Double_t Rndm()  {
+      return m_engine->flat();
+    }
+    /// Single shot random number creation
+    virtual Double_t Rndm(Int_t)  {
       return m_engine->flat();
     }
     /// Return an array of n random numbers uniformly distributed in ]0,1].
diff --git a/examples/AlignDet/CMakeLists.txt b/examples/AlignDet/CMakeLists.txt
index b001ec0e8..e71a3d540 100644
--- a/examples/AlignDet/CMakeLists.txt
+++ b/examples/AlignDet/CMakeLists.txt
@@ -24,13 +24,12 @@ dd4hep_add_plugin( AlignDetExample SOURCES src/*.cpp  )
 dd4hep_install_dir( compact DESTINATION examples/AlignDet )
 dd4hep_configure_scripts( AlignDet DEFAULT_SETUP WITH_TESTS)
 
-if ( NEVER )
 #
 #---Testing: Load Telescope geometry and read conditions ------------------
 dd4hep_add_test_reg( test_AlignDet_Telescope_dump_geometry
   COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh"
   EXEC_ARGS  geoPluginRun -volmgr -destroy
-  -compact file:${DD4hep_DIR}/examples/AlignDetcompact/Telescope.xml
+  -compact file:${DD4hep_DIR}/examples/AlignDet/compact/Telescope.xml
   -plugin DD4hepDetectorDump
   REGEX_PASS "/world/Telescope/module_9 NumDau\\:1 VolID\\:00000903 Place")
 #
@@ -38,17 +37,30 @@ dd4hep_add_test_reg( test_AlignDet_Telescope_dump_geometry
 dd4hep_add_test_reg( test_AlignDet_Telescope_populate
   COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh"
   EXEC_ARGS  geoPluginRun -volmgr -destroy -plugin DD4hep_AlignmentExample_populate
-     -input file:${DD4hep_DIR}/examples/AlignDet/compact/Telescope.xml
-     -deltas file:${DD4hep_DIR}/examples/Conditions/data/repository.xml
-  REGEX_PASS "\\[E42813AA\\] -> \\[E42813AA\\] /world/Telescope/module_9/sensor#alignment/Tranformations")
+     -input file:${DD4hep_DIR}/examples/AlignDet/compact/Telescope.xml -iovs 10
+  REGEX_PASS "\\[7522800AD665C239\\] -> \\[7522800AD665C239\\] /world/Telescope/module_9/sensor#alignment/Tranformations")
 #
 #---Testing: Load Telescope geometry and read and print alignments --------
 dd4hep_add_test_reg( test_AlignDet_Telescope_read_xml
   COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh"
   EXEC_ARGS  geoPluginRun -volmgr -destroy -plugin DD4hep_AlignmentExample_read_xml
-     -input file:${DD4hep_DIR}/examples/AlignDet/compact/Telescope.xml
+     -input  file:${DD4hep_DIR}/examples/AlignDet/compact/Telescope.xml
      -deltas file:${DD4hep_DIR}/examples/Conditions/data/repository.xml
-  REGEX_PASS "\\[E42813AA\\] -> \\[E42813AA\\] /world/Telescope/module_9/sensor#alignment/Tranformations")
+  REGEX_PASS "\\[7522800AD665C239\\] -> \\[7522800AD665C239\\] /world/Telescope/module_9/sensor#alignment/Tranformations")
+#
+#---Testing: Simple stress: Load Telescope geometry and have multiple runs on IOVs
+dd4hep_add_test_reg( test_AlignDet_Telescope_stress
+  COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh"
+  EXEC_ARGS  geoPluginRun  -volmgr -destroy -plugin DD4hep_AlignmentExample_stress
+      -input file:${DD4hep_DIR}/examples/AlignDet/compact/Telescope.xml -iovs 20 -runs 111
+  REGEX_PASS "Summary: # of IOV:  20  # of Runs: 111")
+#
+#---Testing: Extended stress: Load CLICSiD geometry and have multiple runs on IOVs
+dd4hep_add_test_reg( test_AlignDet_CLICSiD_stress_LONGTEST
+  COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh"
+  EXEC_ARGS  geoPluginRun  -volmgr -destroy -plugin DD4hep_AlignmentExample_stress
+      -input file:${DD4hep_DIR}/examples/CLICSiD/compact/compact.xml -iovs 10 -runs 100
+  REGEX_PASS "Summary: # of IOV:  10  # of Runs: 100")
 #
 #---Testing: Load ALEPH TPC geometry --------------------------------------
 dd4hep_add_test_reg( test_AlignDet_AlephTPC_load
@@ -78,5 +90,3 @@ dd4hep_add_test_reg( test_AlignDet_Global_AlephTPC_reset
              -plugin DD4hepXMLLoader file:${DD4hep_DIR}/examples/AlignDet/compact/AlephTPC_alignment.xml
              -plugin DD4hepXMLLoader file:${DD4hep_DIR}/examples/AlignDet/compact/AlephTPC_reset.xml
   REGEX_PASS "Successfully parsed XML: AlephTPC_reset.xml" )
-
-endif()
diff --git a/examples/AlignDet/src/AlignmentExampleObjects.cpp b/examples/AlignDet/src/AlignmentExampleObjects.cpp
index 6df52ac89..aeefe1620 100644
--- a/examples/AlignDet/src/AlignmentExampleObjects.cpp
+++ b/examples/AlignDet/src/AlignmentExampleObjects.cpp
@@ -59,7 +59,7 @@ int AlignmentDataAccess::processElement(DetElement de)  {
   }
   // Keep it simple. To know how to access stuff,
   // simply look in DDDCore/src/AlignmentsPrinter.cpp...
-  Alignments::printElementPlacement("Example",de,pool);
+  Alignments::printElementPlacement(printLevel,"Example",de,pool);
   return 1;
 }
 
diff --git a/examples/AlignDet/src/AlignmentExample_read_xml.cpp b/examples/AlignDet/src/AlignmentExample_read_xml.cpp
index 3a2cc6e9b..a4e2684fe 100644
--- a/examples/AlignDet/src/AlignmentExample_read_xml.cpp
+++ b/examples/AlignDet/src/AlignmentExample_read_xml.cpp
@@ -76,20 +76,27 @@ static int alignment_example (Geometry::LCDD& lcdd, int argc, char** argv)  {
   }
   IOV req_iov(iov_typ,1500);      // IOV goes from run 1000 ... 2000
   dd4hep_ptr<ConditionsSlice> slice(createSlice(condMgr,*iov_typ));
-  ConditionsManager::Result res = condMgr.prepare(req_iov,*slice);
-  printout(INFO,"Prepare","Total %ld/%ld conditions (S:%ld,L:%ld,C:%ld,M:%ld) of type %s.",
-             slice->conditions().size(), res.total(), res.selected, res.loaded,
-             res.computed, res.missing, iov_typ->str().c_str());
-
+  ConditionsManager::Result cres = condMgr.prepare(req_iov,*slice);
+    
   // ++++++++++++++++++++++++ We need a valid set of conditions to do this!
   registerAlignmentCallbacks(lcdd,*slice,alignMgr);
 
   // ++++++++++++++++++++++++ Compute the tranformation matrices
-  alignMgr.compute(*slice);
+  AlignmentsManager::Result ares = alignMgr.compute(*slice);
 
   // What else ? let's access the data
   Scanner().scan2(AlignmentDataAccess(slice->pool().get()),lcdd.world());
-  
+
+  // What else ? let's print the current selection
+  Alignments::AlignedVolumePrinter printer(slice->pool().get(),"Example");
+  Scanner().scan(printer,lcdd.world());
+
+  printout(INFO,"Example",
+           "Setup %ld/%ld conditions (S:%ld,L:%ld,C:%ld,M:%ld) (A:%ld,M:%ld) for IOV:%-12s",
+           slice->conditions().size(),
+           cres.total(), cres.selected, cres.loaded, cres.computed, cres.missing, 
+           ares.computed, ares.missing, iov_typ->str().c_str());
+
   // ++++++++++++++++++++++++ All done.
   return 1;
 }
diff --git a/examples/AlignDet/src/AlignmentExample_stress.cpp b/examples/AlignDet/src/AlignmentExample_stress.cpp
index ded4f2cc3..113348170 100644
--- a/examples/AlignDet/src/AlignmentExample_stress.cpp
+++ b/examples/AlignDet/src/AlignmentExample_stress.cpp
@@ -144,14 +144,14 @@ static int alignment_example (Geometry::LCDD& lcdd, int argc, char** argv)  {
              res.total(), res.selected, res.loaded, res.computed, res.missing, rndm,
              iov_typ->str().c_str(), stop.AsDouble()-start.AsDouble());
   }
-  printout(INFO,"Statistics","+=======================================================================");
+  printout(INFO,"Statistics","+======= Summary: # of IOV: %3d  # of Runs: %3d ===========================", num_iov, num_runs);
   printout(INFO,"Statistics","+  %-12s:  %11.5g +- %11.4g  RMS = %11.5g  N = %lld",
            cr_stat.GetName(), cr_stat.GetMean(), cr_stat.GetMeanErr(), cr_stat.GetRMS(), cr_stat.GetN());
   printout(INFO,"Statistics","+  %-12s:  %11.5g +- %11.4g  RMS = %11.5g  N = %lld",
            comp_stat.GetName(), comp_stat.GetMean(), comp_stat.GetMeanErr(), comp_stat.GetRMS(), comp_stat.GetN());
   printout(INFO,"Statistics","+  %-12s:  %11.5g +- %11.4g  RMS = %11.5g  N = %lld",
            access_stat.GetName(), access_stat.GetMean(), access_stat.GetMeanErr(), access_stat.GetRMS(), access_stat.GetN());
-  printout(INFO,"Statistics","+=======================================================================");
+  printout(INFO,"Statistics","+==========================================================================");
   // All done.
   return 1;
 }
diff --git a/examples/Conditions/CMakeLists.txt b/examples/Conditions/CMakeLists.txt
index 3e82fd1bd..8b7e5776e 100644
--- a/examples/Conditions/CMakeLists.txt
+++ b/examples/Conditions/CMakeLists.txt
@@ -29,17 +29,51 @@ dd4hep_configure_scripts ( Conditions DEFAULT_SETUP WITH_TESTS )
 dd4hep_add_test_reg( test_Conditions_Telescope_cond_dump_by_pool
   COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_Conditions.sh"
   EXEC_ARGS  geoPluginRun -volmgr -destroy
-  -compact file:${CMAKE_CURRENT_SOURCE_DIR}/../AlignDet/compact/Telescope.xml
-  -plugin DD4hep_ConditionsXMLRepositoryParser file:${CMAKE_CURRENT_SOURCE_DIR}/data/repository.xml
+  -compact file:${DD4hep_DIR}/examples/AlignDet/compact/Telescope.xml
+  -plugin DD4hep_ConditionsXMLRepositoryParser file:${DD4hep_DIR}/examples/Conditions/data/repository.xml
   -plugin DD4hep_ConditionsDump
   REGEX_PASS "Data:\\[\\(0,0,1\\), \\{phi\\(Z angle\\)\\: 3.14159   theta\\(Y angle\\)\\: 0   psi\\(X angle\\)\\: 0\\} , 0  0  0 \\]")
 #
-#
 #---Testing: Load Telescope geometry and read conditions ------------------
 dd4hep_add_test_reg( test_Conditions_Telescope_cond_dump_by_detelement
   COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_Conditions.sh"
   EXEC_ARGS  geoPluginRun -volmgr -destroy
-  -compact file:${CMAKE_CURRENT_SOURCE_DIR}/../AlignDet/compact/Telescope.xml
-  -plugin DD4hep_ConditionsXMLRepositoryParser file:${CMAKE_CURRENT_SOURCE_DIR}/data/repository.xml
+  -compact file:${DD4hep_DIR}/examples/AlignDet/compact/Telescope.xml
+  -plugin DD4hep_ConditionsXMLRepositoryParser file:${DD4hep_DIR}/examples/Conditions/data/repository.xml
   -plugin DD4hep_DetElementConditionsDump
   REGEX_PASS "Path\\:/world/Telescope/module_9#alignment")
+#
+#---Testing: Simple stress: Load Telescope geometry and have multiple runs on IOVs
+dd4hep_add_test_reg( test_Conditions_Telescope_populate
+  COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_Conditions.sh"
+  EXEC_ARGS  geoPluginRun  -volmgr -destroy -plugin DD4hep_ConditionExample_populate
+      -input file:${DD4hep_DIR}/examples/AlignDet/compact/Telescope.xml -iovs 5
+  REGEX_PASS "Total 160 conditions \\(S:100,L:0,C:60,M:0\\) of IOV run\\(0\\):\\[45-45\\]")
+#
+#---Testing: Simple stress: Load Telescope geometry and have multiple runs on IOVs
+dd4hep_add_test_reg( test_Conditions_Telescope_stress
+  COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_Conditions.sh"
+  EXEC_ARGS  geoPluginRun  -volmgr -destroy -plugin DD4hep_ConditionExample_stress
+    -input file:${DD4hep_DIR}/examples/AlignDet/compact/Telescope.xml -iovs 10 -runs 20
+  REGEX_PASS "Summary: # of IOV:  10  # of Runs:  20")
+#
+#---Testing: Simple stress: Load Telescope geometry and have multiple runs on IOVs
+dd4hep_add_test_reg( test_Conditions_Telescope_stress2
+  COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_Conditions.sh"
+  EXEC_ARGS  geoPluginRun  -volmgr -destroy -plugin DD4hep_ConditionExample_stress2
+    -input file:${DD4hep_DIR}/examples/AlignDet/compact/Telescope.xml -iovs 10
+  REGEX_PASS "Summary: # of IOV:  10")
+#
+#---Testing: Simple stress: Load CLICSiD geometry and have multiple runs on IOVs
+dd4hep_add_test_reg( test_Conditions_CLICSiD_stress_LONGTEST
+  COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_Conditions.sh"
+  EXEC_ARGS  geoPluginRun  -volmgr -destroy -plugin DD4hep_ConditionExample_stress
+    -input file:${DD4hep_DIR}/examples/CLICSiD/compact/compact.xml -iovs 10 -runs 100
+  REGEX_PASS "Summary: # of IOV:  10  # of Runs: 100")
+#
+#---Testing: Simple stress: Load CLICSiD geometry and have multiple runs on IOVs
+dd4hep_add_test_reg( test_Conditions_CLICSiD_stress2_LONGTEST
+  COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_Conditions.sh"
+  EXEC_ARGS  geoPluginRun  -volmgr -destroy -plugin DD4hep_ConditionExample_stress2
+    -input file:${DD4hep_DIR}/examples/CLICSiD/compact/compact.xml -iovs 20
+  REGEX_PASS "Summary: # of IOV:  20")
diff --git a/examples/Conditions/src/ConditionExample_populate.cpp b/examples/Conditions/src/ConditionExample_populate.cpp
index 02ce748a0..492c44882 100644
--- a/examples/Conditions/src/ConditionExample_populate.cpp
+++ b/examples/Conditions/src/ConditionExample_populate.cpp
@@ -98,14 +98,14 @@ static int condition_example (Geometry::LCDD& lcdd, int argc, char** argv)  {
     IOV req_iov(iov_typ,i*10+5);
     // Attach the proper set of conditions to the user pool
     ConditionsManager::Result r = condMgr.prepare(req_iov,*slice);
+    if ( 0 == i )  { // First one we print...
+      ConditionsPrinter printer(slice->pool().get(),"Example");
+      Scanner().scan(printer,lcdd.world());
+    }
     // Now compute the tranformation matrices
-    printout(INFO,"Prepare","Total %ld conditions (S:%ld,L:%ld,C:%ld,M:%ld) of type %s",
-             r.total(), r.selected, r.loaded, r.computed, r.missing, iov_typ->str().c_str());
-  }
-  // What else ? let's access/print the current selection
-  ConditionsPrinter printer(slice->pool().get(),"Example");
-  Scanner().scan(printer,lcdd.world());
-  
+    printout(INFO,"Prepare","Total %ld conditions (S:%ld,L:%ld,C:%ld,M:%ld) of IOV %s",
+             r.total(), r.selected, r.loaded, r.computed, r.missing, req_iov.str().c_str());
+  }  
   // All done.
   return 1;
 }
diff --git a/examples/Conditions/src/ConditionExample_stress.cpp b/examples/Conditions/src/ConditionExample_stress.cpp
index 70a5cb046..4769068ca 100644
--- a/examples/Conditions/src/ConditionExample_stress.cpp
+++ b/examples/Conditions/src/ConditionExample_stress.cpp
@@ -120,12 +120,12 @@ static int condition_example (Geometry::LCDD& lcdd, int argc, char** argv)  {
              res.total(), res.selected, res.loaded, res.computed, res.missing,
              req_iov.str().c_str(), stop.AsDouble()-start.AsDouble());
   }
-  printout(INFO,"Statistics","+=======================================================================");
+  printout(INFO,"Statistics","+======= Summary: # of IOV: %3d  # of Runs: %3d ===========================", num_iov, num_runs);
   printout(INFO,"Statistics","+  %-12s:  %11.5g +- %11.4g  RMS = %11.5g  N = %lld",
            cr_stat.GetName(), cr_stat.GetMean(), cr_stat.GetMeanErr(), cr_stat.GetRMS(), cr_stat.GetN());
   printout(INFO,"Statistics","+  %-12s:  %11.5g +- %11.4g  RMS = %11.5g  N = %lld",
            acc_stat.GetName(), acc_stat.GetMean(), acc_stat.GetMeanErr(), acc_stat.GetRMS(), acc_stat.GetN());
-  printout(INFO,"Statistics","+=======================================================================");
+  printout(INFO,"Statistics","+=========================================================================");
   // All done.
   return 1;
 }
diff --git a/examples/Conditions/src/ConditionExample_stress2.cpp b/examples/Conditions/src/ConditionExample_stress2.cpp
index 3281870ab..68d0e29d7 100644
--- a/examples/Conditions/src/ConditionExample_stress2.cpp
+++ b/examples/Conditions/src/ConditionExample_stress2.cpp
@@ -112,12 +112,12 @@ static int condition_example (Geometry::LCDD& lcdd, int argc, char** argv)  {
                req_iov.str().c_str(), stop.AsDouble()-start.AsDouble());
     }
   }
-  printout(INFO,"Statistics","+=======================================================================");
+  printout(INFO,"Statistics","+======= Summary: # of IOV: %3d ===========================================", num_iov);
   printout(INFO,"Statistics","+  %-12s:  %11.5g +- %11.4g  RMS = %11.5g  N = %lld",
            cr_stat.GetName(), cr_stat.GetMean(), cr_stat.GetMeanErr(), cr_stat.GetRMS(), cr_stat.GetN());
   printout(INFO,"Statistics","+  %-12s:  %11.5g +- %11.4g  RMS = %11.5g  N = %lld",
            acc_stat.GetName(), acc_stat.GetMean(), acc_stat.GetMeanErr(), acc_stat.GetRMS(), acc_stat.GetN());
-  printout(INFO,"Statistics","+=======================================================================");
+  printout(INFO,"Statistics","+=========================================================================");
   // All done.
   return 1;
 }
diff --git a/examples/DDDB/CMakeLists.txt b/examples/DDDB/CMakeLists.txt
index acb2af151..305d027aa 100644
--- a/examples/DDDB/CMakeLists.txt
+++ b/examples/DDDB/CMakeLists.txt
@@ -26,8 +26,8 @@ if (DD4HEP_USE_XERCESC)
   dd4hep_configure_output ()
   dd4hep_package (DDDB MAJOR 0 MINOR 0 PATCH 1
     USES  [XERCESC REQUIRED]
-    [ROOT    REQUIRED COMPONENTS Geom] 
-    [DD4hep  REQUIRED COMPONENTS DDCore DDDB]
+          [ROOT    REQUIRED COMPONENTS Geom] 
+          [DD4hep  REQUIRED COMPONENTS DDCore DDDB]
     )
   #---Package installation procedure(s) -----------------------------------------
   install ( PROGRAMS scripts/run_dddb.sh DESTINATION bin)
@@ -60,66 +60,64 @@ if (DD4HEP_USE_XERCESC)
     COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_DDDB.sh"
     EXEC_ARGS  ${CMAKE_INSTALL_PREFIX}/bin/run_dddb.sh
     -config DD4hep_ConditionsManagerInstaller
-    -exec   DDDB_ConditionsDump
-    REGEX_PASS "Path\\:/dd/Conditions/ReadoutConf/Velo/Tell1Module03 Class\\:5 \\[DD4hep\\:\\:Conditions\\:\\:AbstractMap\\]" )
+    -exec DDDB_ConditionsSummary
+    REGEX_PASS "DDDB Total Number of parameters:    19057  " )
   #
   #---Testing: Load the geometry + dump detector elemets ------------------------
   dd4hep_add_test_reg( test_DDDB_det_elements_LONGTEST
     COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_DDDB.sh"
     EXEC_ARGS  ${CMAKE_INSTALL_PREFIX}/bin/run_dddb.sh
-    -config DD4hep_ConditionsManagerInstaller
-    -exec   DDDB_DetectorDump
-    REGEX_PASS "Detector\\: /world/LHCb/UpstreamRegion #Dau\\:5" )
+    -config DD4hep_ConditionsManagerInstaller  -end-plugin
+    -plugin   DDDB_DetectorDump -print DEBUG   -end-plugin
+    REGEX_PASS "DDDB: Number of DetElements in the geometry:     3060" )
   #
   #---Testing: Load the geometry + dump volumes ---------------------------------
   dd4hep_add_test_reg( test_DDDB_det_volumes_LONGTEST
     COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_DDDB.sh"
     EXEC_ARGS  ${CMAKE_INSTALL_PREFIX}/bin/run_dddb.sh
     -config DD4hep_ConditionsManagerInstaller
-    -exec   DDDB_DetectorVolumeDump
-    REGEX_PASS "Detector\\: /world/LHCb/MagnetRegion/BcmDown #Dau\\:10" )
+    -plugin DDDB_DetectorVolumeDump -print DEBUG
+    REGEX_PASS "DDDB: Number of DetElement placements:           3056" )
   #
   #---Testing: Load the geometry + dump condition keys --------------------------
   dd4hep_add_test_reg( test_DDDB_det_conditions_keys_LONGTEST
     COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_DDDB.sh"
     EXEC_ARGS  ${CMAKE_INSTALL_PREFIX}/bin/run_dddb.sh
     -config DD4hep_ConditionsManagerInstaller
-    -exec   DDDB_DetectorConditionKeysDump
-    REGEX_PASS "Key\\: D88E83E7 -> 20537B67 -> /dd/Conditions/ReadoutConf/Prs/Readout")
+    -plugin DDDB_DetectorConditionKeysDump -print DEBUG
+    REGEX_PASS "DDDB: Number of DetElement condition keys:      14042")
   #
   #---Testing: Load the geometry + dump condition keys --------------------------
   dd4hep_add_test_reg( test_DDDB_det_conditions_data_LONGTEST
     COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_DDDB.sh"
     EXEC_ARGS  ${CMAKE_INSTALL_PREFIX}/bin/run_dddb.sh
     -config DD4hep_ConditionsManagerInstaller
-    -exec   DDDB_DetectorConditionDump
-    REGEX_PASS "Path\\:/dd/Conditions/Alignment/Spd/SpdCSystem Class\\:6 .DD4hep\\:\\:Conditions\\:\\:AbstractMap." )
+    -plugin DDDB_DetectorConditionDump -print DEBUG
+    REGEX_PASS "DDDB: Number of attached conditions:             2261" )
   #
   #---Testing: Load the geometry + dump condition keys --------------------------
   dd4hep_add_test_reg( test_DDDB_det_conditions_align_LONGTEST
     COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_DDDB.sh"
     EXEC_ARGS  ${CMAKE_INSTALL_PREFIX}/bin/run_dddb.sh
     -config DD4hep_ConditionsManagerInstaller
-    -exec   DDDB_DetectorAlignmentDump
-    REGEX_PASS "Number of attached alignments\\:             2496")
+    -plugin DDDB_DetectorAlignmentDump -print DEBUG
+    REGEX_PASS "Number of attached alignments:             2496")
   #
   #---Testing: Load the geometry + conditions dump as view from DetElement ------
   dd4hep_add_test_reg( test_DDDB_detelement_conditions_dump_LONGTEST
     COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_DDDB.sh"
     EXEC_ARGS  ${CMAKE_INSTALL_PREFIX}/bin/run_dddb.sh
     -config DD4hep_ConditionsManagerInstaller
-    -exec   DDDB_DetElementConditionDump
-    REGEX_PASS "Path\\:/dd/Conditions/Alignment/Spd/SpdCSystem Class\\:6 .DD4hep\\:\\:Conditions\\:\\:AbstractMap." )
-
+    -plugin DDDB_DetElementConditionDump -print DEBUG
+    REGEX_PASS "Total Number of parameters:    18383" )
   #
   #---Testing: Load the geometry + conditions + conditions derives
   dd4hep_add_test_reg( test_DDDB_derived_conditions_LONGTEST
     COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_DDDB.sh"
     EXEC_ARGS  ${CMAKE_INSTALL_PREFIX}/bin/run_dddb.sh
     -config DD4hep_ConditionsManagerInstaller
-    -exec   DDDB_DerivedCondTest
-    REGEX_PASS "Building dependent condition\\: /dd/Conditions/Alignment/TT/TTbVLayerR1Module3B/derived_3" )
-
+    -plugin DDDB_DerivedCondTest -print DEBUG
+    REGEX_PASS "Total Number of callbacks:    7479" )
   #
   #---Testing: Load the geometry + conditions + run basic derived alignments test
   dd4hep_add_test_reg( test_DDDB_derived_alignments_LONGTEST
@@ -127,9 +125,8 @@ if (DD4HEP_USE_XERCESC)
     EXEC_ARGS  ${CMAKE_INSTALL_PREFIX}/bin/run_dddb.sh
     -config DD4hep_ConditionsManagerInstaller
     -config DD4hep_AlignmentsManagerInstaller
-    -exec   DDDB_DerivedAlignmentsTest
-    REGEX_PASS "|     24950| 24950|        0|DD4hep\\:\\:Alignments\\:\\:Interna\\:\\:AlignmentConditionObject" )
-
+    -plugin DDDB_DerivedAlignmentsTest -print DEBUG
+    REGEX_PASS "AlignmentManager: 9353 conditions \\(S:9353,L:0,C:0,M:0\\) \\(A:2493,M:0\\) for IOV:epoch\\(0\\)" )
   #
   #---Testing: Load the geometry + conditions + access derived alignments from DetElement structures
   dd4hep_add_test_reg( test_DDDB_alignment_access_LONGTEST
@@ -137,9 +134,8 @@ if (DD4HEP_USE_XERCESC)
     EXEC_ARGS  ${CMAKE_INSTALL_PREFIX}/bin/run_dddb.sh
     -config DD4hep_ConditionsManagerInstaller
     -config DD4hep_AlignmentsManagerInstaller
-    -exec   DDDB_AlignmentsAccessTest
+    -plugin DDDB_AlignmentsAccessTest -print DEBUG
     REGEX_PASS "Accessed 4990 conditions from the DetElement objects" )
-
   #
   #---Testing: Extract DDDB data from zip archive -------------------------------
   dd4hep_add_test_reg( test_DDDB_clean_LONGTEST
diff --git a/examples/DDDB/scripts/run_dddb.sh b/examples/DDDB/scripts/run_dddb.sh
index fa0200e42..29ed3efaf 100755
--- a/examples/DDDB/scripts/run_dddb.sh
+++ b/examples/DDDB/scripts/run_dddb.sh
@@ -35,13 +35,27 @@ exec="";
 vis="";
 debug="";
 last_cmd="";
+plugins="";
 #
+all_args="$*";
 #
 while [[ "$1" == -* ]]; do
     #echo "Arg:$1 $2 [$*]";
     a1=`echo $1 | tr A-Z a-z`;
     #echo "Arg: $1 -- ${last_cmd}";
     case ${a1} in
+        -plugin)
+            plugins="$*";
+            while test -n "$1"; do 
+                shift;
+            done;
+            ;;
+        -end-plugin)
+            plugins="$*";
+            while test -n "$1"; do 
+                shift;
+            done;
+            ;;
         -debug)
             debug="gdb --args";
             last_cmd="";
@@ -109,7 +123,10 @@ if [ "$(uname)" == "Darwin" ]; then
   export DYLD_LIBRARY_PATH=${DD4HEP_LIBRARY_PATH}
 fi
 export DD4HEP_TRACE=ON;
-ARGS=`echo -plugin DDDB_Executor ${loader} ${params} ${input} ${config} ${exec} ${vis}`;
+echo "Command(1): ${debug} `which geoPluginRun` -destroy -plugin DDDB_Executor ${loader} ${params} ${input} ${config} ${exec} ${vis} ${plugins}"
+echo "Command(2): ${debug} `which geoPluginRun` -destroy -plugin DDDB_Executor ${all_args} ${plugins}"
+
+ARGS=`echo -plugin DDDB_Executor ${loader} ${params} ${input} ${config} ${exec} ${vis} ${plugins}`;
 echo "Command: ${debug} `which geoPluginRun` -destroy $ARGS";
 if test -z "${debug}";then
     exec `which geoPluginRun` -destroy ${ARGS};
-- 
GitLab