diff --git a/DDAlign/include/DDAlign/AlignmentsManager.h b/DDAlign/include/DDAlign/AlignmentsManager.h
index d20de301195d0bb32607e5a46d55ca5a9849e373..feb74bcc4b5d33505b60992e24ca47d0107d70b0 100644
--- a/DDAlign/include/DDAlign/AlignmentsManager.h
+++ b/DDAlign/include/DDAlign/AlignmentsManager.h
@@ -1,4 +1,3 @@
-// $Id$
 //==========================================================================
 //  AIDA Detector description implementation for LCD
 //--------------------------------------------------------------------------
@@ -120,7 +119,7 @@ namespace DD4hep {
       /// Compute the transformation from the closest detector element of the alignment to the world system
       void to_world(AlignContext& new_alignments, UserPool& pool, DetElement det, TGeoHMatrix& mat)  const;
       /// Compute all alignment conditions of the lower levels
-      void compute(AlignContext& new_alignments, UserPool& pool, DetElement child, int level) const;
+      void compute(AlignContext& new_alignments, UserPool& pool, DetElement child) const;
 
     public:
       /// Initializing constructor
diff --git a/DDAlign/include/DDAlign/DDAlignForwardCall.h b/DDAlign/include/DDAlign/DDAlignForwardCall.h
new file mode 100644
index 0000000000000000000000000000000000000000..ab95f1e4fe17f2a5127165f2f1c17ac01b3421e5
--- /dev/null
+++ b/DDAlign/include/DDAlign/DDAlignForwardCall.h
@@ -0,0 +1,44 @@
+//==========================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------------
+// 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_DDALIGN_DDALIGNFORWARDCALL_H
+#define DD4HEP_DDALIGN_DDALIGNFORWARDCALL_H
+
+// Framework includes
+#include "DDAlign/AlignmentUpdateCall.h"
+
+/// Namespace for the AIDA detector description toolkit
+namespace DD4hep {
+
+  /// Namespace of the DDAlign conversion stuff
+  namespace Alignments  {
+    
+    /// Specialized conditions forward callback for DDAlign alignments
+    /**
+     *
+     *  \author  M.Frank
+     *  \version 1.0
+     *  \ingroup DD4HEP_ALIGNMENT
+     */
+    class DDAlignForwardCall : public AlignmentUpdateCall  {
+    public:
+      /// Default constructor
+      DDAlignForwardCall() = default;
+      /// Default destructor
+      virtual ~DDAlignForwardCall() = default;
+      /// Interface to client Callback in order to forward the condition
+      virtual Condition operator()(const ConditionKey& key, const UpdateContext& context);
+    };
+
+  }    /* End namespace Alignments            */
+}      /* End namespace DD4hep                */
+#endif /* DD4HEP_DDALIGN_DDALIGNFORWARDCALL_H */
diff --git a/DDAlign/include/DDAlign/DDAlignTest.h b/DDAlign/include/DDAlign/DDAlignTest.h
deleted file mode 100644
index 2760fb9d853726907ad52d7aa41f4a04e42fbc3b..0000000000000000000000000000000000000000
--- a/DDAlign/include/DDAlign/DDAlignTest.h
+++ /dev/null
@@ -1,54 +0,0 @@
-//==========================================================================
-//  AIDA Detector description implementation for LCD
-//--------------------------------------------------------------------------
-// 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_DDALIGNTEST_H
-#define DD4HEP_DDALIGNTEST_H
-
-// Framework includes
-#include "DDAlign/AlignmentsManager.h"
-#include "DDCond/ConditionsManager.h"
-
-
-/// Namespace for the AIDA detector description toolkit
-namespace DD4hep {
-
-  /// Test class to chain variou test sequences for DDCond and DDAlign
-  /**
-   *
-   *  \author  M.Frank
-   *  \version 1.0
-   *  \ingroup DD4HEP
-   */
-  class DDAlignTest  {
-    typedef Alignments::AlignmentsManager AlignmentsManager;
-    typedef Alignments::UserPool          AlignmentsPool;
-
-    typedef Conditions::ConditionsManager ConditionsManager;
-    typedef Conditions::UserPool          ConditionsPool;
-
-  public:
-    /// Reference to alignments manager object
-    AlignmentsManager          alignmentsMgr;
-    dd4hep_ptr<ConditionsPool> alignmentsPool;
-
-    /// Reference to conditions manager object
-    ConditionsManager          conditionsMgr;
-    dd4hep_ptr<ConditionsPool> conditionsPool;
-
-  public:
-    /// Default constructor
-    DDAlignTest() = default;
-    /// Default destructor
-    virtual ~DDAlignTest() = default;
-  };
-}      /* End namespace DD4hep         */
-#endif /* DD4HEP_DDALIGN_DDALIGNTEST_H */
diff --git a/DDAlign/src/AlignmentsManager.cpp b/DDAlign/src/AlignmentsManager.cpp
index 5d189595e003285f4a804f193da154e5f7a57d44..bff4c8c4aab927c1c1f2a28b13bf00021bf4997f 100644
--- a/DDAlign/src/AlignmentsManager.cpp
+++ b/DDAlign/src/AlignmentsManager.cpp
@@ -1,4 +1,3 @@
-// $Id$
 //==========================================================================
 //  AIDA Detector description implementation for LCD
 //--------------------------------------------------------------------------
@@ -38,7 +37,7 @@ namespace DD4hep {
         const Dependency*           dep;
         DetElement::Object*         det;
         AlignmentCondition::Object* cond;
-        unsigned int key, top;
+        unsigned int key, top, valid;
       };
       struct PathOrdering {
         bool operator()(const DetElement& a, const DetElement& b) const
@@ -62,11 +61,12 @@ namespace DD4hep {
         if ( det.isValid() )  {
           Entry entry;
           unsigned int key = det.key();
-          entry.top  = 0;
-          entry.cond = con;
-          entry.dep  = dep;
-          entry.det  = det.ptr();
-          entry.key  = key;
+          entry.valid = 0;
+          entry.top   = 0;
+          entry.cond  = con;
+          entry.dep   = dep;
+          entry.det   = det.ptr();
+          entry.key   = key;
           detectors.insert(std::make_pair(det, entries.size()));
           keys.insert(std::make_pair(key, entries.size()));
           entries.insert(entries.end(), entry);
@@ -87,6 +87,7 @@ namespace DD4hep {
 
 
 DD4HEP_INSTANTIATE_HANDLE_NAMED(AlignmentsManagerObject);
+static PrintLevel s_PRINT = WARNING;
 
 /// Initializing constructor
 AlignmentsManagerObject::AlignmentsManagerObject() : NamedObject() {
@@ -103,7 +104,11 @@ AlignmentsManagerObject::~AlignmentsManagerObject()   {
   InstanceCount::decrement(this);
 }
 
-void AlignmentsManagerObject::to_world(AlignContext& new_alignments, UserPool& pool, DetElement det, TGeoHMatrix& mat)  const  {
+void AlignmentsManagerObject::to_world(AlignContext& new_alignments,
+                                       UserPool&     pool,
+                                       DetElement    det,
+                                       TGeoHMatrix&  delta)  const
+{
   using Conditions::Condition;
   DetElement par = det.parent();
   while( par.isValid() )   {
@@ -112,12 +117,24 @@ void AlignmentsManagerObject::to_world(AlignContext& new_alignments, UserPool& p
     AlignContext::Keys::const_iterator i = new_alignments.keys.find(par.key());
     if ( i != new_alignments.keys.end() )  {
       const AlignContext::Entry& e = new_alignments.entries[(*i).second];
+      // The parent entry is (not yet) valid. need to compute it first
+      if ( 0 == e.valid )  {
+        compute(new_alignments, pool, par);
+      }
       AlignmentCondition cond(e.cond);
       AlignmentData&     align = cond.data();
-      mat.MultiplyLeft(&align.worldTransformation());
+      if ( s_PRINT <= INFO )  {
+        printf("Multiply-left ALIGNMENT %s:", det.path().c_str()); delta.Print();
+        printf("  with ALIGN(world) %s :", par.path().c_str());
+        align.worldDelta.Print();
+      }
+      delta.MultiplyLeft(&align.worldDelta);
+      if ( s_PRINT <= INFO )  {
+        printf("  Result :"); delta.Print();
+      }
       return;
     }
-    // The parent did not get updated: We have to search the the conditions pool if
+    // The parent did not get updated: We have to search the conditions pool if
     // there is a still valid condition, which we can use to build the world transformation
     // The parent's alignment condition by defintiion must be present in the pool,
     // since it got updated in the past!
@@ -127,12 +144,28 @@ void AlignmentsManagerObject::to_world(AlignContext& new_alignments, UserPool& p
       Condition::key_type key = e.dep->target.hash;
       AlignmentCondition cond = pool.get(key);
       AlignmentData&    align = cond.data();
-      mat.MultiplyLeft(&align.worldTransformation());
+      if ( s_PRINT <= INFO )  {
+        printf("Multiply-left ALIGNMENT %s:", det.path().c_str()); delta.Print();
+        printf("  with ALIGN(world) %s :", par.path().c_str());
+        align.worldDelta.Print();
+      }
+      delta.MultiplyLeft(&align.worldDelta);
+      if ( s_PRINT <= INFO ) {
+        printf("  Result :"); delta.Print();
+      }
       return;
     }
     // There is no special alignment for this detector element.
     // Hence to nominal (relative) transformation to the parent is valid
-    mat.MultiplyLeft(&par.nominal().detectorTransformation());
+    if ( s_PRINT <= INFO )  {
+      printf("Multiply-left ALIGNMENT %s:", det.path().c_str()); delta.Print();
+      printf("  with NOMINAL(det) %s :", par.path().c_str());
+      par.nominal().detectorTransformation().Print();
+    }
+    delta.MultiplyLeft(&par.nominal().detectorTransformation());
+    if ( s_PRINT <= INFO )  {
+      printf("  Result :"); delta.Print();
+    }
     par = par.parent();
   }
 }
@@ -144,12 +177,16 @@ void AlignmentsManagerObject::compute(UserPool& user_pool)  const  {
   
 /// Compute all alignment conditions of the specified dependency list
 void AlignmentsManagerObject::compute(UserPool& pool, const Dependencies& deps) const  {
-  AlignContext::DetectorMap::const_iterator i;
   AlignContext new_alignments;
   new_alignments.entries.reserve(deps.size());
   pool.compute(deps, &new_alignments);
+  for(auto i=new_alignments.entries.begin(); i != new_alignments.entries.end(); ++i)
+    compute(new_alignments, pool, (*i).det);
+  for(auto i=new_alignments.entries.begin(); i != new_alignments.entries.end(); ++i)
+    compute(new_alignments, pool, (*i).det);
+#if 0
   std::string prev = "-----";
-  for(i=new_alignments.detectors.begin(); i!=new_alignments.detectors.end(); ++i)  {
+  for(auto i=new_alignments.detectors.begin(); i!=new_alignments.detectors.end(); ++i)  {
     AlignContext::Entry& e = new_alignments.entries[(*i).second];
     DetElement         det = e.det;
     const std::string&   p = det.path();
@@ -158,25 +195,26 @@ void AlignmentsManagerObject::compute(UserPool& pool, const Dependencies& deps)
       continue;
     }
     prev = p;
-    printout(DEBUG,"Alignment","Update top Node: Lvl:%d Key:%08X: %s", det.level(), det.key(), p.c_str());
+    printout(s_PRINT,"Alignment","Update top Node: Lvl:%d Key:%08X: %s", det.level(), det.key(), p.c_str());
     e.top = 1;
   }
   // We got now the top nodes of the new_alignments. From the top nodes we have to
   // recursively calculate all changes downwards the lower levels!
   // Note: The upper levels are already correct and do not need to be updated!
   printout(INFO,"Alignment","Working down the tree....");
-  for(i=new_alignments.detectors.begin(); i != new_alignments.detectors.end(); ++i)  {
+  for(auto i=new_alignments.detectors.begin(); i != new_alignments.detectors.end(); ++i)  {
     AlignContext::Entry& e = new_alignments.entries[(*i).second];
     if ( e.top )     {
-      compute(new_alignments, pool, e.det, 0);
+      compute(new_alignments, pool, e.det);
     }
   }
+#endif
 }
+
 /// Compute the alignment delta for one detector element and it's alignment condition
 static void computeDelta(AlignmentCondition cond, TGeoHMatrix& tr_delta)  {
   const AlignmentData& align = cond.data();
   const Delta&         delta = align.delta;
-  const TGeoHMatrix&     nom = align.detectorTransformation();
   const Position&        pos = delta.translation;
   const Translation3D&   piv = delta.pivot;
   const RotationZYX&     rot = delta.rotation;
@@ -200,28 +238,44 @@ static void computeDelta(AlignmentCondition cond, TGeoHMatrix& tr_delta)  {
   default:
     break;
   }
-  tr_delta.MultiplyLeft(&nom);
-  align.detectorTrafo = tr_delta;
-  align.worldTrafo    = tr_delta;
 }
+
 /// Compute all alignment conditions of the lower levels
-void AlignmentsManagerObject::compute(AlignContext& new_alignments, UserPool& pool, DetElement det, int level) const  {
-  AlignContext::Keys::const_iterator k=new_alignments.keys.find(det.key());
-  bool has_cond    = k != new_alignments.keys.end();
-  const AlignContext::Entry* ent = has_cond ? &new_alignments.entries[(*k).second] : 0;
+void AlignmentsManagerObject::compute(AlignContext& new_alignments, UserPool& pool, DetElement det) const  {
+  auto k=new_alignments.keys.find(det.key());
+  bool has_cond = (k != new_alignments.keys.end());
+  AlignContext::Entry* ent = has_cond ? &new_alignments.entries[(*k).second] : 0;
 
-  if ( ent )  {
-    char fmt[128];
+  if ( ent && ent->valid == 1 )  {
+    printout(DEBUG,"ComputeAlignment","================ IGNORE %s (already valid)",det.path().c_str());
+    return;
+  }
+  if ( ent && ent->valid == 0 )  {
     TGeoHMatrix        tr_delta;
-    AlignmentCondition cond(ent->cond);
+    AlignmentCondition cond  = ent->cond;
     AlignmentData&     align = cond.data();
+    printout(INFO,"ComputeAlignment",
+             "============================== Compute transformation of %s ============================== ",
+             det.path().c_str());
+
+    ent->valid          = 1;
     computeDelta(cond, tr_delta);
-    to_world(new_alignments, pool, det, align.worldTrafo);
-    align.trToWorld = Geometry::_transform(&align.worldTrafo);
-    ::snprintf(fmt,sizeof(fmt),"%%d %%%ds %%s %%08X: %%s IOV:%%s",2*level);
-    printout(DEBUG,"ComputeAlignment",fmt,
-             det.level(), "", has_cond ? "NO " : "YES",
-             det.key(), det.path().c_str(), cond.iov().str().c_str());
+    align.worldDelta    = tr_delta;
+    to_world(new_alignments, pool, det, align.worldDelta);
+    align.worldTrafo    = det.nominal().worldTransformation()*align.worldDelta;
+    align.detectorTrafo = det.nominal().detectorTransformation()*tr_delta;
+    align.trToWorld     = Geometry::_transform(&align.worldDelta);
+    printout(INFO,"ComputeAlignment","Level:%d Path:%s DetKey:%08X: Cond:%s key:%08X IOV:%s",
+             det.level(), det.path().c_str(), det.key(),
+             yes_no(has_cond), cond.key(), cond.iov().str().c_str());
+    if ( s_PRINT <= INFO )  {  
+      printf("DetectorTrafo: '%s' -> '%s' ",det.path().c_str(), det.parent().path().c_str());
+      det.nominal().detectorTransformation().Print();
+      printf("Delta:       '%s' ",det.path().c_str()); tr_delta.Print();
+      printf("World-Delta: '%s' ",det.path().c_str()); align.worldDelta.Print();
+      printf("Nominal:     '%s' ",det.path().c_str()); det.nominal().worldTransformation().Print();
+      printf("Result:      '%s' ",det.path().c_str()); align.worldTrafo.Print();
+    }
   }
   else  {
     // DetElement 'det' has no specific alignment. If any of the children has one
@@ -233,11 +287,20 @@ void AlignmentsManagerObject::compute(AlignContext& new_alignments, UserPool& po
     // Alternatively we could inject 'special' alignment conditions, which would depend
     // on the parent...
     // Under circumstances, this might be cheaper to re-compute.
+    //
+    // NOT HANDLED HERE!
+    // Solution uses derived conditions to generate AlignmentCondition
+    // objects with an empty Delta.
+    //
+    // Handled in the alignment plugin: DDAlign_AlignmentForward,
+    // to be executed AFTER DDAlign_AlignmentRegister.
+    // This plugin will inject the relevant dependency calls.
+    // 
   }
   const DetElement::Children& children = det.children();
   for(auto c=children.begin(); c!=children.end(); ++c)    {
     DetElement child = (*c).second;
-    compute(new_alignments, pool, child, level+1);
+    compute(new_alignments, pool, child);
   }
 }
 
@@ -275,12 +338,12 @@ const AlignmentsManager::Dependencies& AlignmentsManager::knownDependencies()  c
 /// Compute all alignment conditions of the internal dependency list
 void AlignmentsManager::compute(dd4hep_ptr<UserPool>& user_pool) const   {
   Object* o = access();
-  o->compute(*(user_pool.get()), *(o->dependencies));
+  o->compute(*user_pool, *(o->dependencies));
 }
 
 /// Compute all alignment conditions of the specified dependency list
 void AlignmentsManager::compute(dd4hep_ptr<UserPool>& user_pool, const Dependencies& deps) const  {
-  access()->compute(*(user_pool.get()), deps);
+  access()->compute(*user_pool, deps);
 }
 
 /// Register new updated derived alignment during the computation step
diff --git a/DDAlign/src/DDAlignForwardCall.cpp b/DDAlign/src/DDAlignForwardCall.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..dcc558377137ab5ae14b0cbe7a2f65626b56fea9
--- /dev/null
+++ b/DDAlign/src/DDAlignForwardCall.cpp
@@ -0,0 +1,32 @@
+//==========================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------------
+// 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 includes
+#include "DDAlign/DDAlignForwardCall.h"
+#include "DD4hep/ConditionsData.h"
+#include "DD4hep/Printout.h"
+
+using namespace DD4hep;
+using namespace DD4hep::Conditions;
+
+/// Interface to client Callback in order to update the condition
+Condition
+Alignments::DDAlignForwardCall::operator()(const ConditionKey& key, const UpdateContext& context)
+{
+  const Data::Delta delta;
+  DetElement det  = context.dependency.detector;
+  Condition c = AlignmentUpdateCall::handle(key, context, delta);
+  printout(INFO,"DDAlignForward","++ Building child alignment condition: %s Detector [%d]: %s [%p]",
+           key.name.c_str(), det.level(), det.path().c_str(), c.ptr());
+  return c;
+}
diff --git a/DDAlign/src/DDAlignUpdateCall.cpp b/DDAlign/src/DDAlignUpdateCall.cpp
index 4faf638edf0eecd9b04fe58c3e46f873d1f386b5..e8a7e2a196e9e04628e1578860134601952abe5a 100644
--- a/DDAlign/src/DDAlignUpdateCall.cpp
+++ b/DDAlign/src/DDAlignUpdateCall.cpp
@@ -28,7 +28,7 @@ Alignments::DDAlignUpdateCall::operator()(const ConditionKey& key, const UpdateC
   if ( cond.typeInfo() == typeid(Data::Delta) )  {
     const Data::Delta& delta = cond.get<Data::Delta>();
     Condition c = AlignmentUpdateCall::handle(key, context, delta);
-    printout(INFO,"AlignmentUpdate","++ Building dependent condition: %s Detector [%d]: %s [%p]",
+    printout(INFO,"DDAlignUpdate","++ Building dependent condition: %s Detector [%d]: %s [%p]",
              key.name.c_str(), det.level(), det.path().c_str(), c.ptr());
     return c;
   }
diff --git a/DDAlign/src/plugins/AlignmentDependencyTest.cpp b/DDAlign/src/plugins/AlignmentDependencyTest.cpp
index 43adc47da435dfe46660592f72eba80aa3c3677e..f476764e8751490c329fbdf33038cb97e4d77a31 100644
--- a/DDAlign/src/plugins/AlignmentDependencyTest.cpp
+++ b/DDAlign/src/plugins/AlignmentDependencyTest.cpp
@@ -11,6 +11,7 @@
 // Author     : M.Frank
 //
 //==========================================================================
+#if 0
 
 // Framework includes
 #include "DD4hep/Plugins.h"
@@ -38,52 +39,6 @@ using Conditions::DetConditions;
 using Conditions::DependencyBuilder;
 
 // ======================================================================================
-#include "DDAlign/AlignmentsManager.h"
-
-namespace {
-  /// Print alignments
-  /**
-   *
-   *   \author  M.Frank
-   *   \version 1.0
-   *   \date    18/11/2016
-   *   \ingroup DD4HEP_DDALIGN
-   */
-  class AlignmentPrinter : public AlignmentsProcessor {
-  public:
-    /// Initializing constructor
-    AlignmentPrinter() : AlignmentsProcessor(0) {}
-    /// Default destructor
-    virtual ~AlignmentPrinter() = default;
-    /// Callback to output conditions information
-    virtual int operator()(Alignment a)  {
-      const Alignments::Delta& D = a.data().delta;
-      printout(INFO,"Alignment","++ (%11s-%8s-%5s) Cond:%p 'Alignment'",
-               D.hasTranslation() ? "Translation" : "",
-               D.hasRotation() ? "Rotation" : "",
-               D.hasPivot() ? "Pivot" : "",
-               a.data().hasCondition() ? a.data().condition.ptr() : 0);
-      return 1;
-    }
-    /// Container callback for object processing
-    virtual int operator()(Container container)
-    {  return this->self_t::operator()(container);  }
-    /// Callback to output conditions information
-    virtual int operator()(DetElement de)
-    {  return this->self_t::operator()(de);         }
-  };
-}
-
-/// Convert alignments conditions to alignment objects
-static void* ddalign_AlignmentsPrinter(Geometry::LCDD& /* lcdd */, int /* argc */, char** /* argv */)  {
-  return (AlignmentsProcessor*)(new AlignmentPrinter()); 
-}
-
-DECLARE_LCDD_CONSTRUCTOR(DDAlign_AlignmentsPrinter,ddalign_AlignmentsPrinter)
-
-  
-
-#if 0
 /// Compute dependent alignment conditions
 int computeDependencies(dd4hep_ptr<UserPool>& user_pool,
                         ConditionsManager conds,
diff --git a/DDAlign/src/plugins/AlignmentForward.cpp b/DDAlign/src/plugins/AlignmentForward.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a684f21f6a02ef6b888599c8559489cc5f793ebd
--- /dev/null
+++ b/DDAlign/src/plugins/AlignmentForward.cpp
@@ -0,0 +1,119 @@
+//==========================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------------
+// 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 includes
+#include "DD4hep/Plugins.h"
+#include "DD4hep/Printout.h"
+#include "DD4hep/DetAlign.h"
+#include "DD4hep/DetFactoryHelper.h"
+#include "DD4hep/objects/AlignmentsInterna.h"
+
+#include "DDAlign/AlignmentsManager.h"
+#include "DDAlign/AlignmentUpdateCall.h"
+
+using namespace DD4hep;
+using namespace DD4hep::Alignments;
+
+// ======================================================================================
+
+/// Anonymous namespace for plugins
+namespace  {
+
+  /// Create lignment dependencies from conditions
+  /**
+   *   Conditions analyser to select alignments.and create the
+   *   corresponding alignment condition dependencies.
+   *
+   *   \author  M.Frank
+   *   \version 1.0
+   *   \date    31/03/2016
+   *   \ingroup DD4HEP_DDALIGN
+   */
+  class AlignmentForward : public DetElement::Processor {
+  public:
+    LCDD&                  lcdd;
+    AlignmentsManager      alignmentMgr;
+    AlignmentUpdateCall*   updateCall;
+    Conditions::UserPool*  user_pool;
+
+    /// Initializing constructor
+    AlignmentForward(LCDD& l, AlignmentUpdateCall* c, UserPool* p)
+      : lcdd(l), updateCall(c), user_pool(p)
+    {
+      alignmentMgr = AlignmentsManager::from(lcdd);
+    }
+    /// Default destructor
+    virtual ~AlignmentForward()   {
+      releasePtr(updateCall);
+    }
+    /// Callback to output conditions information
+    virtual int processElement(DetElement de)  {
+      if ( de.isValid() )  {
+        DetElement parent = de.parent();
+        if ( parent.isValid() && parent.hasAlignments() && !de.hasAlignments() )  {
+          DetAlign align(de);
+          Conditions::ConditionKey k(de.path()+"#alignment/Tranformations");
+          //
+          // The alignment access through the DetElement object is optional!
+          // It is slow and deprecated. The access using the UserPool directly
+          // is highly favored.
+          //
+          align.alignments()->addKey(k.name);
+          align.alignments()->addKey("Alignment",k.name);
+          //
+          // Now add the dependency to the alignmant manager
+          Conditions::DependencyBuilder b(k, updateCall->addRef(), de);
+          bool result = alignmentMgr.adoptDependency(b.release());
+          if ( result )   {
+            printout(INFO,"AlignForward",
+                     "++ Added Alignment child dependency Cond:%s Key:%08X",
+                     k.name.c_str(), k.hash);
+            return 1;
+          }
+          printout(ERROR,"AlignForward",
+                   "++ FAILED to add Alignment dependency Cond:%s Key:%08X",
+                   k.name.c_str(), k.hash);
+        }
+      }
+      return 1;
+    }
+  };
+}
+
+#include "DD4hep/PluginTester.h"
+#include "DDCond/ConditionsPool.h"
+/// Convert alignments conditions to alignment objects
+static void* ddalign_AlignmentForward(Geometry::LCDD& lcdd, int argc, char** argv)  {
+  std::vector<char*> args_prepare, args_call;
+
+  for(int i=0; i<argc && argv[i]; ++i)  {
+    if ( ::strcmp(argv[i],"-call") == 0 )  {
+      while( (++i)<argc && argv[i] && 0 != ::strcmp(argv[i],"-call-end") )
+        args_call.push_back(argv[i]);
+    }
+  }
+
+  PluginTester* test = lcdd.extension<PluginTester>();
+  Conditions::UserPool* pool = test->extension<Conditions::UserPool>("ConditionsTestUserPool");
+  AlignmentUpdateCall*  call = (AlignmentUpdateCall*)
+    PluginService::Create<void*>((const char*)args_call[0],&lcdd,
+                                 int(args_call.size())-1,
+                                 (char**)&args_call[1]);
+  if ( 0 == call )  {
+    except("AlignForward","++ Failed to create update call!");
+  }
+  AlignmentForward* obj = new AlignmentForward(lcdd, call, pool);
+  return obj;
+}
+DECLARE_LCDD_CONSTRUCTOR(DDAlign_AlignmentForward,ddalign_AlignmentForward)
+
diff --git a/DDAlign/src/plugins/AlignmentPlugins.cpp b/DDAlign/src/plugins/AlignmentPlugins.cpp
index f36c150210215f1f51c9445b616734058df96b35..9d1329fbcb3d292217ed4ff761b1583048cd203c 100644
--- a/DDAlign/src/plugins/AlignmentPlugins.cpp
+++ b/DDAlign/src/plugins/AlignmentPlugins.cpp
@@ -16,6 +16,7 @@
 #include "DD4hep/DetectorTools.h"
 #include "DD4hep/DetFactoryHelper.h"
 
+using namespace std;
 using namespace DD4hep;
 using namespace DD4hep::Alignments;
 
@@ -51,10 +52,10 @@ namespace {
   namespace DetectorTools = DD4hep::Geometry::DetectorTools;
   long create_global_alignment_file(Geometry::LCDD& lcdd, int argc, char** argv)   {
     Geometry::DetElement top;
-    std::string output, path = "/world";
-    bool enable_transactions = false;
+    string output, path = "/world";
+    bool enable_transactions = false, arg_error = false;
     for(int i=1; i<argc;++i) {
-      if ( argv[i][0]=='-' || argv[i][0]=='/' ) {
+      if ( argv[i] && (argv[i][0]=='-' || argv[i][0]=='/') ) {
         const char* p = ::strchr(argv[i],'=');
         if ( p && strncmp(argv[i]+1,"-output",7)==0 )
           output = p+1;
@@ -63,18 +64,33 @@ namespace {
         else if ( strncmp(argv[i]+1,"-transactions",5)==0 )
           enable_transactions = true;
         else
-          throw std::runtime_error("AlignmentWriter: Invalid argument:"+std::string(argv[i]));
+          arg_error = true;
       }
     }
+          
+    if ( arg_error || output.empty() || path.empty() )  {
+      /// Help printout describing the basic command line interface
+      cout <<
+        "Usage: -plugin <name> -arg [-arg]                                      \n"
+        "     name:   factory nameDD4hep_GlobalAlignmentWriter                \n\n"
+        "     -output <string>         Path to the output file generated.       \n"
+        "     -path   <string>         Path to the detector element for which   \n"
+        "                              the alignment file should be written.    \n"
+        "     -transactions            Enable output transactions.              \n"
+        "\tArguments given: " << arguments(argc,argv) << endl << flush;
+      ::_exit(EINVAL);
+    }
+
     printout(ALWAYS,"AlignmentWriter",
-             "++++ Writing DD4hep alignment constants of the \"%s\" DetElement tree to file \"%s\"",
+             "++ Writing DD4hep alignment constants of the \"%s\" DetElement tree to file \"%s\"",
              path.c_str(), output.c_str());
     top = DetectorTools::findDaughterElement(lcdd.world(),path);
     if ( top.isValid() )   {
       GlobalAlignmentWriter wr(lcdd);
       return wr.write(wr.dump(top,enable_transactions), output);
     }
-    throw std::runtime_error("AlignmentWriter: Invalid top level element name:"+path);
+    except("AlignmentWriter","++ Invalid top level detector element name: %s",path.c_str());
+    return 1;
   }
 }  /* End anonymous namespace  */
 DECLARE_APPLY(DD4hep_GlobalAlignmentWriter, create_global_alignment_file)
@@ -87,10 +103,21 @@ static void* create_DDAlignUpdateCall(Geometry::LCDD& /* lcdd */, int /* argc */
 DECLARE_LCDD_CONSTRUCTOR(DDAlign_UpdateCall, create_DDAlignUpdateCall)
 
 // ======================================================================================
-#include "DDAlign/DDAlignTest.h"
+#include "DDAlign/DDAlignForwardCall.h"
+static void* create_DDAlignForwardCall(Geometry::LCDD& /* lcdd */, int /* argc */, char** /* argv */)   {
+  return (AlignmentUpdateCall*)(new DDAlignForwardCall());
+}
+DECLARE_LCDD_CONSTRUCTOR(DDAlign_ForwardCall, create_DDAlignForwardCall)
+
+#include "DD4hep/PluginTester.h"
+#include "DDCond/ConditionsPool.h"
+// ======================================================================================
 static long compute_alignments(Geometry::LCDD& lcdd, int /* argc */, char** /* argv */)   {
-  DDAlignTest* test = lcdd.extension<DDAlignTest>();
-  test->alignmentsMgr.compute(test->alignmentsPool);
+  AlignmentsManager mgr = AlignmentsManager::from(lcdd);
+  PluginTester*     tst = lcdd.extension<PluginTester>();
+  dd4hep_ptr<UserPool> pool(tst->extension<UserPool>("ConditionsTestUserPool"));
+  mgr.compute(pool);
+  pool.release();
   return 1;
 }
 DECLARE_APPLY(DDAlign_ComputeAlignments, compute_alignments)
diff --git a/DDAlign/src/plugins/Conditions2Alignments.cpp b/DDAlign/src/plugins/AlignmentRegister.cpp
similarity index 72%
rename from DDAlign/src/plugins/Conditions2Alignments.cpp
rename to DDAlign/src/plugins/AlignmentRegister.cpp
index 87efa0c4dd5b95a87aea68aa329ca2100910ddc5..995b64cc5d74ac7fa599d5d262b5f60e127d42a8 100644
--- a/DDAlign/src/plugins/Conditions2Alignments.cpp
+++ b/DDAlign/src/plugins/AlignmentRegister.cpp
@@ -47,7 +47,7 @@ namespace  {
    *   \date    31/03/2016
    *   \ingroup DD4HEP_DDALIGN
    */
-  class Conditions2Alignments : public DetElement::Processor {
+  class AlignmentRegister : public DetElement::Processor {
   public:
     LCDD&                            lcdd;
     Alignments::AlignmentsManager    alignmentMgr;
@@ -55,32 +55,32 @@ namespace  {
     Conditions::UserPool*            user_pool;
 
     /// Initializing constructor
-    Conditions2Alignments(LCDD& l, AlignmentUpdateCall* c, UserPool* p)
+    AlignmentRegister(LCDD& l, AlignmentUpdateCall* c, UserPool* p)
       : lcdd(l), updateCall(c), user_pool(p)
     {
       alignmentMgr = AlignmentsManager::from(lcdd);
     }
     /// Default destructor
-    virtual ~Conditions2Alignments()   {
+    virtual ~AlignmentRegister()   {
       releasePtr(updateCall);
     }
     /// Callback to output conditions information
-    virtual int operator()(DetElement de)  {
+    virtual int processElement(DetElement de)  {
       if ( de.isValid() )  {
         if ( de.hasConditions() )  {
           DetAlign align(de);
           DetConditions conditions(de);
           Conditions::Container cont = conditions.conditions();
-          printout(INFO,"Conditions2Alignments",
+          printout(DEBUG,"AlignRegister",
                    "++ Processing DE %s hasConditions:%s [%d entries]",
                    de.path().c_str(), yes_no(de.hasConditions()), int(cont.numKeys()));
           for ( const auto& c : cont.keys() )  {
             Condition cond = cont.get(c.first, *user_pool);
-            printout(INFO,"Conditions2Alignments",
+            printout(DEBUG,"AlignRegister",
                      "++ Processing DE %s Cond:%s Key:%08X flags:%d",
-                     de.path().c_str(), cond.name().c_str(), cond.key(), cond->flags);
+                     de.path().c_str(), cond.name(), cond.key(), cond->flags);
             if ( (cond->flags&Condition::ALIGNMENT) )  {
-              ConditionKey k(cond.name()+"/Tranformations");
+              ConditionKey k(cond->name+"/Tranformations");
               //
               // The alignment access through the DetElement object is optional!
               // It is slow and deprecated. The access using the UserPool directly
@@ -90,25 +90,23 @@ namespace  {
               align.alignments()->addKey("Alignment",k.name);
               //
               // Now add the dependency to the alignmant manager
-              DependencyBuilder b(k, updateCall->addRef());
-              b->detector = de;
+              DependencyBuilder b(k, updateCall->addRef(), de);
               b.add(ConditionKey(cond->name));
-              Conditions::ConditionDependency* dep = b.release();
-              bool result = alignmentMgr.adoptDependency(dep);
+              bool result = alignmentMgr.adoptDependency(b.release());
               if ( result )   {
-                printout(INFO,"Conditions2Alignments",
-                         "++ Added Alignment dependency Cond:%s Key:%08X",
-                         k.name.c_str(), k.hash);
+                printout(INFO,"AlignRegister",
+                         "++ Added Alignment dependency Cond:%s Key:%08X flags:%d",
+                         k.name.c_str(), k.hash, cond->flags);
                 continue;
               }
-              printout(ERROR,"Conditions2Alignments",
-                       "++ FAILED to add Alignment dependency Cond:%s Key:%08X",
-                       k.name.c_str(), k.hash);
+              printout(ERROR,"AlignRegister",
+                       "++ FAILED to add Alignment dependency Cond:%s Key:%08X flags:%d",
+                       k.name.c_str(), k.hash, cond->flags);
             }
           }
           return 1;
         }
-        printout(INFO,"Conditions2Alignments","++ Processing DE %s hasConditions:%s",
+        printout(DEBUG,"AlignRegister","++ Processing DE %s hasConditions:%s",
                  de.path().c_str(), yes_no(de.hasConditions()));
       }
       return 1;
@@ -116,41 +114,41 @@ namespace  {
   };
 }
 
-
-#include "DDAlign/DDAlignTest.h"
-
+#include "DD4hep/PluginTester.h"
+#include "DDCond/ConditionsPool.h"
 /// Convert alignments conditions to alignment objects
-static void* ddalign_Conditions2Alignments(Geometry::LCDD& lcdd, int argc, char** argv)  {
+static void* ddalign_AlignmentRegister(Geometry::LCDD& lcdd, int argc, char** argv)  {
   std::vector<char*> args_prepare, args_call;
 
   for(int i=0; i<argc && argv[i]; ++i)  {
     if ( ::strcmp(argv[i],"-prepare") == 0 )  {
-      while( 0 != ::strcmp(argv[++i],"-prepare-end") && i<argc )
+      while( (++i)<argc && argv[i] && 0 != ::strcmp(argv[i],"-prepare-end") )
         args_prepare.push_back(argv[i]);
     }
     if ( ::strcmp(argv[i],"-call") == 0 )  {
-      while( 0 != ::strcmp(argv[++i],"-call-end") && i<argc )
+      while( (++i)<argc && argv[i] && 0 != ::strcmp(argv[i],"-call-end") )
         args_call.push_back(argv[i]);
     }
   }
 
-  DDAlignTest* test = lcdd.extension<DDAlignTest>();
+  PluginTester* test = lcdd.extension<PluginTester>();
   Conditions::UserPool* pool = (Conditions::UserPool*)
     PluginService::Create<void*>((const char*)args_prepare[0],&lcdd,
                                  int(args_prepare.size())-1,
                                  (char**)&args_prepare[1]);
   if ( 0 == pool )  {
-    except("Conditions2Alignments","++ Failed to prepare conditions user-pool!");
+    except("AlignRegister","++ Failed to prepare conditions user-pool!");
   }
-  test->alignmentsPool.adopt(pool);
+  test->addExtension<Conditions::UserPool>(pool,"ConditionsTestUserPool");
   AlignmentUpdateCall* call = (AlignmentUpdateCall*)
     PluginService::Create<void*>((const char*)args_call[0],&lcdd,
                                  int(args_call.size())-1,
                                  (char**)&args_call[1]);
   if ( 0 == call )  {
-    except("Conditions2Alignments","++ Failed to create update call!");
+    except("AlignRegister","++ Failed to create update call!");
   }
-  Conditions2Alignments* obj = new Conditions2Alignments(lcdd, call, pool);
+  AlignmentRegister* obj = new AlignmentRegister(lcdd, call, pool);
   return obj;
 }
-DECLARE_LCDD_CONSTRUCTOR(DDAlign_Conditions2Alignments,ddalign_Conditions2Alignments)
+DECLARE_LCDD_CONSTRUCTOR(DDAlign_AlignmentRegister,ddalign_AlignmentRegister)
+
diff --git a/DDAlign/src/plugins/AlignmentsPrinter.cpp b/DDAlign/src/plugins/AlignmentsPrinter.cpp
deleted file mode 100644
index f7b6fdcf8ef861a8c75afe353c5649124910d2b7..0000000000000000000000000000000000000000
--- a/DDAlign/src/plugins/AlignmentsPrinter.cpp
+++ /dev/null
@@ -1,66 +0,0 @@
-//==========================================================================
-//  AIDA Detector description implementation for LCD
-//--------------------------------------------------------------------------
-// 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 includes
-#include "DD4hep/Printout.h"
-#include "DD4hep/DetFactoryHelper.h"
-//#include "DD4hep/Conditions.h"
-//#include "DD4hep/DetAlign.h"
-#include "DD4hep/AlignmentsProcessor.h"
-#include "DD4hep/objects/AlignmentsInterna.h"
-
-using namespace DD4hep;
-using namespace DD4hep::Alignments;
-
-// ======================================================================================
-
-namespace {
-  /// Print alignments
-  /**
-   *
-   *   \author  M.Frank
-   *   \version 1.0
-   *   \date    18/11/2016
-   *   \ingroup DD4HEP_DDALIGN
-   */
-  class AlignmentPrinter : public AlignmentsProcessor {
-  public:
-    /// Initializing constructor
-    AlignmentPrinter() : AlignmentsProcessor(0) {}
-    /// Default destructor
-    virtual ~AlignmentPrinter() = default;
-    /// Callback to output conditions information
-    virtual int operator()(Alignment a)  {
-      const Alignments::Delta& D = a.data().delta;
-      printout(INFO,"Alignment","++ (%11s-%8s-%5s) Cond:%p 'Alignment'",
-               D.hasTranslation() ? "Translation" : "",
-               D.hasRotation() ? "Rotation" : "",
-               D.hasPivot() ? "Pivot" : "",
-               a.data().hasCondition() ? a.data().condition.ptr() : 0);
-      return 1;
-    }
-    /// Container callback for object processing
-    virtual int operator()(Container container)
-    {  return this->self_t::operator()(container);  }
-    /// Callback to output conditions information
-    virtual int operator()(DetElement de)
-    {  return this->self_t::operator()(de);         }
-  };
-}
-
-/// Convert alignments conditions to alignment objects
-static void* ddalign_AlignmentsPrinter(Geometry::LCDD& /* lcdd */, int /* argc */, char** /* argv */)  {
-  return (AlignmentsProcessor*)(new AlignmentPrinter()); 
-}
-
-DECLARE_LCDD_CONSTRUCTOR(DDAlign_AlignmentsPrinter,ddalign_AlignmentsPrinter)
diff --git a/DDAlign/src/plugins/DDAlignTest.cpp b/DDAlign/src/plugins/DDAlignTest.cpp
deleted file mode 100644
index 63751a3061eaac8c82565fe9ac617e98b13cad12..0000000000000000000000000000000000000000
--- a/DDAlign/src/plugins/DDAlignTest.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-//==========================================================================
-//  AIDA Detector description implementation for LCD
-//--------------------------------------------------------------------------
-// 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 includes
-#include "DD4hep/Printout.h"
-#include "DD4hep/DetectorTools.h"
-#include "DD4hep/DetFactoryHelper.h"
-
-using namespace DD4hep;
-
-// ======================================================================================
-#include "DDAlign/DDAlignTest.h"
-static long install_ddalign_tester(Geometry::LCDD& lcdd, int /* argc */, char** /* argv */)   {
-  Alignments::AlignmentsManager alignMgr = Alignments::AlignmentsManager::from(lcdd);
-  Conditions::ConditionsManager condMgr  = Conditions::ConditionsManager::from(lcdd);
-  DDAlignTest* test = new DDAlignTest();
-  test->alignmentsMgr = alignMgr;
-  test->conditionsMgr = condMgr;
-  lcdd.addExtension<DDAlignTest>(test);
-  return 1;
-}
-DECLARE_APPLY(DDAlign_InstallTest, install_ddalign_tester)
diff --git a/DDCond/src/ConditionsInterna.cpp b/DDCond/src/ConditionsInterna.cpp
index 539c3fd6a4d76c94c5b249c8b87149098f473723..32150b794a0a4cda4fb530ed89b3837724474202 100644
--- a/DDCond/src/ConditionsInterna.cpp
+++ b/DDCond/src/ConditionsInterna.cpp
@@ -626,14 +626,14 @@ ConditionsManagerObject::get(Condition::key_type key, const Condition::iov_type&
     RC::const_iterator start = conditions.begin();
     Condition first = *start;
     printout(ERROR,"ConditionsManager","+++ Condition %s [%08X] is ambiguous for IOV %s:",
-             first.name().c_str(), key, iov.str().c_str());
+             first.name(), key, iov.str().c_str());
     for(RC::const_iterator i=start; i!=conditions.end(); ++i)  {
       Condition c = *i;
       printout(ERROR,"ConditionsManager","+++ %s [%s] = %s",
-               c.name().c_str(), c->iov->str().c_str(), c->value.c_str());
+               c.name(), c->iov->str().c_str(), c->value.c_str());
     }
     except("ConditionsManager","+++ Condition %s [%08X] is ambiguous for IOV %s:",
-           first.name().c_str(), key, iov.str().c_str());
+           first.name(), key, iov.str().c_str());
   }
   return Condition();
 }
diff --git a/DDCond/src/ConditionsRepository.cpp b/DDCond/src/ConditionsRepository.cpp
index 14d9ebe4a5eb09dee812737887d07ba56f3a2256..f4b187ac73e549d0ab3c15969bd6b2c64d74a46a 100644
--- a/DDCond/src/ConditionsRepository.cpp
+++ b/DDCond/src/ConditionsRepository.cpp
@@ -129,7 +129,7 @@ namespace {
         << "." << long(siz_tot) << endl;
     for(AllConditions::const_iterator i=all.begin(); i!=all.end(); ++i)  {
       Condition c = (*i).second;
-      ::snprintf(text, sizeof(text), fmt, c.key(), c.name().c_str(), c.address().c_str());
+      ::snprintf(text, sizeof(text), fmt, c.key(), c.name(), c.address().c_str());
       out << text << endl;
     }
     out.close();
diff --git a/DDCond/src/ConditionsTest.cpp b/DDCond/src/ConditionsTest.cpp
index e9e8c71890af946a9613c339d72b13bdec196b16..eea73192f91d3f01831832cb3d56b634aa855d9b 100644
--- a/DDCond/src/ConditionsTest.cpp
+++ b/DDCond/src/ConditionsTest.cpp
@@ -49,23 +49,23 @@ namespace DD4hep {
           T val = _multiply(c.get<T>(),norm);
           ::snprintf(text_format,sizeof(text_format),"  Bound value  %%s : value:%s [%s] Type: %%s",
                      Primitive<T>::default_format(),Primitive<T>::default_format());
-          printout(INFO,"Cond_Value",text_format, c.name().c_str(), value, val, typeName(c.typeInfo()).c_str());
+          printout(INFO,"Cond_Value",text_format, c.name(), value, val, typeName(c.typeInfo()).c_str());
           return;
         }
         ::snprintf(text_format,sizeof(text_format),"  Bound value  %%s : value:%s Type: %%s",
                    Primitive<T>::default_format());
-        printout(INFO,"Cond_Value",text_format, c.name().c_str(), value, typeName(c.typeInfo()).c_str());
+        printout(INFO,"Cond_Value",text_format, c.name(), value, typeName(c.typeInfo()).c_str());
       }
       template <> void __print_bound_val<string>(Condition c, const char*)   {
         const string& v = access_val<string>(c);
         printout(INFO,"Cond_Value","  Bound value  %s : string value:%s  Type: %s Ptr:%016X",
-                 c.name().c_str(), c.get<string>().c_str(),typeName(c.typeInfo()).c_str(),
+                 c.name(), c.get<string>().c_str(),typeName(c.typeInfo()).c_str(),
                  (void*)&v);
       }
       template <typename T> void __print_bound_container(Condition c, const char*)   {
         const T& v = access_val<T>(c);
         printout(INFO,"Cond_Value","  Bound value  %s : size:%d = %s Type: %s Ptr:%016X",
-                 c.name().c_str(), int(v.size()), c.data().str().c_str(),
+                 c.name(), int(v.size()), c.data().str().c_str(),
                  typeName(c.typeInfo()).c_str(), (void*)&v);
       }
 
@@ -114,8 +114,8 @@ namespace DD4hep {
       template <> void print_condition<void>(Condition c)   {
         string type = c.type();
         printout(INFO,"Cond_Value","%-32s  [%16s] :  %s [%s] ", 
-                 c.name().c_str(),c.type().c_str(),
-                 c.value().c_str(),c->validity.c_str());
+                 c.name(), c.type().c_str(),
+                 c.value().c_str(), c->validity.c_str());
         if ( type == "alignment" )
           print_bound_value<string>(c);
         else if ( type == "temperature" )
diff --git a/DDCond/src/ConditionsTextRepository.cpp b/DDCond/src/ConditionsTextRepository.cpp
index 4798d526cd792c99101ed4ec0e28dc68ebda4d6f..e9913f7d4e2522cd5a9042a8a4d6680f224a308e 100644
--- a/DDCond/src/ConditionsTextRepository.cpp
+++ b/DDCond/src/ConditionsTextRepository.cpp
@@ -129,7 +129,7 @@ namespace {
         << "." << long(siz_tot) << endl;
     for(AllConditions::const_iterator i=all.begin(); i!=all.end(); ++i)  {
       Condition c = (*i).second;
-      ::snprintf(text, sizeof(text), fmt, c.key(), c.name().c_str(), c.address().c_str());
+      ::snprintf(text, sizeof(text), fmt, c.key(), c.name(), c.address().c_str());
       out << text << endl;
     }
     out.close();
diff --git a/DDCond/src/plugins/ConditionsPlugins.cpp b/DDCond/src/plugins/ConditionsPlugins.cpp
index 5f281d4dcddd59c5e5ce3afe9e1352df2ba3007d..7e4deaf39c3991cab6ad993f3b9944c2a1b6986b 100644
--- a/DDCond/src/plugins/ConditionsPlugins.cpp
+++ b/DDCond/src/plugins/ConditionsPlugins.cpp
@@ -16,6 +16,7 @@
 #include "DD4hep/Plugins.h"
 #include "DD4hep/Printout.h"
 #include "DD4hep/Conditions.h"
+#include "DD4hep/PluginCreators.h"
 #include "DD4hep/DetFactoryHelper.h"
 #include "DD4hep/ConditionsPrinter.h"
 
@@ -59,32 +60,6 @@ static int ddcond_install_cond_mgr (LCDD& lcdd, int argc, char** argv)  {
 }
 DECLARE_APPLY(DD4hep_ConditionsManagerInstaller,ddcond_install_cond_mgr)
 
-// ======================================================================================
-static ConditionsProcessor* create_processor(lcdd_t& lcdd, int argc, char** argv)  {
-  class Processor {public:    virtual ~Processor() {}  };
-  ConditionsProcessor* processor = 0;
-  if ( argc < 2 )   {
-    except("CondPoolProcessor","++ No processor creator name given!");
-  }
-  for(int i=0; i<argc; ++i)  {
-    if ( 0 == ::strncmp(argv[i],"-processor",3) )  {
-      vector<char*> args;
-      for(int j=2; j<argc && argv[j]; ++j) args.push_back(argv[j]);
-      args.push_back(0);
-      string fac = argv[++i];
-      Condition::Processor* p = (Condition::Processor*)
-        PluginService::Create<void*>(fac,&lcdd,int(args.size()),&args[0]);
-      processor = dynamic_cast<ConditionsProcessor*>(p);
-      break;
-    }
-  }
-  if ( !processor )  {
-    except("CondPoolProcessor",
-           "++ Found arguments in plugin call, but could not make any sense of them....");
-  }
-  return processor;
-}
-
 // ======================================================================================
 /// Plugin function: Dump of all Conditions pool with or without conditions
 /**
@@ -96,7 +71,8 @@ static ConditionsProcessor* create_processor(lcdd_t& lcdd, int argc, char** argv
  *  \date    01/04/2016
  */
 static int ddcond_conditions_pool_processor(lcdd_t& lcdd, bool process_pool, bool process_conditions, int argc, char** argv)   {
-  ConditionsProcessor* processor = create_processor(lcdd,argc,argv);
+  DetElement::Processor* p = createProcessor<DetElement::Processor>(lcdd,argc,argv);
+  ConditionsProcessor* processor = dynamic_cast<ConditionsProcessor*>(p);
   typedef std::vector<const IOVType*> _T;
   typedef ConditionsIOVPool::Elements _E;
   typedef RangeConditions _R;
@@ -220,7 +196,7 @@ static int ddcond_detelement_dump(LCDD& lcdd, int /* argc */, char** /* argv */)
                (unsigned long)de.volumeID(), sens);
       printer.setName(string(tmp)+de.name());
       if ( de.hasConditions() )  {
-        (printer)(de);
+        printer.processElement(de);
       }
       for (const auto& c : de.children() )
         dump(c.second,level+1);
@@ -308,7 +284,7 @@ static int ddcond_detelement_processor(LCDD& lcdd, int argc, char** argv)   {
     /// Dump method.
     long dump(DetElement de)   {
       if ( de.hasConditions() )  {
-        (*processor)(de);
+        processor->processElement(de);
       }
       for (const auto& c : de.children() )
         dump(c.second);
@@ -317,11 +293,11 @@ static int ddcond_detelement_processor(LCDD& lcdd, int argc, char** argv)   {
   };
   ConditionsProcessor* processor = 0;
   if ( argc > 0 )   {
-    processor = create_processor(lcdd, argc, argv);
+    processor = createProcessor<ConditionsProcessor>(lcdd, argc, argv);
   }
   else  {
     const void* args[] = { "-processor", "DD4hepConditionsPrinter", 0};
-    processor = create_processor(lcdd, 2, (char**)args);
+    processor = createProcessor<ConditionsProcessor>(lcdd, 2, (char**)args);
   }
   return Actor(processor,ConditionsManager::from(lcdd)).dump(lcdd.world());
 }
@@ -337,7 +313,7 @@ DECLARE_APPLY(DD4hep_DetElementConditionsProcessor,ddcond_detelement_processor)
  *  \date    01/04/2016
  */
 static long ddcond_synchronize_conditions(lcdd_t& lcdd, int argc, char** argv) {
-  if ( argc > 0 )   {
+  if ( argc >= 2 )   {
     string iov_type = argv[0];
     IOV::Key::first_type iov_key = *(IOV::Key::first_type*)argv[1];
     ConditionsManager    manager = ConditionsManager::from(lcdd);
@@ -366,7 +342,8 @@ static long ddcond_synchronize_conditions(lcdd_t& lcdd, int argc, char** argv) {
     user_pool->clear();
     return 1;
   }
-  except("Conditions","+++ Failed update conditions. No event time argument given!");
+  except("Conditions","+++ Failed update conditions. Arguments were: '%s'",
+         arguments(argc,argv).c_str());
   return 0;
 }
 DECLARE_APPLY(DD4hep_ConditionsSynchronize,ddcond_synchronize_conditions)
@@ -407,16 +384,28 @@ DECLARE_APPLY(DD4hep_ConditionsClean,ddcond_clean_conditions)
  *  \date    01/04/2016
  */
 static long ddcond_create_repository(lcdd_t& lcdd, int argc, char** argv) {
-  if ( argc > 0 )   {
-    string output = argv[0];
-    printout(INFO,"Conditions",
-             "+++ ConditionsRepository: Creating %s",output.c_str());
-    ConditionsManager manager = ConditionsManager::from(lcdd);
-    ConditionsRepository().save(manager,output);
-    return 1;
+  bool arg_error = false;
+  string output = "";
+  for(int i=0; i<argc && argv[i]; ++i)  {      
+    if ( 0 == ::strncmp("-output",argv[i],4) )
+      output = argv[++i];
+    else
+      arg_error = true;
   }
-  except("Conditions","+++ Failed creating conditions repository. Insufficient arguments!");
-  return 0;
+  if ( arg_error || output.empty() )  {
+    /// Help printout describing the basic command line interface
+    cout <<
+      "Usage: -plugin <name> -arg [-arg]                                             \n"
+      "     name:   factory name     DD4hep_ConditionsCreateRepository             \n\n"
+      "     -output <string>         Output file name.                             \n\n"
+      "\tArguments given: " << arguments(argc,argv) << endl << flush;
+    ::_exit(EINVAL);
+  }
+  printout(INFO,"Conditions",
+           "+++ ConditionsRepository: Creating %s",output.c_str());
+  ConditionsManager manager = ConditionsManager::from(lcdd);
+  ConditionsRepository().save(manager,output);
+  return 1;
 }
 DECLARE_APPLY(DD4hep_ConditionsCreateRepository,ddcond_create_repository)
 
@@ -429,31 +418,99 @@ DECLARE_APPLY(DD4hep_ConditionsCreateRepository,ddcond_create_repository)
  *  \version 1.0
  *  \date    01/04/2016
  */
-static long ddcond_dump_repository(lcdd_t& lcdd, int argc, char** argv) {
-  if ( argc > 0 )   {
-    typedef ConditionsRepository::Data Data;
-    Data data;
-    string input = argv[0];
-    printout(INFO,"Conditions",
-             "+++ ConditionsRepository: Dumping %s",input.c_str());
-    ConditionsManager manager = ConditionsManager::from(lcdd);
-    if ( ConditionsRepository().load(input, data) )  {
-      printout(INFO,"Repository","%-8s  %-60s %-60s","Key","Name","Address");
-      for(Data::const_iterator i=data.begin(); i!=data.end(); ++i)  {
-        const ConditionsRepository::Entry& e = *i;
-        string add = e.address;
-        if ( add.length() > 80 ) add = e.address.substr(0,60) + "...";
-        printout(INFO,"Repository","%08X  %s",e.key,e.name.c_str());
-        printout(INFO,"Repository","          -> %s",e.address.c_str());
-      }
+static long ddcond_dump_repository(lcdd_t& lcdd, int argc, char** argv)   {
+  typedef ConditionsRepository::Data Data;
+  bool arg_error = false;
+  string input = "";
+  Data data;
+  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_ConditionsDumpRepository               \n\n"
+      "     -input <string>          Input file name.                              \n\n"
+      "\tArguments given: " << arguments(argc,argv) << endl << flush;
+    ::_exit(EINVAL);
+  }
+  printout(INFO,"Conditions",
+           "+++ ConditionsRepository: Dumping %s",input.c_str());
+  ConditionsManager manager = ConditionsManager::from(lcdd);
+  if ( ConditionsRepository().load(input, data) )  {
+    printout(INFO,"Repository","%-8s  %-60s %-60s","Key","Name","Address");
+    for(Data::const_iterator i=data.begin(); i!=data.end(); ++i)  {
+      const ConditionsRepository::Entry& e = *i;
+      string add = e.address;
+      if ( add.length() > 80 ) add = e.address.substr(0,60) + "...";
+      printout(INFO,"Repository","%08X  %s",e.key,e.name.c_str());
+      printout(INFO,"Repository","          -> %s",e.address.c_str());
     }
-    return 1;
   }
-  except("Conditions","+++ Failed dumping conditions repository. Insufficient arguments!");
-  return 0;
+  return 1;
 }
 DECLARE_APPLY(DD4hep_ConditionsDumpRepository,ddcond_dump_repository)
 
+/// Basic entry point to instantiate the basic DD4hep conditions/alignmants printer
+/**
+ *  Factory: DD4hepConditionsPrinter, DD4hepAlignmentsPrinter 
+ *
+ *  \author  M.Frank
+ *  \version 1.0
+ *  \date    17/11/2016
+ */
+#include "DD4hep/PluginTester.h"
+template <typename PRINTER>
+static void* create_printer(Geometry::LCDD& lcdd, int argc,char** argv)  {
+  typedef typename PRINTER::pool_type pool_t;
+  string prefix = "", name = "";
+  int    flags = 0, have_pool = 0, arg_error = false;
+  for(int i=0; i<argc && argv[i]; ++i)  {
+    if ( 0 == ::strncmp("-prefix",argv[i],4) )
+      prefix = argv[++i];
+    else if ( 0 == ::strncmp("-name",argv[i],5) )
+      name = argv[++i];
+    else if ( 0 == ::strncmp("-flags",argv[i],5) )
+      flags = ::atol(argv[++i]);
+    else if ( 0 == ::strncmp("-pool",argv[i],5) )
+      have_pool = 1;
+    else
+      arg_error = true;
+  }
+  if ( arg_error )   {
+    /// Help printout describing the basic command line interface
+    cout <<
+      "Usage: -plugin <name> -arg [-arg]                                             \n"
+      "     name:   factory name DD4hep_ConditionsPrinter, DD4hep_AlignmentsPrinter\n\n"
+      "     -prefix <string>         Printout prefix for user customized output.     \n"
+      "     -flags  <number>         Printout processing flags.                      \n"
+      "     -pool                    Attach conditions user pool from                \n"
+      "                              PluginTester instance attached to LCDD.       \n\n"
+      "\tArguments given: " << arguments(argc,argv) << endl << flush;
+    ::_exit(EINVAL);
+  }
+  DetElement world = lcdd.world();
+  printout(INFO,"Printer","World=%s [%p]",world.path().c_str(),world.ptr());
+  PRINTER* p = (flags) ? new PRINTER(prefix,flags) : new PRINTER(prefix);
+  if ( have_pool != 0 )  {
+    PluginTester* test = lcdd.extension<PluginTester>();
+    pool_t* pool = test->extension<pool_t>("ConditionsTestUserPool");
+    if ( !name.empty() ) p->name = name;
+    p->setPool(pool);
+  }
+  return (void*)dynamic_cast<DetElement::Processor*>(p);
+}
+#include "DD4hep/ConditionsPrinter.h"
+DECLARE_LCDD_CONSTRUCTOR(DD4hep_ConditionsPrinter,create_printer<Conditions::ConditionsPrinter>)
+#include "DD4hep/AlignmentsPrinter.h"
+DECLARE_LCDD_CONSTRUCTOR(DD4hep_AlignmentsPrinter,create_printer<Alignments::AlignmentsPrinter>)
+#include "DD4hep/AlignedVolumePrinter.h"
+DECLARE_LCDD_CONSTRUCTOR(DD4hep_AlignedVolumePrinter,create_printer<Alignments::AlignedVolumePrinter>)
+
 // ======================================================================================
 /// Plugin entry point: Load conditions repository csv file into conditions manager
 /**
diff --git a/DDCond/src/plugins/ConditionsRepositoryParser.cpp b/DDCond/src/plugins/ConditionsRepositoryParser.cpp
index 616394b61ef2ced02f10aff675210fe721f49c52..f8dd4a02930b9df4ddf7d161ee6b119570a97672 100644
--- a/DDCond/src/plugins/ConditionsRepositoryParser.cpp
+++ b/DDCond/src/plugins/ConditionsRepositoryParser.cpp
@@ -418,6 +418,7 @@ namespace DD4hep {
     xml_coll_t(e,_UC(mapping)).for_each(Converter<mapping>(lcdd,param,optional));
     xml_coll_t(e,_UC(sequence)).for_each(Converter<sequence>(lcdd,param,optional));
     xml_coll_t(e,_UC(alignment)).for_each(Converter<alignment>(lcdd,param,optional));
+    xml_coll_t(e,_UC(detelement)).for_each(Converter<detelement>(lcdd,param,optional));
   }
 
   /** Convert repository objects
diff --git a/DDCore/include/DD4hep/AlignedVolumePrinter.h b/DDCore/include/DD4hep/AlignedVolumePrinter.h
new file mode 100644
index 0000000000000000000000000000000000000000..77759adbed0f8c2e1432ce2236d59c3c4a70e6c0
--- /dev/null
+++ b/DDCore/include/DD4hep/AlignedVolumePrinter.h
@@ -0,0 +1,64 @@
+//==========================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------------
+// 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_DDCORE_ALIGNEDVOLUMEPRINTER_H
+#define DD4HEP_DDCORE_ALIGNEDVOLUMEPRINTER_H
+
+// Framework includes
+#include "DD4hep/AlignmentsProcessor.h"
+
+/// Namespace for the AIDA detector description toolkit
+namespace DD4hep {
+
+  /// Namespace for the AIDA detector description toolkit supporting XML utilities
+  namespace Alignments {
+
+    /// Generic Alignments data dumper.
+    /**
+     *   Please note that the principle of locality applies:
+     *   The object is designed for stack allocation and configuration.
+     *   It may NOT be shared across threads!
+     *
+     *   \author  M.Frank
+     *   \version 1.0
+     *   \date    31/03/2016
+     *   \ingroup DD4HEP_DDDB
+     */
+    class AlignedVolumePrinter : public AlignmentsProcessor  {
+    public:
+      /// Printer name. Want to know who is printing what
+      std::string   name;
+      /// Printout prefix
+      std::string   prefix;
+    protected:
+      /// Printout processing and customization flag
+      int           m_flag;
+
+    public:
+      /// Initializing constructor
+      AlignedVolumePrinter(const std::string& prefix="",int flags=0);
+      /// Default destructor
+      virtual ~AlignedVolumePrinter() = default;
+      /// Set name for printouts
+      void setName(const std::string& value)    {  name = value;   }
+      /// Set prefix for printouts
+      void setPrefix(const std::string& value)  {  prefix = value; }
+      /// Callback to output alignments information
+      virtual int operator()(Alignment cond);
+      /// Container callback for object processing
+      virtual int operator()(Container container);
+      /// Callback to output alignments information of an entire DetElement
+      virtual int processElement(DetElement de);
+    };
+  }    /* End namespace Alignments              */
+}      /* End namespace DD4hep                  */
+#endif /* DD4HEP_DDCORE_ALIGNEDVOLUMEPRINTER_H  */
diff --git a/DDCore/include/DD4hep/AlignmentData.h b/DDCore/include/DD4hep/AlignmentData.h
index 7cd0fa7c9b95337931f8055b8e6497e00d637351..1c582c8a3875b33fa066321d735b6200c93ba443 100644
--- a/DDCore/include/DD4hep/AlignmentData.h
+++ b/DDCore/include/DD4hep/AlignmentData.h
@@ -135,6 +135,8 @@ namespace DD4hep {
       Delta                delta;
       /// Intermediate buffer to store the transformation to the world coordination system
       mutable TGeoHMatrix  worldTrafo;
+      /// Delta transformation to the world coordination system
+      mutable TGeoHMatrix  worldDelta;
       /// Intermediate buffer to store the transformation to the parent detector element
       mutable TGeoHMatrix  detectorTrafo;
       /// The list of TGeoNodes (physical placements)
diff --git a/DDCore/include/DD4hep/Alignments.h b/DDCore/include/DD4hep/Alignments.h
index 7a0668411a4406214066299526e7845562a6e632..f3bc6aee32851dc7a01d2eb451252b44cbfa41fb 100644
--- a/DDCore/include/DD4hep/Alignments.h
+++ b/DDCore/include/DD4hep/Alignments.h
@@ -176,6 +176,8 @@ namespace DD4hep {
       const IOVType& iovType()  const;
       /// Access the IOV block
       const iov_type& iov()  const;
+      /// Access the hash identifier
+      key_type key()  const;
 
       /** Data block (bound type)         */
       /// Data accessor for the use of decorators
diff --git a/DDCore/include/DD4hep/AlignmentsPrinter.h b/DDCore/include/DD4hep/AlignmentsPrinter.h
index 0a9863b5e1216c7eaaf1b15a3e76f2f797914e0d..1c7a6726b44c19f46b74e656e9d857084a14368a 100644
--- a/DDCore/include/DD4hep/AlignmentsPrinter.h
+++ b/DDCore/include/DD4hep/AlignmentsPrinter.h
@@ -35,9 +35,12 @@ namespace DD4hep {
      */
     class AlignmentsPrinter : public AlignmentsProcessor  {
     public:
+      /// Printer name. Want to know who is printing what
       std::string   name;
+      /// Printout prefix
       std::string   prefix;
     protected:
+      /// Printout processing and customization flag
       int           m_flag;
 
     public:
@@ -54,10 +57,21 @@ namespace DD4hep {
       /// Container callback for object processing
       virtual int operator()(Container container);
       /// Callback to output alignments information of an entire DetElement
-      virtual int operator()(DetElement de)
-      {  return this->AlignmentsProcessor::operator()(de);         }
+      virtual int processElement(DetElement de);
     };
 
+    /// Default printout of an alignment entry
+    void printAlignment(const std::string& prefix, Alignment alignment);
+
+    /// Default printout of a container entry
+    void printContainer(const std::string& prefix, Container container, UserPool* pool);
+
+    /// Default printout of a detector element entry
+    void printElement(const std::string& prefix, DetElement element, UserPool* pool);
+
+    /// PrintElement placement with/without alignment applied
+    void printElementPlacement(const std::string& prefix, DetElement detector, UserPool* pool);
+
   }    /* End namespace Alignments           */
 }      /* End namespace DD4hep               */
 #endif /* DD4HEP_DDCORE_ALIGNMENTSPRINTER_H  */
diff --git a/DDCore/include/DD4hep/AlignmentsProcessor.h b/DDCore/include/DD4hep/AlignmentsProcessor.h
index 4b1463fd6d0930b58e0aa893f97541a97fe8d582..725d0bc88cf7e451957103dd5dede1b76f742045 100644
--- a/DDCore/include/DD4hep/AlignmentsProcessor.h
+++ b/DDCore/include/DD4hep/AlignmentsProcessor.h
@@ -40,30 +40,33 @@ namespace DD4hep {
      *   \ingroup DD4HEP_ALIGNMENTS
      */
     class AlignmentsProcessor :
-      public Alignment::Processor,
-      public Container::Processor,
-      public Geometry::DetElement::Processor
+      virtual public Alignment::Processor,
+      virtual public Container::Processor,
+      virtual public Geometry::DetElement::Processor
     {
-    protected:
+    public:
       /// Self type definition
-      typedef AlignmentsProcessor self_t;
+      typedef AlignmentsProcessor  self_type;
+      /// Pool definition
+      typedef UserPool             pool_type;
+    protected:
       /// Make DetElement type local
       typedef Geometry::DetElement DetElement;
       /// Reference to the user pool
-      UserPool* m_pool;
+      pool_type* m_pool;
     public:
       /// Initializing constructor
-      AlignmentsProcessor(UserPool* p) : m_pool(p) {}
+      AlignmentsProcessor(pool_type* p) : m_pool(p) {}
       /// Default destructor
       virtual ~AlignmentsProcessor() = default;
       /// Set pool
-      void setPool(UserPool* value)  { m_pool = value; }
+      void setPool(pool_type* value)  { m_pool = value; }
       /// Callback to output alignments information
       virtual int operator()(Alignment cond);
       /// Container callback for object processing
       virtual int operator()(Container container);
       /// Callback to output alignments information of an entire DetElement
-      virtual int operator()(DetElement de);
+      virtual int processElement(DetElement de);
     };
 
     /// Generic Alignment object collector
@@ -72,7 +75,7 @@ namespace DD4hep {
      *   AlignmentsProcessor base class for further information.
      *
      */
-    class AlignmentsCollector : public AlignmentsProcessor  {
+    class AlignmentsCollector : virtual public AlignmentsProcessor  {
     public:
       /// Collection container
       std::vector<Alignment> alignments;
@@ -88,10 +91,10 @@ namespace DD4hep {
       }
       /// Container callback for object processing
       virtual int operator()(Container container)
-      {  return this->self_t::operator()(container);      }
+      {  return this->self_type::operator()(container);   }
       /// Callback to output alignments information of an entire DetElement
-      virtual int operator()(DetElement detector)
-      {  return this->self_t::operator()(detector);       }
+      virtual int processElement(DetElement detector)
+      {  return this->self_type::processElement(detector);    }
     };
     
   }    /* End namespace Alignments  */
diff --git a/DDCore/include/DD4hep/ConditionDerived.h b/DDCore/include/DD4hep/ConditionDerived.h
index af5426159a44a952e313a336d2fafa21f3afc595..e7b8095a94426ec38ffd6c32a0c7336e646e8780 100644
--- a/DDCore/include/DD4hep/ConditionDerived.h
+++ b/DDCore/include/DD4hep/ConditionDerived.h
@@ -206,6 +206,8 @@ namespace DD4hep {
     public:
       /// Initializing constructor
       DependencyBuilder(const ConditionKey& target, ConditionUpdateCall* call);
+      /// Initializing constructor
+      DependencyBuilder(const ConditionKey& target, ConditionUpdateCall* call, Geometry::DetElement de);
       /// Default destructor
       virtual ~DependencyBuilder();
       /// Access underlying object directly
diff --git a/DDCore/include/DD4hep/Conditions.h b/DDCore/include/DD4hep/Conditions.h
index bb0e9e97123ed46fe096abc65a8f2a02dd72314a..97e71a8dc0014ca0c0bfa2d45c8d7319b7bcb811 100644
--- a/DDCore/include/DD4hep/Conditions.h
+++ b/DDCore/include/DD4hep/Conditions.h
@@ -148,8 +148,6 @@ namespace DD4hep {
       const iov_type& iov()  const;
 
       /** Direct data items in string form */
-      /// Access the name of the condition
-      const std::string& name()  const;
       /// Access the type field of the condition
       const std::string& type()  const;
       /// Access the comment field of the condition
diff --git a/DDCore/include/DD4hep/ConditionsPrinter.h b/DDCore/include/DD4hep/ConditionsPrinter.h
index 4b7b9742f728de1580794999d1c92b51b24d8baf..24979431ab98542139c87c643e0c22b9e60be8e8 100644
--- a/DDCore/include/DD4hep/ConditionsPrinter.h
+++ b/DDCore/include/DD4hep/ConditionsPrinter.h
@@ -35,9 +35,12 @@ namespace DD4hep {
      */
     class ConditionsPrinter : public ConditionsProcessor  {
     public:
+      /// Printer name. Want to know who is printing what
       std::string   name;
+      /// Printout prefix
       std::string   prefix;
     protected:
+      /// Printout processing and customization flag
       int           m_flag;
 
     public:
@@ -55,8 +58,8 @@ namespace DD4hep {
       /// Container callback for object processing
       virtual int operator()(Container container);
       /// Callback to output conditions information of an entire DetElement
-      virtual int operator()(DetElement de)
-      {  return this->ConditionsProcessor::operator()(de);         }
+      virtual int processElement(DetElement de)
+      {  return this->ConditionsProcessor::processElement(de);     }
     };
 
   }    /* End namespace Conditions           */
diff --git a/DDCore/include/DD4hep/ConditionsProcessor.h b/DDCore/include/DD4hep/ConditionsProcessor.h
index 1a4c96e48ad538b88a2a86935a4a42b501fd6275..cc46848e6f4cd634f2fc2c01555386a8e0a5b02e 100644
--- a/DDCore/include/DD4hep/ConditionsProcessor.h
+++ b/DDCore/include/DD4hep/ConditionsProcessor.h
@@ -40,30 +40,33 @@ namespace DD4hep {
      *   \ingroup DD4HEP_CONDITIONS
      */
     class ConditionsProcessor :
-      public Condition::Processor,
-      public Container::Processor,
-      public Geometry::DetElement::Processor
+      virtual public Condition::Processor,
+      virtual public Container::Processor,
+      virtual public Geometry::DetElement::Processor
     {
-    protected:
+    public:
       /// Self type definition
-      typedef ConditionsProcessor self_t;
+      typedef ConditionsProcessor  self_type;
+      /// Pool definition
+      typedef UserPool             pool_type;
+    protected:
       /// Make DetElement type local
       typedef Geometry::DetElement DetElement;
       /// Reference to the user pool
-      UserPool* m_pool;
+      pool_type* m_pool;
     public:
       /// Initializing constructor
-      ConditionsProcessor(UserPool* p) : m_pool(p) {}
+      ConditionsProcessor(pool_type* p) : m_pool(p) {}
       /// Default destructor
       virtual ~ConditionsProcessor() = default;
       /// Set pool
-      void setPool(UserPool* value)  { m_pool = value; }
+      void setPool(pool_type* value)  { m_pool = value; }
       /// Callback to output conditions information
       virtual int operator()(Condition cond);
       /// Container callback for object processing
       virtual int operator()(Container container);
       /// Callback to output conditions information of an entire DetElement
-      virtual int operator()(DetElement de);
+      virtual int processElement(DetElement de);
     };
 
     /// Generic Condition object collector
@@ -72,7 +75,7 @@ namespace DD4hep {
      *   ConditionsProcessor base class for further information.
      *
      */
-    class ConditionsCollector : public ConditionsProcessor  {
+    class ConditionsCollector : virtual public ConditionsProcessor  {
     public:
       /// Collection container
       std::vector<Condition> conditions;
@@ -88,10 +91,10 @@ namespace DD4hep {
       }
       /// Container callback for object processing
       virtual int operator()(Container container)
-      {  return this->self_t::operator()(container);      }
+      {  return this->self_type::operator()(container);   }
       /// Callback to output conditions information of an entire DetElement
-      virtual int operator()(DetElement detector)
-      {  return this->self_t::operator()(detector);       }
+      virtual int processElement(DetElement detector)
+      {  return this->self_type::processElement(detector);    }
     };
   }    /* End namespace Conditions  */
 }      /* End namespace DD4hep      */
diff --git a/DDCore/include/DD4hep/Detector.h b/DDCore/include/DD4hep/Detector.h
index af37ace0cc83275151b90ac07c0b65a5e7cdef9a..b913261ab484ee66b7237f82b6929eba5f73836c 100644
--- a/DDCore/include/DD4hep/Detector.h
+++ b/DDCore/include/DD4hep/Detector.h
@@ -182,9 +182,9 @@ namespace DD4hep {
         /// Default constructor
         Processor();
         /// Default destructor
-        virtual ~Processor() = default;
+        virtual ~Processor();
         /// Container callback for object processing
-        virtual int operator()(DetElement detector) = 0;
+        virtual int processElement(DetElement detector) = 0;
       };
 
       /// Internal object type
diff --git a/DDCore/include/DD4hep/PluginCreators.h b/DDCore/include/DD4hep/PluginCreators.h
index 0ed1af10f3d9ee713e14d2bd20d360c0920fcfa5..dcb5fced92bac1a63ad15c1409b34fefc43bfb21 100644
--- a/DDCore/include/DD4hep/PluginCreators.h
+++ b/DDCore/include/DD4hep/PluginCreators.h
@@ -39,6 +39,7 @@ namespace DD4hep {
   void* createPlugin(const std::string& factory, Geometry::LCDD& lcdd, void* (*cast)(void*));
   void* createPlugin(const std::string& factory, Geometry::LCDD& lcdd, const std::string& arg, void* (*cast)(void*));
   void* createPlugin(const std::string& factory, Geometry::LCDD& lcdd, int argc, char** argv, void* (*cast)(void*));
+  void* createProcessor(Geometry::LCDD& lcdd, int argc, char** argv, void* (*cast)(void*));
 
   /// Handler for factories of type: ConstructionFactory with casted return type
   template <typename T> T* createPlugin(const std::string& factory, Geometry::LCDD& lcdd)   {
@@ -59,6 +60,20 @@ namespace DD4hep {
     return (plugin_t*)createPlugin(factory, lcdd, argc, (char**)argv, __cast::cast);
   }
 
+  /// Handler for factories of type: ConstructionFactory with casted return type
+  template <typename T> T* createProcessor(Geometry::LCDD& lcdd, int argc, char** argv)   {
+    typedef T plugin_t;
+    struct __cast{ static void* cast(void* p) { return &dynamic_cast<plugin_t&>(*(plugin_t*)p); } };
+    return (plugin_t*)createProcessor(lcdd, argc, argv, __cast::cast);
+  }
+
+  /// Handler for factories of type: ConstructionFactory with casted return type
+  template <typename T> T* createProcessor(Geometry::LCDD& lcdd, int argc, const void** argv)   {
+    typedef T plugin_t;
+    struct __cast{ static void* cast(void* p) { return &dynamic_cast<plugin_t&>(*(plugin_t*)p); } };
+    return (plugin_t*)createProcessor(lcdd, argc, (char**)argv, __cast::cast);
+  }
+
 } /* End namespace DD4hep      */
 
 #endif // DD4HEP_PLUGINCREATORS_H
diff --git a/DDCore/include/DD4hep/PluginTester.h b/DDCore/include/DD4hep/PluginTester.h
new file mode 100644
index 0000000000000000000000000000000000000000..34ed9d37b17307ec69e1080d98d92ba78076df6c
--- /dev/null
+++ b/DDCore/include/DD4hep/PluginTester.h
@@ -0,0 +1,85 @@
+//==========================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------------
+// 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   Markus Frank
+//  \date     2016-02-02
+//  \version  1.0
+//
+//==========================================================================
+#ifndef DD4HEP_PLUGINTESTER_H 
+#define DD4HEP_PLUGINTESTER_H 1
+
+// Framework includes
+
+// C/C++ include files
+#include <typeinfo>
+#include <string>
+#include <map>
+
+
+/// Namespace for the AIDA detector description toolkit
+namespace DD4hep {
+  class PluginTester  {
+  public:
+    /// Definition of the extension type
+    typedef std::pair<const std::type_info*,std::string> key_type;
+    typedef std::map<key_type, void*> Extensions;
+    /// Extensions destructor type
+    typedef void (*destruct_t)(void*);
+    /// Defintiion of the extension entry
+    struct Entry {
+      destruct_t destruct;
+      int id;
+    };
+    typedef std::map<const std::type_info*, Entry> ExtensionMap;
+
+    /// The extensions object
+    Extensions    extensions; //!
+    /// Pointer to the extension map
+    ExtensionMap* extensionMap; //!
+
+    /// Function to be passed as dtor if object should NOT be deleted!
+    static void _noDelete(void*) {}
+
+    /// Templated destructor function
+    template <typename T> static void _delete(void* ptr) {
+      delete (T*) (ptr);
+    }
+    
+    /// Add an extension object to the detector element
+    void* addExtension(void* ptr, const std::string& name, const std::type_info& info, destruct_t dtor);
+    /// Access an existing extension object from the detector element
+    void* extension(const std::string& name, const std::type_info& info, bool alert) const;
+    /// Remove an existing extension object from the instance
+    void* removeExtension(const std::string& name, const std::type_info& info, bool destroy);
+
+  public:
+    /// Default constructor
+    PluginTester();
+    /// Copy constructor
+    PluginTester(const PluginTester& copy) = delete;
+    /// Default destructor
+    virtual ~PluginTester();
+    /// Assignment operator
+    PluginTester& operator=(const PluginTester& copy) = delete;
+    /// Clear all extensions
+    void clear(bool destroy=true);
+    template<typename Q> Q* addExtension(Q* ptr, const std::string& name)  {
+      return (Q*)addExtension(ptr, name, typeid(Q), _delete<Q>);
+    }
+    template<typename Q> Q* extension(const std::string& name, bool alert=true)  {
+      return (Q*)extension(name, typeid(Q), alert);
+    }
+    template<typename Q> Q* removeExtension(const std::string& name, bool destroy=true)  {
+      return (Q*)removeExtension(name, typeid(Q), destroy);
+    }
+  };
+  
+} /* End namespace DD4hep             */
+#endif  // DD4HEP_PLUGINTESTER_H
diff --git a/DDCore/include/DD4hep/Printout.h b/DDCore/include/DD4hep/Printout.h
index a754e905b85d5b379bd0650bdbd44911be29a8d3..85b2369333f1f612ed76d5cba7a5df151a4d9652 100644
--- a/DDCore/include/DD4hep/Printout.h
+++ b/DDCore/include/DD4hep/Printout.h
@@ -59,7 +59,16 @@ namespace DD4hep {
   typedef size_t (*output_function1_t)(void*, PrintLevel severity, const char*, const char*);
   typedef size_t (*output_function2_t)(void*, PrintLevel severity, const char*, const char*, va_list& args);
 
-  /** Calls the display action
+  /// Helper function to serialize argument list to a single string
+  /**
+   *  @arg argc       [int,read-only]      Number of arguments.
+   *  @arg argv       [char**,read-only]   Argument strings
+   *  @return String containing the concatenated arguments
+   */
+  std::string arguments(int argc, char** argv);
+  
+  /// Calls the display action with a given severity level
+  /**
    *  @arg severity   [int,read-only]      Display severity flag (see enum)
    *  @arg src        [string,read-only]   Information source (component, etc.)
    *  @arg fmt        [string,read-only]   Format string for ellipsis args
@@ -67,7 +76,8 @@ namespace DD4hep {
    */
   int printout(PrintLevel severity, const char* src, const char* fmt, ...);
 
-  /** Calls the display action
+  /// Calls the display action with a given severity level
+  /**
    *  @arg severity   [int,read-only]      Display severity flag (see enum)
    *  @arg src        [string,read-only]   Information source (component, etc.)
    *  @arg fmt        [string,read-only]   Format string for ellipsis args
@@ -75,7 +85,8 @@ namespace DD4hep {
    */
   int printout(PrintLevel severity, const std::string& src, const char* fmt, ...);
 
-  /** Calls the display action
+  /// Calls the display action with a given severity level
+  /**
    *  @arg severity   [int,read-only]      Display severity flag (see enum)
    *  @arg src        [string,read-only]   Information source (component, etc.)
    *  @arg fmt        [string,read-only]   Format string for ellipsis args
@@ -83,7 +94,8 @@ namespace DD4hep {
    */
   int printout(PrintLevel severity, const std::string& src, const std::string& fmt, ...);
 
-  /** Calls the display action
+  /// Calls the display action with a given severity level
+  /**
    *  @arg severity   [int,read-only]      Display severity flag (see enum)
    *  @arg src        [string,read-only]   Information source (component, etc.)
    *  @arg fmt        [string,read-only]   Format string for ellipsis args
@@ -91,7 +103,8 @@ namespace DD4hep {
    */
   int printout(PrintLevel severity, const char* src, const std::string& fmt, ...);
 
-  /** Calls the display action
+  /// Calls the display action with a given severity level
+  /**
    *  @arg severity   [int,read-only]      Display severity flag (see enum)
    *  @arg src        [string,read-only]   Information source (component, etc.)
    *  @arg fmt        [string,read-only]   Format string for ellipsis args
@@ -100,7 +113,8 @@ namespace DD4hep {
    */
   int printout(PrintLevel severity, const char* src, const char* fmt, va_list& args);
 
-  /** Calls the display action
+  /// Calls the display action with a given severity level
+  /**
    *  @arg severity   [int,read-only]      Display severity flag (see enum)
    *  @arg src        [string,read-only]   Information source (component, etc.)
    *  @arg fmt        [string,read-only]   Format string for ellipsis args
@@ -109,7 +123,8 @@ namespace DD4hep {
    */
   int printout(PrintLevel severity, const std::string& src, const char* fmt, va_list& args);
 
-  /** Calls the display action
+  /// Calls the display action with a given severity level
+  /**
    *  @arg severity   [int,read-only]      Display severity flag (see enum)
    *  @arg src        [string,read-only]   Information source (component, etc.)
    *  @arg fmt        [string,read-only]   Format string for ellipsis args
@@ -118,7 +133,8 @@ namespace DD4hep {
    */
   int printout(PrintLevel severity, const std::string& src, const std::string& fmt, va_list& args);
 
-  /** Calls the display action
+  /// Calls the display action with a given severity level
+  /**
    *  @arg severity   [int,read-only]      Display severity flag (see enum)
    *  @arg src        [string,read-only]   Information source (component, etc.)
    *  @arg fmt        [string,read-only]   Format string for ellipsis args
@@ -127,51 +143,58 @@ namespace DD4hep {
    */
   int printout(PrintLevel severity, const char* src, const std::string& fmt, va_list& args);
 
-  /** Calls the display action with ERROR and throws an std::runtime_error exception
+  /// Calls the display action with ERROR and throws an std::runtime_error exception
+  /**
    *  @arg src        [string,read-only]   Information source (component, etc.)
    *  @arg fmt        [string,read-only]   Format string for ellipsis args
    *  @return Status code indicating success or failure
    */
-  void except(const std::string& src, const std::string& fmt, ...);
+  int except(const std::string& src, const std::string& fmt, ...);
 
-  /** Calls the display action with ERROR and throws an std::runtime_error exception
+  /// Calls the display action with ERROR and throws an std::runtime_error exception
+  /**
    *  @arg src        [string,read-only]   Information source (component, etc.)
    *  @arg fmt        [string,read-only]   Format string for ellipsis args
    *  @return Status code indicating success or failure
    */
-  void except(const char* src, const char* fmt, ...);
+  int except(const char* src, const char* fmt, ...);
 
-  /** Calls the display action with ERROR and throws an std::runtime_error exception
+  /// Calls the display action with ERROR and throws an std::runtime_error exception
+  /**
    *  @arg src        [string,read-only]   Information source (component, etc.)
    *  @arg fmt        [string,read-only]   Format string for ellipsis args
    *  @arg args       [ap_list,read-only]  List with variable number of arguments to fill format string.
    *  @return Status code indicating success or failure
    */
-  void except(const std::string& src, const std::string& fmt, va_list& args);
+  int except(const std::string& src, const std::string& fmt, va_list& args);
 
-  /** Calls the display action with ERROR and throws an std::runtime_error exception
+  /// Calls the display action with ERROR and throws an std::runtime_error exception
+  /**
    *  @arg src        [string,read-only]   Information source (component, etc.)
    *  @arg fmt        [string,read-only]   Format string for ellipsis args
    *  @arg args       [ap_list,read-only]  List with variable number of arguments to fill format string.
    *  @return Status code indicating success or failure
    */
-  void except(const char* src, const char* fmt, va_list& args);
+  int except(const char* src, const char* fmt, va_list& args);
 
-  /** Build formatted string
+  /// Build formatted string
+  /*
    *  @arg src        [string,read-only]   Information source (component, etc.)
    *  @arg fmt        [string,read-only]   Format string for ellipsis args
    *  @return Status code indicating success or failure
    */
   std::string format(const std::string& src, const std::string& fmt, ...);
 
-  /** Build exception string
+  /// Build exception string
+  /**
    *  @arg src        [string,read-only]   Information source (component, etc.)
    *  @arg fmt        [string,read-only]   Format string for ellipsis args
    *  @return Status code indicating success or failure
    */
   std::string format(const char* src, const char* fmt, ...);
 
-  /** Build formatted string
+  /// Build formatted string
+  /**
    *  @arg src        [string,read-only]   Information source (component, etc.)
    *  @arg fmt        [string,read-only]   Format string for ellipsis args
    *  @arg args       [ap_list,read-only]  List with variable number of arguments to fill format string.
@@ -179,7 +202,8 @@ namespace DD4hep {
    */
   std::string format(const std::string& src, const std::string& fmt, va_list& args);
 
-  /** Build exception string and throw std::runtime_error
+  /// Build formatted string
+  /**
    *  @arg src        [string,read-only]   Information source (component, etc.)
    *  @arg fmt        [string,read-only]   Format string for ellipsis args
    *  @arg args       [ap_list,read-only]  List with variable number of arguments to fill format string.
diff --git a/DDCore/include/DD4hep/Shapes.h b/DDCore/include/DD4hep/Shapes.h
index f416c4a3454432e4a4077aca0ff0d4a078d920ea..c0cad1cb2b01ed9cb835ce8fd4857bc4429d569e 100644
--- a/DDCore/include/DD4hep/Shapes.h
+++ b/DDCore/include/DD4hep/Shapes.h
@@ -90,6 +90,8 @@ namespace DD4hep {
 
       /// Access to shape name
       const char* name() const;
+      /// Access to shape type (The TClass name of the ROOT implementation)
+      const char* type() const;
       /// Auto conversion to underlying ROOT object
       operator T*() const {
         return this->m_element;
diff --git a/DDCore/include/DD4hep/objects/AlignmentsInterna.h b/DDCore/include/DD4hep/objects/AlignmentsInterna.h
index 4d266d70660b699e6761906bdd95416f942cdfcc..860d7b2df7a907d23d53a5fdf7eb5cd461cc6e52 100644
--- a/DDCore/include/DD4hep/objects/AlignmentsInterna.h
+++ b/DDCore/include/DD4hep/objects/AlignmentsInterna.h
@@ -80,7 +80,7 @@ namespace DD4hep {
       class AlignmentContainer;
       class AlignmentConditionObject;
       
-      /// The data class behind a alignments handle.
+      /// The data class behind an alignments handle.
       /**
        *  See AlignmentsInterna.cpp for the implementation.
        *
@@ -101,7 +101,7 @@ namespace DD4hep {
         void clear();
       };
 
-      /// The data class behind a alignments container handle.
+      /// The data class behind an alignments container handle.
       /**
        *  See AlignmentsInterna.cpp for the implementation.
        *
diff --git a/DDCore/src/AlignedVolumePrinter.cpp b/DDCore/src/AlignedVolumePrinter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8323ef3a4db3fc4b2ae81c2a8d85d5b768d85cce
--- /dev/null
+++ b/DDCore/src/AlignedVolumePrinter.cpp
@@ -0,0 +1,44 @@
+//==========================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------------
+// 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 includes
+#include "DD4hep/AlignmentsPrinter.h"
+#include "DD4hep/AlignedVolumePrinter.h"
+
+using std::string;
+using namespace DD4hep;
+using namespace DD4hep::Alignments;
+
+/// Initializing constructor
+AlignedVolumePrinter::AlignedVolumePrinter(const string& pref, int flg)
+  : AlignmentsProcessor(0), name("Alignment"), prefix(pref), m_flag(flg)
+{
+}
+
+/// Callback to output alignments information
+int AlignedVolumePrinter::operator()(Alignment a)    {
+  printAlignment(name, a);
+  return 1;
+}
+
+/// Container callback for object processing
+int AlignedVolumePrinter::operator()(Container container)   {
+  printContainer(name, container, m_pool);
+  return 1;
+}
+
+/// Callback to output alignments information of an entire DetElement
+int AlignedVolumePrinter::processElement(DetElement de)  {
+  printElementPlacement(name, de, m_pool);
+  return 1;
+}
diff --git a/DDCore/src/AlignmentData.cpp b/DDCore/src/AlignmentData.cpp
index 15d9a4d05c4c82c83733cfbf62aea247aab25854..0e212b0a811977406a6aaa51c47491f7fd3a196b 100644
--- a/DDCore/src/AlignmentData.cpp
+++ b/DDCore/src/AlignmentData.cpp
@@ -75,7 +75,8 @@ AlignmentData::AlignmentData()
 
 /// Copy constructor
 AlignmentData::AlignmentData(const AlignmentData& copy)
-  : delta(copy.delta), worldTrafo(copy.worldTrafo), detectorTrafo(copy.detectorTrafo),
+  : delta(copy.delta), worldTrafo(copy.worldTrafo), worldDelta(copy.worldDelta),
+    detectorTrafo(copy.detectorTrafo),
     nodes(copy.nodes), trToWorld(copy.trToWorld), detector(copy.detector),
     placement(copy.placement), flag(copy.flag), magic(magic_word())
 {
diff --git a/DDCore/src/Alignments.cpp b/DDCore/src/Alignments.cpp
index 21722e7c3d14b6d7a8924bbaf9fb9ec79fd18b34..1ef0b6afdbbd895cb3c5dab8e15672f216ef97b6 100644
--- a/DDCore/src/Alignments.cpp
+++ b/DDCore/src/Alignments.cpp
@@ -77,6 +77,11 @@ const DD4hep::IOV& AlignmentCondition::iov() const   {
   return *(access()->iovData());
 }
 
+/// Access the hash identifier
+AlignmentCondition::key_type AlignmentCondition::key() const   {
+  return access()->hash;
+}
+
 /// Data accessor for the use of decorators
 AlignmentCondition::Data& AlignmentCondition::data()              {
   Object* o = access();
diff --git a/DDCore/src/AlignmentsPrinter.cpp b/DDCore/src/AlignmentsPrinter.cpp
index cf177feba824fedfd869fb9c8a3465012535d569..08413dbe2c00b33cfc788c495a0e7ea839abc350 100644
--- a/DDCore/src/AlignmentsPrinter.cpp
+++ b/DDCore/src/AlignmentsPrinter.cpp
@@ -17,57 +17,246 @@
 #include "DD4hep/AlignmentsPrinter.h"
 #include "DD4hep/objects/AlignmentsInterna.h"
 
+// C/C++ include files
+#include <sstream>
+
+using std::string;
+using std::stringstream;
 using namespace DD4hep;
 using namespace DD4hep::Alignments;
 
 /// Initializing constructor
-AlignmentsPrinter::AlignmentsPrinter(const std::string& pref, int flg)
+AlignmentsPrinter::AlignmentsPrinter(const string& pref, int flg)
   : AlignmentsProcessor(0), name("Alignment"), prefix(pref), m_flag(flg)
 {
 }
 
 /// Callback to output alignments information
 int AlignmentsPrinter::operator()(Alignment a)    {
+  printAlignment(name, a);
+  return 1;
+}
+
+/// Container callback for object processing
+int AlignmentsPrinter::operator()(Container container)   {
+  printContainer(name, container, m_pool);
+  return 1;
+}
+
+/// Callback to output alignments information of an entire DetElement
+int AlignmentsPrinter::processElement(DetElement de)  {
+  printElement(name, de, m_pool);
+  return 1;
+}
+
+
+/// Default printout of an alignment entry
+void DD4hep::Alignments::printAlignment(const string& prefix, Alignment a)   {
   if ( a.isValid() )   {
-    printout(INFO,name,"++ %s%s [%p]",prefix.c_str(),a.name(),a.ptr());
-    const Alignments::Delta& D = a.data().delta;
-    std::string new_prefix = prefix;
+    const Alignment::Data& data = a.data();
+    Conditions::Condition  cond = data.condition;
+    const Delta& D = data.delta;
+    string new_prefix = prefix;
     new_prefix.assign(prefix.length(),' ');
-    printout(INFO,name,"++ %s \tPath:%s",
-             new_prefix.c_str(), a.name());
-    printout(INFO,name,"++ %s \tData:(%11s-%8s-%5s) Cond:%p 'Alignment'",
+    printout(INFO,prefix,"++ %s \tPath:%s [%p] Typ:%s",
+             new_prefix.c_str(), cond.name(), a.ptr(),
+             typeName(typeid(*(a.ptr()))).c_str());
+    printout(INFO,prefix,"++ %s \tData:(%11s-%8s-%5s)",
              new_prefix.c_str(), 
              D.hasTranslation() ? "Translation" : "",
              D.hasRotation() ? "Rotation" : "",
-             D.hasPivot() ? "Pivot" : "",
-             a.data().hasCondition() ? a.data().condition.ptr() : 0);
+             D.hasPivot() ? "Pivot" : "");
+    printf("WorldTrafo: "); data.worldTrafo.Print();
+    printf("DetTrafo:   "); data.detectorTrafo.Print();
   }
-  return 1;
 }
 
-/// Container callback for object processing
-int AlignmentsPrinter::operator()(Container container)   {
-  if ( m_pool )  {
-    printout(INFO,name,"++ Alignments of DE %s [%d entries]",
-             container->detector.path().c_str(), int(container.keys().size()));
+/// Default printout of an container entry
+void DD4hep::Alignments::printContainer(const string& prefix, Container container, UserPool* pool)   {
+  string tag = prefix+"Cont";
+  if ( pool )  {
     for(const auto& k : container.keys() )  {
       try {
-        Alignment align = container.get(k.first,*m_pool);
-        std::string an = align.name();
-        std::string cn = an.substr(an.find('#')+1);
-        Alignment::key_type key = hash32(cn);
-        printout(INFO,name,"++ %s %s %s [%08X] -> %s [%08X]",
-                 prefix.c_str(), "Alignment:", an.c_str(), key==k.first ? key : k.first,
-                 align.name(), k.second.first);
-        (*this)(align);
+        Alignment align = container.get(k.first,*pool);
+        printout(INFO,tag,"++ %s Alignment [%08X] -> [%08X] %s",
+                 prefix.c_str(), k.first, k.second.first, k.second.second.c_str());
+        printAlignment(prefix,align);
       }
       catch(...)  {
-        printout(ERROR,name,"++ %s %s [%08X] -> [%08X]",
+        printout(ERROR,tag,"++ %s %s [%08X] -> [%08X]",
                  prefix.c_str(), "FAILED Alignment:", k.first, k.second.first);
       }
     }
-    return 1;
+    return;
+  }
+  except(tag,"Cannot dump alignments container without valid user-pool.");
+}
+
+/// Default printout of a detector element entry
+void DD4hep::Alignments::printElement(const string& prefix, DetElement de, UserPool* pool)   {
+  string tag = prefix+"Element";
+  if ( de.isValid() )  {
+    if ( pool )  {
+      DetAlign  a(de);
+      Container c = a.alignments();
+      printout(INFO,tag,"++ Alignments of DE %s [%d entries]",
+               de.path().c_str(), int(c.keys().size()));
+      printContainer(prefix, c, pool);
+      return;
+    }
+    except(tag,"Cannot process DetElement alignments from '%s' without valid user-pool",de.name());
+  }
+  except(tag,"Cannot process alignments of an invalid detector element");
+}
+
+
+#include "TClass.h"
+#include "DD4hep/ToStream.h"
+static string replace_all(const string& in, const string& from, const string& to)  {
+  string res = in;
+  size_t idx;
+  while( string::npos != (idx=res.find(from)) )
+    res.replace(idx,from.length(),to);
+  return res;
+}
+static string _transformPoint2World(const Alignment::Data& data, const Position& local)  {
+  char text[256];
+  Position world = data.localToWorld(local);
+  ::snprintf(text,sizeof(text),"Local: (%7.3f , %7.3f , %7.3f )  -- > World:  (%7.3f , %7.3f , %7.3f )",
+             local.x(), local.y(), local.z(), world.x(), world.y(), world.z());
+  return text;
+}
+
+static string _transformPoint2Detector(const Alignment::Data& data, const Position& local)  {
+  char text[256];
+  Position world = data.localToDetector(local);
+  ::snprintf(text,sizeof(text),"Local: (%7.3f , %7.3f , %7.3f )  -- > Parent: (%7.3f , %7.3f , %7.3f )",
+             local.x(), local.y(), local.z(), world.x(), world.y(), world.z());
+  return text;
+}
+
+static void printAlignmentEx(const string& prefix, const string& opt, DetElement de, Alignment alignment)  {
+  using Geometry::Box;
+  DetAlign      a(de);
+  const string& tag = prefix;
+  const Alignment::Data& align_data = alignment.data();
+  Conditions::Condition  align_cond = align_data.condition;
+  const Delta& align_delta = align_data.delta;
+  string par = de.parent().isValid() ? de.parent().path() : string();
+  Box bbox = de.placement().volume().solid();
+  /// The edge positions of the bounding box:
+  Position p1( bbox.x(), bbox.y(), bbox.z());
+  Position p2( bbox.x(),-bbox.y(), bbox.z());
+  Position p3(-bbox.x(), bbox.y(), bbox.z());
+  Position p4(-bbox.x(),-bbox.y(), bbox.z());
+  Position p5( bbox.x(), bbox.y(),-bbox.z());
+  Position p6( bbox.x(),-bbox.y(),-bbox.z());
+  Position p7(-bbox.x(), bbox.y(),-bbox.z());
+  Position p8(-bbox.x(),-bbox.y(),-bbox.z());
+
+  if ( align_cond.isValid() )  {
+    printout(INFO,tag,"++ %s DATA: (%11s-%8s-%5s) %p IOV:%s", opt.c_str(), 
+             align_delta.hasTranslation() ? "Translation" : "",
+             align_delta.hasRotation() ? "Rotation" : "",
+             align_delta.hasPivot() ? "Pivot" : "",
+             alignment.ptr(),
+             align_cond.iov().str().c_str());
+  }
+  else  {
+    printout(INFO,tag,"++ %s DATA: (%11s-%8s-%5s) %p", opt.c_str(), 
+             align_delta.hasTranslation() ? "Translation" : "",
+             align_delta.hasRotation() ? "Rotation" : "",
+             align_delta.hasPivot() ? "Pivot" : "",
+             alignment.ptr());
+  }
+  if ( align_delta.hasTranslation() )  {
+    stringstream str;
+    Utils::toStream(align_delta.translation, str);
+    printout(INFO,tag,"++ %s DELTA Translation: %s", opt.c_str(), replace_all(str.str(),"\n","").c_str());
+  }
+  if ( align_delta.hasPivot() )  {
+    stringstream str;
+    Utils::toStream(align_delta.pivot, str);
+    string res = replace_all(str.str(),"\n","");
+    res = "( "+replace_all(res,"  "," , ")+" )";
+    printout(INFO,tag,"++ %s DELTA Pivot:       %s", opt.c_str(), res.c_str());
+  }
+  if ( align_delta.hasRotation() )  {
+    stringstream str;
+    Utils::toStream(align_delta.rotation, str);
+    printout(INFO,tag,"++ %s DELTA Rotation:    %s", opt.c_str(), replace_all(str.str(),"\n","").c_str());
+  }
+  printf("%s %s WorldTrafo (to %s): ",opt.c_str(), tag.c_str(), de.world().path().c_str());
+  align_data.worldTrafo.Print();
+  printf("%s %s DetTrafo (to %s): ",opt.c_str(), tag.c_str(), par.c_str());
+  align_data.detectorTrafo.Print();
+
+  printout(INFO,tag,"++ %s: P1(x,y,z) %s", opt.c_str(), _transformPoint2World(align_data, p1).c_str());
+  printout(INFO,tag,"++ %s: P2(x,y,z) %s", opt.c_str(), _transformPoint2World(align_data, p2).c_str());
+  printout(INFO,tag,"++ %s: P3(x,y,z) %s", opt.c_str(), _transformPoint2World(align_data, p3).c_str());
+  printout(INFO,tag,"++ %s: P4(x,y,z) %s", opt.c_str(), _transformPoint2World(align_data, p4).c_str());
+  printout(INFO,tag,"++ %s: P5(x,y,z) %s", opt.c_str(), _transformPoint2World(align_data, p5).c_str());
+  printout(INFO,tag,"++ %s: P6(x,y,z) %s", opt.c_str(), _transformPoint2World(align_data, p6).c_str());
+  printout(INFO,tag,"++ %s: P7(x,y,z) %s", opt.c_str(), _transformPoint2World(align_data, p7).c_str());
+  printout(INFO,tag,"++ %s: P8(x,y,z) %s", opt.c_str(), _transformPoint2World(align_data, p8).c_str());
+
+  printout(INFO,tag,"++ %s: P1(x,y,z) %s", opt.c_str(), _transformPoint2Detector(align_data, p1).c_str());
+  printout(INFO,tag,"++ %s: P2(x,y,z) %s", opt.c_str(), _transformPoint2Detector(align_data, p2).c_str());
+  printout(INFO,tag,"++ %s: P3(x,y,z) %s", opt.c_str(), _transformPoint2Detector(align_data, p3).c_str());
+  printout(INFO,tag,"++ %s: P4(x,y,z) %s", opt.c_str(), _transformPoint2Detector(align_data, p4).c_str());
+  printout(INFO,tag,"++ %s: P5(x,y,z) %s", opt.c_str(), _transformPoint2Detector(align_data, p5).c_str());
+  printout(INFO,tag,"++ %s: P6(x,y,z) %s", opt.c_str(), _transformPoint2Detector(align_data, p6).c_str());
+  printout(INFO,tag,"++ %s: P7(x,y,z) %s", opt.c_str(), _transformPoint2Detector(align_data, p7).c_str());
+  printout(INFO,tag,"++ %s: P8(x,y,z) %s", opt.c_str(), _transformPoint2Detector(align_data, p8).c_str());
+}
+
+/// PrintElement placement with/without alignment applied
+void DD4hep::Alignments::printElementPlacement(const string& prefix, DetElement de, UserPool* pool)   {
+  using Geometry::Box;
+  using Geometry::Solid;
+  using Geometry::Volume;
+  using Geometry::PlacedVolume;
+  string tag = prefix+"Element";
+  if ( de.isValid() )  {
+    if ( pool )  {
+      char text[132];
+      DetAlign     a(de);
+      Container    container = a.alignments();
+      Alignment    nominal = de.nominal();
+      Box bbox = de.placement().volume().solid();
+      ::memset(text,'=',sizeof(text));
+      text[sizeof(text)-1] = 0;
+      printout(INFO,tag,text);
+      printout(INFO,tag,"++ Alignments of DE %s [%d entries]",
+               de.path().c_str(), int(container.keys().size()));
+      printout(INFO,tag,"++ Volume: %s  BBox: x=%7.3f y=%7.3f z=%7.3f",bbox.type(),bbox.x(),bbox.y(),bbox.z());
+      printAlignmentEx(tag,"NOMINAL",de,nominal);
+
+      for(const auto& k : container.keys() )  {
+        try {
+          Alignment align = container.get(k.first,*pool);
+          const Alignment::Data& align_data = align.data();
+          Conditions::Condition  align_cond = align_data.condition;
+          if ( k.first != k.second.first )  {
+            printout(INFO,tag,"++ Alignment %p [%08X] -> [%08X] %s (SYNONYM) ignored.",
+                     a.ptr(), k.first, k.second.first, k.second.second.c_str());
+            continue;
+          }
+          printout(INFO,tag,"++ Alignment %p [%08X] -> [%08X] %s",
+                   a.ptr(), k.first, k.second.first, k.second.second.c_str());
+          if ( k.second.second != align_cond.name() )  {
+            printout(INFO,prefix,"++ \tPath:%s [%p]", align_cond.name(), a.ptr());
+          }
+          printAlignmentEx(tag,"ALIGNMENT",de,align);
+        }
+        catch(...)  {
+          printout(ERROR,tag,"++ %s %s [%08X] -> [%08X]",
+                   prefix.c_str(), "FAILED Alignment:", k.first, k.second.first);
+        }
+      }
+      return;
+    }
+    except(tag,"Cannot process DetElement alignments from '%s' without valid user-pool",de.name());
   }
-  except(name,"Cannot dump alignments container without user-pool.");
-  return 0;
+  except(tag,"Cannot process alignments of an invalid detector element");
 }
diff --git a/DDCore/src/AlignmentsProcessor.cpp b/DDCore/src/AlignmentsProcessor.cpp
index fde89123481908f1cb53ecf4ec6ca50ef0443f1c..78cc40a936e424ae478fc19086a5f723995cd70a 100644
--- a/DDCore/src/AlignmentsProcessor.cpp
+++ b/DDCore/src/AlignmentsProcessor.cpp
@@ -38,7 +38,7 @@ int AlignmentsProcessor::operator()(Container container)   {
 }
 
 /// Callback to output alignments information of an entire DetElement
-int AlignmentsProcessor::operator()(Geometry::DetElement de)    {
+int AlignmentsProcessor::processElement(Geometry::DetElement de)    {
   if ( de.isValid() )  {
     if ( m_pool )  {
       DetAlign align(de);
diff --git a/DDCore/src/ConditionDerived.cpp b/DDCore/src/ConditionDerived.cpp
index 53fed76a5dbfc8c816cb976a8b20a59c78ab849e..5be7a996f2607e1169ad3d47c5907e8f5026cf48 100644
--- a/DDCore/src/ConditionDerived.cpp
+++ b/DDCore/src/ConditionDerived.cpp
@@ -87,6 +87,13 @@ DependencyBuilder::DependencyBuilder(const ConditionKey& target, ConditionUpdate
 {
 }
 
+/// Initializing constructor
+DependencyBuilder::DependencyBuilder(const ConditionKey& target, ConditionUpdateCall* call, Geometry::DetElement de)
+  : m_dependency(new ConditionDependency(target,call))
+{
+  m_dependency->detector = de;
+}
+
 /// Default destructor
 DependencyBuilder::~DependencyBuilder()   {
   releasePtr(m_dependency);
diff --git a/DDCore/src/Conditions.cpp b/DDCore/src/Conditions.cpp
index 90d295e2ca952e7ecc372fa74dc373f0d3bf5ada..d7f46714815573a1215cb2cc617f7062db7af9fd 100644
--- a/DDCore/src/Conditions.cpp
+++ b/DDCore/src/Conditions.cpp
@@ -103,11 +103,6 @@ const DD4hep::IOV& Condition::iov() const   {
   return *(access()->iovData());
 }
 
-/// Access the name of the condition
-const string& Condition::name()  const   {
-  return access()->name;
-}
-
 /// Access the type field of the condition
 const string& Condition::type()  const   {
   return access()->type;
@@ -164,7 +159,7 @@ Condition& Condition::rebind()    {
 #endif
   o->data.fromString(o->value);
   printout(INFO,"Condition","+++ condition:%s rebinding value:%s",
-           name().c_str(), o->value.c_str());
+           name(), o->value.c_str());
   return *this;
 }
 
diff --git a/DDCore/src/ConditionsPrinter.cpp b/DDCore/src/ConditionsPrinter.cpp
index 9c2d65b1bcabaf5c6cc9ae1d50f7d1d540b19aa4..1253a6d55858b52de92fd657b705e8401f94d48e 100644
--- a/DDCore/src/ConditionsPrinter.cpp
+++ b/DDCore/src/ConditionsPrinter.cpp
@@ -15,6 +15,7 @@
 #include "DD4hep/Printout.h"
 #include "DD4hep/DetConditions.h"
 #include "DD4hep/ConditionsPrinter.h"
+#include "DD4hep/objects/ConditionsInterna.h"
 
 using namespace DD4hep;
 using namespace DD4hep::Conditions;
@@ -39,12 +40,12 @@ int ConditionsPrinter::operator()(Condition cond)    {
     std::string new_prefix = prefix;
     new_prefix.assign(prefix.length(),' ');
     printout(INFO,name,"++ %s \tPath:%s Key:%08X Type:%s",
-             new_prefix.c_str(), cond.name().c_str(), cond.key(), data.dataType().c_str());
+             new_prefix.c_str(), cond.name(), cond.key(), data.dataType().c_str());
     printout(INFO,name,"++ %s \tData:%s", new_prefix.c_str(), values.c_str());
   }
   return 1;
 }
-#include "DD4hep/objects/ConditionsInterna.h"
+
 /// Container callback for object processing
 int ConditionsPrinter::operator()(Container container)   {
   if ( m_pool )  {
@@ -52,11 +53,12 @@ int ConditionsPrinter::operator()(Container container)   {
              container->detector.path().c_str(), int(container.keys().size()));
     for(const auto& k : container.keys() )  {
       Condition c = container.get(k.first,*m_pool);
-      std::string cn = c.name().substr(c.name().find('#')+1);
+      std::string nam = c.name();
+      std::string cn = nam.substr(nam.find('#')+1);
       Condition::key_type key = ConditionKey::hashCode(cn);
       printout(INFO,name,"++ %s %s %s [%08X] -> %s [%08X]",
                prefix.c_str(), "Condition:", cn.c_str(), key==k.first ? key : k.first,
-               c.name().c_str(), k.second.first);
+               c.name(), k.second.first);
       (*this)(c);
     }
     return 1;
diff --git a/DDCore/src/ConditionsProcessor.cpp b/DDCore/src/ConditionsProcessor.cpp
index defc5c119005cea62a1144dc81fa081e995ce508..96770054b7e1fb1e49ce6c57263e17a4bac07eb1 100644
--- a/DDCore/src/ConditionsProcessor.cpp
+++ b/DDCore/src/ConditionsProcessor.cpp
@@ -38,7 +38,7 @@ int ConditionsProcessor::operator()(Container container)   {
 }
 
 /// Callback to output conditions information of an entire DetElement
-int ConditionsProcessor::operator()(DetElement de)    {
+int ConditionsProcessor::processElement(DetElement de)    {
   if ( de.isValid() )  {
     if ( m_pool )  {
       DetConditions conds(de);
diff --git a/DDCore/src/Detector.cpp b/DDCore/src/Detector.cpp
index 377f2e0bcb8111764994f6e9c4a2290595d10932..3712736cc7a3c882ef1415bc66327ad6f805d200 100644
--- a/DDCore/src/Detector.cpp
+++ b/DDCore/src/Detector.cpp
@@ -32,6 +32,10 @@ namespace {
 DetElement::Processor::Processor()   {
 }
 
+/// Default destructor
+DetElement::Processor::~Processor()   {
+}
+
 /// Clone constructor
 DetElement::DetElement(Object* det_data, const string& det_name, const string& det_type)
   : RefObject(det_data)
diff --git a/DDCore/src/ObjectExtensions.cpp b/DDCore/src/ObjectExtensions.cpp
index 182d8cefcdbabf88ced5e9ab98748afd34c39397..d1c9b825d5fa0ffacd0cf17fb208cac0b62dfede 100644
--- a/DDCore/src/ObjectExtensions.cpp
+++ b/DDCore/src/ObjectExtensions.cpp
@@ -1,4 +1,3 @@
-// $Id: $
 //==========================================================================
 //  AIDA Detector description implementation for LCD
 //--------------------------------------------------------------------------
diff --git a/DDCore/src/PluginCreators.cpp b/DDCore/src/PluginCreators.cpp
index d33a5d0beb55d0ba714ef0da020a1f1a3c5f6e54..257976c140e491e9ced633e09392b7c8ca8d383b 100644
--- a/DDCore/src/PluginCreators.cpp
+++ b/DDCore/src/PluginCreators.cpp
@@ -1,4 +1,3 @@
-// $Id$
 //==========================================================================
 //  AIDA Detector description implementation for LCD
 //--------------------------------------------------------------------------
@@ -18,19 +17,60 @@
 #include "DD4hep/Printout.h"
 #include "DD4hep/Plugins.h"
 
+// C/C++ include files
+#include <cstring>
+
 /// Namespace for the AIDA detector description toolkit
 namespace DD4hep {
 
   static inline ComponentCast* component(void* p) { return (ComponentCast*)p; }
 
-  void* createPlugin(const std::string& factory, Geometry::LCDD& lcdd, int argc, char** argv, void* (*cast)(void*))
-  {
+  void* createProcessor(Geometry::LCDD& lcdd, int argc, char** argv, void* (*cast)(void*))  {
+    void* processor = 0;
+    if ( argc < 2 )   {
+      except("createProcessor","++ DD4hep-plugins: No processor creator name given!");
+    }
+    for(int i=0; i<argc; ++i)  {
+      if ( 0 == ::strncmp(argv[i],"-processor",4) )  {
+        std::vector<char*> args;
+        std::string fac = argv[++i];
+        for(int j=++i; j<argc && argv[j] &&
+              0 != ::strncmp(argv[j],"-processor",4) &&
+              0 != ::strncmp(argv[j],"-end-processor",8); ++j)
+          args.push_back(argv[j]);
+        int num_arg = int(args.size());
+        args.push_back(0);
+        processor = PluginService::Create<void*>(fac,&lcdd,num_arg,&args[0]);
+        if ( !processor ) {
+          PluginDebug dbg;
+          processor = PluginService::Create<void*>(fac, &lcdd, argc, argv);
+          if ( !processor )  {
+            except("createProcessor","DD4hep-plugins: Failed to locate plugin %s. \n%s.",
+                   fac.c_str(), dbg.missingFactory(fac).c_str());
+          }
+        }
+        if ( cast )   {
+          void* obj = cast(processor);
+          if ( obj ) return obj;
+          invalidHandleAssignmentError(typeid(cast),typeid(*component(processor)));
+        }
+      }
+    }
+    if ( !processor )  {
+      except("createProcessor",
+             "DD4hep-plugins: Found arguments in plugin call, but could not make any sense of them: %s",
+             arguments(argc,argv).c_str());
+    }
+    return processor;
+  }
+
+  void* createPlugin(const std::string& factory, Geometry::LCDD& lcdd, int argc, char** argv, void* (*cast)(void*))  {
     void* object = PluginService::Create<void*>(factory, &lcdd, argc, argv);
     if ( !object ) {
       PluginDebug dbg;
       object = PluginService::Create<void*>(factory, &lcdd, argc, argv);
       if ( !object )  {
-        except("ConditionsManager","DD4hep: plugin: Failed to locate plugin %s. [%s].",
+        except("ConditionsManager","DD4hep-plugins: Failed to locate plugin %s. \n%s.",
                factory.c_str(), dbg.missingFactory(factory).c_str());
       }
     }
@@ -43,8 +83,7 @@ namespace DD4hep {
   }
 
   /// Handler for factories of type: ConstructionFactory
-  void* createPlugin(const std::string& factory, Geometry::LCDD& lcdd, void* (*cast)(void*))
-  {
+  void* createPlugin(const std::string& factory, Geometry::LCDD& lcdd, void* (*cast)(void*))  {
     char* argv[] = {0};
     int   argc = 0;
     return createPlugin(factory, lcdd, argc, argv, cast);
diff --git a/DDCore/src/PluginTester.cpp b/DDCore/src/PluginTester.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3810e0e50d9aea2f4009a9abfa1610ba8304d3ba
--- /dev/null
+++ b/DDCore/src/PluginTester.cpp
@@ -0,0 +1,111 @@
+//==========================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------------
+// 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 "DD4hep/PluginTester.h"
+#include "DD4hep/InstanceCount.h"
+#include "DD4hep/Primitives.h"
+
+// C/C++ include files
+#include <stdexcept>
+
+using namespace DD4hep;
+
+namespace {
+  static int s_extensionID = 0;
+  PluginTester::ExtensionMap* extensionContainer(const std::type_info& typ) {
+    static std::map<const std::type_info*, PluginTester::ExtensionMap> s_map;
+    return &s_map[&typ];
+  }
+}
+
+/// Default constructor
+PluginTester::PluginTester()    {
+  extensionMap = extensionContainer(typeid(*this));
+  InstanceCount::increment(this);
+}
+
+/// Default destructor
+PluginTester::~PluginTester()   {
+  clear();
+  InstanceCount::decrement(this);
+}
+
+/// Internal object destructor: release extension object(s)
+void PluginTester::clear(bool destroy)    {
+  for (Extensions::iterator i = extensions.begin(); i != extensions.end(); ++i) {
+    void* ptr = (*i).second;
+    if (ptr) {
+      ExtensionMap::iterator j = extensionMap->find((*i).first.first);
+      if (j != extensionMap->end()) {
+        Entry& e = (*j).second;
+        if (destroy && e.destruct)
+          (*(e.destruct))(ptr);
+      }
+    }
+  }
+  extensions.clear();
+}
+
+/// Add an extension object to the detector element
+void* PluginTester::addExtension(void* ptr, const std::string& name, const std::type_info& info, destruct_t dtor)  {
+  key_type key(&info,name);
+  Extensions::iterator j = extensions.find(key);
+  if (j == extensions.end()) {
+    ExtensionMap::iterator i = extensionMap->find(&info);
+    if (i == extensionMap->end()) {
+      Entry entry;
+      entry.destruct = dtor;
+      entry.id = ++s_extensionID;
+      extensionMap->insert(make_pair(&info, entry));
+    }
+    return extensions[key] = ptr;
+  }
+  throw std::runtime_error("DD4hep: addExtension: Object already has an extension "+name+
+                           " of type:" + typeName(info) + ".");
+}
+
+/// Remove an existing extension object from the instance
+void* PluginTester::removeExtension(const std::string& name, const std::type_info& info, bool destroy)  {
+  key_type key(&info,name);
+  Extensions::iterator j = extensions.find(key);
+  if (j != extensions.end()) {
+    void *ptr = (*j).second;
+    if ( destroy )  {
+      ExtensionMap::iterator i = extensionMap->find(&info);
+      if (i != extensionMap->end()) {
+        Entry& e = (*i).second;
+        (*e.destruct)((*j).second);
+        ptr = 0;
+      }
+    }
+    extensions.erase(j);
+    return ptr;
+  }
+  throw std::runtime_error("DD4hep: removeExtension: The object "+name+
+                           " of type " + typeName(info) + " is not present.");
+}
+
+/// Access an existing extension object from the detector element
+void* PluginTester::extension(const std::string& name, const std::type_info& info, bool alert) const {
+  key_type key(&info,name);
+  Extensions::const_iterator j = extensions.find(key);
+  if (j != extensions.end()) {
+    return (*j).second;
+  }
+  else if ( !alert )
+    return 0;
+  throw std::runtime_error("DD4hep: extension: Object has no extension "+name+
+                           " of type:" + typeName(info) + ".");
+}
+
diff --git a/DDCore/src/Plugins.cpp b/DDCore/src/Plugins.cpp
index 1ef820abfec5f847a43965917d532841a104823b..3bc5de85deb93fbbd5f4f8f3c639300aa8631405 100644
--- a/DDCore/src/Plugins.cpp
+++ b/DDCore/src/Plugins.cpp
@@ -58,7 +58,8 @@ PluginDebug::~PluginDebug() {
 string PluginDebug::missingFactory(const string& name) const {
   ROOT::Reflex::Scope factories = ROOT::Reflex::Scope::ByName(PLUGINSVC_FACTORY_NS);
   string factoryname = ROOT::Reflex::PluginService::FactoryName(name);
-  string msg = "\n\t\tNo factory with name " + factoryname + " for type " + name + " found.\n\t\tPlease check library load path.";
+  string msg = "\t\tNo factory with name " + factoryname + " for type " + name + " found.\n"
+    "\t\tPlease check library load path and/or plugin factory name.";
   return msg;
 }
 
@@ -144,8 +145,9 @@ PluginDebug::~PluginDebug() {
 
 /// Helper to check factory existence
 string PluginDebug::missingFactory(const string& name) const {
-  string factoryname = "??? Create("+name+")";
-  string msg = "\n\t\tNo factory with name " + factoryname + " for type " + name + " found.\n\t\tPlease check library load path.";
+  string factoryname = "Create("+name+")";
+  string msg = "\t\tNo factory with name " + factoryname + " for type " + name + " found.\n"
+    "\t\tPlease check library load path and/or plugin factory name.";
   return msg;
 }
 
diff --git a/DDCore/src/Printout.cpp b/DDCore/src/Printout.cpp
index 9b29dd48d454a2dafb1ceb1fab3771acb3d3a7ec..c342ba62eac741405f1f53db11911adbde58edee 100644
--- a/DDCore/src/Printout.cpp
+++ b/DDCore/src/Printout.cpp
@@ -17,6 +17,7 @@
 // C/C++ include files
 #include <cstring>
 #include <cstdarg>
+#include <sstream>
 #include <stdexcept>
 // Disable some diagnostics for ROOT dictionaries
 #ifdef __GNUC__
@@ -86,6 +87,21 @@ namespace {
   }
 }
 
+/// Helper function to serialize argument list to a single string
+/**
+ *  @arg argc       [int,read-only]      Number of arguments.
+ *  @arg argv       [char**,read-only]   Argument strings
+ *  @return String containing the concatenated arguments
+ */
+string DD4hep::arguments(int argc, char** argv)   {
+  stringstream str;
+  for(int i=0; i<argc;)  {
+    str << argv[i];
+    if ( ++i < argc ) str << " ";
+  }
+  return str.str();
+}  
+
 /** Calls the display action
  *  @arg severity   [int,read-only]      Display severity flag
  *  @arg src        [string,read-only]   Information source (component, etc.)
@@ -198,10 +214,10 @@ int DD4hep::printout(PrintLevel severity, const string& src, const string& fmt,
  *  @arg fmt        [string,read-only]   Format string for ellipsis args
  *  @return Status code indicating success or failure
  */
-void DD4hep::except(const string& src, const string& fmt, ...) {
+int DD4hep::except(const string& src, const string& fmt, ...) {
   va_list args;
   va_start(args, &fmt);
-  except(src.c_str(),fmt.c_str(), args);
+  return except(src.c_str(),fmt.c_str(), args);
 }
 
 /** Calls the display action with ERROR and throws an std::runtime_error exception
@@ -209,10 +225,10 @@ void DD4hep::except(const string& src, const string& fmt, ...) {
  *  @arg fmt        [string,read-only]   Format string for ellipsis args
  *  @return Status code indicating success or failure
  */
-void DD4hep::except(const char* src, const char* fmt, ...) {
+int DD4hep::except(const char* src, const char* fmt, ...) {
   va_list args;
   va_start(args, fmt);
-  except(src, fmt, args);
+  return except(src, fmt, args);
 }
 
 /** Calls the display action with ERROR and throws an std::runtime_error exception
@@ -221,7 +237,7 @@ void DD4hep::except(const char* src, const char* fmt, ...) {
  *  @arg args       [ap_list,read-only]  List with variable number of arguments to fill format string.
  *  @return Status code indicating success or failure
  */
-void DD4hep::except(const string& src, const string& fmt, va_list& args) {
+int DD4hep::except(const string& src, const string& fmt, va_list& args) {
   string msg = __format(fmt.c_str(), args);
   va_end(args);
   printout(ERROR, src.c_str(), "%s", msg.c_str());
@@ -235,8 +251,8 @@ void DD4hep::except(const string& src, const string& fmt, va_list& args) {
  *  @arg args       [ap_list,read-only]  List with variable number of arguments to fill format string.
  *  @return Status code indicating success or failure
  */
-void DD4hep::except(const char* src, const char* fmt, va_list& args) {
-  string msg = format(src, fmt, args);
+int DD4hep::except(const char* src, const char* fmt, va_list& args) {
+  string msg = __format(fmt, args);
   va_end(args);
   printout(ERROR, src, "%s", msg.c_str());
   // No return. Must call va_end here!
diff --git a/DDCore/src/Shapes.cpp b/DDCore/src/Shapes.cpp
index 8ef9f02e938115f3c5a8b564bb18cbc315c528de..67a5888124ad396f180ff48933e4d72c3bae30ea 100644
--- a/DDCore/src/Shapes.cpp
+++ b/DDCore/src/Shapes.cpp
@@ -1,4 +1,3 @@
-// $Id$
 //==========================================================================
 //  AIDA Detector description implementation for LCD
 //--------------------------------------------------------------------------
@@ -173,6 +172,14 @@ template <typename T> const char* Solid_type<T>::name() const {
   return this->ptr()->GetName();
 }
 
+/// Access to shape type (The TClass name of the ROOT implementation)
+template <typename T> const char* Solid_type<T>::type() const  {
+  if ( this->ptr() )  {
+    return this->ptr()->IsA()->GetName();
+  }
+  return "";
+}
+
 void Box::make(double x_val, double y_val, double z_val) {
   _assign(new TGeoBBox(x_val, y_val, z_val), "", "box", true);
 }
diff --git a/DDCore/src/plugins/StandardPlugins.cpp b/DDCore/src/plugins/StandardPlugins.cpp
index 32d993376fed9b649372584ac7c3a4f4cae2e0ed..2e546c197639d3e223dc3a70c01649f493695500 100644
--- a/DDCore/src/plugins/StandardPlugins.cpp
+++ b/DDCore/src/plugins/StandardPlugins.cpp
@@ -17,6 +17,7 @@
 #include "DD4hep/Factories.h"
 #include "DD4hep/Printout.h"
 #include "DD4hep/DetectorTools.h"
+#include "DD4hep/PluginCreators.h"
 #include "DD4hep/DD4hepRootPersistency.h"
 #include "../LCDDImp.h"
 
@@ -392,32 +393,6 @@ static long dump_volume_tree(LCDD& lcdd, int argc, char** argv) {
 }
 DECLARE_APPLY(DD4hepVolumeDump,dump_volume_tree)
 
-// ======================================================================================
-static DetElement::Processor* create_processor(LCDD& lcdd, int argc, char** argv)  {
-  DetElement::Processor* processor = 0;
-  if ( argc < 2 )   {
-    except("DetectorProcessor","++ No processor creator name given!");
-  }
-  for(int i=0; i<argc; ++i)  {
-    if ( 0 == ::strncmp(argv[i],"-processor",4) )  {
-      vector<char*> args;
-      string fac = argv[++i];
-      for(int j=++i; j<argc && argv[j] && 0 != ::strncmp(argv[j],"-processor",4); ++j)
-        args.push_back(argv[j]);
-      args.push_back(0);
-      DetElement::Processor* p = (DetElement::Processor*)
-        PluginService::Create<void*>(fac,&lcdd,int(args.size()),&args[0]);
-      processor = dynamic_cast<DetElement::Processor*>(p);
-      break;
-    }
-  }
-  if ( !processor )  {
-    except("DetectorProcessor",
-           "++ Found arguments in plugin call, but could not make any sense of them....");
-  }
-  return processor;
-}
-
 // ======================================================================================
 /// Plugin function: Apply arbitrary functor callback on the tree of detector elements
 /**
@@ -443,7 +418,7 @@ static int detelement_processor(LCDD& lcdd, int argc, char** argv)   {
     long process(DetElement de)   {
       if ( de.isValid() )  {
         int result = 1;
-        (*processor)(de);
+        (*processor).processElement(de);
         for (const auto& c : de.children() )  {
           int ret = process(c.second);
           if ( 1 != ret )  {
@@ -458,14 +433,15 @@ static int detelement_processor(LCDD& lcdd, int argc, char** argv)   {
     }
   };
   DetElement det = lcdd.world();
-  DetElement::Processor* processor = create_processor(lcdd, argc, argv);
+  DetElement::Processor* proc =
+    DD4hep::createProcessor<DetElement::Processor>(lcdd, argc, argv);
   for(int i=0, num=std::min(argc,3); i<num; ++i)  {
     if ( 0 == ::strncmp(argv[i],"-detector",4) )  {
       det = DetectorTools::findElement(lcdd, argv[++i]);
       break;
     }
   }
-  return Actor(processor).process(det);
+  return Actor(proc).process(det);
 }
 DECLARE_APPLY(DD4hep_DetElementProcessor,detelement_processor)
 
@@ -608,31 +584,15 @@ DECLARE_APPLY(DD4hepDetectorTypes,detectortype_cache)
 typedef SurfaceInstaller TestSurfacesPlugin;
 DECLARE_SURFACE_INSTALLER(TestSurfaces,TestSurfacesPlugin)
 
-/// Basic entry point to instantiate the basic DD4hep conditions/alignmants printer
-/**
- *  Factory: DD4hepConditionsPrinter, DD4hepAlignmentsPrinter 
- *
- *  \author  M.Frank
- *  \version 1.0
- *  \date    17/11/2016
- */
-namespace  {
-  template <typename PRINTER>
-  void* create_printer(Geometry::LCDD& /* lcdd */, int argc,char** argv)  {
-    string prefix = "";
-    int flags = 0;
-    for(int i=0; i<argc && argv[i]; ++i)  {
-      if ( 0 == ::strncmp("-prefix",argv[i],4) )
-        prefix = argv[++i];
-      else if ( 0 == ::strncmp("-flags",argv[i],2) )
-        flags = ::atol(argv[++i]);
-    }
-    if ( flags )
-      return (void*)new PRINTER(prefix,flags);
-    return (void*)new PRINTER(prefix);
+#include "DD4hep/PluginTester.h"
+static long install_plugin_tester(LCDD& lcdd, int , char** ) {
+  PluginTester* test = lcdd.extension<PluginTester>(false);
+  if ( !test )  {
+    lcdd.addExtension<PluginTester>(new PluginTester());
+    printout(INFO,"PluginTester",
+             "+++ Successfully installed PluginTester instance to LCDD.");
   }
+  return 1;
 }
-#include "DD4hep/ConditionsPrinter.h"
-DECLARE_LCDD_CONSTRUCTOR(DD4hepConditionsPrinter,create_printer<Conditions::ConditionsPrinter>)
-#include "DD4hep/AlignmentsPrinter.h"
-DECLARE_LCDD_CONSTRUCTOR(DD4hepAlignmentsPrinter,create_printer<Alignments::AlignmentsPrinter>)
+DECLARE_APPLY(DD4hepPluginTester,install_plugin_tester)
+
diff --git a/DDDB/src/DDDBConditionPrinter.cpp b/DDDB/src/DDDBConditionPrinter.cpp
index 573ee61f04e286669f1d1217b4ab3f8baeaca9c8..12dd05fa7d2b3d25e3c32d2f5eaaf93d1e8b3116 100644
--- a/DDDB/src/DDDBConditionPrinter.cpp
+++ b/DDDB/src/DDDBConditionPrinter.cpp
@@ -89,7 +89,7 @@ int ConditionPrinter::operator()(Condition cond)    {
     new_prefix.assign(m_prefix.length(),' ');
     printout(INFO,"Condition","++ %s Path:%s Class:%d [%s]",
              m_prefix.c_str(),
-             cond.name().c_str(),
+             cond.name(),
              data.classID, 
              cond.data().dataType().c_str());
     if ( !data.params.empty() )  {
diff --git a/examples/AlignDet/src/Telescope_geo.cpp b/examples/AlignDet/src/Telescope_geo.cpp
index e9094a09ab82d87b81ac9e3a3a7e180e998c0f1d..a882e63000f0c93b3c48b27fb85fcab284a49e06 100644
--- a/examples/AlignDet/src/Telescope_geo.cpp
+++ b/examples/AlignDet/src/Telescope_geo.cpp
@@ -46,12 +46,14 @@ static Ref_t create_element(LCDD& lcdd, xml_h e, SensitiveDetector sd)  {
     Volume modvol(_toString(mod.id(),"module_%d"), box, air);
     modvol.setVisAttributes(lcdd.visAttributes(mod.visStr()));
 
+    DetElement sens_det(mod_det,"sensor",x_det.id());
     box = Box(pitch*noPixX/2e0, pitch*noPixY/2e0, sens.thickness()/2e0);
     vol = Volume(_toString(mod.id(),"sensor_%d"), box, air);
     vol.setSensitiveDetector(sd);
     vol.setVisAttributes(lcdd.visAttributes(sens.visStr()));
     phv = modvol.placeVolume(vol, Position(0, 0, -mod_thick/2e0+sens.thickness()/2e0));
     phv.addPhysVolID("sensor",1);
+    sens_det.setPlacement(phv);
 
     box = Box(pitch*noPixX/2e0, pitch*noPixY/2e0, chip.thickness()/2e0);
     vol = Volume(_toString(mod.id(),"chip_%d"), box, air);
diff --git a/examples/Conditions/data/Modules_run-1000...2000.xml b/examples/Conditions/data/Modules_run-1000...2000.xml
index 4534ee872b0d82cec40a25ec16d1924cd6dfdbfb..c9f74bc0edb1e88dcdd49b9ea6e2024338d69bcf 100644
--- a/examples/Conditions/data/Modules_run-1000...2000.xml
+++ b/examples/Conditions/data/Modules_run-1000...2000.xml
@@ -3,6 +3,13 @@
 <!--- Created : 2016-11-07   -->
 <conditions>
 
+  <detelement path="/world/Telescope">
+    <alignment>
+      <position x="0" y="0" z="5*cm"/>
+      <rotation x="0" y="0" z="0"/>     
+    </alignment>
+  </detelement>
+<!--
   <detelement path="/world/Telescope/module_1">
   </detelement>
 
@@ -38,13 +45,26 @@
       <rotation x="0" y="pi/2" z="0"/>     
     </alignment>
   </detelement>
-
+-->
   <detelement path="/world/Telescope/module_9" ref="default_module.xml">
     <alignment>
-      <position x="0" y="0"    z="290.0*mm"/>
-      <rotation x="0" y="pi/2" z="0"/>     
+      <position x="0" y="0" z="10.0*mm"/>
+      <rotation x="0" y="0" z="0"/>     
       <pivot    x="0" y="0" z="0"/>     
     </alignment>
+    <detelement path="/world/Telescope/module_9/sensor">
+      <alignment>
+        <position x="0" y="0" z="10.0*mm"/>
+        <!-- This is a point symmetry of 180 degree. 
+             Can be checked with the printer. 
+             x,y coordinates should invert sign.
+         -->
+        <rotation x="0" y="0" z="pi"/>     
+        <pivot    x="0" y="0" z="0"/>     
+      </alignment>
+    </detelement>
+<!--
+-->
   </detelement>
 
 </conditions>