diff --git a/DDCore/CMakeLists.txt b/DDCore/CMakeLists.txt
index 10d8be783a6e4d1ffe05752c47fda5877a5c24df..c43a1dc689cb8a6f4314d06756e21d0d62c19551 100644
--- a/DDCore/CMakeLists.txt
+++ b/DDCore/CMakeLists.txt
@@ -21,7 +21,8 @@ dd4hep_add_dictionary( G__DD4hep
   SOURCES include/ROOT/Warnings.h
   include/DD4hep/*.h
   include/DD4hep/detail/*.h
-  include/XML/*.h 
+  include/XML/*.h
+  src/DetectorImp.h
   EXCLUDE include/DD4hep/DetFactoryHelper.h
   include/DD4hep/Factories.h
   include/DD4hep/Plugins.h
diff --git a/DDCore/include/DD4hep/BasicGrammar.h b/DDCore/include/DD4hep/BasicGrammar.h
index 81af61d2cb19e2e0635f0e0bc29c60e796ddbd60..561a4c0cbd7070c5b761db80082e9544941870be 100644
--- a/DDCore/include/DD4hep/BasicGrammar.h
+++ b/DDCore/include/DD4hep/BasicGrammar.h
@@ -17,6 +17,9 @@
 #include <string>
 #include <typeinfo>
 
+// Forward declarations
+class TClass;
+
 /// Namespace for the AIDA detector description toolkit
 namespace dd4hep {
 
@@ -35,27 +38,56 @@ namespace dd4hep {
    *   \ingroup DD4HEP
    */
   class BasicGrammar {
-  protected:
-    /// Instance pointer
-    BasicGrammar* self = 0;
-
   public:
+    typedef unsigned long long int key_type;
+    /// Instance type name
+    const std::string  name;
+    /// Instance hash code
+    const key_type     hash_value     = 0;
+    /// Cached TClass reference for speed improvements
+    mutable TClass*    root_class     = 0;
+    /// Cached TDataType information for fundamental types
+    mutable int        root_data_type = -1;
+    /// Initialization flag
+    mutable bool       inited         = false;
+    
+  protected:
     /// Default constructor
-    BasicGrammar();
+    BasicGrammar(const std::string& typ);
 
     /// Default destructor
     virtual ~BasicGrammar();
 
+    /// Second step initialization after the virtual table is fixed
+    void initialize()   const;
+    int initialized_data_type()  const;
+    TClass* initialized_clazz()  const;
+
+  public:
     /// Instance factory
     template <typename TYPE> static const BasicGrammar& instance();
+    /// Lookup existing grammar using the grammar's hash code/hash64(type-name) (used for reading objects)
+    static const BasicGrammar& get(unsigned long long int hash_code);
     /// Error callback on invalid conversion
     static void invalidConversion(const std::type_info& from, const std::type_info& to);
     /// Error callback on invalid conversion
     static void invalidConversion(const std::string& value, const std::type_info& to);
+    /// Access the hash value for this grammar type
+    key_type hash() const                 {  return hash_value;   }
+    /// Access to the type information name
+    const std::string& type_name() const  {  return name;         }
+    /// Access ROOT data type for fundamentals
+    int data_type()  const  {
+      if ( inited ) return root_data_type;
+      return initialized_data_type();
+    }
+    /// Access the ROOT class for complex objects
+    TClass* clazz()  const   {
+      if ( inited ) return root_class;
+      return initialized_clazz();
+    }
     /// Access to the type information
     virtual const std::type_info& type() const = 0;
-    /// Access to the type information name
-    virtual const std::string& type_name() const = 0;    
     /// Access the object size (sizeof operator)
     virtual size_t sizeOf() const = 0;
     /// Serialize an opaque value to a string
@@ -66,6 +98,8 @@ namespace dd4hep {
     virtual void destruct(void* pointer) const = 0;
     /// Opaque object copy construction. Memory must be allocated externally
     virtual void copy(void* to, const void* from)  const = 0;
+    /// Bind opaque address to object
+    virtual void bind(void* pointer)  const = 0;
   };
 }      // End namespace dd4hep
 
diff --git a/DDCore/include/DD4hep/DD4hepRootPersistency.h b/DDCore/include/DD4hep/DD4hepRootPersistency.h
index f838b7ef33211bfb2b76b6ee4c03ec5f20a25fc6..58c0b6cba96184b6e1c376757325ffcc591ef5b0 100644
--- a/DDCore/include/DD4hep/DD4hepRootPersistency.h
+++ b/DDCore/include/DD4hep/DD4hepRootPersistency.h
@@ -20,108 +20,62 @@
 class DD4hepRootPersistency : public TNamed  {
 public:
   typedef std::map<std::string, dd4hep::Handle<dd4hep::NamedObject> >  HandleMap;
-  typedef std::map<std::string, std::string>          PropertyValues;
-  typedef std::map<std::string, PropertyValues>       Properties;
 
+  /// The main data block
+  dd4hep::DetectorData*     m_data = 0;
   /// Helper since plain segmentations cannot be saved
   std::map<dd4hep::Readout,std::pair<dd4hep::IDDescriptor,dd4hep::DDSegmentation::Segmentation*> > m_segments;
+  /// Helper to save alignment conditions from the DetElement nominals
+  std::map<dd4hep::DetElement,dd4hep::AlignmentCondition> nominals;
 
-  std::map<dd4hep::DetElement,dd4hep::AlignmentCondition> nominals;  //!
-  
-  /// The main data block
-  dd4hep::DetectorData*     m_data = 0;
-  
   /// Default constructor
   DD4hepRootPersistency() : TNamed() {}
   /// Default destructor
   virtual ~DD4hepRootPersistency() {}
-
+  /// Save an existing detector description in memory to a ROOT file
   static int save(dd4hep::Detector& description, const char* fname, const char* instance = "Geometry");
+  /// Load an detector description from a ROOT file to memory
   static int load(dd4hep::Detector& description, const char* fname, const char* instance = "Geometry");
   /// Access the geometry manager of this instance
-  TGeoManager& manager() const {
-    return *m_data->m_manager;
-  }
-  /// Access to properties
-  Properties& properties() const {
-    return *(Properties*)&m_data->m_properties;
-  }
+  TGeoManager& manager() const                {    return *m_data->m_manager;         }
   /// Return handle to material describing air
-  dd4hep::Material air() const {
-    return m_data->m_materialAir;
-  }
+  dd4hep::Material air() const                {    return m_data->m_materialAir;      }
   /// Return handle to material describing vacuum
-  dd4hep::Material vacuum() const {
-    return m_data->m_materialVacuum;
-  }
+  dd4hep::Material vacuum() const             {    return m_data->m_materialVacuum;   }
   /// Return handle to "invisible" visualization attributes
-  dd4hep::VisAttr invisible() const {
-    return m_data->m_invisibleVis;
-  }
+  dd4hep::VisAttr invisible() const           {    return m_data->m_invisibleVis;     }
   /// Return reference to the top-most (world) detector element
-  dd4hep::DetElement world() const {
-    return m_data->m_world;
-  }
+  dd4hep::DetElement world() const            {    return m_data->m_world;            }
   /// Return reference to detector element with all tracker devices.
-  dd4hep::DetElement trackers() const {
-    return m_data->m_trackers;
-  }
+  dd4hep::DetElement trackers() const         {    return m_data->m_trackers;         }
   /// Return handle to the world volume containing everything
-  dd4hep::Volume worldVolume() const {
-    return m_data->m_worldVol;
-  }
+  dd4hep::Volume worldVolume() const          {    return m_data->m_worldVol;         }
   /// Return handle to the world volume containing the volume with the tracking devices
-  dd4hep::Volume trackingVolume() const {
-    return m_data->m_trackingVol;
-  }
+  dd4hep::Volume trackingVolume() const       {    return m_data->m_trackingVol;      }
   /// Return handle to the VolumeManager
-  dd4hep::VolumeManager volumeManager() const {
-    return m_data->m_volManager;
-  }
+  dd4hep::VolumeManager volumeManager() const {    return m_data->m_volManager;       }
   /// Return handle to the combined electromagentic field description.
-  dd4hep::OverlayedField field() const {
-    return m_data->m_field;
-  }
+  dd4hep::OverlayedField field() const        {    return m_data->m_field;            }
   /// Accessor to the header entry
-  dd4hep::Header header() const {
-    return m_data->m_header;
-  }
+  dd4hep::Header header() const               {    return m_data->m_header;           }
   /// Accessor to the map of constants
-  const HandleMap& constants() const {
-    return m_data->m_define;
-  }
+  const HandleMap& constants() const          {    return m_data->m_define;           }
   /// Accessor to the map of visualisation attributes
-  const HandleMap& visAttributes() const {
-    return m_data->m_display;
-  }
+  const HandleMap& visAttributes() const      {    return m_data->m_display;          }
   /// Accessor to the map of limit settings
-  const HandleMap& limitsets() const {
-    return m_data->m_limits;
-  }
+  const HandleMap& limitsets() const          {    return m_data->m_limits;           }
   /// Accessor to the map of region settings
-  const HandleMap& regions() const {
-    return m_data->m_regions;
-  }
+  const HandleMap& regions() const            {    return m_data->m_regions;          }
   /// Accessor to the map of readout structures
-  const HandleMap& readouts() const {
-    return m_data->m_readouts;
-  }
+  const HandleMap& readouts() const           {    return m_data->m_readouts;         }
   /// Accessor to the map of sub-detectors
-  const HandleMap& detectors() const {
-    return m_data->m_detectors;
-  }
+  const HandleMap& detectors() const          {    return m_data->m_detectors;        }
   /// Retrieve a sensitive detector by it's name from the detector description
-  const HandleMap& sensitiveDetectors() const {
-    return m_data->m_sensitive;
-  }
+  const HandleMap& sensitiveDetectors() const {    return m_data->m_sensitive;        }
   /// Accessor to the map of field entries, which together form the global field
-  const HandleMap& fields() const {
-    return m_data->m_fields;
-  }
+  const HandleMap& fields() const             {    return m_data->m_fields;           }
   /// Accessor to the map of ID specifications
-  const HandleMap& idSpecifications() const {
-    return m_data->m_idDict;
-  }
+  const HandleMap& idSpecifications() const   {    return m_data->m_idDict;           }
 
   /// ROOT implementation macro
   ClassDef(DD4hepRootPersistency,1);
@@ -161,8 +115,12 @@ public:
   size_t checkLimitSets()   const;
   /// Call to check the volume manager hierarchy
   size_t checkVolManager()   const;
+  /// Call to check the nominal alignments in the DetElement hierarchy
+  size_t checkNominals()   const;
   /// Call to check a top level Detector element (subdetector)
   size_t checkDetectors()  const;
+  /// Call to check segmentations starting from the top level Detector element
+  size_t checkSegmentations()  const;
   /// Check all of the above
   size_t checkAll()   const;
 };
diff --git a/DDCore/include/DD4hep/DetectorData.h b/DDCore/include/DD4hep/DetectorData.h
index 5b547e50a6ac3852113ff0ad0dbe322b68f82c22..e8a6bfada25b27f24563859f8ac5819a8a35e259 100644
--- a/DDCore/include/DD4hep/DetectorData.h
+++ b/DDCore/include/DD4hep/DetectorData.h
@@ -150,6 +150,47 @@ namespace dd4hep {
     void clearData();
     /// Adopt all data from source structure.
     void adoptData(DetectorData& source, bool CLR=true);
+
+    /// Access the geometry manager of this instance
+    TGeoManager& manager() const                          {    return *m_manager;         }
+    /// Return handle to material describing air
+    dd4hep::Material air() const                          {    return m_materialAir;      }
+    /// Return handle to material describing vacuum
+    dd4hep::Material vacuum() const                       {    return m_materialVacuum;   }
+    /// Return handle to "invisible" visualization attributes
+    dd4hep::VisAttr invisible() const                     {    return m_invisibleVis;     }
+    /// Return reference to the top-most (world) detector element
+    dd4hep::DetElement world() const                      {    return m_world;            }
+    /// Return reference to detector element with all tracker devices.
+    dd4hep::DetElement trackers() const                   {    return m_trackers;         }
+    /// Return handle to the world volume containing everything
+    dd4hep::Volume worldVolume() const                    {    return m_worldVol;         }
+    /// Return handle to the world volume containing the volume with the tracking devices
+    dd4hep::Volume trackingVolume() const                 {    return m_trackingVol;      }
+    /// Return handle to the VolumeManager
+    dd4hep::VolumeManager volumeManager() const           {    return m_volManager;       }
+    /// Return handle to the combined electromagentic field description.
+    dd4hep::OverlayedField field() const                  {    return m_field;            }
+    /// Accessor to the header entry
+    dd4hep::Header header() const                         {    return m_header;           }
+    /// Accessor to the map of constants
+    const Detector::HandleMap& constants() const          {    return m_define;           }
+    /// Accessor to the map of visualisation attributes
+    const Detector::HandleMap& visAttributes() const      {    return m_display;          }
+    /// Accessor to the map of limit settings
+    const Detector::HandleMap& limitsets() const          {    return m_limits;           }
+    /// Accessor to the map of region settings
+    const Detector::HandleMap& regions() const            {    return m_regions;          }
+    /// Accessor to the map of readout structures
+    const Detector::HandleMap& readouts() const           {    return m_readouts;         }
+    /// Accessor to the map of sub-detectors
+    const Detector::HandleMap& detectors() const          {    return m_detectors;        }
+    /// Retrieve a sensitive detector by it's name from the detector description
+    const Detector::HandleMap& sensitiveDetectors() const {    return m_sensitive;        }
+    /// Accessor to the map of field entries, which together form the global field
+    const Detector::HandleMap& fields() const             {    return m_fields;           }
+    /// Accessor to the map of ID specifications
+    const Detector::HandleMap& idSpecifications() const   {    return m_idDict;           }
   };
 
 }         /* End namespace dd4hep         */
