diff --git a/DDCore/CMakeLists.txt b/DDCore/CMakeLists.txt
index affdb5bf9dd4c1bfd487dc1e96d18d59a3bcfce6..10d8be783a6e4d1ffe05752c47fda5877a5c24df 100644
--- a/DDCore/CMakeLists.txt
+++ b/DDCore/CMakeLists.txt
@@ -27,6 +27,7 @@ dd4hep_add_dictionary( G__DD4hep
   include/DD4hep/Plugins.h
   include/DD4hep/IoStreams.h
   include/DD4hep/SurfaceInstaller.h
+  include/DD4hep/detail/BasicGrammar_inl.h
   include/XML/UnicodeValues.h
   include/XML/tinyxml.h
   include/XML/tinystring.h
diff --git a/DDCore/include/DD4hep/BasicGrammar.h b/DDCore/include/DD4hep/BasicGrammar.h
index a10099a9520159956c7c4946104f2f14987cfc57..81af61d2cb19e2e0635f0e0bc29c60e796ddbd60 100644
--- a/DDCore/include/DD4hep/BasicGrammar.h
+++ b/DDCore/include/DD4hep/BasicGrammar.h
@@ -35,9 +35,14 @@ namespace dd4hep {
    *   \ingroup DD4HEP
    */
   class BasicGrammar {
+  protected:
+    /// Instance pointer
+    BasicGrammar* self = 0;
+
   public:
     /// Default constructor
     BasicGrammar();
+
     /// Default destructor
     virtual ~BasicGrammar();
 
diff --git a/DDCore/include/DD4hep/DD4hepRootPersistency.h b/DDCore/include/DD4hep/DD4hepRootPersistency.h
index f41839f98d7f01db69145fe64ca675a1e8fbbf55..f838b7ef33211bfb2b76b6ee4c03ec5f20a25fc6 100644
--- a/DDCore/include/DD4hep/DD4hepRootPersistency.h
+++ b/DDCore/include/DD4hep/DD4hepRootPersistency.h
@@ -25,6 +25,9 @@ public:
 
   /// Helper since plain segmentations cannot be saved
   std::map<dd4hep::Readout,std::pair<dd4hep::IDDescriptor,dd4hep::DDSegmentation::Segmentation*> > m_segments;
+
+  std::map<dd4hep::DetElement,dd4hep::AlignmentCondition> nominals;  //!
+  
   /// The main data block
   dd4hep::DetectorData*     m_data = 0;
   
@@ -126,11 +129,17 @@ public:
 
 class DD4hepRootCheck  {
 public:
+  /// Reference to the detector model object
   dd4hep::Detector* object=0;
+  /// Default constructor
   DD4hepRootCheck() = default;
+  /// Copy constructor
   DD4hepRootCheck(const DD4hepRootCheck& copy) = default;
+  /// Initializing constructor
   DD4hepRootCheck(dd4hep::Detector* o) : object(o) {}
-  ~DD4hepRootCheck() = default;
+  /// Default destructor
+  virtual ~DD4hepRootCheck() = default;
+  /// Assignment operator
   DD4hepRootCheck& operator=(const DD4hepRootCheck& copy) = default;
   /// Call to check a Material object
   size_t checkMaterials()  const;
@@ -154,6 +163,7 @@ public:
   size_t checkVolManager()   const;
   /// Call to check a top level Detector element (subdetector)
   size_t checkDetectors()  const;
+  /// Check all of the above
   size_t checkAll()   const;
 };
 
diff --git a/DDCore/include/DD4hep/Dictionary.h b/DDCore/include/DD4hep/Dictionary.h
index e08fe7e6a526049a10514eb5956dd1671a4b0409..e9277981c048157287cb1848f2341ca6e7f0b38e 100644
--- a/DDCore/include/DD4hep/Dictionary.h
+++ b/DDCore/include/DD4hep/Dictionary.h
@@ -19,6 +19,7 @@
 // Framework include files
 #include "DDParsers/Evaluator.h"
 #include "DD4hep/DD4hepRootPersistency.h"
+#include "DD4hep/detail/Grammar.h"
 #include "DD4hep/detail/ObjectsInterna.h"
 #include "DD4hep/detail/DetectorInterna.h"
 #include "DD4hep/detail/ConditionsInterna.h"
@@ -52,6 +53,11 @@ namespace dd4hep {
   XmlTools::Evaluator& g4Evaluator();
 }
 
+namespace dd4hep   {   namespace Parsers   {
+    int parse(dd4hep::AlignmentData&, const std::string&);
+    int parse(dd4hep::detail::AlignmentObject&, const std::string&);
+  }}
+
 // -------------------------------------------------------------------------
 // Regular dd4hep dictionaries
 // -------------------------------------------------------------------------
@@ -211,19 +217,18 @@ template class dd4hep::Handle<TNamed>;
 #pragma link C++ class dd4hep::Delta+;
 #pragma link C++ class dd4hep::Alignment+;
 #pragma link C++ class dd4hep::AlignmentData+;
-
-#pragma link C++ class dd4hep::detail::AlignmentConditionObject+;
-#pragma link C++ class dd4hep::align::GlobalAlignment+;
-#pragma link C++ class dd4hep::AlignmentDecorator<AlignmentData>+;
 #pragma link C++ class dd4hep::Handle<dd4hep::AlignmentData>+;
-#pragma link C++ class dd4hep::Handle<TGeoPhysicalNode>+;
+//#pragma link C++ class dd4hep::Grammar<dd4hep::AlignmentData>+;
 
 #pragma link C++ class dd4hep::AlignmentCondition+;
 #pragma link C++ class dd4hep::detail::AlignmentObject+;
 #pragma link C++ class dd4hep::Handle<dd4hep::detail::AlignmentObject>+;
+//#pragma link C++ class dd4hep::Grammar<dd4hep::detail::AlignmentObject>+;
 
+#pragma link C++ class dd4hep::align::GlobalAlignment+;
+#pragma link C++ class dd4hep::Handle<TGeoPhysicalNode>+;
 
-
+// Conditions stuff
 #pragma link C++ class dd4hep::Condition+;
 #pragma link C++ class vector<dd4hep::Condition>+;
 #pragma link C++ class dd4hep::ConditionKey+;
diff --git a/DDCore/include/DD4hep/OpaqueData.h b/DDCore/include/DD4hep/OpaqueData.h
index dfcede3c52f59192750ac2907f6ba62387ae6d0b..4d816184bda07741aa850a9240c0b1597956762b 100644
--- a/DDCore/include/DD4hep/OpaqueData.h
+++ b/DDCore/include/DD4hep/OpaqueData.h
@@ -47,7 +47,7 @@ namespace dd4hep {
 
   public:
     /// Data type
-    const BasicGrammar* grammar = 0;
+    const BasicGrammar* grammar = 0;  //!
 
   protected:
     /// Pointer to object data
diff --git a/DDCore/include/DD4hep/detail/BasicGrammar_inl.h b/DDCore/include/DD4hep/detail/BasicGrammar_inl.h
index d3c10f91df48ad6d37aaf5656a3f79fa164fdaee..16c54aaab11ae3ee7b3719eeafbc7e90fd90b9cc 100644
--- a/DDCore/include/DD4hep/detail/BasicGrammar_inl.h
+++ b/DDCore/include/DD4hep/detail/BasicGrammar_inl.h
@@ -23,7 +23,7 @@
 
 // Framework include files
 #include "DD4hep/Primitives.h"
-#include "DD4hep/BasicGrammar.h"
+#include "DD4hep/detail/Grammar.h"
 
 #if defined(DD4HEP_PARSER_HEADER)
 
@@ -52,42 +52,6 @@ namespace {  static XmlTools::Evaluator& s__eval(dd4hep::g4Evaluator());  }
 /// Namespace for the AIDA detector description toolkit
 namespace dd4hep {
 
-  /// Concrete type dependent grammar definition
-  /**
-   *   \author  M.Frank
-   *   \date    13.08.2013
-   *   \ingroup DD4HEP
-   */
-  template <typename TYPE> class Grammar : public BasicGrammar {
-    /// Cached type information name
-    std::string m_typeName;
-  public:
-    /// Standarsd constructor
-    Grammar();
-    /// Default destructor
-    virtual ~Grammar();
-
-    /** 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
-    virtual std::string str(const void* ptr) const  override;
-    /// PropertyGrammar overload: Retrieve value from string
-    virtual bool fromString(void* ptr, const std::string& value) const  override;
-    /// Opaque object destructor
-    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;
-
-    /** Class member function   */
-    /// Evaluate string value if possible before calling boost::spirit
-    virtual int evaluate(void* ptr, const std::string& value) const;
-  };
-
   /// Standarsd constructor
   template <typename TYPE> Grammar<TYPE>::Grammar() {
     m_typeName = typeName(typeid(TYPE));
diff --git a/DDCore/include/DD4hep/detail/Grammar.h b/DDCore/include/DD4hep/detail/Grammar.h
new file mode 100644
index 0000000000000000000000000000000000000000..b9579af79ec837bd07e7ee0aa4758c5050d67514
--- /dev/null
+++ b/DDCore/include/DD4hep/detail/Grammar.h
@@ -0,0 +1,67 @@
+//==========================================================================
+//  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
+//
+//==========================================================================
+//
+// NOTE:
+//
+// This is an internal include file. It should only be included to 
+// instantiate code. Otherwise the BasicGrammar include file should be
+// sufficient for all practical purposes.
+//
+//==========================================================================
+#ifndef DD4HEP_DDCORE_DETAIL_GRAMMAR_H
+#define DD4HEP_DDCORE_DETAIL_GRAMMAR_H
+
+// Framework include files
+#include "DD4hep/BasicGrammar.h"
+
+/// Namespace for the AIDA detector description toolkit
+namespace dd4hep {
+
+  /// Concrete type dependent grammar definition
+  /**
+   *   \author  M.Frank
+   *   \date    13.08.2013
+   *   \ingroup 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();
+
+    /** 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
+    virtual std::string str(const void* ptr) const  override;
+    /// PropertyGrammar overload: Retrieve value from string
+    virtual bool fromString(void* ptr, const std::string& value) const  override;
+    /// Opaque object destructor
+    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;
+
+    /** Class member function   */
+    /// Evaluate string value if possible before calling boost::spirit
+    virtual int evaluate(void* ptr, const std::string& value) const;
+  };
+}
+#endif  /* DD4HEP_DDCORE_DETAIL_GRAMMAR_H */
diff --git a/DDCore/src/AlignmentsInterna.cpp b/DDCore/src/AlignmentsInterna.cpp
index 00576ef4fc0cd9a0cdc8764b3379f82ad9d0a321..65ae9c1385a87a0f05ddcf1ab49c7bf223d01318 100644
--- a/DDCore/src/AlignmentsInterna.cpp
+++ b/DDCore/src/AlignmentsInterna.cpp
@@ -62,3 +62,21 @@ void AlignmentObject::clear()   {
   d.nodes.clear();
   flags = Condition::ALIGNMENT_DERIVED;
 }
+
+
+#include "DDParsers/Parsers.h"
+#include "DDParsers/ToStream.h"
+DD4HEP_DEFINE_PARSER_DUMMY(AlignmentObject)
+
+#include "DD4hep/detail/BasicGrammar_inl.h"
+#include "DD4hep/detail/ConditionsInterna.h"
+namespace dd4hep {
+  template <> bool Grammar<AlignmentObject>::fromString(void*, const std::string&) const {return true;}
+  template <> void Grammar<AlignmentObject>::copy(void*, const void*) const {}
+  namespace Utils {
+    template <> std::ostream& toStream(const AlignmentObject&, std::ostream& s) { return s; }
+  }
+}
+DD4HEP_DEFINE_PARSER_GRAMMAR(AlignmentObject,eval_none<AlignmentObject>)
+DD4HEP_DEFINE_CONDITIONS_TYPE(AlignmentObject)
+
diff --git a/DDCore/src/BasicGrammar.cpp b/DDCore/src/BasicGrammar.cpp
index 16be7ecc9987f2283c93cc7f6864d44c62116b20..18c4419ace2d4259d4287b0a494dc3b08636baec 100644
--- a/DDCore/src/BasicGrammar.cpp
+++ b/DDCore/src/BasicGrammar.cpp
@@ -21,10 +21,12 @@
 
 /// Default constructor
 dd4hep::BasicGrammar::BasicGrammar()  {
+  self = this;
 }
 
 /// Default destructor
 dd4hep::BasicGrammar::~BasicGrammar()   {
+  self = 0;
 }
 
 /// Error callback on invalid conversion
diff --git a/DDCore/src/DD4hepRootPersistency.cpp b/DDCore/src/DD4hepRootPersistency.cpp
index 9d34fae43868fb2e7bb572bcf9564a085677de68..8869f71bf623ae27e32aef8d2ed733ab1a50b2df 100644
--- a/DDCore/src/DD4hepRootPersistency.cpp
+++ b/DDCore/src/DD4hepRootPersistency.cpp
@@ -54,7 +54,13 @@ int DD4hepRootPersistency::save(Detector& description, const char* fname, const
         persist->m_segments[ro].second = ro.segmentation().segmentation();
       }
     }
-
+    for( const auto& mgr : persist->m_data->m_volManager->managers )  {
+      for( const auto& v : mgr.second->volumes )  {
+        persist->nominals[v.second->element] = v.second->element.nominal();
+      }
+    }
+    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'.");
@@ -64,6 +70,7 @@ int DD4hepRootPersistency::save(Detector& description, const char* fname, const
       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());    
@@ -95,7 +102,7 @@ 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'.");
@@ -105,6 +112,7 @@ int DD4hepRootPersistency::load(Detector& description, const char* fname, const
     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());    
@@ -142,23 +150,32 @@ int DD4hepRootPersistency::load(Detector& description, const char* fname, const
       persist->m_segments.clear();
 
       const auto& sdets = persist->volumeManager()->subdetectors;
+      size_t num[3] = {0,0,0};
       for( const auto& vm : sdets )  {
-        DetElement det = vm.first;
         VolumeManager::Object* obj = vm.second.ptr();
         obj->system = obj->id.field("system");
         if ( 0 != obj->system )   {
           printout(ALWAYS,"DD4hepRootPersistency",
-                   "+++ Fixed VolumeManager.system for '%s'.",
-                   det.path().c_str());
+                   "+++ Fixed VolumeManager.system for %-24s  %6ld volumes %4ld sdets %4ld mgrs.",
+                   obj->detector.path().c_str(), obj->volumes.size(),
+                   obj->subdetectors.size(), obj->managers.size());
+          num[0] += obj->volumes.size();
+          num[1] += obj->subdetectors.size();
+          num[2] += obj->managers.size();
           continue;
         }
         printout(ALWAYS,"DD4hepRootPersistency",
                  "+++ FAILED to fix VolumeManager.system for '%s: %s'.",
-                 det.path().c_str(), "[No IDDescriptor field 'system']");
+                 obj->detector.path().c_str(), "[No IDDescriptor field 'system']");
       }
-      
+      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();
+      //target->clearData();
       delete persist;
       printout(ALWAYS,"DD4hepRootPersistency",
                "+++ Successfully loaded detector description from file:%s",fname);
diff --git a/DDCore/src/VolumeManager.cpp b/DDCore/src/VolumeManager.cpp
index 3cd04b450cac07b971e014f800cc68aac5492b91..26646576c5cc7b82fdeab19fefa7c9be9be38eaf 100644
--- a/DDCore/src/VolumeManager.cpp
+++ b/DDCore/src/VolumeManager.cpp
@@ -176,7 +176,9 @@ namespace dd4hep {
       /// Set of already added entries
       set<VolumeID> m_entries;
       /// Debug flag
-      bool          m_debug;
+      bool          m_debug    = false;
+      /// Node counter
+      size_t        m_numNodes = 0;
 
     public:
       /// Default constructor
@@ -186,6 +188,9 @@ namespace dd4hep {
         m_debug = (0 != ::getenv("DD4HEP_VOLMGR_DEBUG"));
       }
 
+      /// Access node count
+      size_t numNodes()  const  {   return m_numNodes;  }
+
       /// Populate the Volume manager
       void populate(DetElement e) {
         //const char* typ = 0;//::getenv("VOLMGR_NEW");
@@ -385,6 +390,7 @@ namespace dd4hep {
               print_node(sd, parent, e, n, code, nodes);
             }
             m_entries.insert(code.first);
+            ++m_numNodes;
           }
         }
       }
@@ -442,6 +448,7 @@ const TGeoHMatrix& VolumeManagerContext::toElement()  const   {
 /// Initializing constructor to create a new object
 VolumeManager::VolumeManager(Detector& description, const string& nam, DetElement elt, Readout ro, int flags) {
   printout(INFO, "VolumeManager", " - populating volume ids - be patient ..."  );
+  size_t node_count = 0;
   Object* obj_ptr = new Object();
   assign(obj_ptr, nam, "VolumeManager");
   if (elt.isValid()) {
@@ -451,8 +458,9 @@ VolumeManager::VolumeManager(Detector& description, const string& nam, DetElemen
     obj_ptr->top   = obj_ptr;
     obj_ptr->flags = flags;
     p.populate(elt);
+    node_count = p.numNodes();
   }
-  printout(INFO, "VolumeManager", " - populating volume ids - done"  );
+  printout(INFO, "VolumeManager", " - populating volume ids - done. %ld nodes.",node_count);
 }
 
 /// Initializing constructor to create a new object