diff --git a/DDCore/CMakeLists.txt b/DDCore/CMakeLists.txt
index c6519b47f032e09b10aecbb8deed41f20a97554b..990199c939f181949604429c5c91ebe55437cdc4 100644
--- a/DDCore/CMakeLists.txt
+++ b/DDCore/CMakeLists.txt
@@ -24,6 +24,7 @@ list(REMOVE_ITEM headers ${CMAKE_CURRENT_SOURCE_DIR}/include/DD4hep/DetFactoryHe
   ${CMAKE_CURRENT_SOURCE_DIR}/include/DD4hep/Factories.h
   ${CMAKE_CURRENT_SOURCE_DIR}/include/DD4hep/Plugins.h
   ${CMAKE_CURRENT_SOURCE_DIR}/include/DD4hep/IoStreams.h
+  ${CMAKE_CURRENT_SOURCE_DIR}/include/DD4hep/SurfaceInstaller.h
   )
 root_generate_dictionary( G__DD4hep ${headers} ${internal_headers} LINKDEF include/ROOT/LinkDef.h)
 list(APPEND sources G__DD4hep.cxx)
diff --git a/DDCore/include/DD4hep/Handle.h b/DDCore/include/DD4hep/Handle.h
index 7fc02ee25b9814d563af52ed763520dcc59b57d9..579a8281cc15fafc54efc0918001fd678c938a97 100644
--- a/DDCore/include/DD4hep/Handle.h
+++ b/DDCore/include/DD4hep/Handle.h
@@ -49,11 +49,16 @@ namespace DD4hep {
     /// String conversions: boolean value to string  \ingroup DD4HEP_GEOMETRY
     std::string _toString(bool value);
     /// String conversions: integer value to string  \ingroup DD4HEP_GEOMETRY
-    std::string _toString(int value);
+    std::string _toString(int value, const char* fmt = "%d");
     /// String conversions: float value to string  \ingroup DD4HEP_GEOMETRY
-    std::string _toString(float value);
+    std::string _toString(float value, const char* fmt = "%f");
     /// String conversions: double value to string  \ingroup DD4HEP_GEOMETRY
-    std::string _toString(double value);
+    std::string _toString(double value, const char* fmt = "%f");
+    /// Pointer to text conversion
+    std::string _ptrToString(const void* p, const char* fmt = "%p");
+    /// Format any pointer (64 bits) to string  \ingroup DD4HEP_XML
+    template <typename T> std::string _toString(const T* p, const char* fmt = "%p")   
+      {      return _ptrToString((void*)p, fmt);       }
 
     /// String conversions: string to boolean value  \ingroup DD4HEP_GEOMETRY
     bool _toBool(const std::string& value);
diff --git a/DDCore/include/DD4hep/Plugins.h b/DDCore/include/DD4hep/Plugins.h
index 24b01e9e505bb7d215e2f8190f32ad3573767834..54df4f3372f2281045a280106af2fe5ad50622bc 100644
--- a/DDCore/include/DD4hep/Plugins.h
+++ b/DDCore/include/DD4hep/Plugins.h
@@ -24,8 +24,9 @@ namespace DD4hep {
    *  for a limited code scope. Automatically back-adjusts the debug
    *  level at object destruction.
    *
-   *  @author  M.Frank
-   *  @version 1.0
+   *  \author  M.Frank
+   *  \version 1.0
+   *  \ingroup DD4HEP
    */
   struct PluginDebug {
     int m_debug;
diff --git a/DDCore/include/DD4hep/Shapes.h b/DDCore/include/DD4hep/Shapes.h
index 70c26f9c7abf7557e017614fe64d9c2c1370342d..7659b4e94c0d34013426058b3ea641667760bacb 100644
--- a/DDCore/include/DD4hep/Shapes.h
+++ b/DDCore/include/DD4hep/Shapes.h
@@ -108,9 +108,13 @@ namespace DD4hep {
       void make(const std::string& name, double x, double y, double z);
 
     public:
-      /// Constructor to be used when reading the already parsed box object
-      template <typename Q>
-      Box(const Handle<Q>& e)
+      /// Constructor to be used with an existing object
+      template <typename Q> Box(const Q* p)
+          : Solid_type<TGeoBBox>(p) {
+      }
+
+      /// Constructor to be used with an existing object
+      template <typename Q> Box(const Handle<Q>& e)
           : Solid_type<TGeoBBox>(e) {
       }
 
@@ -158,6 +162,11 @@ namespace DD4hep {
      */
     class Polycone: public Solid_type<TGeoPcon> {
     public:
+      /// Constructor to be used with an existing object
+      template <typename Q> Polycone(const Q* p)
+          : Solid_type<TGeoPcon>(p) {
+      }
+
       /// Constructor to be used when reading the already parsed polycone object
       template <typename Q> Polycone(const Handle<Q>& e)
           : Solid_type<TGeoPcon>(e) {
@@ -188,6 +197,11 @@ namespace DD4hep {
      */
     class ConeSegment: public Solid_type<TGeoConeSeg> {
     public:
+      /// Constructor to be used with an existing object
+      template <typename Q> ConeSegment(const Q* p)
+          : Solid_type<TGeoConeSeg>(p) {
+      }
+
       /// Constructor to be used when reading the already parsed ConeSegment object
       template <typename Q> ConeSegment(const Handle<Q>& e)
           : Solid_type<TGeoConeSeg>(e) {
@@ -236,6 +250,10 @@ namespace DD4hep {
       void make(const std::string& name, double rmin, double rmax, double z, double startPhi, double deltaPhi);
 
     public:
+      /// Constructor to be used with an existing object
+      template <typename Q> Tube(const Q* p) : Solid_type<MyConeSeg>(p) {
+      }
+
       /// Constructor to assign an object
       template <typename Q> Tube(const Handle<Q>& e)
           : Solid_type<MyConeSeg>(e) {
@@ -291,6 +309,10 @@ namespace DD4hep {
       void make(const std::string& name, double z, double rmin1, double rmax1, double rmin2, double rmax2);
 
     public:
+      /// Constructor to be used with an existing object
+      template <typename Q> Cone(const Q* p)
+          : Solid_type<TGeoCone>(p) {
+      }
 
       /// Constructor to be used when passing an already created object
       template <typename Q> Cone(const Handle<Q>& e)
@@ -324,7 +346,13 @@ namespace DD4hep {
     private:
       /// Internal helper method to support object construction
       void make(double pz, double py, double px, double pLTX);
+
     public:
+      /// Constructor to be used with an existing object
+      template <typename Q> Trap(const Q* p)
+          : Solid_type<TGeoTrap>(p) {
+      }
+
       /// Constructor to be used when passing an already created object
       Trap(const Trap& e)
           : Solid_type<TGeoTrap>(e) {
@@ -364,21 +392,31 @@ namespace DD4hep {
     private:
       /// Internal helper method to support object construction
       void make(double x1, double x2, double y1, double y2, double z);
+
     public:
+      /// Constructor to be used with an existing object
+      template <typename Q> Trapezoid(const Q* p)
+          : Solid_type<TGeoTrd2>(p) {
+      }
+
       /// Constructor to be used when passing an already created object
       Trapezoid(const Trapezoid& e)
           : Solid_type<TGeoTrd2>(e) {
       }
+
       /// Constructor to be used when passing an already created object
       template <typename Q> Trapezoid(const Handle<Q>& e)
           : Solid_type<TGeoTrd2>(e) {
       }
+
       /// Constructor to create a new anonymous object with attribute initialization
       Trapezoid(double x1, double x2, double y1, double y2, double z);
+
       /// Constructor to create a new anonymous object with attribute initialization
       template <typename X1,typename X2,typename Y1,typename Y2,typename Z>
 	Trapezoid(X1 x1, X2 x2, Y1 y1, Y2 y2, Z z)
       { make(_toDouble(x1),_toDouble(x2),_toDouble(y1),_toDouble(y2),_toDouble(z)); } 
+
       /// Set the Trapezoid dimensions
       Trapezoid& setDimensions(double x1, double x2, double y1, double y2, double z);
     };
@@ -397,21 +435,30 @@ namespace DD4hep {
       /// Internal helper method to support object construction
       void make(double r, double rmin, double rmax, double phi, double delta_phi);
     public:
+      /// Constructor to be used with an existing object
+      template <typename Q> Torus(const Q* p)
+          : Solid_type<TGeoTorus>(p) {
+      }
+
       /// Constructor to be used when passing an already created object
       Torus(const Torus& e)
           : Solid_type<TGeoTorus>(e) {
       }
+
       /// Constructor to be used when passing an already created object
       template <typename Q> Torus(const Handle<Q>& e)
           : Solid_type<TGeoTorus>(e) {
       }
+
       /// Constructor to create a new anonymous object with attribute initialization
       template<typename R, typename RMIN, typename RMAX, typename PHI, typename DELTA_PHI>
 	Torus(R r, RMIN rmin, RMAX rmax, PHI phi=M_PI, DELTA_PHI delta_phi = 2.*M_PI)
       {   make(_toDouble(r),_toDouble(rmin),_toDouble(rmax),_toDouble(phi),_toDouble(delta_phi));  }
+
       /// Constructor to create a new anonymous object with attribute initialization
       Torus(double r, double rmin, double rmax, double phi=M_PI, double delta_phi = 2.*M_PI)
 	{   make(r,rmin,rmax,phi,delta_phi);  }
+
       /// Set the Torus dimensions
       Torus& setDimensions(double r, double rmin, double rmax, double phi, double delta_phi);
     };
@@ -428,17 +475,25 @@ namespace DD4hep {
      */
     class Sphere: public Solid_type<TGeoSphere> {
     public:
+      /// Constructor to be used with an existing object
+      template <typename Q> Sphere(const Q* p)
+          : Solid_type<TGeoSphere>(p) {
+      }
+
       /// Constructor to be used when passing an already created object
       Sphere(const Sphere& e)
           : Solid_type<TGeoSphere>(e) {
       }
+
       /// Constructor to be used when passing an already created object
       template <typename Q> Sphere(const Handle<Q>& e)
           : Solid_type<TGeoSphere>(e) {
       }
+
       /// Constructor to create a new anonymous object with attribute initialization
       Sphere(double rmin, double rmax, double theta = 0., double delta_theta = M_PI, double phi = 0.0,
           double delta_phi = 2. * M_PI);
+
       /// Set the Sphere dimensions
       Sphere& setDimensions(double rmin, double rmax, double theta, double delta_theta, double phi, double delta_phi);
     };
@@ -453,17 +508,26 @@ namespace DD4hep {
      *   \version 1.0
      *   \ingroup DD4HEP_GEOMETRY
      */
-    struct Paraboloid: public Solid_type<TGeoParaboloid> {
+    class Paraboloid: public Solid_type<TGeoParaboloid> {
+    public:
+      /// Constructor to be used with an existing object
+      template <typename Q> Paraboloid(const Q* p)
+          : Solid_type<TGeoParaboloid>(p) {
+      }
+
       /// Constructor to be used when passing an already created object
       Paraboloid(const Paraboloid& e)
           : Solid_type<TGeoParaboloid>(e) {
       }
+
       /// Constructor to be used when passing an already created object
       template <typename Q> Paraboloid(const Handle<Q>& e)
           : Solid_type<TGeoParaboloid>(e) {
       }
+
       /// Constructor to create a new anonymous object with attribute initialization
       Paraboloid(double r_low, double r_high, double delta_z);
+
       /// Set the Paraboloid dimensions
       Paraboloid& setDimensions(double r_low, double r_high, double delta_z);
     };
@@ -483,10 +547,16 @@ namespace DD4hep {
       void _create(const std::string& name, int nsides, double rmin, double rmax, double zpos, double zneg, double start,
           double delta);
     public:
+      /// Constructor to be used with an existing object
+      template <typename Q> PolyhedraRegular(const Q* p)
+	: Solid_type<TGeoPgon>(p) {
+      }
+
       /// Constructor to be used when passing an already created object
       PolyhedraRegular(const PolyhedraRegular& e)
           : Solid_type<TGeoPgon>(e) {
       }
+
       /// Constructor to be used when passing an already created object
       template <typename Q>
       PolyhedraRegular(const Handle<Q>& e)
@@ -514,15 +584,23 @@ namespace DD4hep {
     private: 
       /// Internal helper method to support object construction
       void make(double dz, const double* vtx);
+
     public:
+      /// Constructor to be used with an existing object
+      template <typename Q> EightPointSolid(const Q* p)
+	: Solid_type<TGeoArb8>(p) {
+      }
+
       /// Constructor to be used when passing an already created object
       EightPointSolid(const EightPointSolid& e)
           : Solid_type<TGeoArb8>(e) {
       }
+
       /// Constructor to be used when passing an already created object
       template <typename Q> EightPointSolid(const Handle<Q>& e)
           : Solid_type<TGeoArb8>(e) {
       }
+
       /// Constructor to create a new anonymous object with attribute initialization
       EightPointSolid(double dz, const double* vertices) { make(dz,vertices);  }
     };
diff --git a/DDCore/include/DD4hep/SurfaceInstaller.h b/DDCore/include/DD4hep/SurfaceInstaller.h
new file mode 100644
index 0000000000000000000000000000000000000000..b0af1ddcc8ccc115be3da19f1250a50c1140bea2
--- /dev/null
+++ b/DDCore/include/DD4hep/SurfaceInstaller.h
@@ -0,0 +1,179 @@
+// $Id: SiTrackerBarrel_geo.cpp 1360 2014-10-27 16:32:06Z Nikiforos.Nikiforou@cern.ch $
+//====================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+#ifndef DD4HEP_DDREC_SURFACEINSTALLER_H
+#define DD4HEP_DDREC_SURFACEINSTALLER_H 1
+
+// Framework include files
+#include "DD4hep/LCDD.h"
+#include "DD4hep/DetectorTools.h"
+#include "DD4hep/DetFactoryHelper.h"
+
+// C/C++ include files
+#include <map>
+#include <algorithm>
+
+/// Namespace for the tracking surfaces of the AIDA detector description toolkit
+namespace DDSurfaces  {  
+  /// Class describing the surface types
+  class SurfaceType;
+}
+
+/// Namespace for the AIDA detector description toolkit
+namespace DD4hep  {
+
+  /// Namespace for the reconstruction part of the AIDA detector description toolkit
+  namespace DDRec  {  
+    /// Class describing surface data
+    class SurfaceData;
+  }
+
+  /** Base class to implement surface installers for known detector patterns
+   *
+   *  The class scans the geometry of a subdetector and gives callbacks
+   *  to user classes, which then should install in the proper callback
+   *  routines the surface instances to the detector elements.
+   *
+   *  \author  M.Frank
+   *  \version 1.0
+   *  \ingroup DD4HEP
+   */
+  class SurfaceInstaller  {
+  protected:
+    typedef Geometry::LCDD         LCDD;
+    typedef Geometry::DetElement   DetElement;
+    typedef Geometry::Volume       Volume;
+    typedef Geometry::PlacedVolume PlacedVolume;
+    typedef Geometry::DetectorTools::ElementPath   ElementPath;
+    typedef Geometry::DetectorTools::PlacementPath PlacementPath;
+    typedef DDRec::SurfaceData      SurfaceData;
+    typedef DDSurfaces::SurfaceType SurfaceType;
+
+    typedef std::map<TGeoVolume*, SurfaceData* > Surfaces;
+    /// Reference to the LCDD instance
+    LCDD&         m_lcdd;
+    /// Reference to the detector element of the subdetector
+    DetElement    m_det;
+    /// Map of surface instances keyed by the logical volume
+    Surfaces      m_surfaces;
+
+    /// Scan through tree of detector elements
+    void scan(DetElement de);
+
+  public:
+    /// Initializing constructor
+    SurfaceInstaller(LCDD& lcdd, const std::string& det_name);
+    /// Default destructor
+    virtual ~SurfaceInstaller() {}
+    /// Indicate error message and throw exception
+    void invalidInstaller(const std::string& msg) const;
+    /// Scan through tree of detector elements
+    void scan();
+    /// Install volume information. Default implementation only prints!
+    virtual void install(DetElement e, PlacedVolume pv);
+    /// Executor
+    template <typename T> static long run(LCDD& lcdd,int argc,char** argv);
+  };
+
+  /// Action routine to execute the test
+  template <typename T> inline long SurfaceInstaller::run(Geometry::LCDD& lcdd,int argc,char** argv)
+  {
+    for(; argc>0; --argc)   {
+      std::string name = argv[argc-1];
+      T installer(lcdd,name);
+      installer.scan();
+    }
+    return 1;
+  }
+
+#define DECLARE_SURFACE_INSTALLER(name,class)		\
+  namespace DD4hep { \
+    template long SurfaceInstaller::run< class >(Geometry::LCDD& lcdd,int argc,char** argv); \
+  } \
+  DECLARE_APPLY(name,SurfaceInstaller::run< class >)
+
+}   // End namespace DD4hep
+
+
+#ifdef DD4HEP_USE_SURFACEINSTALL_HELPER
+
+#include "DDRec/Surface.h"
+#include "DDRec/DetectorData.h"
+
+/** If you want to save yourself some typing when creating surface installers, 
+ *  set the compile macro DD4HEP_USE_SURFACEINSTALL_HELPER LOCALLY !
+ *  This will then enable the code below and the only thing you will have to
+ *  type is the installer member function to create a measurement surface for
+ *  a given volume.
+ *
+ *  \author  M.Frank
+ *  \version 1.0
+ *  \ingroup DD4HEP
+ */
+namespace {
+
+  /** Install class template to create surface installer plugins
+   *
+   *  See the base class SurfaceInstaller for further details.
+   *
+   *  \author  M.Frank
+   *  \version 1.0
+   *  \ingroup DD4HEP
+   */
+  class Installer : public DD4hep::SurfaceInstaller {
+  public:
+    typedef DD4hep::DDRec::Vector3D     Vector3D;
+    typedef DD4hep::DDRec::VolSurface   VolSurface;
+    typedef DD4hep::DDRec::VolPlane     VolPlane;
+    typedef DDSurfaces::SurfaceType     Type;
+  public:
+    /// Initializing constructor
+    Installer(LCDD& lcdd, const std::string& nam) : DD4hep::SurfaceInstaller(lcdd, nam) {}
+    /// Default destructor
+    virtual ~Installer() {}
+    /// Install volume information. Default implementation only prints!
+    virtual void install(DetElement component, PlacedVolume pv);
+    /// Try to handle surface using the surface cache
+    bool handleUsingCache(DetElement comp, Volume vol)  const  {
+      Surfaces::const_iterator is = m_surfaces.find(vol.ptr());
+      if ( is != m_surfaces.end() )  {
+	VolSurface surf((*is).second);
+	DD4hep::DDRec::volSurfaceList(comp)->push_back(surf);
+	return true;
+      }
+      return false;
+    }
+    Volume parentVolume(DetElement component)  const  {
+      DetElement module = component.parent();
+      if ( module.isValid() )   {
+	return module.placement().volume();
+      }
+      return Volume();
+    }
+    const double* placementTranslation(DetElement component)  const  {
+      TGeoMatrix* mat = component.placement()->GetMatrix();
+      const double* trans = mat->GetTranslation();
+      return trans;
+    }
+    void addSurface(DetElement component, const DD4hep::DDRec::VolSurface& surf)   {
+      m_surfaces.insert(std::make_pair(surf.volume().ptr(),surf.ptr()));
+      DD4hep::DDRec::volSurfaceList(component)->push_back(surf);
+    }
+    template <typename T> bool checkShape(const T& shape) const   {
+      if ( shape.isValid() ) return true;
+      invalidInstaller("Shape is not of the required type:"+DD4hep::typeName(typeid(T)));
+     return false;
+    }
+  };
+}
+
+DECLARE_SURFACE_INSTALLER(DD4HEP_USE_SURFACEINSTALL_HELPER,Installer)
+
+#endif /* DD4HEP_USE_SURFACEINSTALL_HELPER */
+
+#endif /* DD4HEP_DDREC_SURFACEINSTALLER_H */
diff --git a/DDCore/include/XML/UnicodeValues.h b/DDCore/include/XML/UnicodeValues.h
index 372159baed4b30bc03639a85235130c863834680..1ba1fa22a90f382cc358071c1df7a8fb7ef91b39 100644
--- a/DDCore/include/XML/UnicodeValues.h
+++ b/DDCore/include/XML/UnicodeValues.h
@@ -33,6 +33,8 @@ namespace DD4hep {
     UNICODE (alpha3);
     UNICODE (alpha4);
     UNICODE (arb8);
+    UNICODE (arg);
+    UNICODE (argument);
     UNICODE (assembly);
     UNICODE (atom);
     UNICODE (attributes);
@@ -264,6 +266,8 @@ namespace DD4hep {
     UNICODE (phi_size_max);
     UNICODE (physvol);
     UNICODE (physvolid);
+    UNICODE (plugin);
+    UNICODE (plugins);
     UNICODE (polyhedra);
     UNICODE (polycone);
     UNICODE (position);
diff --git a/DDCore/include/XML/XMLElements.h b/DDCore/include/XML/XMLElements.h
index d922a7584f67d6f40efa66e4a24248dfc2b437e5..3ac19a1da94f466eca44ac5ba074fe81f7fb58a4 100644
--- a/DDCore/include/XML/XMLElements.h
+++ b/DDCore/include/XML/XMLElements.h
@@ -109,6 +109,11 @@ namespace DD4hep {
     std::string _toString(float d, const char* fmt = "%f");
     /// Format double procision float number (64 bits) to string with atrbitrary format  \ingroup DD4HEP_XML
     std::string _toString(double d, const char* fmt = "%f");
+    /// Format void pointer (64 bits) to string with atrbitrary format  \ingroup DD4HEP_XML
+    std::string _ptrToString(const void* p, const char* fmt = "%p");
+    /// Format void pointer (64 bits) to string with atrbitrary format  \ingroup DD4HEP_XML
+    template <typename T> std::string _toString(const T* p, const char* fmt = "%p")   
+      {      return _ptrToString((void*)p,fmt);       }
 
     /// Helper function to populate the evaluator dictionary  \ingroup DD4HEP_XML
     void _toDictionary(const XmlChar* name, const XmlChar* value);
diff --git a/DDCore/src/Handle.cpp b/DDCore/src/Handle.cpp
index 9b331b1300c15feb0fc0ae29a1b826072fb76aba..1fc3ea21ae0af93a81c57109a22e60170e73b7ca 100644
--- a/DDCore/src/Handle.cpp
+++ b/DDCore/src/Handle.cpp
@@ -122,29 +122,32 @@ void DD4hep::Geometry::_toDictionary(const string& name, const string& value) {
   eval.setVariable(n.c_str(), result);
 }
 
-string DD4hep::Geometry::_toString(bool value) {
-  char text[32];
-  ::snprintf(text, sizeof(text), "%s", value ? "true" : "false");
+template <typename T> static inline string __to_string(T value, const char* fmt) {
+  char text[128];
+  ::snprintf(text, sizeof(text), fmt, value);
   return text;
 }
 
-string DD4hep::Geometry::_toString(int value) {
-  char text[32];
-  ::snprintf(text, sizeof(text), "%d", value);
-  return text;
+string DD4hep::Geometry::_toString(bool value) {
+  return value ? "true" : "false";
 }
 
-string DD4hep::Geometry::_toString(float value) {
-  char text[32];
-  ::snprintf(text, sizeof(text), "%f", value);
-  return text;
+string DD4hep::Geometry::_toString(int value, const char* fmt) {
+  return __to_string(value, fmt);
 }
 
-string DD4hep::Geometry::_toString(double value) {
-  char text[32];
-  ::snprintf(text, sizeof(text), "%f", value);
-  return text;
+string DD4hep::Geometry::_toString(float value, const char* fmt) {
+  return __to_string(value, fmt);
 }
+
+string DD4hep::Geometry::_toString(double value, const char* fmt) {
+  return __to_string(value, fmt);
+}
+
+string DD4hep::Geometry::_ptrToString(const void* value, const char* fmt) {
+  return __to_string(value, fmt);
+}
+
 namespace DD4hep {
   namespace Geometry {
     static long s_numVerifies = 0;
diff --git a/DDCore/src/LCDDImp.cpp b/DDCore/src/LCDDImp.cpp
index 24f13ef5868055ecf53d1900c55f5ac9a6fb2153..4cbad73a5f30a86d4d4dc6ca055351e15b53feb5 100644
--- a/DDCore/src/LCDDImp.cpp
+++ b/DDCore/src/LCDDImp.cpp
@@ -229,6 +229,7 @@ namespace {
     }
     void patchShapes() {
       GeoHandler::Data& data = *m_data;
+      char text[32];
       string nam;
       printout(INFO,"LCDD","+++ Patching names of anonymous shapes....");
       for (GeoHandler::Data::const_reverse_iterator i = data.rbegin(); i != data.rend(); ++i) {
@@ -238,20 +239,21 @@ namespace {
           TGeoVolume* v = n->GetVolume();
           TGeoShape* s = v->GetShape();
           const char* sn = s->GetName();
+	  ::snprintf(text,sizeof(text),"_shape_%p",(void*)s);
           if (0 == sn || 0 == ::strlen(sn)) {
             nam = v->GetName();
-            nam += "_shape";
+            nam += text;
             s->SetName(nam.c_str());
           }
           else if (0 == ::strcmp(sn, s->IsA()->GetName())) {
             nam = v->GetName();
-            nam += "_shape";
+            nam += text;
             s->SetName(nam.c_str());
           }
           else {
             nam = sn;
             if (nam.find("_shape") == string::npos)
-              nam += "_shape";
+              nam += text;
             s->SetName(nam.c_str());
           }
           if (s->IsA() == TGeoCompositeShape::Class()) {
diff --git a/DDCore/src/SurfaceInstaller.cpp b/DDCore/src/SurfaceInstaller.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e94670f1aaaae6ce3f2413d7ea8445830fe8d91d
--- /dev/null
+++ b/DDCore/src/SurfaceInstaller.cpp
@@ -0,0 +1,102 @@
+// $Id: SiTrackerBarrel_geo.cpp 1360 2014-10-27 16:32:06Z Nikiforos.Nikiforou@cern.ch $
+//====================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+#include "DD4hep/Printout.h"
+#include "DD4hep/SurfaceInstaller.h"
+
+// C/C++ include files
+#include <stdexcept>
+#include "TClass.h"
+
+using namespace std;
+using namespace DD4hep;
+using namespace DD4hep::Geometry;
+
+typedef DetElement::Children _C;
+
+/// Initializing constructor
+SurfaceInstaller::SurfaceInstaller(LCDD& lcdd, const std::string& det_name) 
+  : m_lcdd(lcdd), m_det()
+{
+  string n = det_name[0] == '-' ? det_name.substr(1) : det_name;
+  m_det = lcdd.detector(n);
+  if ( !m_det.isValid() )   {
+    stringstream err;
+    err << "The subdetector " << det_name << " is not known to the geometry.";
+    printout(INFO,"SurfaceInstaller",err.str().c_str());
+    throw runtime_error(err.str());
+  }
+  printout(INFO,m_det.name(),"+++ Processing SurfaceInstaller for subdetector: '%s'",m_det.name());
+}
+
+/// Indicate error message and throw exception
+void SurfaceInstaller::invalidInstaller(const std::string& msg)   const  {
+  const char* det = m_det.isValid() ? m_det.name() : "<UNKNOWN>";
+  const char* typ = m_det.isValid() ? m_det.type().c_str() : "<UNKNOWN>";
+  printout(FATAL,"SurfaceInstaller","+++ Surfaces for: %s",det);
+  printout(FATAL,"SurfaceInstaller","+++ %s.",msg.c_str());
+  printout(FATAL,"SurfaceInstaller","+++ You sure you apply the correct plugin to generate");
+  printout(FATAL,"SurfaceInstaller","+++ surfaces for a detector of type %s",typ);
+  throw std::runtime_error("+++ Failed to install Surfaces to detector "+string(det));
+}
+
+/// Printout volume information
+void SurfaceInstaller::install(DetElement component, PlacedVolume pv)   {
+  if ( pv.volume().isSensitive() )  {
+    stringstream log;
+    PlacementPath all_nodes;
+    ElementPath   det_elts;
+    DetectorTools::elementPath(component,det_elts);
+    DetectorTools::placementPath(component,all_nodes);
+    string elt_path  = DetectorTools::elementPath(det_elts);
+    string node_path = DetectorTools::placementPath(all_nodes);
+
+    log << "Lookup " << " Detector[" << det_elts.size() << "]: " << elt_path;
+    printout(INFO,m_det.name(),log.str());
+    log.str("");
+    log << "       " << " Places[" <<  all_nodes.size()  << "]:   " << node_path;
+    printout(INFO,m_det.name(),log.str());
+    log.str("");
+    log << "       " << " Matrices[" <<  all_nodes.size()  << "]: ";
+    log << pv->GetVolume()->GetShape()->IsA()->GetName() << " ";
+    for(PlacementPath::const_reverse_iterator i=all_nodes.rbegin(); i!=all_nodes.rend(); ++i)  {
+      log << (void*)((*i)->GetMatrix()) << "  ";
+      if ( i+1 == all_nodes.rend() ) log << "( -> " << (*i)->GetName() << ")";
+    }
+    // Get the module element:
+    TClass* cl = pv->GetVolume()->GetShape()->IsA();
+    printout(INFO,m_det.name(),log.str());
+    log.str("");
+    log << "       "
+	<< " Sensitive:" << (pv.volume().isSensitive() ? "YES" : "NO ") 
+	<< " Shape: " << cl->GetName();
+    TGeoBBox* box = (TGeoBBox*)pv.volume()->GetShape();
+    if ( cl == TGeoBBox::Class() )   {
+      log << " ["  << (void*)box << "]"
+	  << " x:" << box->GetDX() 
+	  << " y:" << box->GetDY()
+	  << " z:" << box->GetDZ();
+    }
+  }
+}
+
+/// Scan through tree of volume placements
+void SurfaceInstaller::scan(DetElement e)  {
+  const _C& children = e.children();  
+  install(e,e.placement());
+  for (_C::const_iterator i=children.begin(); i!=children.end(); ++i)
+    scan((*i).second);
+}
+
+/// Scan through tree of volume placements
+void SurfaceInstaller::scan()  {
+  scan(m_det);
+}
+
+typedef DD4hep::SurfaceInstaller TestSurfacesPlugin;
+DECLARE_SURFACE_INSTALLER(TestSurfaces,TestSurfacesPlugin)
diff --git a/DDCore/src/XML/XMLElements.cpp b/DDCore/src/XML/XMLElements.cpp
index 441d1485372e13313ca56ebb0ea13d464f3e51e0..681d3ba3b0e8493a9ac53596f1fef757bec8023f 100644
--- a/DDCore/src/XML/XMLElements.cpp
+++ b/DDCore/src/XML/XMLElements.cpp
@@ -229,6 +229,11 @@ string DD4hep::XML::_toString(double v, const char* fmt) {
   return __to_string(v, fmt);
 }
 
+/// Format pointer to string with atrbitrary format
+string DD4hep::XML::_ptrToString(const void* v, const char* fmt) {
+  return __to_string(v, fmt);
+}
+
 int DD4hep::XML::_toInt(const XmlChar* value) {
   if (value) {
     string s = _toString(value);
diff --git a/DDCore/src/plugins/Compact2Objects.cpp b/DDCore/src/plugins/Compact2Objects.cpp
index 009f81a9e129392b58bc5348f0e9458be7350203..86e467395c79c82f33e035130d5f94e66697aa5b 100644
--- a/DDCore/src/plugins/Compact2Objects.cpp
+++ b/DDCore/src/plugins/Compact2Objects.cpp
@@ -35,6 +35,7 @@ using namespace DD4hep::Geometry;
 
 namespace DD4hep {
   namespace Geometry {
+    struct Plugin;
     struct Compact;
     struct Includes;
     struct GdmlFile;
@@ -43,6 +44,7 @@ namespace DD4hep {
     struct AlignmentFile;
     struct DetElementInclude {};
   }
+  template <> void Converter<Plugin>::operator()(xml_h e) const;
   template <> void Converter<Constant>::operator()(xml_h e) const;
   template <> void Converter<Material>::operator()(xml_h e) const;
   template <> void Converter<Atom>::operator()(xml_h e) const;
@@ -217,6 +219,28 @@ static long create_Compact(lcdd_t& lcdd, xml_h element) {
 }
 DECLARE_XML_DOC_READER(lccdd,create_Compact)
 
+/** Convert/execute plugin objects from the xml (plugins)
+ *
+ *
+ */
+template <> void Converter<Plugin>::operator()(xml_h e) const {
+  xml_comp_t plugin(e);
+  vector<char*> argv;
+  vector<string> arguments;
+  string name = plugin.nameStr();
+  for (xml_coll_t coll(e, _U(arg)); coll; ++coll) {
+    string val = coll.attr<string>(_U(value));
+    arguments.push_back(val);
+  }
+  for (xml_coll_t coll(e, _U(argument)); coll; ++coll) {
+    string val = coll.attr<string>(_U(value));
+    arguments.push_back(val);
+  }
+  for(std::vector<string>::iterator i=arguments.begin(); i!=arguments.end(); ++i)
+    argv.push_back(&((*i)[0]));
+  lcdd.apply(name.c_str(),int(argv.size()), &argv[0]);
+}
+
 /** Convert compact constant objects (defines)
  *
  *
@@ -228,7 +252,6 @@ template <> void Converter<Constant>::operator()(xml_h e) const {
   _toDictionary(obj->GetName(), obj->GetTitle());
   lcdd.addConstant(cons);
 }
-
 /** Convert compact constant objects (defines)
  *
  *
@@ -870,6 +893,7 @@ template <> void Converter<Compact>::operator()(xml_h element) const {
   xml_coll_t(compact, _U(alignments)).for_each(_U(alignment), Converter < AlignmentEntry > (lcdd));
   xml_coll_t(compact, _U(fields)).for_each(_U(field), Converter < CartesianField > (lcdd));
   xml_coll_t(compact, _U(sensitive_detectors)).for_each(_U(sd), Converter < SensitiveDetector > (lcdd));
+  xml_coll_t(compact, _U(plugins)).for_each(_U(plugin), Converter < Plugin > (lcdd));
   ::snprintf(text, sizeof(text), "%u", xml_h(element).checksum(0));
   lcdd.addConstant(Constant("compact_checksum", text));
   if ( --num_calls == 0 )  {
diff --git a/DDCore/src/plugins/GeometryWalk.cpp b/DDCore/src/plugins/GeometryWalk.cpp
index fc314ec2477b23910410d79775051236c39502bc..2db01ff64df802e72a8859e41bf0ce4692e79bbb 100644
--- a/DDCore/src/plugins/GeometryWalk.cpp
+++ b/DDCore/src/plugins/GeometryWalk.cpp
@@ -57,7 +57,6 @@ namespace  {
     void print(DetElement e, PlacedVolume pv, const VolIDs& child_ids)  const;
     /// Action routine to execute the test
     static long run(LCDD& lcdd,int argc,char** argv);
-    void dumpPathes(DetElement e, PlacedVolume pv)  const;
   };
 }
 
@@ -130,6 +129,7 @@ long GeometryWalk::run(LCDD& lcdd,int argc,char** argv)    {
   return 1;
 }
 
+
 namespace DD4hep {
   namespace Geometry {
     using ::GeometryWalk;
diff --git a/DDCore/src/plugins/LCDDConverter.cpp b/DDCore/src/plugins/LCDDConverter.cpp
index e511dc7ced3a23bec0a09c931aa3bccbb4a9f1ce..6bf092795019499c0acd8b9c8c221fd0def0bd68 100644
--- a/DDCore/src/plugins/LCDDConverter.cpp
+++ b/DDCore/src/plugins/LCDDConverter.cpp
@@ -600,18 +600,18 @@ xml_h LCDDConverter::handleRotation(const std::string& name, const TGeoMatrix* t
 }
 
 /// Dump logical volume in GDML format to output stream
-xml_h LCDDConverter::handleVolume(const string& name, Volume volume) const {
+xml_h LCDDConverter::handleVolume(const string& /* name */, Volume volume) const {
   GeometryInfo& geo = data();
   xml_h vol = geo.xmlVolumes[volume];
   if (!vol) {
     const TGeoVolume* v = volume;
     Volume _v = Ref_t(v);
-    string n = v->GetName();
+    string n = v->GetName()+_toString(v,"_%p");
     TGeoMedium* m = v->GetMedium();
     TGeoShape* s = v->GetShape();
     xml_ref_t sol = handleSolid(s->GetName(), s);
 
-    geo.checkVolume(name, volume);
+    geo.checkVolume(n, volume);
     if (v->IsAssembly()) {
       vol = xml_elt_t(geo.doc, _U(assembly));
       vol.setAttr(_U(name), n);
@@ -707,10 +707,11 @@ void LCDDConverter::collectVolume(const string& /* name */, const TGeoVolume* vo
   }
 }
 
-void LCDDConverter::checkVolumes(const string& name, Volume v) const {
-  NameSet::const_iterator i = m_checkNames.find(name);
+void LCDDConverter::checkVolumes(const string& /* name */, Volume v) const {
+  string n = v.name()+_toString(v.ptr(),"_%p");
+  NameSet::const_iterator i = m_checkNames.find(n);
   if (i != m_checkNames.end()) {
-    cout << "checkVolumes: Volume " << name << " ";
+    cout << "checkVolumes: Volume " << n << " ";
     if (is_volume(v.ptr()))     {
       SensitiveDetector s = v.sensitiveDetector();
       VisAttr vis = v.visAttributes();
@@ -724,7 +725,7 @@ void LCDDConverter::checkVolumes(const string& name, Volume v) const {
     cout << "has duplicate entries." << endl;
     return;
   }
-  m_checkNames.insert(name);
+  m_checkNames.insert(n);
 }
 
 /// Dump volume placement in GDML format to output stream
diff --git a/DDDetectors/CMakeLists.txt b/DDDetectors/CMakeLists.txt
index 7fb544c08072f309887b09a79345b652b74cdf69..4b0b7a4e76d1d3ba4c93881e2b09feed0c3d21c7 100644
--- a/DDDetectors/CMakeLists.txt
+++ b/DDDetectors/CMakeLists.txt
@@ -12,6 +12,7 @@ find_package( ROOT REQUIRED COMPONENTS Geom Reflex )
 #---Includedirs---------------------------------------------------------------------
 include_directories(${CMAKE_SOURCE_DIR}/DDCore/include
 	            ${CMAKE_SOURCE_DIR}/DDRec/include	
+	            ${CMAKE_SOURCE_DIR}/DDSurfaces/include	
 	            ${CMAKE_SOURCE_DIR}/DDSegmentation/include	
                     ${ROOT_INCLUDE_DIR} )
 #
diff --git a/DDDetectors/compact/SiD/SiD_Tracker.xml b/DDDetectors/compact/SiD/SiD_Tracker.xml
index 00d6b2becc1b479b90e0de5643042a768e8968c7..9b828cbd1243c05910c9aa7e9785f19819d5fe84 100644
--- a/DDDetectors/compact/SiD/SiD_Tracker.xml
+++ b/DDDetectors/compact/SiD/SiD_Tracker.xml
@@ -43,9 +43,10 @@
   </readouts>
   
   <!--  Includes for sensitives and support                -->
+<!--
   <include ref="SiD_TrackerEndcap.xml"/>
   <include ref="SiD_TrackerBarrel.xml"/>
   <include ref="SiD_TrackerForward.xml"/>
   <include ref="SiD_TrackerSupport.xml"/>
-
+-->
 </lccdd>
diff --git a/DDDetectors/src/SiTrackerBarrel_geo.cpp b/DDDetectors/src/SiTrackerBarrel_geo.cpp
index 4a64bdab60fe81f2a20b70ded1e50db437f3eb89..dceead3356f4eb7f0b8deae33c2c9d3fb953fa2f 100644
--- a/DDDetectors/src/SiTrackerBarrel_geo.cpp
+++ b/DDDetectors/src/SiTrackerBarrel_geo.cpp
@@ -14,13 +14,15 @@ using namespace DD4hep;
 using namespace DD4hep::Geometry;
 
 static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens)  {
+  typedef vector<PlacedVolume> Placements;
   xml_det_t   x_det     = e;
   Material    air       = lcdd.air();
   int         det_id    = x_det.id();
   string      det_name  = x_det.nameStr();
   DetElement  sdet       (det_name,det_id);
-  Assembly    assembly   (det_name+"_assembly");
+  Assembly    assembly   (det_name);
   map<string, Volume>    volumes;
+  map<string, Placements>  sensitives;
   PlacedVolume pv;
 
   sens.setType("tracker");
@@ -28,7 +30,7 @@ static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens)  {
     xml_comp_t x_mod  = mi;
     xml_comp_t m_env  = x_mod.child(_U(module_envelope));
     string     m_nam  = x_mod.nameStr();
-    Volume     m_vol(det_name+"_"+m_nam,Box(m_env.width()/2,m_env.length()/2,m_env.thickness()/2),air);
+    Volume     m_vol(m_nam,Box(m_env.width()/2,m_env.length()/2,m_env.thickness()/2),air);
     int        ncomponents = 0, sensor_number = 1;
 
     if ( volumes.find(m_nam) != volumes.end() )   {
@@ -36,37 +38,38 @@ static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens)  {
       throw runtime_error("Logics error in building modules.");
     }
     volumes[m_nam] = m_vol;
+    m_vol.setVisAttributes(lcdd.visAttributes(x_mod.visStr()));
     for(xml_coll_t ci(x_mod,_U(module_component)); ci; ++ci, ++ncomponents)  {
       xml_comp_t x_comp = ci;
       xml_comp_t x_pos  = x_comp.position(false);
-      xml_comp_t x_rot  = x_comp.rotation(false);	
-      string     c_nam  = det_name+"_"+m_nam+_toString(ncomponents,"_component%d");
+      xml_comp_t x_rot  = x_comp.rotation(false);        
+      string     c_nam  = _toString(ncomponents,"component%d");
       Box        c_box(x_comp.width()/2,x_comp.length()/2,x_comp.thickness()/2);
       Volume     c_vol(c_nam,c_box,lcdd.material(x_comp.materialStr()));
 
       if ( x_pos && x_rot ) {
-	Position    c_pos(x_pos.x(0),x_pos.y(0),x_pos.z(0));
-	RotationZYX c_rot(x_rot.z(0),x_rot.y(0),x_rot.x(0));
-	pv = m_vol.placeVolume(c_vol, Transform3D(c_rot,c_pos));
+        Position    c_pos(x_pos.x(0),x_pos.y(0),x_pos.z(0));
+        RotationZYX c_rot(x_rot.z(0),x_rot.y(0),x_rot.x(0));
+        pv = m_vol.placeVolume(c_vol, Transform3D(c_rot,c_pos));
       }
       else if ( x_rot ) {
-	pv = m_vol.placeVolume(c_vol,RotationZYX(x_rot.z(0),x_rot.y(0),x_rot.x(0)));
+        pv = m_vol.placeVolume(c_vol,RotationZYX(x_rot.z(0),x_rot.y(0),x_rot.x(0)));
       }
       else if ( x_pos ) {
-	pv = m_vol.placeVolume(c_vol,Position(x_pos.x(0),x_pos.y(0),x_pos.z(0)));
+        pv = m_vol.placeVolume(c_vol,Position(x_pos.x(0),x_pos.y(0),x_pos.z(0)));
       }
       else {
-	pv = m_vol.placeVolume(c_vol);
+        pv = m_vol.placeVolume(c_vol);
       }
       c_vol.setRegion(lcdd, x_comp.regionStr());
       c_vol.setLimitSet(lcdd, x_comp.limitsStr());
       c_vol.setVisAttributes(lcdd, x_comp.visStr());
       if ( x_comp.isSensitive() ) {
-	pv.addPhysVolID(_U(sensor),sensor_number++);
-	c_vol.setSensitiveDetector(sens);
+        pv.addPhysVolID(_U(sensor),sensor_number++);
+        c_vol.setSensitiveDetector(sens);
+	sensitives[m_nam].push_back(pv);
       }
     }
-    m_vol.setVisAttributes(lcdd.visAttributes(x_mod.visStr()));
   }
   for(xml_coll_t li(x_det,_U(layer)); li; ++li)  {
     xml_comp_t x_layer  = li;
@@ -75,8 +78,7 @@ static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens)  {
     xml_comp_t z_layout = x_layer.child(_U(z_layout));      // Get the <z_layout> element.
     int        lay_id   = x_layer.id();
     string     m_nam    = x_layer.moduleStr();
-    Volume     m_env    = volumes[m_nam];
-    string     lay_nam  = det_name+"_"+m_nam+_toString(x_layer.id(),"_layer%d");
+    string     lay_nam  = _toString(x_layer.id(),"layer%d");
     Tube       lay_tub   (x_barrel.inner_r(),x_barrel.outer_r(),x_barrel.z_length()/2);
     Volume     lay_vol   (lay_nam,lay_tub,air);         // Create the layer envelope volume.
     double     phi0     = x_layout.phi0();              // Starting phi of first module.
@@ -89,6 +91,9 @@ static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens)  {
     double     z0       = z_layout.z0();                // Z position of first module in phi.
     double     nz       = z_layout.nz();                // Number of modules to place in z.
     double     z_dr     = z_layout.dr();                // Radial displacement parameter, of every other module.
+    Volume     m_env    = volumes[m_nam];
+    DetElement lay_elt(sdet,_toString(x_layer.id(),"layer%d"),lay_id);
+    Placements& sensVols = sensitives[m_nam];
 
     // Z increment for module placement along Z axis.
     // Adjust for z0 at center of module rather than
@@ -99,28 +104,40 @@ static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens)  {
     int module = 1;
       
     // Loop over the number of modules in phi.
-    for (int ii = 0; ii < nphi; ii++)	{
-      double dx = z_dr * std::cos(phic + phi_tilt);	// Delta x of module position.
-      double dy = z_dr * std::sin(phic + phi_tilt);	// Delta y of module position.
-      double  x = rc * std::cos(phic);                  // Basic x module position.
-      double  y = rc * std::sin(phic);               	// Basic y module position.
-        
+    for (int ii = 0; ii < nphi; ii++)        {
+      double dx = z_dr * std::cos(phic + phi_tilt);        // Delta x of module position.
+      double dy = z_dr * std::sin(phic + phi_tilt);        // Delta y of module position.
+      double  x = rc * std::cos(phic);                     // Basic x module position.
+      double  y = rc * std::sin(phic);                     // Basic y module position.
+
       // Loop over the number of modules in z.
-      for (int j = 0; j < nz; j++)	  {
-	// Module PhysicalVolume.
-	// 	Transform3D tr(RotationZYX(0,-((M_PI/2)-phic-phi_tilt),M_PI/2),Position(x,y,module_z));
-	//NOTE (Nikiforos, 26/08 Rotations needed to be fixed so that component1 (silicon) is on the outside
-	Transform3D tr(RotationZYX(0,((M_PI/2)-phic-phi_tilt),-M_PI/2),Position(x,y,module_z));
-	pv = lay_vol.placeVolume(m_env,tr);
-	pv.addPhysVolID("module", module++);
-	// Adjust the x and y coordinates of the module.
-	x += dx;
-	y += dy;
-	// Flip sign of x and y adjustments.
-	dx *= -1;
-	dy *= -1;
-	// Add z increment to get next z placement pos.
-	module_z += z_incr;
+      for (int j = 0; j < nz; j++)          {
+	string module_name = _toString(module,"module%d");
+	DetElement mod_elt(lay_elt,module_name,module);
+        // Module PhysicalVolume.
+        //         Transform3D tr(RotationZYX(0,-((M_PI/2)-phic-phi_tilt),M_PI/2),Position(x,y,module_z));
+        //NOTE (Nikiforos, 26/08 Rotations needed to be fixed so that component1 (silicon) is on the outside
+        Transform3D tr(RotationZYX(0,((M_PI/2)-phic-phi_tilt),-M_PI/2),Position(x,y,module_z));
+
+        pv = lay_vol.placeVolume(m_env,tr);
+        pv.addPhysVolID("module", module);
+	mod_elt.setPlacement(pv);
+	for(size_t ic=0; ic<sensVols.size(); ++ic)  {
+	  PlacedVolume sens_pv = sensVols[ic];
+	  DetElement comp_elt(mod_elt,sens_pv.volume().name(),module);
+	  comp_elt.setPlacement(sens_pv);
+	}
+
+	/// Increase counters etc.
+	module++;
+        // Adjust the x and y coordinates of the module.
+        x += dx;
+        y += dy;
+        // Flip sign of x and y adjustments.
+        dx *= -1;
+        dy *= -1;
+        // Add z increment to get next z placement pos.
+        module_z += z_incr;
       }
       phic     += phi_incr;      // Increment the phi placement of module.
       rc       += rphi_dr;       // Increment the center radius according to dr parameter.
@@ -128,14 +145,13 @@ static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens)  {
       module_z  = -z0;           // Reset the Z placement parameter for module.
     }
     // Create the PhysicalVolume for the layer.
-    assembly.setVisAttributes(lcdd.invisible());
     pv = assembly.placeVolume(lay_vol); // Place layer in mother
     pv.addPhysVolID("layer", lay_id);       // Set the layer ID.
-    DetElement m_elt(sdet,lay_nam,lay_id);
-    m_elt.setAttributes(lcdd,lay_vol,x_layer.regionStr(),x_layer.limitsStr(),x_layer.visStr());
-    m_elt.setPlacement(pv);
+    lay_elt.setAttributes(lcdd,lay_vol,x_layer.regionStr(),x_layer.limitsStr(),x_layer.visStr());
+    lay_elt.setPlacement(pv);
   }
   sdet.setAttributes(lcdd,assembly,x_det.regionStr(),x_det.limitsStr(),x_det.visStr());
+  assembly.setVisAttributes(lcdd.invisible());
   pv = lcdd.pickMotherVolume(sdet).placeVolume(assembly);
   pv.addPhysVolID("system", det_id);      // Set the subdetector system ID.
   pv.addPhysVolID("barrel", 0);           // Flag this as a barrel subdetector.
diff --git a/DDDetectors/src/SiTrackerBarrel_surfaces.cpp b/DDDetectors/src/SiTrackerBarrel_surfaces.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6d88ea2296774585cf257c233fcf545ea1e97684
--- /dev/null
+++ b/DDDetectors/src/SiTrackerBarrel_surfaces.cpp
@@ -0,0 +1,36 @@
+// $Id: SiTrackerBarrel_geo.cpp 1360 2014-10-27 16:32:06Z Nikiforos.Nikiforou@cern.ch $
+//====================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+// Framework include files
+#define DD4HEP_USE_SURFACEINSTALL_HELPER DD4hep_SiTrackerBarrel_Surfaces
+#include "DD4hep/SurfaceInstaller.h"
+
+/// Install volume information. Default implementation only prints!
+void Installer::install(DetElement component, PlacedVolume pv)   {
+  Volume comp_vol = pv.volume();
+  if ( comp_vol.isSensitive() )  {  
+    Volume mod_vol  = parentVolume(component);
+    DD4hep::Geometry::Box mod_shape(mod_vol.solid()), comp_shape(comp_vol.solid());
+
+    if ( !comp_shape.isValid() || !mod_shape.isValid() )   {
+      invalidInstaller("Components and/or modules are not boxes -- invalid shapes");
+    }
+    else if ( !handleUsingCache(component,comp_vol) )  {
+      const double* trans = placementTranslation(component);
+      double half_module_thickness = mod_shape->GetDZ();
+      double sensitive_z_position  = trans[2];
+      double outer_thickness = half_module_thickness + sensitive_z_position;
+      double inner_thickness = half_module_thickness - sensitive_z_position;
+      Vector3D u(1.,0.,0.), v(0.,1.,0.), n(0.,0.,1.), o(0.,0.,sensitive_z_position);
+
+      VolPlane surf(comp_vol,Type(Type::Sensitive,Type::Measurement1D),
+		    inner_thickness, outer_thickness, u, v, n, o);
+      addSurface(component,surf);
+    }
+  }
+}
diff --git a/DDDetectors/src/SiTrackerEndcap2_geo.cpp b/DDDetectors/src/SiTrackerEndcap2_geo.cpp
index 4dbf5f38c9a02052f9407724da15c01c89cee4f6..68ced8f8251ca566105ce76992b3295b0e7efe85 100644
--- a/DDDetectors/src/SiTrackerEndcap2_geo.cpp
+++ b/DDDetectors/src/SiTrackerEndcap2_geo.cpp
@@ -15,17 +15,19 @@ using namespace DD4hep;
 using namespace DD4hep::Geometry;
 
 static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens)  {
+  typedef vector<PlacedVolume> Placements;
   xml_det_t   x_det     = e;
   Material    vacuum    = lcdd.vacuum();
   int         det_id    = x_det.id();
   string      det_name  = x_det.nameStr();
   bool        reflect   = x_det.reflect(false);
   DetElement  sdet        (det_name,det_id);
-  Assembly    assembly    (det_name+"_assembly");
-  //Volume      assembly    (det_name+"_assembly",Box(10000,10000,10000),vacuum);
+  Assembly    assembly    (det_name);
+  //Volume      assembly    (det_name,Box(10000,10000,10000),vacuum);
   Volume      motherVol = lcdd.pickMotherVolume(sdet);
   int         m_id=0, c_id=0, n_sensor=0;
   map<string,Volume> modules;
+  map<string, Placements>  sensitives;
   PlacedVolume pv;
 
   assembly.setVisAttributes(lcdd.invisible());
@@ -45,23 +47,23 @@ static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens)  {
       total_thickness += xml_comp_t(ci).thickness();
       
     y1 = y2 = total_thickness / 2;
-    Volume  m_volume(det_name+"_"+m_nam, Trapezoid(x1, x2, y1, y2, z), vacuum);      
+    Volume  m_volume(m_nam, Trapezoid(x1, x2, y1, y2, z), vacuum);      
     m_volume.setVisAttributes(lcdd.visAttributes(x_mod.visStr()));
 
     for(ci.reset(), n_sensor=1, c_id=0, posY=-y1; ci; ++ci, ++c_id)  {
       xml_comp_t c       = ci;
       double     c_thick = c.thickness();
       Material   c_mat   = lcdd.material(c.materialStr());
-      string     c_name  = m_volume.name() + _toString(c_id,"_component%d");
+      string     c_name  = _toString(c_id,"component%d");
       Volume     c_vol(c_name, Trapezoid(x1,x2,c_thick/2e0,c_thick/2e0,z), c_mat);
 
       c_vol.setVisAttributes(lcdd.visAttributes(c.visStr()));
       pv = m_volume.placeVolume(c_vol,Position(0,posY+c_thick/2,0));
-      //pv.addPhysVolID("component",c_id);
       if ( c.isSensitive() ) {
 	sdet.check(n_sensor > 2,"SiTrackerEndcap2::fromCompact: "+c_name+" Max of 2 modules allowed!");
 	pv.addPhysVolID("sensor",n_sensor);
 	c_vol.setSensitiveDetector(sens);
+	sensitives[m_nam].push_back(pv);
 	++n_sensor;
       }
       posY += c_thick;
@@ -84,6 +86,7 @@ static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens)  {
       Volume m_vol    = modules[m_nam];
       double iphi     = 2*M_PI/nmodules;
       double phi      = phi0;
+      Placements& sensVols = sensitives[m_nam];
 
       for(int k=0; k<nmodules; ++k) {
 	string m_base = _toString(l_id,"layer%d") + _toString(mod_num,"_module%d");
@@ -93,11 +96,22 @@ static Ref_t create_detector(LCDD& lcdd, xml_h e, SensitiveDetector sens)  {
 	pv = assembly.placeVolume(m_vol,Transform3D(RotationZYX(0,-M_PI/2-phi,-M_PI/2),Position(x,y,zstart+dz)));
 	pv.addPhysVolID("barrel",1).addPhysVolID("layer", l_id).addPhysVolID("module",mod_num);
 	module.setPlacement(pv);
+	for(size_t ic=0; ic<sensVols.size(); ++ic)  {
+	  PlacedVolume sens_pv = sensVols[ic];
+	  DetElement comp_elt(module,sens_pv.volume().name(),mod_num);
+	  comp_elt.setPlacement(sens_pv);
+	}
+
 	if ( reflect ) {
 	  pv = assembly.placeVolume(m_vol,Transform3D(RotationZYX(M_PI,-M_PI/2-phi,-M_PI/2),Position(x,y,-zstart-dz)));
 	  pv.addPhysVolID("barrel",2).addPhysVolID("layer",l_id).addPhysVolID("module",mod_num);
 	  DetElement r_module(sdet,m_base+"_neg",det_id);
 	  r_module.setPlacement(pv);
+	  for(size_t ic=0; ic<sensVols.size(); ++ic)  {
+	    PlacedVolume sens_pv = sensVols[ic];
+	    DetElement comp_elt(r_module,sens_pv.volume().name(),mod_num);
+	    comp_elt.setPlacement(sens_pv);
+	  }
 	}
 	dz   = -dz;
 	phi += iphi;
diff --git a/DDDetectors/src/SiTrackerEndcap_surfaces.cpp b/DDDetectors/src/SiTrackerEndcap_surfaces.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..297a54e5701df4b432333c9a026143a2f3791d1e
--- /dev/null
+++ b/DDDetectors/src/SiTrackerEndcap_surfaces.cpp
@@ -0,0 +1,36 @@
+// $Id: $
+//====================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+// Framework include files
+#define  DD4HEP_USE_SURFACEINSTALL_HELPER  DD4hep_SiTrackerEndcap_Surfaces
+#include "DD4hep/SurfaceInstaller.h"
+
+void Installer::install(DetElement component, PlacedVolume pv)   {
+  Volume comp_vol = pv.volume();
+  if ( comp_vol.isSensitive() )  {  
+    Volume mod_vol = parentVolume(component);
+    DD4hep::Geometry::Trapezoid comp_shape(comp_vol.solid()), mod_shape(mod_vol.solid());
+
+    if ( !comp_shape.isValid() || !mod_shape.isValid() )   {
+      invalidInstaller("Components and/or modules are not Trapezoid -- invalid shapes");
+    }
+    else if ( !handleUsingCache(component,comp_vol) )  {
+      const double* trans = placementTranslation(component);
+      double half_mod_thickness  = mod_shape->GetDy1();
+      double half_comp_thickness = comp_shape->GetDy1();
+      double si_position         = trans[1];
+      double outer_thickness = half_mod_thickness + si_position;
+      double inner_thickness = half_mod_thickness - si_position;
+      Vector3D u(0.,0.,-1.), v(-1.,0.,0.), n(0.,-1.,0.), o(0.,0.,0.);
+
+      VolPlane surf(comp_vol,Type(Type::Sensitive,Type::Measurement1D),
+		    inner_thickness, outer_thickness, u, v, n, o);
+      addSurface(component,surf);
+    }
+  }
+}
diff --git a/DDG4/examples/CLICSidSimuMarkus.py b/DDG4/examples/CLICSidSimuMarkus.py
index b5dea3f23e7c73090e7341fa7e0c38180bdca4ac..750bca4481ffec21cbff74a211ee6c29ffd630a0 100644
--- a/DDG4/examples/CLICSidSimuMarkus.py
+++ b/DDG4/examples/CLICSidSimuMarkus.py
@@ -18,7 +18,7 @@ def run():
   lcdd = kernel.lcdd()
   install_dir = os.environ['DD4hepINSTALL']
   example_dir = install_dir+'/examples/DDG4/examples';
-  kernel.loadGeometry("file:"+install_dir+"/DDDetectors/compact/SiD.xml")
+  kernel.loadGeometry("file:"+install_dir+"/DDDetectors/compact/SiD_Markus.xml")
   kernel.loadXML("file:"+example_dir+"/DDG4_field.xml")
   DDG4.importConstants(lcdd,debug=False)
   simple = DDG4.Simple(kernel,tracker='Geant4TrackerCombineAction')
@@ -43,7 +43,7 @@ def run():
   # Configure I/O
   ##evt_lcio = simple.setupLCIOOutput('LcioOutput','CLICSiD_'+time.strftime('%Y-%m-%d_%H-%M'))
   ##evt_lcio.OutputLevel = generator_output_level
-  ##evt_root = simple.setupROOTOutput('RootOutput','CLICSiD_'+time.strftime('%Y-%m-%d_%H-%M'))
+  evt_root = simple.setupROOTOutput('RootOutput','CLICSiD_'+time.strftime('%Y-%m-%d_%H-%M'))
 
   gen = DDG4.GeneratorAction(kernel,"Geant4GeneratorActionInit/GenerationInit")
   gen.OutputLevel = generator_output_level
@@ -111,7 +111,7 @@ def run():
   kernel.generatorAction().adopt(rdr)
   """
 
-  seq,act = simple.setupTracker('SiTrackerBarrel')
+  seq,act = simple.setupTracker('SiVertexBarrel')
   """
   # First the tracking detectors
   seq,act = simple.setupTracker('SiVertexBarrel')
diff --git a/DDG4/plugins/Geant4SDActions.cpp b/DDG4/plugins/Geant4SDActions.cpp
index 7fed4852fca4a8fe9e53a1252f9fc669df732340..16434403c610e31f3257c5ad52593b2b411f99a6 100644
--- a/DDG4/plugins/Geant4SDActions.cpp
+++ b/DDG4/plugins/Geant4SDActions.cpp
@@ -66,7 +66,7 @@ namespace DD4hep {
 	mark(h.track);
 	if ( 0 == hit->cellID )  {
 	  hit->cellID        = volumeID( step ) ;
-	  throw runtime_error("Invalid CELL ID for hit!");
+	  except("+++ Invalid CELL ID for hit!");
 	}
 	print("Geant4Tracker","%s> Hit with deposit:%f  Pos:%f %f %f ID=%016X",
 	      c_name(),step->GetTotalEnergyDeposit(),position.X(),position.Y(),position.Z(),
@@ -75,7 +75,8 @@ namespace DD4hep {
 	print("Geant4Tracker","%s>     Geant4 path:%s",c_name(),handler.path().c_str());
 	return true;
       }
-      throw runtime_error("new() failed: Cannot allocate hit object");
+      except("new() failed: Cannot allocate hit object");
+      return false;
     }
     typedef Geant4SensitiveAction<Geant4Tracker> Geant4TrackerAction;
 
@@ -110,7 +111,7 @@ namespace DD4hep {
 		c_name(),contrib.deposit,pos.X,pos.Y,pos.Z,handler.path().c_str());
 	if ( 0 == hit->cellID )  { // for debugging only!
 	  hit->cellID = cellID(step);
-	  throw runtime_error("Invalid CELL ID for hit!");
+	  except("+++ Invalid CELL ID for hit!");
 	}
       }
       hit->truth.push_back(contrib);
@@ -160,7 +161,7 @@ namespace DD4hep {
 	  coll->add(hit);
 	  if ( 0 == hit->cellID )  {
 	    hit->cellID = volumeID(step);
-	    throw runtime_error("Invalid CELL ID for hit!");
+	    except("+++ Invalid CELL ID for hit!");
 	  }
 	}
 	hit->energyDeposit += contrib.deposit;
@@ -189,8 +190,9 @@ namespace DD4hep {
       double            e_cut;
       int               current;
       int               combined;
+      long long int     cell;
       
-      TrackerCombine() : pre(), post(), sensitive(0), e_cut(0.0), current(-1), combined(0)  {
+      TrackerCombine() : pre(), post(), sensitive(0), e_cut(0.0), current(-1), combined(0), cell(0)  {
       }
 
       /// Start a new hit
@@ -201,12 +203,20 @@ namespace DD4hep {
 	sensitive->mark(step->GetTrack());
 	post = pre;
 	combined = 0;
+	cell = 0;
       }
 
       /// Update energy and track information during hit info accumulation
       void update(G4Step* step) {
 	post.storePoint(step,step->GetPostStepPoint());
 	pre.truth.deposit += post.truth.deposit;
+	if ( 0 == cell )   {
+	  cell = sensitive->cellID(step);
+	  if ( 0 == cell )  {
+	    cell = sensitive->volumeID(step) ;
+	    sensitive->except("+++ Invalid CELL ID for hit!");
+	  }
+	}
 	++combined;
       }
 
@@ -216,6 +226,7 @@ namespace DD4hep {
 	pre.clear();
 	current = -1;
 	combined = 0;
+	cell = 0;
       }
 
       bool mustSaveTrack(const G4Track* tr)  const   {
@@ -236,7 +247,8 @@ namespace DD4hep {
 							 deposit,time);
 	hit->position = pos;
 	hit->momentum = mom;
-	hit->length = path_len;
+	hit->length   = path_len;
+	hit->cellID   = cell;
 	collection->add(hit);
 	sensitive->printM2("+++ TrackID:%6d [%s] CREATE hit combination with %2d deposit(s):"
 			   " %e MeV  Pos:%8.2f %8.2f %8.2f",
diff --git a/DDG4/src/Geant4ParticleGun.cpp b/DDG4/src/Geant4ParticleGun.cpp
index 9a2f4893a6e521598490690bc6a7a5b9d1d4a8ce..f10ed36ab431b9e7a61a5d77307e537b82c07f72 100644
--- a/DDG4/src/Geant4ParticleGun.cpp
+++ b/DDG4/src/Geant4ParticleGun.cpp
@@ -91,6 +91,9 @@ void Geant4ParticleGun::operator()(G4Event* event)   {
   inter->vertices.insert(make_pair(m_mask,vtx));
   prim->add(m_mask, inter);
 
+  vtx->x = m_position.X();
+  vtx->y = m_position.Y();
+  vtx->z = m_position.Z();
   for(int i=0; i<m_multiplicity; ++i)    {
     Geant4ParticleHandle p = new Geant4Particle(i);
     p->reason       = 0;
@@ -100,12 +103,12 @@ void Geant4ParticleGun::operator()(G4Event* event)   {
     p->psz          = m_direction.Z()*m_energy;
     p->time         = 0;
     p->properTime   = 0;
-    p->vsx          = m_position.X();
-    p->vsy          = m_position.Y();
-    p->vsz          = m_position.Z();
-    p->vex          = m_position.X();
-    p->vey          = m_position.Y();
-    p->vez          = m_position.Z();
+    p->vsx          = vtx->x;
+    p->vsy          = vtx->y;
+    p->vsz          = vtx->z;
+    p->vex          = vtx->x;
+    p->vey          = vtx->y;
+    p->vez          = vtx->z;
     //p->definition   = m_particle;
     //p->process      = 0;
     p->spin[0]      = 0;