diff --git a/DDCore/include/DD4hep/DetectorLoad.h b/DDCore/include/DD4hep/DetectorLoad.h
index daf83357a45df2f114ff5e57bde20bad01edf1c1..4c1f35ba4ca7ffd7cc6ae53919915c90be51a192 100644
--- a/DDCore/include/DD4hep/DetectorLoad.h
+++ b/DDCore/include/DD4hep/DetectorLoad.h
@@ -10,8 +10,8 @@
 // Author     : M.Frank
 //
 //==========================================================================
-#ifndef DD4HEP_DDCORE_DetectorLOAD_H
-#define DD4HEP_DDCORE_DetectorLOAD_H
+#ifndef DD4HEP_DDCORE_DETECTORLOAD_H
+#define DD4HEP_DDCORE_DETECTORLOAD_H
 
 // Framework includes
 #include "DD4hep/Detector.h"
@@ -59,5 +59,5 @@ namespace dd4hep {
     virtual void processXMLElement(const xml::Handle_t& root, DetectorBuildType type);
   };
 
-}         /* End namespace dd4hep     */
-#endif    /* DD4HEP_DDCORE_DetectorLOAD_H */
+}         /* End namespace dd4hep         */
+#endif    /* DD4HEP_DDCORE_DETECTORLOAD_H */
diff --git a/DDCore/include/DD4hep/Dictionary.h b/DDCore/include/DD4hep/Dictionary.h
index e9277981c048157287cb1848f2341ca6e7f0b38e..e53df5bc29d9be920a46e69b3bcc7d503b078e95 100644
--- a/DDCore/include/DD4hep/Dictionary.h
+++ b/DDCore/include/DD4hep/Dictionary.h
@@ -116,6 +116,7 @@ template class dd4hep::Handle<TNamed>;
 #pragma link C++ class dd4hep::OpaqueDataBlock+;
 
 #pragma link C++ class dd4hep::Detector+;
+#pragma link C++ class dd4hep::DetectorLoad+;
 #pragma link C++ class dd4hep::DetectorData+;
 #pragma link C++ class dd4hep::DetectorData::ObjectHandleMap+;
 #pragma link C++ class dd4hep::Detector::PropertyValues+;
diff --git a/DDCore/include/DD4hep/OpaqueData.h b/DDCore/include/DD4hep/OpaqueData.h
index 4d816184bda07741aa850a9240c0b1597956762b..6e5b444d53ddadccfbf9f4c1a23216b7bed98137 100644
--- a/DDCore/include/DD4hep/OpaqueData.h
+++ b/DDCore/include/DD4hep/OpaqueData.h
@@ -75,6 +75,8 @@ namespace dd4hep {
 
   /// Class describing an opaque conditions data block
   /**
+   *  This class is used to handle the actual data IO.
+   *  Hence, we have write access to the data in abstract form.
    *
    *  \author  M.Frank
    *  \version 1.0
@@ -107,10 +109,12 @@ namespace dd4hep {
     OpaqueDataBlock& operator=(const OpaqueDataBlock& clone);
     /// Move the data content: 'from' will be reset to NULL
     bool move(OpaqueDataBlock& from);
+    /// Write access to the data buffer. Is only valid after call to bind<T>()
+    void* ptr()  const {  return pointer;      }
     /// Bind data value
-    bool bind(const BasicGrammar* grammar);
+    void* bind(const BasicGrammar* grammar);
     /// Bind data value in place
-    bool bind(void* ptr, size_t len, const BasicGrammar* grammar);
+    void* bind(void* ptr, size_t len, const BasicGrammar* grammar);
     /// Bind data value
     template <typename T> T& bind();
     /// Bind data value
diff --git a/DDCore/include/DD4hep/detail/AlignmentsInterna.h b/DDCore/include/DD4hep/detail/AlignmentsInterna.h
index 5eee59e931b6e3f1de9e071c11c27d732bce5269..4611cf9dcf160b6982ca9aef9cb0de98b2c7ebdd 100644
--- a/DDCore/include/DD4hep/detail/AlignmentsInterna.h
+++ b/DDCore/include/DD4hep/detail/AlignmentsInterna.h
@@ -56,7 +56,7 @@ namespace dd4hep {
     class AlignmentObject : public detail::ConditionObject    {
     public:
       /// Cached pointer to the bound conditions data, since these may be accessed very frequently
-      AlignmentData* alignment_data = 0;
+      AlignmentData* alignment_data = 0;  //! This valiable is internally bound and not ROOT persistent!
 
     public:
       /// Default constructor. Alignment data wuill be bound to the heap.
diff --git a/DDCore/include/DD4hep/detail/BasicGrammar_inl.h b/DDCore/include/DD4hep/detail/BasicGrammar_inl.h
index 16c54aaab11ae3ee7b3719eeafbc7e90fd90b9cc..2de0631dc556cda94b15a81a1de3f8892410e293 100644
--- a/DDCore/include/DD4hep/detail/BasicGrammar_inl.h
+++ b/DDCore/include/DD4hep/detail/BasicGrammar_inl.h
@@ -53,8 +53,7 @@ namespace {  static XmlTools::Evaluator& s__eval(dd4hep::g4Evaluator());  }
 namespace dd4hep {
 
   /// Standarsd constructor
-  template <typename TYPE> Grammar<TYPE>::Grammar() {
-    m_typeName = typeName(typeid(TYPE));
+  template <typename TYPE> Grammar<TYPE>::Grammar() : BasicGrammar(typeName(typeid(TYPE)))  {
   }
 
   /// Default destructor
@@ -66,16 +65,16 @@ namespace dd4hep {
     return typeid(TYPE);
   }
 
-  /// PropertyGrammar overload: Access to the type information
-  template <typename TYPE> const std::string& Grammar<TYPE>::type_name() const {
-    return m_typeName;
-  }
-
   /// Access the object size (sizeof operator)
   template <typename TYPE> size_t Grammar<TYPE>::sizeOf() const   {
     return sizeof(TYPE);
   }
 
+  /// Bind opaque address to object
+  template <typename TYPE> void Grammar<TYPE>::bind(void* pointer)  const  {
+    new(pointer) TYPE();
+  }
+
   /// Evaluate string value if possible before calling boost::spirit
   template <typename TYPE> int Grammar<TYPE>::evaluate(void*, const std::string&) const {
     return 0;
@@ -276,6 +275,7 @@ namespace dd4hep {
   // Containers of objects are not handled!
   
 }      // End namespace dd4hep
+#define DD4HEP_PARSER_GRAMMAR_CNAME(serial,name)  namespace_dd4hep__grammar_##serial##_##name
 
 #define DD4HEP_DEFINE_PARSER_GRAMMAR_TYPE(x)                            \
   namespace dd4hep {                                                    \
@@ -285,61 +285,71 @@ namespace dd4hep {
   namespace dd4hep {                                                    \
     template<> int Grammar<x >::evaluate(void* ptr, const std::string& val) const { return func ((x*)ptr,val); }}
 
-#define DD4HEP_DEFINE_PARSER_GRAMMAR(x,func)    \
-  DD4HEP_DEFINE_PARSER_GRAMMAR_TYPE(x)          \
-  DD4HEP_DEFINE_PARSER_GRAMMAR_EVAL(x,func)
+#define DD4HEP_DEFINE_PARSER_GRAMMAR_INSTANCE(serial,x) namespace DD4HEP_PARSER_GRAMMAR_CNAME(serial,0) { \
+    static const ::dd4hep::BasicGrammar& DD4HEP_PARSER_GRAMMAR_CNAME(serial,100) = ::dd4hep::BasicGrammar::instance<x>();  }
 
-#define DD4HEP_DEFINE_PARSER_GRAMMAR_DUMMY(x,func)                      \
-  PARSERS_DECL_FOR_SINGLE(x)                                            \
+#define DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,ctxt,x,func)         \
   DD4HEP_DEFINE_PARSER_GRAMMAR_TYPE(x)                                  \
   DD4HEP_DEFINE_PARSER_GRAMMAR_EVAL(x,func)                             \
-  namespace dd4hep   {   namespace Parsers   {                          \
-      int parse(x&, const std::string&)     {  return 1;  }             \
-    }}
+  DD4HEP_DEFINE_PARSER_GRAMMAR_INSTANCE(DD4HEP_PARSER_GRAMMAR_CNAME(serial,ctxt),x)
+
+#define DD4HEP_DEFINE_PARSER_GRAMMAR_DUMMY_SERIAL(serial,x,func)  \
+  PARSERS_DECL_FOR_SINGLE(x)                                      \
+  namespace dd4hep   {   namespace Parsers   {                    \
+      int parse(x&, const std::string&)     {  return 1;  }    }} \
+  DD4HEP_DEFINE_PARSER_GRAMMAR_TYPE(x)                            \
+  DD4HEP_DEFINE_PARSER_GRAMMAR_EVAL(x,func)                       \
+  DD4HEP_DEFINE_PARSER_GRAMMAR_INSTANCE(serial,x)
 
 #if defined(DD4HEP_HAVE_ALL_PARSERS)
-#define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(x,eval_func)                  \
-  DD4HEP_DEFINE_PARSER_GRAMMAR(x,eval_func)                             \
-  DD4HEP_DEFINE_PARSER_GRAMMAR(std::vector<x>, eval_container)          \
-  DD4HEP_DEFINE_PARSER_GRAMMAR(std::list<x>,   eval_container)          \
-  DD4HEP_DEFINE_PARSER_GRAMMAR(std::set<x>,    eval_container)          \
-  DD4HEP_DEFINE_PARSER_GRAMMAR(std::deque<x>,  eval_container)          \
-  DD4HEP_DEFINE_PARSER_GRAMMAR(dd4hep::detail::Primitive<x>::int_map_t,     eval_container) \
-  DD4HEP_DEFINE_PARSER_GRAMMAR(dd4hep::detail::Primitive<x>::ulong_map_t,   eval_container) \
-  DD4HEP_DEFINE_PARSER_GRAMMAR(dd4hep::detail::Primitive<x>::string_map_t,  eval_container) \
-  DD4HEP_DEFINE_PARSER_GRAMMAR(dd4hep::detail::Primitive<x>::int_pair_t,    eval_pair) \
-  DD4HEP_DEFINE_PARSER_GRAMMAR(dd4hep::detail::Primitive<x>::ulong_pair_t,  eval_pair) \
-  DD4HEP_DEFINE_PARSER_GRAMMAR(dd4hep::detail::Primitive<x>::string_pair_t, eval_pair) 
-
-#define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_VL(x,eval_func)     \
-  DD4HEP_DEFINE_PARSER_GRAMMAR(x,eval_func)                   \
-  DD4HEP_DEFINE_PARSER_GRAMMAR(std::vector<x>,eval_container) \
-  DD4HEP_DEFINE_PARSER_GRAMMAR(std::list<x>,eval_container)   
-
-#define DD4HEP_DEFINE_PARSER_GRAMMAR_U_CONT(x)            \
-  DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(x,eval_item)          \
-  DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(unsigned x,eval_item)
+#define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_SERIAL(serial,x,eval_func)    \
+  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,1,x,eval_func)             \
+  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,2,std::vector<x>, eval_container) \
+  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,3,std::list<x>,   eval_container) \
+  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,4,std::set<x>,    eval_container) \
+  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,5,std::deque<x>,  eval_container) \
+  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,6,dd4hep::detail::Primitive<x>::int_map_t,     eval_container) \
+  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,7,dd4hep::detail::Primitive<x>::ulong_map_t,   eval_container) \
+  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,8,dd4hep::detail::Primitive<x>::string_map_t,  eval_container) \
+  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,9,dd4hep::detail::Primitive<x>::int_pair_t,    eval_pair) \
+  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,10,dd4hep::detail::Primitive<x>::ulong_pair_t,  eval_pair) \
+  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,11,dd4hep::detail::Primitive<x>::string_pair_t, eval_pair) 
+
+#define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_VL_SERIAL(serial,x,eval_func) \
+  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,12,x,eval_func)            \
+  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,13,std::vector<x>,eval_container) \
+  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,14,std::list<x>,eval_container)   
+
+#define DD4HEP_DEFINE_PARSER_GRAMMAR_U_CONT_SERIAL(serial,x)            \
+  DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_SERIAL(serial,x,eval_item)          \
+  DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_SERIAL(serial,unsigned x,eval_item)
 
 #else
 
-#define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(x,eval_func)                  \
-  DD4HEP_DEFINE_PARSER_GRAMMAR(x,eval_func)                             \
-  DD4HEP_DEFINE_PARSER_GRAMMAR(std::vector<x>, eval_container)          \
-  DD4HEP_DEFINE_PARSER_GRAMMAR(std::list<x>,   eval_container)          \
-  DD4HEP_DEFINE_PARSER_GRAMMAR(std::set<x>,    eval_container)          \
-  DD4HEP_DEFINE_PARSER_GRAMMAR(dd4hep::detail::Primitive<x>::int_map_t,     eval_container) \
-  DD4HEP_DEFINE_PARSER_GRAMMAR(dd4hep::detail::Primitive<x>::string_map_t,  eval_container) \
-  DD4HEP_DEFINE_PARSER_GRAMMAR(dd4hep::detail::Primitive<x>::int_pair_t,    eval_pair) \
-  DD4HEP_DEFINE_PARSER_GRAMMAR(dd4hep::detail::Primitive<x>::string_pair_t, eval_pair) 
+#define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_SERIAL(serial,x,eval_func)    \
+  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,1,x,eval_func)             \
+  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,2,std::vector<x>, eval_container) \
+  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,3,std::list<x>,   eval_container) \
+  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,4,std::set<x>,    eval_container) \
+  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,5,dd4hep::detail::Primitive<x>::int_map_t,     eval_container) \
+    DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,6,dd4hep::detail::Primitive<x>::string_map_t,  eval_container) \
+  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,7,dd4hep::detail::Primitive<x>::int_pair_t,    eval_pair) \
+  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,8,dd4hep::detail::Primitive<x>::string_pair_t, eval_pair) 
 
-#define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_VL(x,eval_func)     \
-  DD4HEP_DEFINE_PARSER_GRAMMAR(x,eval_func)                   \
-  DD4HEP_DEFINE_PARSER_GRAMMAR(std::vector<x>,eval_container) \
-  DD4HEP_DEFINE_PARSER_GRAMMAR(std::list<x>,eval_container)   
+#define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_VL_SERIAL(serial,x,eval_func) \
+  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,9,x,eval_func)             \
+  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,10,std::vector<x>,eval_container) \
+  DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(serial,11,std::list<x>,eval_container)   
 
-#define DD4HEP_DEFINE_PARSER_GRAMMAR_U_CONT(x)    \
-  DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(x,eval_item)
+#define DD4HEP_DEFINE_PARSER_GRAMMAR_U_CONT_SERIAL(serial,x)    \
+  DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_SERIAL(serial,x,eval_item)
 
 #endif
 
+#define DD4HEP_DEFINE_PARSER_GRAMMAR(x,func)              DD4HEP_DEFINE_PARSER_GRAMMAR_SERIAL(__LINE__,__LINE__,x,func)
+#define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT(x,eval_func)    DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_SERIAL(__LINE__,x,eval_func)
+#define DD4HEP_DEFINE_PARSER_GRAMMAR_U_CONT(x)            DD4HEP_DEFINE_PARSER_GRAMMAR_U_CONT_SERIAL(__LINE__,x)
+#define DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_VL(x,eval_func) DD4HEP_DEFINE_PARSER_GRAMMAR_CONT_VL_SERIAL(__LINE__x,eval_func)
+#define DD4HEP_DEFINE_PARSER_GRAMMAR_DUMMY(x,func)        DD4HEP_DEFINE_PARSER_GRAMMAR_DUMMY_SERIAL(__LINE__,x,func)
+
 #endif  /* DD4HEP_DDCORE_BASICGRAMMAR_INL_H */
diff --git a/DDCore/include/DD4hep/detail/ConditionsInterna.h b/DDCore/include/DD4hep/detail/ConditionsInterna.h
index 072b38363d3649948575c9edbdada1307788e73a..b60184ef1988cd1907cfb421259b3e502a066948 100644
--- a/DDCore/include/DD4hep/detail/ConditionsInterna.h
+++ b/DDCore/include/DD4hep/detail/ConditionsInterna.h
@@ -68,7 +68,7 @@ namespace dd4hep {
       /// Data block
       OpaqueDataBlock data;
       /// Interval of validity
-      const IOV* iov   = 0;
+      const IOV* iov   = 0;     //! No ROOT persistency
       /// Hash value of the name
       Condition::key_type  hash  = 0;
       /// Flags
diff --git a/DDCore/include/DD4hep/detail/Grammar.h b/DDCore/include/DD4hep/detail/Grammar.h
index b9579af79ec837bd07e7ee0aa4758c5050d67514..51803796b20cb9204962ffdef0d88925d9fe60d1 100644
--- a/DDCore/include/DD4hep/detail/Grammar.h
+++ b/DDCore/include/DD4hep/detail/Grammar.h
@@ -35,19 +35,16 @@ namespace dd4hep {
    */
   template <typename TYPE> class Grammar : public BasicGrammar {
     friend class BasicGrammar;
-    /// Cached type information name
-    std::string m_typeName;
-  public:
     /// Default destructor
     virtual ~Grammar();
     /// Standarsd constructor
     Grammar();
 
+  public:
+
     /** Base class overrides   */
     /// PropertyGrammar overload: Access to the type information
     virtual const std::type_info& type() const  override;
-    /// Access to the type information name
-    virtual const std::string& type_name() const  override;    
     /// Access the object size (sizeof operator)
     virtual size_t sizeOf() const  override;
     /// PropertyGrammar overload: Serialize a property to a string
@@ -58,6 +55,8 @@ namespace dd4hep {
     virtual void destruct(void* pointer) const  override;
     /// Opaque object copy construction. Memory must be allocated externally
     virtual void copy(void* to, const void* from)  const  override;
+    /// Bind opaque address to object
+    virtual void bind(void* pointer)  const override;
 
     /** Class member function   */
     /// Evaluate string value if possible before calling boost::spirit
diff --git a/DDCore/src/BasicGrammar.cpp b/DDCore/src/BasicGrammar.cpp
index 18c4419ace2d4259d4287b0a494dc3b08636baec..d55ffac8bc3a40bc08246425d2ecba8a3ea8d6dc 100644
--- a/DDCore/src/BasicGrammar.cpp
+++ b/DDCore/src/BasicGrammar.cpp
@@ -12,21 +12,83 @@
 //==========================================================================
 
 // Framework include files
+#include "DD4hep/Printout.h"
 #include "DD4hep/Primitives.h"
 #include "DD4hep/Exceptions.h"
 #include "DD4hep/BasicGrammar.h"
 
+// ROOT include files
+#include "TDataType.h"
+#include "TROOT.h"
+
 // C/C++ include files
 #include <stdexcept>
+#include <mutex>
+#include <map>
+
+namespace {
+
+  std::mutex s_mutex;
+  
+  // This static object needs to be in function to trick out static constructors populating this registry....
+  static std::map<dd4hep::BasicGrammar::key_type, dd4hep::BasicGrammar*>& registry()  {
+    static std::map<dd4hep::BasicGrammar::key_type, dd4hep::BasicGrammar*> s_registry;
+    return s_registry;
+  }
+}
 
 /// Default constructor
-dd4hep::BasicGrammar::BasicGrammar()  {
-  self = this;
+dd4hep::BasicGrammar::BasicGrammar(const std::string& typ)
+  : name(typ), hash_value(dd4hep::detail::hash64(typ))
+{
+  if ( !registry().insert(std::make_pair(hash_value,this)).second )  {
+    // Error: Already existing grammar.
+    dd4hep::except("BasicGrammar","FAILED to add existent registry: %s [%016llX]",name.c_str(), hash_value);    
+  }
 }
 
 /// Default destructor
 dd4hep::BasicGrammar::~BasicGrammar()   {
-  self = 0;
+}
+
+/// Second step initialization after the virtual table is fixed
+void dd4hep::BasicGrammar::initialize()  const  {
+  std::lock_guard<std::mutex> lock(s_mutex);
+  if ( !inited )   {
+    TClass* cl = gROOT->GetClass(type());
+    if ( cl )  {
+      root_class = cl;
+      inited = true;
+      return;
+    }
+    root_data_type = TDataType::GetType(type());
+    if ( root_data_type == kOther_t )  {
+      except("BasicGrammar",
+             "+++ ERROR +++ Cannot initialize gammar object: %s. "
+             "No TClass and no data type information present!",name.c_str());
+    }
+    inited = true;
+  }
+}
+
+/// Access ROOT data type for fundamentals
+int dd4hep::BasicGrammar::initialized_data_type()  const   {
+  this->initialize();
+  return root_data_type;
+}
+
+/// Access the ROOT class for complex objects
+TClass* dd4hep::BasicGrammar::initialized_clazz()  const   {
+  this->initialize();
+  return root_class;
+}
+
+/// Lookup existing grammar using hash code (reading objects)
+const dd4hep::BasicGrammar& dd4hep::BasicGrammar::get(key_type hash_code)   {
+  auto i = registry().find(hash_code);
+  if ( i != registry().end() ) return *((*i).second);
+  dd4hep::except("BasicGrammar","FAILED to look up non existent registry: %016llX",hash_code);
+  throw "Error";  // Not reachable anyhow. Simply to please the compiler!
 }
 
 /// Error callback on invalid conversion
@@ -45,3 +107,4 @@ void dd4hep::BasicGrammar::invalidConversion(const std::type_info& from, const s
                              "Data conversion from '" + from_name + 
                              "' to '" + to_name + "' is not implemented.");
 }
+
diff --git a/DDCore/src/DD4hepRootPersistency.cpp b/DDCore/src/DD4hepRootPersistency.cpp
index 8869f71bf623ae27e32aef8d2ed733ab1a50b2df..e58fe3b5487683c84193e18d5198066036891618 100644
--- a/DDCore/src/DD4hepRootPersistency.cpp
+++ b/DDCore/src/DD4hepRootPersistency.cpp
@@ -18,31 +18,19 @@
 #include "DD4hep/detail/SegmentationsInterna.h"
 
 // ROOT include files
-#include "TClassStreamer.h"
-#include "TDataMember.h"
-#include "TClass.h"
 #include "TFile.h"
-#include "TROOT.h"
+#include "TTimeStamp.h"
 
 ClassImp(DD4hepRootPersistency)
 
 using namespace dd4hep;
 using namespace std;
 
-namespace  {
-  void stream_opaque_datablock(TBuffer& b, void* obj)    {
-    if ( b.IsReading() )  {
-      printout(INFO,"OpaqueData","Streaming IN  opaque data object...");
-    }
-    else  {
-      printout(INFO,"OpaqueData","Streaming OUT opaque data object...");
-    }
-  }
-}
 
 int DD4hepRootPersistency::save(Detector& description, const char* fname, const char* instance)   {
   TFile* f = TFile::Open(fname,"RECREATE");
   if ( f && !f->IsZombie()) {
+    TTimeStamp start;
     DD4hepRootPersistency* persist = new DD4hepRootPersistency();
     persist->m_data = new dd4hep::DetectorData();
     persist->m_data->adoptData(dynamic_cast<DetectorData&>(description),false);
@@ -60,35 +48,14 @@ int DD4hepRootPersistency::save(Detector& description, const char* fname, const
       }
     }
     printout(ALWAYS,"DD4hepRootPersistency","+++ Saving %ld nominals....",persist->nominals.size());
-#if 0
-    TClass* opaqueCl = gROOT->GetClass("dd4hep::OpaqueDataBlock");
-    if ( 0 == opaqueCl )  {
-      printout(ERROR,"DD4hepRootPersistency","+++ Missing TClass for 'dd4hep::OpaqueDataBlock'.");
-      return 0;
-    }
-    if ( 0 == opaqueCl->GetStreamer() )  {
-      opaqueCl->AdoptStreamer(new TClassStreamer(stream_opaque_datablock));
-      printout(ALWAYS,"DD4hepRootPersistency","+++ Set Streamer to %s",opaqueCl->GetName());
-    }
-#endif
-    TDataMember* m = 0;
-    TClass* volCl = TGeoVolume::Class();
-    printout(ALWAYS,"DD4hepRootPersistency","+++ Patching %s.fUserExtension to persistent",volCl->GetName());    
-    m = volCl->GetDataMember("fUserExtension");
-    m->SetTitle(m->GetTitle()+2);
-    m->SetBit(BIT(2));
-    TClass* nodCl = TGeoNode::Class();
-    printout(ALWAYS,"DD4hepRootPersistency","+++ Patching %s.fUserExtension to persistent",nodCl->GetName());    
-    m = nodCl->GetDataMember("fUserExtension");
-    m->SetTitle(m->GetTitle()+2);
-    m->SetBit(BIT(2));
-    
+
     /// Now we write the object
     int nBytes = persist->Write(instance);
     f->Close();
+    TTimeStamp stop;
     printout(ALWAYS,"DD4hepRootPersistency",
-             "+++ Wrote %d Bytes of geometry data '%s' to '%s'.",
-             nBytes, instance, fname);
+             "+++ Wrote %d Bytes of geometry data '%s' to '%s'  [%8.3f seconds].",
+             nBytes, instance, fname, stop.AsDouble()-start.AsDouble());
     if ( nBytes > 0 )  {
       printout(ALWAYS,"DD4hepRootPersistency",
                "+++ Successfully saved geometry data to file.");
@@ -102,42 +69,19 @@ int DD4hepRootPersistency::save(Detector& description, const char* fname, const
 }
 
 int DD4hepRootPersistency::load(Detector& description, const char* fname, const char* instance)  {
-#if 0
-  TClass* opaqueCl = gROOT->GetClass("dd4hep::OpaqueDataBlock");
-  if ( 0 == opaqueCl )  {
-    printout(ERROR,"DD4hepRootPersistency","+++ Missing TClass for 'dd4hep::OpaqueDataBlock'.");
-    return 0;
-  }
-  if ( 0 == opaqueCl->GetStreamer() )  {
-    opaqueCl->AdoptStreamer(new TClassStreamer(stream_opaque_datablock));
-    printout(ALWAYS,"DD4hepRootPersistency","+++ Set Streamer to %s",opaqueCl->GetName());
-  }
-#endif
-  TDataMember* m = 0;
-  TClass* volCl = TGeoVolume::Class();
-  printout(ALWAYS,"DD4hepRootPersistency","+++ Patching %s.fUserExtension to persistent",volCl->GetName());    
-  m = volCl->GetDataMember("fUserExtension");
-  m->SetTitle(m->GetTitle()+2);
-  m->SetBit(BIT(2));
-  TClass* nodCl = TGeoNode::Class();
-  printout(ALWAYS,"DD4hepRootPersistency","+++ Patching %s.fUserExtension to persistent",nodCl->GetName());    
-  m = nodCl->GetDataMember("fUserExtension");
-  m->SetTitle(m->GetTitle()+2);
-  m->SetBit(BIT(2));
-
-
   TFile* f = TFile::Open(fname);
   if ( f && !f->IsZombie()) {
-    DD4hepRootPersistency* persist = (DD4hepRootPersistency*)f->Get(instance);
-    if ( persist )   {
-      DetectorData& data = dynamic_cast<DetectorData&>(description);
-      DetectorData* target = persist->m_data;
-      for( const auto& s : target->m_idDict )  {
+    TTimeStamp start;
+    unique_ptr<DD4hepRootPersistency> persist((DD4hepRootPersistency*)f->Get(instance));
+    if ( persist.get() )   {
+      DetectorData* source = persist->m_data;
+      const auto& iddesc = persist->idSpecifications();
+      for( const auto& s : iddesc )  {
         IDDescriptor id = s.second;
         id.rebuild(id->description);
       }
       printout(ALWAYS,"DD4hepRootPersistency",
-               "+++ Fixed %ld IDDescriptor objects.",target->m_idDict.size());
+               "+++ Fixed %ld IDDescriptor objects.",iddesc.size());
       for( const auto& s : persist->m_segments )  {
         Readout ro = s.first;
         IDDescriptor id = s.second.first;
@@ -148,7 +92,6 @@ int DD4hepRootPersistency::load(Detector& description, const char* fname, const
       printout(ALWAYS,"DD4hepRootPersistency",
                "+++ Fixed %ld segmentation objects.",persist->m_segments.size());
       persist->m_segments.clear();
-
       const auto& sdets = persist->volumeManager()->subdetectors;
       size_t num[3] = {0,0,0};
       for( const auto& vm : sdets )  {
@@ -170,15 +113,14 @@ int DD4hepRootPersistency::load(Detector& description, const char* fname, const
       }
       printout(ALWAYS,"DD4hepRootPersistency",
                "+++ Fixed VolumeManager TOTALS     %-24s  %6ld volumes %4ld sdets %4ld mgrs.","",num[0],num[1],num[2]);
-
-
       printout(ALWAYS,"DD4hepRootPersistency","+++ loaded %ld nominals....",persist->nominals.size());
-
-      data.adoptData(*target);
-      //target->clearData();
-      delete persist;
+      DetectorData* tar_data = dynamic_cast<DetectorData*>(&description);
+      DetectorData* src_data = dynamic_cast<DetectorData*>(source);
+      tar_data->adoptData(*src_data,false);
+      TTimeStamp stop;
       printout(ALWAYS,"DD4hepRootPersistency",
-               "+++ Successfully loaded detector description from file:%s",fname);
+               "+++ Successfully loaded detector description from file:%s  [%8.3f seconds]",
+               fname, stop.AsDouble()-start.AsDouble());
       return 1;
     }
     printout(ERROR,"DD4hepRootPersistency",
@@ -192,6 +134,10 @@ int DD4hepRootPersistency::load(Detector& description, const char* fname, const
   return 0;
 }
 
+
+#include "DD4hep/detail/DetectorInterna.h"
+#include "DD4hep/detail/ConditionsInterna.h"
+#include "DD4hep/detail/AlignmentsInterna.h"
 namespace {
 
   class PersistencyChecks  {
@@ -380,6 +326,55 @@ namespace {
                fld.name());
       return 1;
     }
+    size_t checkAlignment(DetElement det)   {
+      AlignmentCondition::Object* align = det->nominal.ptr();
+      if ( 0 == align )  {
+        printout(ERROR,"chkNominals",
+                 "+++ ERROR +++ Detector element with invalid nominal:%s",
+                 det.path().c_str());
+        ++errors;
+      }
+      else if ( 0 == align->alignment_data )  {
+        printout(ERROR,"chkNominals",
+                 "+++ ERROR +++ Detector element with invalid nominal data:%s",
+                 det.path().c_str());
+        ++errors;
+      }
+      else if ( Condition(align).data().ptr() != align->alignment_data )  {
+        printout(ERROR,"chkNominals",
+                 "+++ ERROR +++ Detector element with inconsisten nominal data:%s [%p != %p]",
+                 det.path().c_str(),Condition(align).data().ptr(),align->alignment_data);
+        ++errors;
+      }
+      else  {
+        return 1;
+      }
+      return 0;
+    }
+    
+    /// Check nominal alignments of the volume manager
+    size_t checkNominals(VolumeManager mgr)   {
+      int count = 0;
+      const auto& sdets = mgr->subdetectors;
+      for( const auto& vm : sdets )  {
+        VolumeManager::Object* obj   = vm.second.ptr();
+        for( const auto& iv : obj->volumes )  {
+          VolumeManagerContext* ctx   = iv.second;
+          count += checkAlignment(ctx->element);
+        }
+      }
+      return count;
+    }
+    size_t checkDetectorNominals(DetElement d)   {
+      int count = 0;
+      Volume v = d.placement().volume();
+      if ( v.isSensitive() )   {
+        count += checkAlignment(d);
+      }
+      for( const auto& c : d.children() )
+        count += checkDetectorNominals(c.second);
+      return count;
+    }
   };
 }
 
@@ -389,8 +384,8 @@ size_t DD4hepRootCheck::checkConstants()   const   {
   PersistencyChecks checks;
   for( const auto& obj : object->constants() )
     count += checks.checkConstant(obj);
-  printout(ALWAYS,"chkProperty","+++ Checked %ld Constant objects. Num.Errors: %ld",
-           count, checks.errors); 
+  printout(ALWAYS,"chkProperty","+++ %s Checked %ld Constant objects. Num.Errors: %ld",
+           checks.errors==0 ? "PASSED" : "FAILED", count, checks.errors); 
   return checks.errors;
 }
 
@@ -400,8 +395,8 @@ size_t DD4hepRootCheck::checkProperties()   const   {
   PersistencyChecks checks;
   for( const auto& obj : object->properties() )
     count += checks.checkProperty(obj);
-  printout(ALWAYS,"chkProperty","+++ Checked %ld Property objects. Num.Errors: %ld",
-           count, checks.errors); 
+  printout(ALWAYS,"chkProperty","+++ %s Checked %ld Property objects. Num.Errors: %ld",
+           checks.errors==0 ? "PASSED" : "FAILED", count, checks.errors); 
   return checks.errors;
 }
 
@@ -418,9 +413,16 @@ size_t DD4hepRootCheck::checkReadouts()   const   {
   PersistencyChecks checks;
   for( const auto& obj : object->readouts() )
     count += checks.checkReadout(obj.second);
-  printout(ALWAYS,"chkReadouts","+++ Checked %ld Readout objects. Num.Errors: %ld",
-           count, checks.errors); 
-  return checks.errors;
+
+  if ( object->sensitiveDetectors().size() != object->readouts().size() )   {
+    printout(ERROR,"chkNominals",
+             "+++ Number of sensitive detectors does NOT match number of readouts: %ld != %ld",
+             object->sensitiveDetectors().size(),object->readouts().size());
+    ++checks.errors;
+  }
+  printout(ALWAYS,"chkNominals","+++ %s Checked %ld readout objects. Num.Errors: %ld",
+           checks.errors==0 ? "PASSED" : "FAILED", count, checks.errors);
+  return count;
 }
 
 /// Call to theck the DD4hep fields
@@ -429,8 +431,8 @@ size_t DD4hepRootCheck::checkFields()   const   {
   PersistencyChecks checks;
   for( const auto& obj : object->fields() )
     count += checks.checkField(obj.second);
-  printout(ALWAYS,"chkFields","+++ Checked %ld Field objects. Num.Errors: %ld",
-           count, checks.errors); 
+  printout(ALWAYS,"chkFields","+++ %s Checked %ld Field objects. Num.Errors: %ld",
+           checks.errors==0 ? "PASSED" : "FAILED", count, checks.errors); 
   return checks.errors;
 }
 
@@ -440,8 +442,8 @@ size_t DD4hepRootCheck::checkRegions()   const   {
   PersistencyChecks checks;
   for( const auto& obj : object->regions() )
     count += checks.checkRegion(obj.second);
-  printout(ALWAYS,"chkRegions","+++ Checked %ld Region objects. Num.Errors: %ld",
-           count, checks.errors); 
+  printout(ALWAYS,"chkRegions","+++ %s Checked %ld Region objects. Num.Errors: %ld",
+           checks.errors==0 ? "PASSED" : "FAILED", count, checks.errors); 
   return checks.errors;
 }
 
@@ -451,8 +453,8 @@ size_t DD4hepRootCheck::checkIdSpecs()   const   {
   PersistencyChecks checks;
   for( const auto& obj : object->idSpecifications() )
     count += checks.checkIDDescriptor(obj.second);
-  printout(ALWAYS,"chkReadouts","+++ Checked %ld Readout objects. Num.Errors: %ld",
-           count, checks.errors); 
+  printout(ALWAYS,"chkReadouts","+++ %s Checked %ld Readout objects. Num.Errors: %ld",
+           checks.errors==0 ? "PASSED" : "FAILED", count, checks.errors); 
   return checks.errors;
 }
 
@@ -462,8 +464,8 @@ size_t DD4hepRootCheck::checkDetectors()  const   {
   PersistencyChecks checks;
   for( const auto& obj : object->detectors() )
     count += checks.checkDetector(obj.second);
-  printout(ALWAYS,"chkDetectors","+++ Checked %ld DetElement objects. Num.Errors: %ld",
-           count, checks.errors); 
+  printout(ALWAYS,"chkDetectors","+++ %s Checked %ld DetElement objects. Num.Errors: %ld",
+           checks.errors==0 ? "PASSED" : "FAILED", count, checks.errors); 
   return checks.errors;
 }
 
@@ -473,8 +475,8 @@ size_t DD4hepRootCheck::checkSensitives()   const   {
   PersistencyChecks checks;
   for( const auto& obj : object->sensitiveDetectors() )
     count += checks.checkSensitive(obj.second);
-  printout(ALWAYS,"chkSensitives","+++ Checked %ld SensitiveDetector objects. Num.Errors: %ld",
-           count, checks.errors); 
+  printout(ALWAYS,"chkSensitives","+++ %s Checked %ld SensitiveDetector objects. Num.Errors: %ld",
+           checks.errors==0 ? "PASSED" : "FAILED", count, checks.errors); 
   return checks.errors;
 }
 
@@ -484,16 +486,43 @@ size_t DD4hepRootCheck::checkLimitSets()   const   {
   size_t count = 0;
   for( const auto& obj : object->limitsets() )
     count += checks.checkLimitset(obj.second);
-  printout(ALWAYS,"chkSensitives","+++ Checked %ld SensitiveDetector objects. Num.Errors: %ld",
-           count, checks.errors); 
+  printout(ALWAYS,"chkSensitives","+++ %s Checked %ld SensitiveDetector objects. Num.Errors: %ld",
+           checks.errors==0 ? "PASSED" : "FAILED", count, checks.errors); 
   return checks.errors;
 }
 
 /// Call to check the volume manager hierarchy
 size_t DD4hepRootCheck::checkVolManager()   const   {
-  const void* args[] = {"SiTrackerBarrel",0};
-  size_t count = object->apply("DD4hepVolumeMgrTest",1,(char**)args);
-  printout(ALWAYS,"chkVolumeMgr","+++ Checked %ld Volume objects.",count); 
+  PersistencyChecks checks;
+  size_t count = checks.checkNominals(object->volumeManager());
+  printout(ALWAYS,"chkNominals","+++ %s Checked %ld VolumeManager contexts. Num.Errors: %ld",
+           checks.errors==0 ? "PASSED" : "FAILED", count, checks.errors);
+  return count;
+}
+
+/// Call to check the nominal alignments in the detector hierarchy (for sensitive detectors)
+size_t DD4hepRootCheck::checkNominals()   const   {
+  size_t count = 0;
+  PersistencyChecks checks;
+  const auto& dets = object->sensitiveDetectors();
+  for( const auto& d : dets )
+    count += checks.checkDetectorNominals(object->detector(d.first));
+  printout(ALWAYS,"chkNominals","+++ %s Checked %ld DetElements. Num.Errors: %ld",
+           checks.errors==0 ? "PASSED" : "FAILED", count, checks.errors);
+  return count;
+}
+
+/// Call to check the segmentations starting from the top level detector
+size_t DD4hepRootCheck::checkSegmentations()   const   {
+  size_t count = 0;
+  PersistencyChecks checks;
+  const auto& dets = object->sensitiveDetectors();
+  for( const auto& d : dets )   {
+    Segmentation seg = SensitiveDetector(d.second).readout().segmentation();
+    if ( seg.isValid() )  count += checks.checkSegmentation(seg);
+  }
+  printout(ALWAYS,"chkNominals","+++ %s Checked %ld readout segmentations. Num.Errors: %ld",
+           checks.errors==0 ? "PASSED" : "FAILED", count, checks.errors);
   return count;
 }
 
diff --git a/DDCore/src/DetectorData.cpp b/DDCore/src/DetectorData.cpp
index 6f2559c9f620196a03888143dc943adf9feb6fa9..83ba19d7651656623ae158333dd94fb013d76e34 100644
--- a/DDCore/src/DetectorData.cpp
+++ b/DDCore/src/DetectorData.cpp
@@ -12,6 +12,7 @@
 //==========================================================================
 
 // Framework include files
+#include "DD4hep/BasicGrammar.h"
 #include "DD4hep/DetectorData.h"
 #include "DD4hep/InstanceCount.h"
 #include "DD4hep/detail/ObjectsInterna.h"
@@ -19,12 +20,135 @@
 
 // ROOT include files
 #include "TGeoManager.h"
+#include "TClassStreamer.h"
+#include "TDataMember.h"
+#include "TDataType.h"
+#include "TClass.h"
+#include "TROOT.h"
+
 
 namespace dd4hep {  namespace detail {    class DetectorImp;  }}
 
 using namespace dd4hep::detail;
 using namespace dd4hep;
 
+namespace {
+
+  union FundamentalData  {
+    Char_t    c;
+    Short_t   s;
+    Int_t     i;
+    Long_t    l;
+    Float_t   f;
+    Double_t  d;
+    UChar_t   uc;
+    UShort_t  us;
+    UInt_t    ui;
+    ULong_t   ul;
+    Long64_t  ll;
+    ULong64_t ull;
+    Bool_t    b;
+    void read(TBuffer& buff,int dtyp)   {
+      switch(dtyp)  {
+      case  1: buff >> c;    break;
+      case  2: buff >> s;    break;
+      case  3: buff >> i;    break;
+      case  4: buff >> l;    break;
+      case  5: buff >> f;    break;
+      case  6: buff >> i;    break;
+        //case  7: buff >> d;   break; // char*
+      case  8: buff >> d;    break;
+      case  9: buff >> d;    break;
+      case 11: buff >> uc;   break;
+      case 12: buff >> us;   break;
+      case 13: buff >> ui;   break;
+      case 14: buff >> ul;   break;
+      case 15: buff >> ui;   break;
+      case 16: buff >> ll;   break;
+      case 17: buff >> ull;  break;
+      case 18: buff >> b;    break;
+      case 19: buff >> f;    break;
+      default:
+        printout(ERROR,"OpaqueData","Unknown fundamental data type: [%X]",dtyp);
+        break;
+      }
+    }
+    void write(TBuffer& buff,int dtyp)  const  {
+      switch(dtyp)  {
+      case  1: buff << c;    break;
+      case  2: buff << s;    break;
+      case  3: buff << i;    break;
+      case  4: buff << l;    break;
+      case  5: buff << f;    break;
+      case  6: buff << i;    break;
+        //case  7: buff << d;   break; // char*
+      case  8: buff << d;    break;
+      case  9: buff << d;    break;
+      case 11: buff << uc;   break;
+      case 12: buff << us;   break;
+      case 13: buff << ui;   break;
+      case 14: buff << ul;   break;
+      case 15: buff << ui;   break;
+      case 16: buff << ll;   break;
+      case 17: buff << ull;  break;
+      case 18: buff << b;    break;
+      case 19: buff << f;    break;
+      default:
+        printout(ERROR,"OpaqueData","Unknown fundamental data type: [%X]",dtyp);
+        break;
+      }
+    }
+  };
+
+  void stream_opaque_datablock(TBuffer& b, void* obj)    {
+    UInt_t R__s = 0; // Start of object.
+    UInt_t R__c = 0; // Count of bytes.
+    TClass* cl = BasicGrammar::instance<OpaqueDataBlock>().clazz();//gROOT->GetClass("dd4hep::OpaqueDataBlock");
+   
+    OpaqueDataBlock* block = (OpaqueDataBlock*)obj;
+    if ( b.IsReading() )  {
+      b.ReadVersion(&R__s, &R__c, cl);
+      BasicGrammar::key_type key = 0;
+      b >> key;
+      const BasicGrammar& gr = BasicGrammar::get(key);
+      //printout(INFO,"OpaqueData","   Data type:%s  [%016llX]",gr.name.c_str(),key);
+      void* ptr = block->ptr();
+      if ( !ptr )  { // Some blocks are already bound. Skip those.
+        ptr = block->bind(&gr);
+        gr.bind(ptr);
+      }
+      /// Now perform the I/O action
+      if ( gr.type() == typeid(std::string) )
+        b.ReadStdString(*(std::string*)ptr);
+      else if ( gr.clazz() )
+        b.ReadClassBuffer(gr.clazz(),ptr);
+      else
+        ((FundamentalData*)ptr)->read(b,gr.data_type());
+      b.CheckByteCount(R__s, R__c, cl);
+    }
+    else if ( 0 == block->grammar )  {
+      printout(ERROR,"OpaqueData","+++ ERROR +++ Opaque data block has no grammar attached. Cannot be saved!");
+    }
+    else  {
+      const BasicGrammar& gr = *block->grammar;
+      std::string typ = gr.type_name();
+      R__c = b.WriteVersion(cl,kTRUE);
+      b << gr.hash();
+      //printout(INFO,"OpaqueData","   Data type:%s  Grammar:%s",typ.c_str(),block->grammar->name.c_str());
+
+      /// Now perform the I/O action
+      if ( gr.type() == typeid(std::string) )
+        b.WriteStdString(*(std::string*)block->ptr());
+      else if ( gr.clazz() )
+        b.WriteClassBuffer(gr.clazz(),block->ptr());
+      else
+        ((const FundamentalData*)block->ptr())->write(b,gr.data_type());
+      b.SetByteCount(R__c, kTRUE);
+    }
+  }
+}
+
+
 /// Default constructor
 DetectorData::DetectorData()
   : m_manager(0), m_world(), m_trackers(), m_worldVol(),
@@ -32,6 +156,29 @@ DetectorData::DetectorData()
     m_buildType(BUILD_DEFAULT), m_extensions(typeid(DetectorData)), m_volManager(),
     m_inhibitConstants(false)
 {
+  static bool first = true;
+  if ( first )   {
+    first = false;
+    TClass* cl = gROOT->GetClass("dd4hep::OpaqueDataBlock");
+    if ( 0 == cl )  {
+      except("PersistencyIO","+++ Missing TClass for 'dd4hep::OpaqueDataBlock'.");
+    }
+    if ( 0 == cl->GetStreamer() )  {
+      cl->AdoptStreamer(new TClassStreamer(stream_opaque_datablock));
+      printout(INFO,"PersistencyIO","+++ Set Streamer to %s",cl->GetName());
+    }
+    TDataMember* m = 0;
+    cl = TGeoVolume::Class();
+    printout(INFO,"PersistencyIO","+++ Patching %s.fUserExtension to persistent",cl->GetName());    
+    m = cl->GetDataMember("fUserExtension");
+    m->SetTitle(m->GetTitle()+2);
+    m->SetBit(BIT(2));
+    cl = TGeoNode::Class();
+    printout(INFO,"PersistencyIO","+++ Patching %s.fUserExtension to persistent",cl->GetName());    
+    m = cl->GetDataMember("fUserExtension");
+    m->SetTitle(m->GetTitle()+2);
+    m->SetBit(BIT(2));
+  }
   InstanceCount::increment(this);
 }
 
diff --git a/DDCore/src/DetectorImp.cpp b/DDCore/src/DetectorImp.cpp
index 47253ea4d60db7bcaebfef101d804f034d579e36..1c5487fabdcf967eb8ba0ae600971f3448a4de8b 100644
--- a/DDCore/src/DetectorImp.cpp
+++ b/DDCore/src/DetectorImp.cpp
@@ -34,6 +34,7 @@
 #include "TGeoVolume.h"
 #include "TGeoShape.h"
 #include "TClass.h"
+
 #include "XML/DocumentHandler.h"
 
 #if DD4HEP_USE_PYROOT
@@ -102,12 +103,12 @@ void Detector::destroyInstance() {
 }
 
 /// Default constructor
-DetectorImp::DetectorImp() : DetectorData(), DetectorLoad(this), m_buildType(BUILD_NONE)
+DetectorImp::DetectorImp()
+  : DetectorData(), DetectorLoad(this), m_buildType(BUILD_NONE)
 {
-
   set_unexpected( description_unexpected ) ;
   set_terminate( description_unexpected ) ;
-
+  
   InstanceCount::increment(this);
   if (0 == gGeoManager) {
     gGeoManager = new TGeoManager("world", "Detector Geometry");
diff --git a/DDCore/src/DetectorImp.h b/DDCore/src/DetectorImp.h
index 50d4f7122c4ca33adad50d5a14a77706e2608f11..9536feb4e37723873e566264966afff59716d2b6 100644
--- a/DDCore/src/DetectorImp.h
+++ b/DDCore/src/DetectorImp.h
@@ -352,4 +352,8 @@ namespace dd4hep {
 
   };
 } /* End namespace dd4hep   */
+
+#if defined(__CINT__) || defined(__MAKECINT__) || defined(__CLING__) || defined(__ROOTCLING__)
+#pragma link C++ class dd4hep::DetectorImp+;
+#endif
 #endif    /* dd4hep_DetectorGEOIMP_H    */
diff --git a/DDCore/src/OpaqueData.cpp b/DDCore/src/OpaqueData.cpp
index ad93d449b148bb89b5e34e5186f9c27c68883ac5..9f5543cb9f1dbf3d7ffa74a86a4add034fd7959c 100644
--- a/DDCore/src/OpaqueData.cpp
+++ b/DDCore/src/OpaqueData.cpp
@@ -119,15 +119,15 @@ OpaqueDataBlock& OpaqueDataBlock::operator=(const OpaqueDataBlock& c)   {
   return *this;
 }
 
-/// Set data value
-bool OpaqueDataBlock::bind(const BasicGrammar* g)   {
+/// Bind data value
+void* OpaqueDataBlock::bind(const BasicGrammar* g)   {
   if ( !grammar )  {
     size_t len = g->sizeOf();
     grammar  = g;
     (len > sizeof(data))
       ? (pointer=::operator new(len),type=ALLOC_DATA)
       : (pointer=data,type=PLAIN_DATA);
-    return true;
+    return pointer;
   }
   else if ( grammar == g )  {
     // We cannot ingore secondary requests for data bindings.
@@ -135,11 +135,11 @@ bool OpaqueDataBlock::bind(const BasicGrammar* g)   {
     except("OpaqueData","You may not bind opaque multiple times!");
   }
   typeinfoCheck(grammar->type(),g->type(),"Opaque data blocks may not be assigned.");
-  return false;
+  return 0;
 }
 
 /// Set data value
-bool OpaqueDataBlock::bind(void* ptr, size_t size, const BasicGrammar* g)   {
+void* OpaqueDataBlock::bind(void* ptr, size_t size, const BasicGrammar* g)   {
   if ( !grammar )  {
     size_t len = g->sizeOf();
     grammar = g;
@@ -149,7 +149,7 @@ bool OpaqueDataBlock::bind(void* ptr, size_t size, const BasicGrammar* g)   {
       pointer=data, type=PLAIN_DATA;
     else 
       pointer=::operator new(len),type=ALLOC_DATA;
-    return true;
+    return pointer;
   }
   else if ( grammar == g )  {
     // We cannot ingore secondary requests for data bindings.
@@ -157,7 +157,7 @@ bool OpaqueDataBlock::bind(void* ptr, size_t size, const BasicGrammar* g)   {
     except("OpaqueData","You may not bind opaque multiple times!");
   }
   typeinfoCheck(grammar->type(),g->type(),"Opaque data blocks may not be assigned.");
-  return false;
+  return 0;
 }
 
 /// Set data value
@@ -170,3 +170,18 @@ void OpaqueDataBlock::assign(const void* ptr, const type_info& typ)  {
   }
   grammar->copy(pointer,ptr);
 }
+
+/// print Conditions object
+std::ostream& operator << (std::ostream& s, const OpaqueDataBlock& data)   {
+  s << data.str();
+  return s;
+}
+#include "DDParsers/Parsers.h"
+#include "DDParsers/ToStream.h"
+DD4HEP_DEFINE_PARSER_DUMMY(OpaqueDataBlock)
+
+#include "DD4hep/detail/BasicGrammar_inl.h"
+#include "DD4hep/detail/ConditionsInterna.h"
+DD4HEP_DEFINE_PARSER_GRAMMAR(OpaqueDataBlock,eval_none<OpaqueDataBlock>)
+DD4HEP_DEFINE_CONDITIONS_TYPE(OpaqueDataBlock)
+
diff --git a/DDCore/src/plugins/StandardPlugins.cpp b/DDCore/src/plugins/StandardPlugins.cpp
index 4501bb1fe30ee40902165627f98e8dbd23f4b30a..b982d9cf387fd113fc55b74cb3c2e028d30a7c69 100644
--- a/DDCore/src/plugins/StandardPlugins.cpp
+++ b/DDCore/src/plugins/StandardPlugins.cpp
@@ -536,6 +536,20 @@ static long load_geometryFromroot(Detector& description, int argc, char** argv)
 }
 DECLARE_APPLY(DD4hepRootLoader,load_geometryFromroot)
 
+/// Basic entry point to check sensitive detector strictures
+/**
+ *  Factory: DD4hepCheckDetectors
+ *
+ *  \author  M.Frank
+ *  \version 1.0
+ *  \date    01/04/2014
+ */
+static long check_detectors(Detector& description, int /* argc */, char** /* argv */) {
+  DD4hepRootCheck check(&description);
+  return check.checkDetectors();
+}
+DECLARE_APPLY(DD4hepCheckDetectors,check_detectors)
+
 /// Basic entry point to check sensitive detector strictures
 /**
  *  Factory: DD4hepCheckSensitives
@@ -552,17 +566,17 @@ DECLARE_APPLY(DD4hepCheckSensitives,check_sensitives)
 
 /// Basic entry point to check sensitive detector strictures
 /**
- *  Factory: DD4hepCheckDetectors
+ *  Factory: DD4hepCheckSegmentations
  *
  *  \author  M.Frank
  *  \version 1.0
  *  \date    01/04/2014
  */
-static long check_detectors(Detector& description, int /* argc */, char** /* argv */) {
+static long check_segmentations(Detector& description, int /* argc */, char** /* argv */) {
   DD4hepRootCheck check(&description);
-  return check.checkDetectors();
+  return check.checkSegmentations();
 }
-DECLARE_APPLY(DD4hepCheckDetectors,check_detectors)
+DECLARE_APPLY(DD4hepCheckSegmentations,check_segmentations)
 
 /// Basic entry point to check sensitive detector strictures
 /**
@@ -592,6 +606,34 @@ static long check_idspecs(Detector& description, int /* argc */, char** /* argv
 }
 DECLARE_APPLY(DD4hepCheckIdspecs,check_idspecs)
 
+/// Basic entry point to check IDDescriptors of the detector object
+/**
+ *  Factory: DD4hepCheckVolumeManager
+ *
+ *  \author  M.Frank
+ *  \version 1.0
+ *  \date    01/04/2014
+ */
+static long check_volumemanager(Detector& description, int /* argc */, char** /* argv */) {
+  DD4hepRootCheck check(&description);
+  return check.checkVolManager();
+}
+DECLARE_APPLY(DD4hepCheckVolumeManager,check_volumemanager)
+
+/// Basic entry point to check IDDescriptors of the detector object
+/**
+ *  Factory: DD4hepCheckNominals
+ *
+ *  \author  M.Frank
+ *  \version 1.0
+ *  \date    01/04/2014
+ */
+static long check_nominals(Detector& description, int /* argc */, char** /* argv */) {
+  DD4hepRootCheck check(&description);
+  return check.checkNominals();
+}
+DECLARE_APPLY(DD4hepCheckNominals,check_nominals)
+
 /// Basic entry point to print out the volume hierarchy
 /**
  *  Factory: DD4hepVolumeDump
diff --git a/examples/CLICSiD/CMakeLists.txt b/examples/CLICSiD/CMakeLists.txt
index 4521b9b64240117086283159002289ad38944c96..ba6d2fbb5706c5cf30f9e5ab0c038a599261a406 100644
--- a/examples/CLICSiD/CMakeLists.txt
+++ b/examples/CLICSiD/CMakeLists.txt
@@ -58,37 +58,6 @@ dd4hep_add_test_reg( CLICSiD_check_overlaps_LONGTEST
                     --tolerance=0.1
   REGEX_PASS " Execution finished..." )
 #
-#  Test saving geometry to ROOT file
-dd4hep_add_test_reg( CLICSiD_ROOT_Save_LONGTEST
-  COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_ClientTests.sh"
-  EXEC_ARGS  geoPluginRun
-  -volmgr -destroy -input file:${CMAKE_CURRENT_SOURCE_DIR}/compact/compact.xml
-  -plugin DD4hepGeometry2ROOT -output CLICSiD_geometry.root
-  REGEX_PASS "\\+\\+\\+ Successfully saved geometry data to file.")
-#
-#  Test restoring geometry from ROOT file: Volume Manager
-dd4hep_add_test_reg( CLICSiD_ROOT_Restore_LONGTEST
-  COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_ClientTests.sh"
-  EXEC_ARGS  geoPluginRun -print WARNING
-  -plugin DD4hepRootLoader CLICSiD_geometry.root
-  REGEX_PASS "\\+\\+\\+ Successfully loaded detector description from file")
-#
-#  Test restoring geometry from ROOT file: Volume Manager
-dd4hep_add_test_reg( CLICSiD_ROOT_Restore_VolMgr_LONGTEST
-  COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_ClientTests.sh"
-  EXEC_ARGS  geoPluginRun -print WARNING
-  -plugin DD4hepRootLoader CLICSiD_geometry.root
-  -plugin DD4hepVolumeMgrTest SiTrackerBarrel
-  REGEX_PASS "\\+\\+\\+ PASSED: Checked 81306 objects. Num.Errors:0")
-#
-#  Test restoring geometry from ROOT file: Volume Manager
-dd4hep_add_test_reg( CLICSiD_ROOT_Restore_Sensitives_LONGTEST
-  COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_ClientTests.sh"
-  EXEC_ARGS  geoPluginRun -print WARNING
-  -plugin DD4hepRootLoader CLICSiD_geometry.root
-  -plugin DD4hepCheckSensitives
-  REGEX_PASS "\\+\\+\\+ Checked 14 SensitiveDetector objects. Num.Errors: 0")
-#
 #---Geant4 Testsing-----------------------------------------------------------------
 #
 if (DD4HEP_USE_GEANT4)
diff --git a/examples/Persistency/CMakeLists.txt b/examples/Persistency/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..51d7751ad9b43a1dffe9bcd3df55341f20c32394
--- /dev/null
+++ b/examples/Persistency/CMakeLists.txt
@@ -0,0 +1,121 @@
+#==========================================================================
+#  AIDA Detector description implementation 
+#--------------------------------------------------------------------------
+# Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+# All rights reserved.
+#
+# For the licensing terms see $DD4hepINSTALL/LICENSE.
+# For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
+#
+#==========================================================================
+cmake_minimum_required(VERSION 3.3 FATAL_ERROR)
+include ( ${DD4hep_DIR}/cmake/DD4hep.cmake )
+
+#--------------------------------------------------------------------------
+dd4hep_configure_output ()
+dd4hep_package ( Persistency MAJOR 0 MINOR 0 PATCH 1
+  USES         [ROOT   REQUIRED COMPONENTS Geom GenVector]
+               [DD4hep REQUIRED COMPONENTS DDCore]
+  OPTIONAL     XERCESC
+)
+#-----------------------------------------------------------------------------------
+dd4hep_add_plugin(PersistencyExample SOURCES src/*.cpp)
+dd4hep_configure_scripts (Persistency DEFAULT_SETUP WITH_TESTS )
+#--------------------------------------------------------------------------
+#
+#  Test saving conditions to ROOT file
+dd4hep_add_test_reg( Persist_Conditions_Save
+  COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_ClientTests.sh"
+  EXEC_ARGS  geoPluginRun
+  -plugin DD4hep_PersistencyExample_write_cond -output Conditions.root
+  REGEX_PASS "\\+\\+\\+ Wrote 1360 bytes to file Conditions.root"
+  REGEX_FAIL " ERROR ;EXCEPTION;Exception;FAILED"
+  )
+#
+#  Test restoring geometry from ROOT file: Volume Manager
+dd4hep_add_test_reg( Persist_Conditions_Restore
+  COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_ClientTests.sh"
+  EXEC_ARGS  geoPluginRun
+  -plugin DD4hep_PersistencyExample_read_cond -input Conditions.root
+  REGEX_PASS "\\+\\+\\+ Read successfully 14 conditions. Result=1637"
+  REGEX_FAIL " ERROR ;EXCEPTION;Exception;FAILED"
+  )
+#
+#  Test saving geometry to ROOT file
+dd4hep_add_test_reg( Persist_CLICSiD_Save_LONGTEST
+  COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_ClientTests.sh"
+  EXEC_ARGS  geoPluginRun
+  -volmgr -destroy -input file:${CMAKE_CURRENT_SOURCE_DIR}/../CLICSiD/compact/compact.xml
+  -plugin DD4hepGeometry2ROOT -output CLICSiD_geometry.root
+  REGEX_PASS "\\+\\+\\+ Successfully saved geometry data to file."
+  REGEX_FAIL " ERROR ;EXCEPTION;Exception;FAILED"
+  )
+#
+#  Test restoring geometry from ROOT file: Volume Manager
+dd4hep_add_test_reg( Persist_CLICSiD_Restore_LONGTEST
+  COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_ClientTests.sh"
+  EXEC_ARGS  geoPluginRun -print WARNING
+  -plugin DD4hepRootLoader CLICSiD_geometry.root
+  REGEX_PASS "\\+\\+\\+ Successfully loaded detector description from file"
+  REGEX_FAIL " ERROR ;EXCEPTION;Exception;FAILED"
+  )
+#
+#  Test restoring geometry from ROOT file: Volume Manager loading+nominals
+dd4hep_add_test_reg( Persist_CLICSiD_Restore_VolMgr1_LONGTEST
+  COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_ClientTests.sh"
+  EXEC_ARGS  geoPluginRun -print WARNING
+  -plugin DD4hepRootLoader CLICSiD_geometry.root
+  -plugin DD4hepCheckVolumeManager
+  REGEX_PASS "\\+\\+\\+ PASSED Checked 29270 VolumeManager contexts. Num.Errors: 0"
+  REGEX_FAIL " ERROR ;EXCEPTION;Exception;FAILED"
+  )
+#
+#  Test restoring geometry from ROOT file: Test Volume Manager results
+dd4hep_add_test_reg( Persist_CLICSiD_Restore_VolMgr2_LONGTEST
+  COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_ClientTests.sh"
+  EXEC_ARGS  geoPluginRun -print WARNING
+  -plugin DD4hepRootLoader CLICSiD_geometry.root
+  -plugin DD4hepVolumeMgrTest SiTrackerBarrel
+  REGEX_PASS "\\+\\+\\+ PASSED: Checked 81306 objects. Num.Errors:0"
+  REGEX_FAIL " ERROR ;EXCEPTION;Exception;FAILED"
+  )
+#
+#  Test restoring geometry from ROOT file: DetElement nominal alignments
+#  Note: BeamCal has a problem. Need to be taken into account
+dd4hep_add_test_reg( Persist_CLICSiD_Restore_Nominal_LONGTEST
+  COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_ClientTests.sh"
+  EXEC_ARGS  geoPluginRun -print WARNING
+  -plugin DD4hepRootLoader CLICSiD_geometry.root
+  -plugin DD4hepCheckNominals
+  REGEX_PASS "\\+\\+\\+ FAILED Checked 15946 DetElements. Num.Errors: 50"
+  )
+#
+#  Test restoring geometry from ROOT file: Sensitive detectors
+dd4hep_add_test_reg( Persist_CLICSiD_Restore_Sensitives_LONGTEST
+  COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_ClientTests.sh"
+  EXEC_ARGS  geoPluginRun -print WARNING
+  -plugin DD4hepRootLoader CLICSiD_geometry.root
+  -plugin DD4hepCheckSensitives
+  REGEX_PASS "\\+\\+\\+ PASSED Checked 14 SensitiveDetector objects. Num.Errors: 0"
+  REGEX_FAIL " ERROR ;EXCEPTION;Exception;FAILED"
+  )
+#
+#  Test restoring geometry from ROOT file: Readout segmentations
+dd4hep_add_test_reg( Persist_CLICSiD_Restore_Segmentations_LONGTEST
+  COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_ClientTests.sh"
+  EXEC_ARGS  geoPluginRun -print WARNING
+  -plugin DD4hepRootLoader CLICSiD_geometry.root
+  -plugin DD4hepCheckSegmentations
+  REGEX_PASS "\\+\\+\\+ PASSED Checked 9 readout segmentations. Num.Errors: 0"
+  REGEX_FAIL " ERROR ;EXCEPTION;Exception;FAILED"
+  )
+#
+#  Test restoring geometry from ROOT file: Readout structures
+dd4hep_add_test_reg( Persist_CLICSiD_Restore_Readouts_LONGTEST
+  COMMAND    "${CMAKE_INSTALL_PREFIX}/bin/run_test_ClientTests.sh"
+  EXEC_ARGS  geoPluginRun -print WARNING
+  -plugin DD4hepRootLoader CLICSiD_geometry.root
+  -plugin DD4hepCheckReadouts
+  REGEX_PASS "\\+\\+\\+ PASSED Checked 14 readout objects. Num.Errors: 0"
+  REGEX_FAIL " ERROR ;EXCEPTION;Exception;FAILED"
+  )
diff --git a/examples/Persistency/src/PersistencySetup.cpp b/examples/Persistency/src/PersistencySetup.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..aea2ad59be32ad9381b4f0bb7ae02742b92d2647
--- /dev/null
+++ b/examples/Persistency/src/PersistencySetup.cpp
@@ -0,0 +1,93 @@
+//==========================================================================
+//  AIDA Detector description implementation 
+//--------------------------------------------------------------------------
+// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+// All rights reserved.
+//
+// For the licensing terms see $DD4hepINSTALL/LICENSE.
+// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
+//
+// Author     : M.Frank
+//
+//==========================================================================
+
+// Framework include files
+#include "PersistencySetup.h"
+
+// ROOT include files
+#include "TFile.h"
+
+using namespace std;
+using namespace dd4hep;
+using namespace PersistencyExamples;
+
+/// Print conditions object
+int dd4hep::PersistencyExamples::printCondition(Condition cond)   {
+  const BasicGrammar* gr = cond.data().grammar;
+  int result = 0;
+
+  if ( gr->type() == typeid(int) )
+    result += int(cond.get<int>());
+  else if ( gr->type() == typeid(long) )
+    result += int(cond.get<long>());
+  else if ( gr->type() == typeid(float) )
+    result += int(cond.get<float>());
+  else if ( gr->type() == typeid(double) )
+    result += int(cond.get<double>());
+  else if ( gr->type() == typeid(string) )
+    result += cond.get<string>().length();
+  else if ( gr->type() == typeid(Delta) )
+    result += sizeof(cond.get<Delta>());
+  else if ( gr->type() == typeid(AlignmentData) )   {
+    if ( dynamic_cast<detail::AlignmentObject*>(cond.ptr()) )  {
+      AlignmentCondition ac = cond;
+      bool ok = (void*)cond.data().ptr() == (void*)&ac->values();
+      printout(ok ? INFO : ERROR,
+               "Data","+++ %s +++ \t\tAlignmentCondition: %s [%p] -- %p %s",
+               ok ? "SUCCESS" : "ERROR", cond.name(),cond.data().ptr(),&ac->values(),
+               ok ? "[Good-payload-mapping]" : "[Bad-payload-mapping]");
+    }
+    result += sizeof(cond.get<AlignmentData>());    
+  }
+  else if ( gr->type() == typeid(vector<int>) )
+    result += int(cond.get<vector<int> >().size());
+  else if ( gr->type() == typeid(vector<long>) )
+    result += int(cond.get<vector<long> >().size());
+  else if ( gr->type() == typeid(vector<float>) )
+    result += int(cond.get<vector<float> >().size());
+  else if ( gr->type() == typeid(vector<double>) )
+    result += int(cond.get<vector<double> >().size());
+  else if ( gr->type() == typeid(vector<string>) )
+    result += int(cond.get<vector<string> >().size());
+
+  else if ( gr->type() == typeid(map<string,int>) )  {
+    const map<string,int>& m = cond.get<map<string,int> >();
+    result += int(m.size());
+    for(const auto& i : m )   {
+      result += i.second;
+      printout(INFO,"Data","\t\tMap: %s [%s] -> %d",cond.name(), i.first.c_str(),i.second);
+    }
+  }
+  printout(INFO,"Data","Condition: [%016llX] %-24s -> %s",cond.key(), cond.name(), cond.data().str().c_str());
+  return result;
+}
+
+/// Default constructor
+PersistencyIO::PersistencyIO()   {
+}
+
+/// Default destructor
+PersistencyIO::~PersistencyIO()   {
+}
+
+/// Generic object write method
+int PersistencyIO::write(const std::string& fname, const std::string& title, const std::type_info& typ, const void* object)   {
+  TFile* f = TFile::Open(fname.c_str(),"RECREATE");
+  if ( f && !f->IsZombie()) {
+    /// Now we write the object
+    int nBytes = f->WriteObjectAny(object,TBuffer::GetClass(typ),title.c_str());
+    f->Close();
+    return nBytes;
+  }
+  return 0;
+}
diff --git a/examples/Persistency/src/PersistencySetup.h b/examples/Persistency/src/PersistencySetup.h
new file mode 100644
index 0000000000000000000000000000000000000000..6d8f68f253e2cff7e5183a21ecb4a7c412c44781
--- /dev/null
+++ b/examples/Persistency/src/PersistencySetup.h
@@ -0,0 +1,62 @@
+//==========================================================================
+//  AIDA Detector description implementation 
+//--------------------------------------------------------------------------
+// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+// All rights reserved.
+//
+// For the licensing terms see $DD4hepINSTALL/LICENSE.
+// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
+//
+// Author     : M.Frank
+//
+//==========================================================================
+#ifndef DD4HEP_PERSISTENCYEXAMPLE_PERSISTENCYSETUP_H
+#define DD4HEP_PERSISTENCYEXAMPLE_PERSISTENCYSETUP_H
+
+#include "DD4hep/Detector.h"
+#include "DD4hep/Printout.h"
+#include "DD4hep/Primitives.h"
+#include "DD4hep/Conditions.h"
+#include "DD4hep/Alignments.h"
+#include "DD4hep/BasicGrammar.h"
+#include "DD4hep/AlignmentData.h"
+#include "DD4hep/detail/AlignmentsInterna.h"
+#include "DD4hep/detail/ConditionsInterna.h"
+
+/// Namespace for the AIDA detector description toolkit
+namespace dd4hep {
+
+  /// Namespace for persistency examples
+  namespace PersistencyExamples {
+
+    template<typename T> Condition make_condition(const std::string& name, T val)   {
+      Condition cond("Test#"+name, name);
+      T& value   = cond.bind<T>();
+      value      = val;
+      cond->hash = ConditionKey(detail::hash32("TestCondition"),name).hash;
+      return cond;
+    }
+
+    /// Print conditions object
+    int printCondition(Condition cond);
+
+    class PersistencyIO   {
+    public:
+      /// Default constructor
+      PersistencyIO();
+      /// Default destructor
+      virtual ~PersistencyIO();
+      /// Generic object write method
+      int write(const std::string& fname, const std::string& title, const std::type_info& typ, const void* object);
+      /// Object write method
+      template <typename T> int write(const std::string& fname, const std::string& title, const T& object)
+      {
+        return write(fname, title, typeid(T), &object);
+      }
+      
+    };
+    
+  }       /* End namespace persistencyexamples            */
+}         /* End namespace dd4hep                         */
+
+#endif  // DD4HEP_PERSISTENCYEXAMPLE_PERSISTENCYSETUP_H
diff --git a/examples/Persistency/src/TestReadConditions.cpp b/examples/Persistency/src/TestReadConditions.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..785832f7aa1b4c4423902ad12326ddd55b0654bd
--- /dev/null
+++ b/examples/Persistency/src/TestReadConditions.cpp
@@ -0,0 +1,84 @@
+//==========================================================================
+//  AIDA Detector description implementation 
+//--------------------------------------------------------------------------
+// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+// All rights reserved.
+//
+// For the licensing terms see $DD4hepINSTALL/LICENSE.
+// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
+//
+// Author     : M.Frank
+//
+//==========================================================================
+
+/* 
+   Plugin invocation:
+   ==================
+   This plugin behaves like a main program.
+   Invoke the plugin with something like this:
+
+   geoPluginRun -plugin DD4hep_PersistencyExample_read_cond \
+                -output <file-name>
+
+   Test the writing of a bunch of standard conditions objects
+   to a native ROOT file.
+
+*/
+// Framework include files
+#include "PersistencySetup.h"
+#include "DD4hep/Factories.h"
+#include "TFile.h"
+
+using namespace std;
+using namespace dd4hep;
+using namespace PersistencyExamples;
+
+/// Plugin function: Condition program example
+/**
+ *  Factory: DD4hep_PersistencyExample_read_cond
+ *
+ *  \author  M.Frank
+ *  \version 1.0
+ *  \date    01/12/2016
+ */
+static int persistency_example (Detector& /* description */, int argc, char** argv)  {
+  string input;
+  bool   arg_error = false;
+  for(int i=0; i<argc && argv[i]; ++i)  {
+    if ( 0 == ::strncmp("-input",argv[i],4) )
+      input = argv[++i];
+    else
+      arg_error = true;
+  }
+  if ( arg_error || input.empty() )   {
+    /// Help printout describing the basic command line interface
+    cout <<
+      "Usage: -plugin <name> -arg [-arg]                                             \n"
+      "     name:   factory name     DD4hep_PersistencyExample_read_cond             \n"
+      "     -input  <string>         Geometry input file                             \n"
+      "     -iovs    <number>        Number of parallel IOV slots for processing.    \n"
+      "\tArguments given: " << arguments(argc,argv) << endl << flush;
+    ::exit(EINVAL);
+  }
+  
+  PersistencyIO io;
+  TFile*f = TFile::Open(input.c_str());
+  f->ls();
+  std::vector<dd4hep::Condition>* p = (std::vector<dd4hep::Condition>*)f->Get("Conditions");
+  if ( p )  {
+    int result = 0;
+    for( const auto& cond : *p )  {
+      //printout(INFO,"Example","+++ Reading condition object: %s",cond.name());
+      result += printCondition(cond);
+    }
+    printout(ALWAYS,"Example","+++ Read successfully %ld conditions. Result=%d",p->size(),result);
+  }
+  else   {
+    printout(ERROR,"Example","+++ ERROR +++ Failed to read object 'Conditions' from %s",f->GetName());
+  }
+  // All done.
+  return 1;
+}
+
+// first argument is the type from the xml file
+DECLARE_APPLY(DD4hep_PersistencyExample_read_cond,persistency_example)
diff --git a/examples/Persistency/src/TestWriteConditions.cpp b/examples/Persistency/src/TestWriteConditions.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dbf5580e92f47830ea1d97fc3f2d96006122579b
--- /dev/null
+++ b/examples/Persistency/src/TestWriteConditions.cpp
@@ -0,0 +1,117 @@
+//==========================================================================
+//  AIDA Detector description implementation 
+//--------------------------------------------------------------------------
+// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+// All rights reserved.
+//
+// For the licensing terms see $DD4hepINSTALL/LICENSE.
+// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
+//
+// Author     : M.Frank
+//
+//==========================================================================
+
+/* 
+   Plugin invocation:
+   ==================
+   This plugin behaves like a main program.
+   Invoke the plugin with something like this:
+
+   geoPluginRun -plugin DD4hep_PersistencyExample_write_cond \
+                -output <file-name>
+
+   Test the writing of a bunch of standard conditions objects
+   to a native ROOT file.
+
+*/
+// Framework include files
+#include "PersistencySetup.h"
+#include "DD4hep/Factories.h"
+
+using namespace std;
+using namespace dd4hep;
+using namespace PersistencyExamples;
+
+/// Plugin function: Condition program example
+/**
+ *  Factory: DD4hep_PersistencyExample_write_cond
+ *
+ *  \author  M.Frank
+ *  \version 1.0
+ *  \date    01/12/2016
+ */
+static int persistency_example (Detector& /* description */, int argc, char** argv)  {
+  string output;
+  bool   arg_error = false;
+  for(int i=0; i<argc && argv[i]; ++i)  {
+    if ( 0 == ::strncmp("-output",argv[i],4) )
+      output = argv[++i];
+    else
+      arg_error = true;
+  }
+  if ( arg_error || output.empty() )   {
+    /// Help printout describing the basic command line interface
+    cout <<
+      "Usage: -plugin <name> -arg [-arg]                                             \n"
+      "     name:   factory name     DD4hep_PersistencyExample_write_cond                \n"
+      "     -output  <string>        Geometry output file                            \n"
+      "     -iovs    <number>        Number of parallel IOV slots for processing.    \n"
+      "\tArguments given: " << arguments(argc,argv) << endl << flush;
+    ::exit(EINVAL);
+  }
+
+  std::vector<Condition> conditions;
+
+  //Condition char_data    = make_condition<char>   ("char_data", 'A');
+  //Condition shrt_data    = make_condition<short>  ("short_data",11);
+  Condition int_data     = make_condition<int>    ("int_data",  12);
+  Condition long_data    = make_condition<long>   ("long_data", 13);
+  Condition dble_data    = make_condition<double> ("dble_data", 14.222);
+  Condition flt_data     = make_condition<float>  ("flt_data",  15.88);
+  Condition str_data     = make_condition<string> ("str_data",  string("Hello"));
+  Condition delta_data   = make_condition<Delta>  ("delta_data",Delta(Position(333.0,0,0)));
+  Condition align_data   = make_condition<AlignmentData>  ("align_data",AlignmentData());
+  Condition alignment    = AlignmentCondition("Test#alignment");
+  
+  Condition flt_vector   = make_condition<vector<float> >  ("float_vector",{0.,1.,2.,3.,4.,5.,6.,7.,8.,9.});
+  Condition dbl_vector   = make_condition<vector<double> > ("double_vector",{0.,1.,2.,3.,4.,5.,6.,7.,8.,9.});
+  //Condition char_vector  = make_condition<vector<char> > ("char_vector",{'a','b','c','d','e','f','g','h','i','j'});
+  //Condition shrt_vector  = make_condition<vector<short> >("short_vector",{0,10,20,30,40,50,60,70,80,90});
+  Condition int_vector   = make_condition<vector<int> >    ("int_vector",{0,10,20,30,40,50,60,70,80,90});
+  Condition long_vector  = make_condition<vector<long> >  ("long_vector",{0,10,20,30,40,50,60,70,80,90});
+  Condition str_vector   = make_condition<vector<string> > ("str_vector",{"Hello","World","!","Here","I","am","!"});
+  Condition string_map   = make_condition<map<string,int> >("string_map",{{"A",10},{"B",20},{"C",30}});
+
+  //conditions.push_back(char_data);
+  //conditions.push_back(shrt_data);
+  conditions.push_back(int_data);
+  conditions.push_back(long_data);
+  conditions.push_back(dble_data);
+  conditions.push_back(flt_data);
+  conditions.push_back(str_data);
+
+  conditions.push_back(flt_vector);
+  conditions.push_back(dbl_vector);
+  //conditions.push_back(char_vector);
+  conditions.push_back(int_vector);
+  conditions.push_back(long_vector);
+  conditions.push_back(str_vector);
+  
+  conditions.push_back(string_map);
+
+  /// Alignment stuff
+  conditions.push_back(delta_data);
+  conditions.push_back(align_data);
+  conditions.push_back(alignment);
+  
+  PersistencyIO io;
+  printout(INFO,"Example","+++ Writing generic conditions vector to %s",output.c_str());
+  int nbytes = io.write(output,"Conditions",conditions);
+  printout(INFO,"Example","+++ Wrote %d bytes to file %s",nbytes,output.c_str());
+  
+  // All done.
+  return 1;
+}
+
+// first argument is the type from the xml file
+DECLARE_APPLY(DD4hep_PersistencyExample_write_cond,persistency_example)