diff --git a/DDCore/include/DD4hep/Detector.h b/DDCore/include/DD4hep/Detector.h
index fc44ab3c65be20329b79eae9aca97d8e86772f4d..5eada6c523bb2821070381063b33f185463ddc50 100644
--- a/DDCore/include/DD4hep/Detector.h
+++ b/DDCore/include/DD4hep/Detector.h
@@ -118,6 +118,7 @@ namespace DD4hep {
 	TGeoMatrix*       worldTrafo;
 	TGeoMatrix*       parentTrafo;
 	TGeoMatrix*       referenceTrafo;
+	std::string       placementPath;
 	/// Default constructor
         Object();
 	/// Construct new empty object
@@ -129,7 +130,7 @@ namespace DD4hep {
 	/// Conversion to reference object
 	Ref_t asRef();
 	/// Top detector element
-	Ref_t top();
+	//Ref_t top();
 	/// Create cached matrix to transform to world coordinates
 	TGeoMatrix* worldTransformation();
 	/// Create cached matrix to transform to parent coordinates
@@ -149,27 +150,36 @@ namespace DD4hep {
       /// Default constructor
       template<typename Q> DetElement(Q* data, const std::string& name, const std::string& type) : Ref_t(data)  
       {  this->assign(data, name, type);                   }
+
       /// Templated constructor for handle conversions
       template<typename Q> DetElement(const Handle<Q>& e) : Ref_t(e)  {}
-      /// DEPRECATED: Constructor for a new subdetector element. First argument lcdd is unused!
-      DetElement(const LCDD& lcdd, const std::string& name, const std::string& type, int id);
+
+      /// Constructor to copy handle
+      DetElement(const DetElement& e) : Ref_t(e) {}
 
       /// Constructor for a new subdetector element
       DetElement(const std::string& name, const std::string& type, int id);
 
+      /// Constructor for a new subdetector element
+      DetElement(const std::string& name, int id);
+
+      /// Constructor for a new subdetector element
+      DetElement(DetElement parent, const std::string& name, int id);
+
       /// Clone (Deep copy) the DetElement structure with a new name
       DetElement clone(const std::string& new_name) const;
+
       /// Clone (Deep copy) the DetElement structure with a new name and new identifier
       DetElement clone(const std::string& new_name, int new_id) const;
       
       DetElement&     setCombineHits(bool value, SensitiveDetector& sens);
-      DetElement&     add(const DetElement& sub_element);
       int             id() const;
       std::string     type() const;
       std::string     path() const;
+      /// Access to the full path to the placed object
+      std::string     placementPath() const;
       bool            isTracker() const;
       bool            isCalorimeter() const;
-      //bool            isInsideTrackingVolume() const;
       bool            combineHits() const;
       
       /// Set all attributes in one go
@@ -189,24 +199,25 @@ namespace DD4hep {
       Readout         readout() const;
       /// Assign readout definition
       DetElement&     setReadout(const Readout& readout);
-      
+
+      /// Access to the logical volume of the placements (all daughters have the same!)
+      Volume          volume() const;
+      /// Set the logical volume of the placements (all daughters have the same!)
+      //void            setVolume(Volume vol);
+
       /// Access to the physical volume of this detector element
       PlacedVolume    placement() const;
       /// Set the physical volumes of the detector element
       DetElement&     setPlacement(const PlacedVolume& volume);
 
-      /// Access the physical volumes of the detector element
-      //Placements      placements() const;
-      /// Set the physical volumes of the detector element
-      //DetElement&     addPlacement(const PlacedVolume& volume);
-
-      /// Access to the logical volume of the placements (all daughters have the same!)
-      Volume          volume() const;
-      
+      /// Add new child to the detector structure
+      DetElement&     add(DetElement sub_element);
       /// Access to the list of children
       const Children& children() const;
       /// Access to individual children by name
       DetElement      child(const std::string& name) const;
+      /// Access to the detector elements's parent
+      DetElement      parent() const;
 
       /// Set detector element for reference transformations. Will delete existing reference trafo.
       DetElement&     setReference(DetElement reference);
diff --git a/DDCore/include/DD4hep/GeoHandler.h b/DDCore/include/DD4hep/GeoHandler.h
new file mode 100644
index 0000000000000000000000000000000000000000..dc81703604eafb72ed0b09b3386504cb2b6d22c6
--- /dev/null
+++ b/DDCore/include/DD4hep/GeoHandler.h
@@ -0,0 +1,94 @@
+// $Id:$
+//====================================================================
+//  AIDA Detector description implementation
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+#ifndef DD4HEP_GEOHANDLER_H
+#define DD4HEP_GEOHANDLER_H
+
+#include "DD4hep/LCDD.h"
+#include <set>
+#include <map>
+#include <vector>
+
+// Forward declarations
+class TGeoMatrix;
+class TGeoVolume;
+class TGeoMedium;
+class TGeoShape;
+class TGeoNode;
+
+/*
+ *   DD4hep namespace declaration
+ */
+namespace DD4hep {
+
+  /*
+   *   Geometry namespace declaration
+   */
+  namespace Geometry {
+
+    /** @class GeoHandler  GeoHandler.h
+     *
+     * @author  M.Frank
+     * @version 1.0
+     */
+    class GeoHandler {
+    public:
+      typedef std::map<std::string, TGeoVolume*>                 VolumeSet;
+      typedef std::vector<std::pair<std::string, TGeoMatrix*> >  TransformSet;
+      typedef std::map<std::string, TGeoShape*>                  SolidSet;
+      typedef std::map<std::string, TGeoMedium*>                 MaterialSet;
+      typedef std::map<int, std::set<const TGeoNode*> >          Data;
+      typedef LCDD::HandleMap                                    VisRefs;
+
+      struct GeometryInfo   {
+	SolidSet           solids;
+	VolumeSet          volumes;
+	TransformSet       trafos;
+	VisRefs            vis;
+	MaterialSet        materials;
+	std::set<TGeoMedium*>   media;
+	std::set<TGeoElement*>  elements;
+      };
+    protected:
+      Data* m_data;
+
+      /// Internal helper to collect geometry information from traversal
+      GeoHandler& i_collect(const TGeoNode* node, int level);
+
+    public:
+      /// Default constructor
+      GeoHandler();
+      /// Initializing constructor
+      GeoHandler(Data* ptr);
+      /// Default destructor
+      virtual ~GeoHandler();
+      /// Collect geometry information from traversal
+      GeoHandler& collect(DetElement top);
+      /// Collect geometry information from traversal with aggregated information
+      GeoHandler& collect(DetElement top, GeometryInfo& info);
+      /// Access to collected node list
+      Data* release();
+    };
+
+    struct GeoScan {
+      protected:
+      /// Data holder
+      GeoHandler::Data* m_data;
+      public:
+      /// Initializing constructor
+      GeoScan(DetElement e);
+      /// Default destructor
+      virtual ~GeoScan();
+      /// Work callback
+      virtual GeoScan& operator()();
+    };
+  }    // End namespace Geometry
+}      // End namespace DD4hep
+
+#endif // DD4HEP_GEOHANDLER_H
+
diff --git a/DDCore/include/DD4hep/Handle.h b/DDCore/include/DD4hep/Handle.h
index 49bca02770a395c26bddbc28c2e69ce15fdb02ea..d9d68a978ba7accf3bfa60ab9134b611b47d7219 100644
--- a/DDCore/include/DD4hep/Handle.h
+++ b/DDCore/include/DD4hep/Handle.h
@@ -23,6 +23,17 @@ class TGeoManager;
 #ifndef RAD_2_DEGREE
 #define RAD_2_DEGREE 57.295779513082320876798154814105
 #endif
+#ifndef DEGREE_2_RAD 
+#define DEGREE_2_RAD 0.017453292519943295769236907684886
+#endif
+#ifndef CM_2_MM
+#define CM_2_MM 10.0
+#endif
+#ifndef MM_2_CM
+#define MM_2_CM 0.1
+#endif
+
+
 #ifndef M_PI
 #define M_PI 3.14159265358979323846
 #endif
diff --git a/DDCore/include/DD4hep/LCDD.h b/DDCore/include/DD4hep/LCDD.h
index 40cad19f94231c48b23a04735362c8dfcbabc901..8af8ffb1e69de30bbdf7b51de2608265826f226e 100644
--- a/DDCore/include/DD4hep/LCDD.h
+++ b/DDCore/include/DD4hep/LCDD.h
@@ -42,7 +42,6 @@ namespace DD4hep {
 
       virtual ~LCDD() {}
 
-      //virtual Document document() const = 0;
       virtual void create() = 0;
       virtual void init() = 0;
       virtual void endDocument() = 0;
@@ -51,14 +50,15 @@ namespace DD4hep {
       virtual Material air() const = 0;
       virtual Material vacuum() const = 0;
 
+      virtual DetElement world() const = 0;
+      virtual DetElement trackers() const = 0;
+
       virtual Volume   worldVolume() const = 0;
       virtual Volume   trackingVolume() const = 0;
 
       virtual const HandleMap& header()  const = 0;
       virtual const HandleMap& constants()  const = 0;
       virtual const HandleMap& regions() const = 0;
-      virtual const HandleMap& structure()  const = 0;
-      virtual const HandleMap& solids()  const = 0;
       virtual const HandleMap& materials()  const = 0;
       virtual const HandleMap& detectors()  const = 0;
       virtual const HandleMap& readouts() const = 0;
@@ -66,23 +66,19 @@ namespace DD4hep {
       virtual const HandleMap& limitsets()  const = 0;
       virtual const HandleMap& alignments()  const = 0;
 
+      virtual Volume         pickMotherVolume(const DetElement& sd) const = 0;
       virtual Region         region(const std::string& name)  const = 0;
       virtual VisAttr        visAttributes(const std::string& name) const = 0;
       virtual LimitSet       limitSet(const std::string& name)  const = 0;
       virtual Material       material(const std::string& name)  const = 0;
       virtual Readout        readout(const std::string& name)  const = 0;
       virtual Ref_t          idSpec(const std::string& name)  const = 0;
-      virtual Volume         pickMotherVolume(const DetElement& sd) const = 0;
       virtual Constant       constant(const std::string& name) const = 0;
-      virtual Solid          solid(const std::string& name) const = 0;
-      virtual Volume         volume(const std::string& name) const = 0;
       virtual AlignmentEntry alignment(const std::string& path) const = 0;
       virtual DetElement     detector(const std::string& name) const = 0;
 
       virtual LCDD& add(const Constant& constant) = 0;
-      //virtual LCDD& add(const Solid& solid) = 0;
       virtual LCDD& add(const Region& region) = 0;
-      //virtual LCDD& add(const Volume& vol) = 0;
       virtual LCDD& add(const Material& mat) = 0;
       virtual LCDD& add(const VisAttr& attr) = 0;
       virtual LCDD& add(const LimitSet& limset) = 0;
@@ -98,9 +94,6 @@ namespace DD4hep {
       virtual LCDD& addRegion(const Ref_t& region) = 0;
       virtual LCDD& addReadout(const Ref_t& readout) = 0;
       virtual LCDD& addDetector(const Ref_t& detector) = 0;
-      virtual LCDD& addSolid(const Ref_t& detector) = 0;
-      /// Add identifyable volume
-      virtual LCDD& addVolume(const Ref_t& detector) = 0;
       /// Add alignment entry
       virtual LCDD& addAlignment(const Ref_t& alignment) = 0;
 
diff --git a/DDCore/include/DD4hep/Objects.h b/DDCore/include/DD4hep/Objects.h
index c7328b7efac38b4ef7b0deecbf36435a83ff19f3..e879bde4ea45422d93f55439df440b181955b446 100644
--- a/DDCore/include/DD4hep/Objects.h
+++ b/DDCore/include/DD4hep/Objects.h
@@ -236,12 +236,14 @@ namespace DD4hep {
     struct VisAttr : public Ref_t  {
       struct Object  {
 	unsigned long magic;
+	void*         col;
         int           color;
+	float         alpha;
         unsigned char drawingStyle, lineStyle, showDaughters, visible;
-        Object() : magic(magic_word()), color(0), drawingStyle(true), showDaughters(true), visible(true)  {}
+        Object() : magic(magic_word()), col(0), color(0), alpha(0), drawingStyle(true), showDaughters(true), visible(true)  {}
       };
       enum DrawingStyle { 
-        WIREFRAME=0x1,
+        WIREFRAME=0x2,
         LAST_DRAWING_STYLE
       };
       enum LineStyle  {
@@ -251,25 +253,49 @@ namespace DD4hep {
       };
       /// Default constructor
       VisAttr() : Ref_t() {}
-      /// Constructor to be used when reading the already parsed DOM tree
+      /// Constructor to be used for assignment from object handle
       template <typename Q> 
       VisAttr(const Handle<Q>& e) : Ref_t(e) {}
+      /// Copy constructor for handle
+      VisAttr(const VisAttr& e) : Ref_t(e) {}
       /// Constructor to be used when creating a new registered visualization object
       VisAttr(LCDD& doc, const std::string& name);
       /// Additional data accessor
       Object& _data()   const {  return *data<Object>();  }
+
+      /// Get Flag to show/hide daughter elements
+      bool showDaughters() const;
       /// Set Flag to show/hide daughter elements
       void setShowDaughters(bool value);
+
+      /// Get visibility flag
+      bool visible() const;
+      /// Set visibility flag
+      void setVisible(bool value);
+
+      /// Get line style
+      int lineStyle() const;
       /// Set line style
       void setLineStyle(LineStyle style);
+
+      /// Get drawing style
+      int drawingStyle()  const;
       /// Set drawing style
       void setDrawingStyle(DrawingStyle style);
-      /// Set visibility flag
-      void setVisible(bool value);
+
+      /// Get alpha value
+      float alpha() const;
       /// Set alpha value
       void setAlpha(float value);
+
+      /// Get object color
+      int color()   const;
       /// Set object color
       void setColor(float red, float green, float blue);
+
+      /// Get RGB values of the color (if valid)
+      bool rgb(float& red, float& green, float& blue) const;
+
       /// String representation of this object
       std::string toString()  const;
     };
diff --git a/DDCore/include/DD4hep/Shapes.h b/DDCore/include/DD4hep/Shapes.h
index 09957c38114702b05d5aff4d764f44383416dd03..8e7f219dd0a76f091da27c3b8e8982595e3356ee 100644
--- a/DDCore/include/DD4hep/Shapes.h
+++ b/DDCore/include/DD4hep/Shapes.h
@@ -22,9 +22,12 @@ class TGeoBBox;
 class TGeoPcon;
 class TGeoPgon;
 class TGeoCone;
+class TGeoSphere;
 class TGeoTrd2;
+class TGeoTorus;
 class TGeoTrap;
 class TGeoTubeSeg;
+class TGeoParaboloid;
 class TGeoCompositeShape;
 
 /*
@@ -53,8 +56,7 @@ namespace DD4hep {
       typedef T Implementation;
       void _setDimensions(double* param);
       /// Assign pointrs and register solid to geometry
-      void _assign(LCDD& lcdd, Implementation* n, const std::string& nam, const std::string& tit, bool cbbox=true);
-      
+      void _assign(Implementation* n, const std::string& nam, const std::string& tit, bool cbbox=true);
 
       public:
 
@@ -68,17 +70,16 @@ namespace DD4hep {
       Solid_type(const Handle<Implementation>& e) : Handle<Implementation>(e) {}
 
       /// Constructor to be used when reading the already parsed object: need to check pointers
-      template <typename Q> 
-      Solid_type(const Handle<Q>& e) : Handle<T>(e) {}
+      template <typename Q> Solid_type(const Handle<Q>& e) : Handle<T>(e) {}
 
       /// Access to shape name
       const char* name() const;
 
       /// Auto conversion to underlying ROOT object
-      operator Implementation*() const     { return this->m_element; }
+      operator Implementation*() const       { return this->m_element; }
 
       /// Overloaded operator -> to access underlying object
-      Implementation* operator->() const   { return this->m_element; }
+      Implementation* operator->() const     { return this->m_element; }
     };
     typedef Solid_type<TGeoShape> Solid;
 
@@ -90,25 +91,38 @@ namespace DD4hep {
      */
     struct Box : public Solid_type<TGeoBBox>  {
       protected:
-      void make(LCDD& lcdd, const std::string& name, double x, double y, double z);
+      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) : Solid_type<Implementation>(e) {}
 
-      /// Constructor to be used when creating a new box object
-      Box(LCDD& lcdd, const std::string& name) 
-      {  make(lcdd, name, 0, 0, 0); }
+      /// Constructor to be used when creating an identifiable new box object
+      Box(const std::string& name) 
+      {  make(name, 0, 0, 0); }
+
+      /// Constructor to be used when creating an anonymous new box object (retrieves name from volume)
+      Box() 
+      {  make("", 0, 0, 0); }
+
+      /// Constructor to be used when creating an identifiable new box object
+      Box(const std::string& name, double x, double y, double z)
+      {  make(name, x, y, z); }
 
-      /// Constructor to be used when creating a new box object
-      Box(LCDD& lcdd, const std::string& name, double x, double y, double z)
-      {  make(lcdd, name, x, y, z); }
+      /// Constructor to be used when creating an anonymous new box object (retrieves name from volume)
+      Box(double x, double y, double z)
+      {  make("", x, y, z); }
+
+      /// Constructor to be used when creating an identifiable new box object
+      template<typename X, typename Y, typename Z>
+      Box(const std::string& name, const X& x, const Y& y, const Z& z)
+      {  make(name, _toDouble(x),_toDouble(y),_toDouble(z)); }
 
-      /// Constructor to be used when creating a new box object
+      /// Constructor to be used when creating an anonymous new box object (retrieves name from volume)
       template<typename X, typename Y, typename Z>
-      Box(LCDD& lcdd, const std::string& name, const X& x, const Y& y, const Z& z)
-      {  make(lcdd, name, _toDouble(x),_toDouble(y),_toDouble(z)); }
+      Box(const X& x, const Y& y, const Z& z)
+      {  make("", _toDouble(x),_toDouble(y),_toDouble(z)); }
 
       /// Set the box dimensions
       Box& setDimensions(double x, double y, double z);
@@ -124,13 +138,19 @@ namespace DD4hep {
       template <typename Q> Polycone(const Handle<Q>& e) : Solid_type<Implementation>(e) {}
 
       /// Constructor to be used when creating a new polycone object
-      Polycone(LCDD& lcdd, const std::string& name);
+      Polycone(const std::string& name="");
 
       /// Constructor to be used when creating a new polycone object
-      Polycone(LCDD& lcdd, const std::string& name, double start, double delta);
+      Polycone(double start, double delta);
+
+      /// Constructor to be used when creating a new polycone object
+      Polycone(const std::string& name, double start, double delta);
 
       /// Constructor to be used when creating a new polycone object. Add at the same time all Z planes
-      Polycone(LCDD& lcdd, const std::string& name, double start, double delta, const std::vector<double>& rmin, const std::vector<double>& rmax, const std::vector<double>& z);
+      Polycone(double start, double delta, const std::vector<double>& rmin, const std::vector<double>& rmax, const std::vector<double>& z);
+
+      /// Constructor to be used when creating a new polycone object. Add at the same time all Z planes
+      Polycone(const std::string& name, double start, double delta, const std::vector<double>& rmin, const std::vector<double>& rmax, const std::vector<double>& z);
 
       /// Add Z-planes to the Polycone
       void addZPlanes(const std::vector<double>& rmin, const std::vector<double>& rmax, const std::vector<double>& z);
@@ -143,25 +163,40 @@ namespace DD4hep {
      */
     struct Tube : public Solid_type<TGeoTubeSeg>  {
       protected:
-      void make(LCDD& lcdd, const std::string& name,double rmin,double rmax,double z,double deltaPhi);
+      void make(const std::string& name,double rmin,double rmax,double z,double deltaPhi);
 
       public:
       /// Constructor to assign an object
       template <typename Q> Tube(const Handle<Q>& e) : Solid_type<Implementation>(e) {}
 
-      /// Constructor to be used when creating a new tube object
-      Tube(LCDD& lcdd, const std::string& name)
-      { make(lcdd,name,0, 0, 0, 0); }
+      /// Constructor to be used when creating a new anonymous tube object
+      Tube()
+      { make("",0, 0, 0, 0); }
+
+      /// Constructor to be used when creating a new identifiable tube object
+      Tube(const std::string& name)
+      { make(name,0, 0, 0, 0); }
 
-      /// Constructor to be used when creating a new tube object with attribute initialization
-      Tube(LCDD& lcdd, const std::string& name, double rmin, double rmax, double z, double deltaPhi=2*M_PI)
-      { make(lcdd,name,rmin, rmax, z, deltaPhi); }
+      /// Constructor to be used when creating a new anonymous tube object with attribute initialization
+      Tube(double rmin, double rmax, double z, double deltaPhi=2*M_PI)
+      { make("",rmin, rmax, z, deltaPhi); }
 
-      /// Constructor to be used when creating a new tube object with attribute initialization
+      /// Constructor to be used when creating a new identifiable tube object with attribute initialization
+      Tube(const std::string& name, double rmin, double rmax, double z, double deltaPhi=2*M_PI)
+      { make(name,rmin, rmax, z, deltaPhi); }
+
+      /// Constructor to be used when creating a new anonymous tube object with attribute initialization
+      template<typename RMIN, typename RMAX, typename Z, typename DELTAPHI>
+      Tube(const RMIN& rmin, const RMAX& rmax, const Z& z, const DELTAPHI& deltaPhi)  
+      {
+        make("",_toDouble(rmin),_toDouble(rmax),_toDouble(z),_toDouble(deltaPhi));
+      }
+
+      /// Constructor to be used when creating a new identifiable tube object with attribute initialization
       template<typename RMIN, typename RMAX, typename Z, typename DELTAPHI>
-      Tube(LCDD& lcdd, const std::string& name, const RMIN& rmin, const RMAX& rmax, const Z& z, const DELTAPHI& deltaPhi)  
+      Tube(const std::string& name, const RMIN& rmin, const RMAX& rmax, const Z& z, const DELTAPHI& deltaPhi)  
       {
-        make(lcdd,name,_toDouble(rmin),_toDouble(rmax),_toDouble(z),_toDouble(deltaPhi));
+        make(name,_toDouble(rmin),_toDouble(rmax),_toDouble(z),_toDouble(deltaPhi));
       }
 
       /// Set the box dimensions
@@ -175,29 +210,40 @@ namespace DD4hep {
      */
     struct Cone : public Solid_type<TGeoCone>  {
       protected:
-      void make(LCDD& lcdd, const std::string& name,double z,double rmin1,double rmax1,double rmin2,double rmax2);
+      void make(const std::string& name,double z,double rmin1,double rmax1,double rmin2,double rmax2);
 
       public:
 
       /// Constructor to be used when reading the already parsed object
       template <typename Q> Cone(const Handle<Q>& e) : Solid_type<Implementation>(e) {}
 
+      /// Constructor to be used when creating a new anonymous object
+      Cone()      { make("",0, 0, 0, 0, 0); }
       /// Constructor to be used when creating a new object
-      Cone(LCDD& lcdd, const std::string& name)
-      { make(lcdd,name,0, 0, 0, 0, 0); }
-
+      Cone(const std::string& name)      { make(name,0, 0, 0, 0, 0); }
+      /// Constructor to be used when creating a new anonymous object with attribute initialization
+      Cone(double z,
+           double rmin1,
+           double rmax1,
+           double rmin2,
+           double rmax2)
+      { make("",z,rmin1,rmax1,rmin2,rmax2); }
       /// Constructor to be used when creating a new object with attribute initialization
-      Cone(LCDD& lcdd, const std::string& name,
+      Cone(const std::string& name,
            double z,
            double rmin1,
            double rmax1,
            double rmin2,
            double rmax2)
-      { make(lcdd,name,z,rmin1,rmax1,rmin2,rmax2); }
+      { make(name,z,rmin1,rmax1,rmin2,rmax2); }
+
+      template<typename Z, typename RMIN1, typename RMAX1, typename RMIN2, typename RMAX2>
+      Cone(const Z& z, const RMIN1& rmin1, const RMAX1& rmax1, const RMIN2& rmin2, const RMAX2& rmax2)
+      { make("",_toDouble(z),_toDouble(rmin1),_toDouble(rmax1),_toDouble(rmin2),_toDouble(rmax2)); }
 
       template<typename Z, typename RMIN1, typename RMAX1, typename RMIN2, typename RMAX2>
-      Cone(LCDD& lcdd, const std::string& name, const Z& z, const RMIN1& rmin1, const RMAX1& rmax1, const RMIN2& rmin2, const RMAX2& rmax2)
-      { make(lcdd,name,_toDouble(z),_toDouble(rmin1),_toDouble(rmax1),_toDouble(rmin2),_toDouble(rmax2)); }
+      Cone(const std::string& name, const Z& z, const RMIN1& rmin1, const RMAX1& rmax1, const RMIN2& rmin2, const RMAX2& rmax2)
+      { make(name,_toDouble(z),_toDouble(rmin1),_toDouble(rmax1),_toDouble(rmin2),_toDouble(rmax2)); }
 
       /// Set the box dimensions
       Cone& setDimensions(double z,double rmin1,double rmax1,double rmin2,double rmax2);
@@ -212,8 +258,8 @@ namespace DD4hep {
       /// Constructor to be used when reading the already parsed object
       template <typename Q> Trap( const Handle<Q>& e) : Solid_type<Implementation>(e) {}
 
-      /// Constructor to be used when creating a new object with attribute initialization
-      Trap( LCDD& lcdd, const std::string& name,
+      /// Constructor to be used when creating a new identified object with attribute initialization
+      Trap( const std::string& name,
             double z,
             double theta,
             double phi,
@@ -225,6 +271,18 @@ namespace DD4hep {
             double x3,
             double x4,
             double alpha2);
+      /// Constructor to be used when creating a new anonymous object with attribute initialization
+      Trap( double z,
+            double theta,
+            double phi,
+            double y1,
+            double x1,
+            double x2,
+            double alpha1,
+            double y2,
+            double x3,
+            double x4,
+            double alpha2);
 
       /// Set the trap dimensions
       Trap& setDimensions(double z,double theta,double phi,
@@ -241,14 +299,81 @@ namespace DD4hep {
       /// Constructor to be used when reading the already parsed object
       template <typename Q> Trapezoid(const Handle<Q>& e) : Solid_type<Implementation>(e) {}
 
-      /// Constructor to be used when creating a new object
-      Trapezoid(LCDD& lcdd, const std::string& name);
-      /// Constructor to be used when creating a new object with attribute initialization
-      Trapezoid(LCDD& lcdd, const std::string& name, double x1, double x2, double y1, double y2, double z);
+      /// Constructor to be used when creating a new anonymous object
+      Trapezoid();
+      /// Constructor to be used when creating a new identified object
+      Trapezoid(const std::string& name);
+      /// Constructor to be used when creating a new anonymous object with attribute initialization
+      Trapezoid(double x1, double x2, double y1, double y2, double z);
+      /// Constructor to be used when creating a new identified object with attribute initialization
+      Trapezoid(const std::string& name, double x1, double x2, double y1, double y2, double z);
       /// Set the Trapezoid dimensions
       Trapezoid& setDimensions(double x1, double x2, double y1, double y2, double z);
     };
 
+    /**@class Torus Shapes.h 
+     *
+     *   @author  M.Frank
+     *   @version 1.0
+     */
+    struct Torus : public Solid_type<TGeoTorus> {
+      /// Constructor to be used when reading the already parsed object
+      template <typename Q> Torus(const Handle<Q>& e) : Solid_type<Implementation>(e) {}
+
+      /// Constructor to be used when creating a new anonymous object
+      Torus();
+      /// Constructor to be used when creating a identified new object
+      Torus(const std::string& name);
+      /// Constructor to be used when creating a new anonymous object with attribute initialization
+      Torus(double r, double rmin, double rmax, double phi=M_PI, double delta_phi=2.*M_PI);
+      /// Constructor to be used when creating a new identified object with attribute initialization
+      Torus(const std::string& name, double r, double rmin, double rmax, double phi=M_PI, double delta_phi=2.*M_PI);
+      /// Set the Torus dimensions
+      Torus& setDimensions(double r, double rmin, double rmax, double phi, double delta_phi);
+    };
+
+    /**@class Sphere Shapes.h 
+     *
+     *   @author  M.Frank
+     *   @version 1.0
+     */
+    struct Sphere : public Solid_type<TGeoSphere> {
+      /// Constructor to be used when reading the already parsed object
+      template <typename Q> Sphere(const Handle<Q>& e) : Solid_type<Implementation>(e) {}
+
+      /// Constructor to be used when creating a new anonymous object
+      Sphere();
+      /// Constructor to be used when creating a identified new object
+      Sphere(const std::string& name);
+      /// Constructor to be used when creating 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);
+      /// Constructor to be used when creating a new identified object with attribute initialization
+      Sphere(const std::string& name, double rmin, double rmax, double theta=0., double delta_theta=M_PI, double phi=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);
+    };
+
+    /**@class Paraboloid Shapes.h 
+     *
+     *   @author  M.Frank
+     *   @version 1.0
+     */
+    struct Paraboloid : public Solid_type<TGeoParaboloid> {
+      /// Constructor to be used when reading the already parsed object
+      template <typename Q> Paraboloid(const Handle<Q>& e) : Solid_type<Implementation>(e) {}
+
+      /// Constructor to be used when creating a new anonymous object
+      Paraboloid();
+      /// Constructor to be used when creating a new identified object
+      Paraboloid(const std::string& name);
+      /// Constructor to be used when creating a new anonymous object with attribute initialization
+      Paraboloid(double r_low, double r_high, double delta_z);
+      /// Constructor to be used when creating a new identified object with attribute initialization
+      Paraboloid(const std::string& name, double r_low, double r_high, double delta_z);
+      /// Set the Paraboloid dimensions
+      Paraboloid& setDimensions(double r_low, double r_high, double delta_z);
+    };
+
     /**@class PolyhedraRegular Shapes.h 
      *
      *   @author  M.Frank
@@ -258,8 +383,11 @@ namespace DD4hep {
       /// Constructor to be used when reading the already parsed object
       template <typename Q> 
       PolyhedraRegular(const Handle<Q>& e) : Solid_type<Implementation>(e) {}
+
       /// Constructor to be used when creating a new object
-      PolyhedraRegular(LCDD& lcdd, const std::string& name, int nsides, double rmin, double rmax, double zlen);
+      PolyhedraRegular(int nsides, double rmin, double rmax, double zlen);
+      /// Constructor to be used when creating a new object
+      PolyhedraRegular(const std::string& name, int nsides, double rmin, double rmax, double zlen);
     };
 
     /**@class BooleanSolid Shapes.h 
@@ -276,9 +404,6 @@ namespace DD4hep {
       /// Constructor to be used when reading the already parsed object
       template <typename Q> 
       BooleanSolid(const Handle<Q>& e) : Solid_type<Implementation>(e) {}
-
-      /// Constructor to be used when creating a new object
-      BooleanSolid(LCDD& lcdd, const std::string& type, const std::string& name, const std::string& expr);
     };
 
     /**@class SubtractionSolid Shapes.h 
@@ -290,11 +415,37 @@ namespace DD4hep {
       /// Constructor to be used when reading the already parsed object
       template<typename Q> SubtractionSolid(const Handle<Q>& e) : BooleanSolid(e) {}
       /// Constructor to be used when creating a new object
-      SubtractionSolid(LCDD& lcdd, const std::string& name, const std::string& expr);
+      SubtractionSolid(const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot);
+       /// Constructor to be used when creating a new object
+      SubtractionSolid(const std::string& name, const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot);
+   };
+
+    /**@class UnionSolid Shapes.h 
+     *
+     *   @author  M.Frank
+     *   @version 1.0
+     */
+    struct UnionSolid : public BooleanSolid  {
+      /// Constructor to be used when reading the already parsed object
+      template<typename Q> UnionSolid(const Handle<Q>& e) : BooleanSolid(e) {}
+      /// Constructor to be used when creating a new object
+      UnionSolid(const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot);
+      /// Constructor to be used when creating a new object
+      UnionSolid(const std::string& name, const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot);
+    };
+
+    /**@class IntersectionSolid Shapes.h 
+     *
+     *   @author  M.Frank
+     *   @version 1.0
+     */
+    struct IntersectionSolid : public BooleanSolid  {
+      /// Constructor to be used when reading the already parsed object
+      template<typename Q> IntersectionSolid(const Handle<Q>& e) : BooleanSolid(e) {}
       /// Constructor to be used when creating a new object
-      SubtractionSolid(LCDD& lcdd, const std::string& name, const Solid& shape1, const Solid& shape2);
+      IntersectionSolid(const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot);
       /// Constructor to be used when creating a new object
-      SubtractionSolid(LCDD& lcdd, const std::string& name, const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot);
+      IntersectionSolid(const std::string& name, const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot);
     };
 
   }       /* End namespace Geometry           */
diff --git a/DDCore/include/DD4hep/Volumes.h b/DDCore/include/DD4hep/Volumes.h
index 07dba2baa7e9c27503b87062f11be5c33a55ae96..0ce4a19c7d93c4631eaa0077f56a8f12f104018e 100644
--- a/DDCore/include/DD4hep/Volumes.h
+++ b/DDCore/include/DD4hep/Volumes.h
@@ -90,6 +90,11 @@ namespace DD4hep {
      *  @version 1.0
      */
     struct Volume : public Handle<TGeoVolume>  {
+      protected:
+      //void inc_ref();
+      //void dec_ref();
+
+      public:
       typedef Handle<TGeoVolume> Base;
       struct Object  {
         unsigned long magic;
@@ -97,7 +102,8 @@ namespace DD4hep {
         LimitSet      limits;
         VisAttr       vis;
         Ref_t         sens_det;
-        Object() : region(), limits(), vis(), sens_det() {}
+	int           referenced;
+        Object() : region(), limits(), vis(), sens_det(), referenced(0)  {}
       };
       /// Default constructor
       Volume() : Base(0) {}
@@ -109,10 +115,10 @@ namespace DD4hep {
       template <typename T> Volume(const Handle<T>& v) : Base(v) {}
       
       /// Constructor to be used when creating a new geometry tree.
-      Volume(LCDD& lcdd, const std::string& name);
+      Volume(const std::string& name);
       
       /// Constructor to be used when creating a new geometry tree. Also sets materuial and solid attributes
-      Volume(LCDD& lcddument, const std::string& name, const Solid& s, const Material& m);
+      Volume(const std::string& name, const Solid& s, const Material& m);
       
       /// Place daughter volume. The position and rotation are the identity
       PlacedVolume placeVolume(const Volume& vol)  const  
@@ -189,7 +195,7 @@ namespace DD4hep {
       template <typename T> Assembly(const Handle<T>& v) : Volume(v) {}
       
       /// Constructor to be used when creating a new geometry tree.
-      Assembly(LCDD& lcdd, const std::string& name);
+      Assembly(const std::string& name);
     };
 
   }       /* End namespace Geometry           */
diff --git a/DDCore/include/XML/XMLDetector.h b/DDCore/include/XML/XMLDetector.h
index af41be26c337832989b4c14a88def441cbaa0bfa..ea5457988d9260a49ca38d74b6fdc0552572a485 100644
--- a/DDCore/include/XML/XMLDetector.h
+++ b/DDCore/include/XML/XMLDetector.h
@@ -6,8 +6,8 @@
 //  Author     : M.Frank
 //
 //====================================================================
-#ifndef DD4hep_XMLDETECTOR_H
-#define DD4hep_XMLDETECTOR_H
+#ifndef DD4HEP_XMLDETECTOR_H
+#define DD4HEP_XMLDETECTOR_H
 
 // Framework include files
 #include "XML/XMLTags.h"
@@ -138,4 +138,4 @@ namespace DD4hep {
     };
   }
 }         /* End namespace DD4hep       */
-#endif    /* DD4hep_XMLDETECTOR_H    */
+#endif    /* DD4HEP_XMLDETECTOR_H    */
diff --git a/DDCore/src/Detector.cpp b/DDCore/src/Detector.cpp
index bc2c7913025770464d545f2a4d4f0de76d61b7de..e77e86ad1cdbba46754a3940c71293424ca470c5 100644
--- a/DDCore/src/Detector.cpp
+++ b/DDCore/src/Detector.cpp
@@ -47,11 +47,34 @@ static bool traverse_up(const DetElement& parent, const DetElement& child, vecto
   return true;
 }
 #include <iostream>
+static string find_path(TGeoNode* top, TGeoNode* child) {
+  if ( top == child ) {
+    return child->GetName();
+  }
+  TIter next(top->GetVolume()->GetNodes());
+  for (TGeoNode *daughter=(TGeoNode*)next(); daughter; daughter=(TGeoNode*)next() ) {
+    if ( daughter == child )   {
+      return child->GetName();
+    }
+  }
+  next.Reset();
+  for (TGeoNode *daughter=(TGeoNode*)next(); daughter; daughter=(TGeoNode*)next() ) {
+    string res = find_path(daughter, child);
+    if ( !res.empty() ) {
+      return top->GetName() + ("/"+res);
+    }
+  }
+  return "";
+}
+
 static string find_child(TGeoNode* top, TGeoNode* child, vector<TGeoNode*>& path) {
+  if ( top == child ) {
+    path.push_back(child);
+    return child->GetName();
+  }
   TIter next(top->GetVolume()->GetNodes());
   for (TGeoNode *daughter=(TGeoNode*)next(); daughter; daughter=(TGeoNode*)next() ) {
     if ( daughter == child )   {
-      cout << "Found child:" << child->GetName() << endl;
       path.push_back(daughter);
       return child->GetName();
     }
@@ -112,6 +135,16 @@ static TGeoHMatrix* create_trafo(const Ref_t& parent, const Ref_t& child)   {
     throw runtime_error("DetElement cannot connect nonexisting parent to not-existing child!");
 }
 
+/// Top detector element
+static DetElement _top(DetElement o)   {
+  DetElement par = o, pp = o;
+  while(par.isValid()) {
+    if ( par.placement().isValid() ) pp = par;
+    par = par.parent();
+  }
+  return pp;
+}
+
 /// Default constructor
 DetElement::Object::Object()  
   : magic(magic_word()), id(0), combine_hits(0), readout(), 
@@ -149,18 +182,11 @@ void DetElement::Object::deepCopy(const Object& source, int new_id, int flag)  {
       child._data().parent = self;
     }
     else {
-      throw runtime_error("DetElement::add: Element "+string(child.name())+" is already present [Double-Insert]");
+      throw runtime_error("DetElement::copy: Element "+string(child.name())+" is already present [Double-Insert]");
     }
   }
 }
 
-/// Top detector element
-Ref_t DetElement::Object::top()   {
-  // This is an ugly staement. Need to rethink it a bit.....(MSF)
-  if ( !this->parent.isValid() )  return this->asRef();
-  return DetElement(this->parent)._data().top();
-}
-
 /// Conversion to reference object
 Ref_t DetElement::Object::asRef() {
   return Ref_t(dynamic_cast<Value<TNamed,DetElement::Object>*>(this));
@@ -174,7 +200,7 @@ DetElement::Object::operator Ref_t() {
 /// Create cached matrix to transform to world coordinates
 TGeoMatrix* DetElement::Object::worldTransformation() {
   if ( !worldTrafo ) {
-    DetElement top_det(this->top());
+    DetElement top_det = _top(DetElement(asRef()));
     vector<TGeoMatrix*> trafos;
     TGeoHMatrix* mat = create_trafo(top_det,asRef());
     // Now we got the point in the top-most detector element. We now have
@@ -209,17 +235,35 @@ TGeoMatrix* DetElement::Object::referenceTransformation() {
 }
 
 /// Constructor for a new subdetector element
-DetElement::DetElement(const LCDD& /* lcdd */, const string& name, const string& type, int id)
-{
+DetElement::DetElement(const string& name, const string& type, int id)   {
   assign(new Value<TNamed,Object>(),name,type);
   _data().id = id;
 }
 
 /// Constructor for a new subdetector element
-DetElement::DetElement(const string& name, const string& type, int id)
-{
-  assign(new Value<TNamed,Object>(),name,type);
+DetElement::DetElement(const string& name, int id)   {
+  assign(new Value<TNamed,Object>(),name,"");
+  _data().id = id;
+}
+
+/// Constructor for a new subdetector element
+DetElement::DetElement(DetElement parent, const string& name, int id)   {
+  assign(new Value<TNamed,Object>(),name,"");
   _data().id = id;
+  parent.add(*this);
+}
+
+/// Access to the full path to the placed object
+std::string DetElement::placementPath() const {
+  if ( isValid() ) {
+    Object& o = _data();
+    if ( o.placementPath.empty() ) {
+      DetElement top =_top(*this);
+      o.placementPath = find_path(top.placement().ptr(),placement().ptr());
+    }
+    return o.placementPath;
+  }
+  return "";
 }
 
 string DetElement::type() const   {
@@ -261,9 +305,20 @@ const DetElement::Children& DetElement::children() const   {
 
 /// Access to individual children by name
 DetElement DetElement::child(const std::string& name) const {
-  const Children& c = _data().children;
-  Children::const_iterator i = c.find(name);
-  return i == c.end() ? DetElement() : (*i).second;
+  if ( isValid() )  {
+    const Children& c = _data().children;
+    Children::const_iterator i = c.find(name);
+    return i == c.end() ? DetElement() : (*i).second;
+  }
+  return DetElement();
+}
+
+/// Access to the detector elements's parent
+DetElement DetElement::parent() const {
+  if ( isValid() )  {
+    return _data().parent;
+  }
+  return DetElement();
 }
 
 void DetElement::check(bool condition, const string& msg) const  {
@@ -272,7 +327,7 @@ void DetElement::check(bool condition, const string& msg) const  {
   }
 }
 
-DetElement& DetElement::add(const DetElement& sdet)  {
+DetElement& DetElement::add(DetElement sdet)  {
   if ( isValid() )  {
     pair<Children::iterator,bool> r = _data().children.insert(make_pair(sdet.name(),sdet));
     if ( r.second )   {
@@ -316,45 +371,35 @@ DetElement& DetElement::setPlacement(const PlacedVolume& placement) {
       Object& o   = _data();
       o.placement = placement;
       o.volume    = placement.volume();
-      //placement.setDetElement(*this);
       return *this;
     }
-    throw runtime_error("DetElement::addPlacement: Placement is not defined [Invalid Handle]");
+    throw runtime_error("DetElement::setPlacement: Placement is not defined [Invalid Handle]");
   }
-  throw runtime_error("DetElement::addPlacement: Self is not defined [Invalid Handle]");
-}
-#if 0
-DetElement::Placements DetElement::placements() const    {
-  return _data().placements;
+  throw runtime_error("DetElement::setPlacement: Self is not defined [Invalid Handle]");
 }
 
-// OBSOLETE: to be replaced by setPlacement
-DetElement& DetElement::addPlacement(const PlacedVolume& placement)  {
-  if ( isValid() ) {
-    if ( placement.isValid() )  {
-      _data().placements.push_back(placement);
-      setPlacement(placement);
-      return *this;
-    }
-    throw runtime_error("DetElement::addPlacement: Placement is not defined [Invalid Handle]");
-  }
-  throw runtime_error("DetElement::addPlacement: Self is not defined [Invalid Handle]");
-}
-#endif
 /// Access to the logical volume of the placements (all daughters have the same!)
-Volume DetElement::volume() const {
+Volume DetElement::volume() const   {
   if ( isValid() )  {
     return _data().volume;
   }
   throw runtime_error("DetElement::volume: Self is not defined [Invalid Handle]");
 }
-
+#if 0
+/// Set the logical volume of the placements (all daughters have the same!)
+void DetElement::setVolume(Volume vol) {
+  if ( isValid() )  {
+    _data().volume = vol;
+  }
+  throw runtime_error("DetElement::setVolume: Self is not defined [Invalid Handle]");
+}
+#endif
 DetElement& DetElement::setVisAttributes(const LCDD& lcdd, const string& name, const Volume& volume)  {
   if ( isValid() )  {
     volume.setVisAttributes(lcdd,name);
     return *this;
   }
-  throw runtime_error("DetElement::setRegion: Self is not defined [Invalid Handle]");
+  throw runtime_error("DetElement::setVisAttributes: Self is not defined [Invalid Handle]");
 }
 
 DetElement& DetElement::setRegion(const LCDD& lcdd, const string& name, const Volume& volume)  {
diff --git a/DDCore/src/Geant4Converter.cpp b/DDCore/src/Geant4Converter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f57928b91d1569e2a16b2646b0686a338e12b44d
--- /dev/null
+++ b/DDCore/src/Geant4Converter.cpp
@@ -0,0 +1,313 @@
+// $Id:$
+//====================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+
+#include "DD4hep/LCDD.h"
+#include "Geant4Converter.h"
+// ROOT includes
+#include "TROOT.h"
+#include "TColor.h"
+#include "TGeoShape.h"
+#include "TGeoCone.h"
+#include "TGeoParaboloid.h"
+#include "TGeoPcon.h"
+#include "TGeoPgon.h"
+#include "TGeoSphere.h"
+#include "TGeoTorus.h"
+#include "TGeoTube.h"
+#include "TGeoTrd1.h"
+#include "TGeoTrd2.h"
+#include "TGeoArb8.h"
+#include "TGeoMatrix.h"
+#include "TGeoBoolNode.h"
+#include "TGeoCompositeShape.h"
+#include "TGeoNode.h"
+#include "TClass.h"
+#include "TMath.h"
+#include <iostream>
+
+using namespace DD4hep::Geometry;
+using namespace DD4hep;
+using namespace std;
+
+namespace {
+  static string indent = "";
+  struct MyTransform3D : public G4Transform3D {
+    MyTransform3D() : G4Transform3D() {}
+    // Set transformation matrix
+    void set(double XX, double XY, double XZ, double DX,
+	     double YX, double YY, double YZ, double DY,
+	     double ZX, double ZY, double ZZ, double DZ) {}
+    //  { G4Transform3D::setTransform(XX,XY,XZ,DX,YX,YY,YZ,DY,ZX,ZY,ZZ,DZ);  }
+  };
+}
+
+/// Dump element in GDML format to output stream
+void* Geant4Converter::handleElement(const string& name, const TGeoElement* element) const {
+  G4Element* g4e = data().g4Elements[element];
+  if ( !g4e ) {
+    g4e = G4Element::GetElement(name,false);
+    if ( !g4e ) {
+      if ( element->GetNisotopes() > 1 ) {
+	g4e = new G4Element(name,element->GetTitle(),element->GetNisotopes());
+	for(int i=0, n=element->GetNisotopes(); i<n; ++i) {
+	  TGeoIsotope*  iso = element->GetIsotope(i);
+	  G4Isotope*  g4iso = G4Isotope::GetIsotope(iso->GetName(),false);
+	  if ( !g4iso ) {
+	    g4iso = new G4Isotope(iso->GetName(),iso->GetZ(),iso->GetN(),iso->GetA());
+	  }
+	  g4e->AddIsotope(g4iso,element->GetRelativeAbundance(i));
+	}
+      }
+      else {
+	g4e = new G4Element(name,element->GetTitle(),element->A(),element->Z());
+      }
+    }
+    data().g4Elements[element] = g4e;
+  }
+  return g4e;
+}
+
+/// Dump material in GDML format to output stream
+void* Geant4Converter::handleMaterial(const std::string& name, const TGeoMedium* medium) const {
+  G4Material* mat = data().g4Materials[medium];
+  if ( !mat ) {
+    mat = G4Material::GetMaterial(name,false);
+    if ( !mat ) {
+      TGeoMaterial* m = medium->GetMaterial();
+      if ( m->IsMixture() ) {
+	TGeoMixture* mix = (TGeoMixture*)m;
+	mat = new G4Material(name,mix->GetDensity(),mix->GetNelements());
+	for(int i=0, n=mix->GetNelements(); i<n; ++i) {
+	  TGeoElement*  e = mix->GetElement(i);
+	  G4Element*  g4e = (G4Element*)handleElement(e->GetName(),e);
+	  mat->AddElement(g4e,(mix->GetWmixt())[i]);
+	}
+      }
+      else {
+	mat = new G4Material(name,m->GetZ(),m->GetA(),m->GetDensity());
+      }
+    }
+    data().g4Materials[medium] = mat;
+  }
+  return mat;
+}
+
+/// Dump solid in GDML format to output stream
+void* Geant4Converter::handleSolid(const string& name, const TGeoShape* shape)   const   {
+  G4VSolid* solid = data().g4Solids[shape];
+  if ( !solid && shape ) {
+    if ( shape->IsA() == TGeoBBox::Class() ) {
+      const TGeoBBox* s = (const TGeoBBox*)shape;
+      solid = new G4Box(name,s->GetDX()*CM_2_MM,s->GetDY()*CM_2_MM,s->GetDZ()*CM_2_MM);
+    }
+    else if ( shape->IsA() == TGeoTube::Class() ) {
+      const TGeoTube* s = (const TGeoTube*)shape;
+      solid = new G4Tubs(name,s->GetRmin()*CM_2_MM,s->GetRmax()*CM_2_MM,s->GetDz()*CM_2_MM,0,2.*M_PI);
+    }
+    else if ( shape->IsA() == TGeoTubeSeg::Class() ) {
+      const TGeoTubeSeg* s = (const TGeoTubeSeg*)shape;
+      solid = new G4Tubs(name,s->GetRmin()*CM_2_MM,s->GetRmax()*CM_2_MM,s->GetDz()*CM_2_MM,s->GetPhi1()*DEGREE_2_RAD,s->GetPhi2()*DEGREE_2_RAD);
+    }
+    else if ( shape->IsA() == TGeoTrd1::Class() ) {
+      const TGeoTrd1* s = (const TGeoTrd1*)shape;
+      solid = new G4Trd(name,s->GetDx1()*CM_2_MM,s->GetDx2()*CM_2_MM,s->GetDy()*CM_2_MM,s->GetDy()*CM_2_MM,s->GetDz()*CM_2_MM);
+    }
+    else if ( shape->IsA() == TGeoTrd2::Class() ) {
+      const TGeoTrd2* s = (const TGeoTrd2*)shape;
+      solid = new G4Trd(name,s->GetDx1()*CM_2_MM,s->GetDx2()*CM_2_MM,s->GetDy1()*CM_2_MM,s->GetDy2()*CM_2_MM,s->GetDz()*CM_2_MM);
+    }
+    else if ( shape->IsA() == TGeoPgon::Class() ) {
+#if 0
+      const TGeoPgon* s = (const TGeoPgon*)shape;
+#endif
+      const TGeoPcon* s = (const TGeoPcon*)shape;
+      vector<double> rmin, rmax, z;
+      for( size_t i=0; i<s->GetNz(); ++i )  {
+	rmin.push_back(s->GetRmin(i)*CM_2_MM);
+	rmax.push_back(s->GetRmax(i)*CM_2_MM);
+	z.push_back(s->GetZ(i)*CM_2_MM);
+      }
+      solid = new G4Polycone(name,s->GetPhi1()*DEGREE_2_RAD,(s->GetDphi()+s->GetPhi1())*DEGREE_2_RAD,s->GetNz(),
+			     &rmin[0], &rmax[0], &z[0]);
+    }
+    else if ( shape->IsA() == TGeoPcon::Class() ) {
+      const TGeoPcon* s = (const TGeoPcon*)shape;
+      vector<double> rmin, rmax, z;
+      for( size_t i=0; i<s->GetNz(); ++i )  {
+	rmin.push_back(s->GetRmin(i)*CM_2_MM);
+	rmax.push_back(s->GetRmax(i)*CM_2_MM);
+	z.push_back(s->GetZ(i)*CM_2_MM);
+      }
+      solid = new G4Polycone(name,s->GetPhi1()*DEGREE_2_RAD,(s->GetDphi()+s->GetPhi1())*DEGREE_2_RAD,s->GetNz(),
+			     &rmin[0], &rmax[0], &z[0]);
+    }
+    else if ( shape->IsA() == TGeoParaboloid::Class() ) {
+      const TGeoParaboloid* s = (const TGeoParaboloid*)shape;
+      solid = new G4Paraboloid(name,s->GetDz()*CM_2_MM,s->GetRlo()*CM_2_MM,s->GetRhi()*CM_2_MM);
+    }
+    else if ( shape->IsA() == TGeoSphere::Class() ) {
+      const TGeoSphere* s = (const TGeoSphere*)shape;
+      solid = new G4Sphere(name,s->GetRmin()*CM_2_MM,s->GetRmax()*CM_2_MM,
+			   s->GetPhi1()*DEGREE_2_RAD,s->GetPhi2()*DEGREE_2_RAD,
+			   s->GetTheta1()*DEGREE_2_RAD,s->GetTheta2()*DEGREE_2_RAD);
+    }
+    else if ( shape->IsA() == TGeoTorus::Class() ) {
+      const TGeoTorus* s = (const TGeoTorus*)shape;
+      solid = new G4Torus(name,s->GetRmin()*CM_2_MM,s->GetRmax()*CM_2_MM, s->GetR()*CM_2_MM,
+			  s->GetPhi1()*DEGREE_2_RAD,s->GetDphi()*DEGREE_2_RAD);
+    }
+    else if ( shape->IsA() == TGeoCompositeShape::Class() ) {
+      const TGeoCompositeShape* s = (const TGeoCompositeShape*)shape;
+      const TGeoBoolNode* boolean = s->GetBoolNode();
+      TGeoBoolNode::EGeoBoolType oper = boolean->GetBooleanOperator();
+      TGeoMatrix* m   = boolean->GetRightMatrix();
+      G4VSolid* left  = (G4VSolid*)handleSolid(name+"_left", boolean->GetLeftShape());
+      G4VSolid* right = (G4VSolid*)handleSolid(name+"_right",boolean->GetRightShape());
+      const Double_t *t = m->GetTranslation();
+      const Double_t *r = m->GetRotationMatrix();
+
+      if ( !left )   {
+	throw runtime_error("G4Converter: No left Geant4 Solid present for composite shape:"+name);
+      }
+      if ( !right )   {
+	throw runtime_error("G4Converter: No right Geant4 Solid present for composite shape:"+name);
+      }
+
+      if ( m->IsRotation()    )   {
+	MyTransform3D transform;
+	transform.set(r[0],r[1],r[2],t[0],
+		      r[3],r[4],r[5],t[1],
+		      r[6],r[7],r[8],t[3]);
+	if (      oper == TGeoBoolNode::kGeoSubtraction )
+	  solid = new G4SubtractionSolid(name,left,right,transform);
+	else if ( oper == TGeoBoolNode::kGeoUnion )
+	  solid = new G4UnionSolid(name,left,right,transform);
+	else if ( oper == TGeoBoolNode::kGeoIntersection )
+	  solid = new G4IntersectionSolid(name,left,right,transform);
+      }
+      else {
+	G4ThreeVector transform(t[0],t[1],t[2]);
+	if (      oper == TGeoBoolNode::kGeoSubtraction )
+	  solid = new G4SubtractionSolid(name,left,right,0,transform);
+	else if ( oper == TGeoBoolNode::kGeoUnion )
+	  solid = new G4UnionSolid(name,left,right,0,transform);
+	else if ( oper == TGeoBoolNode::kGeoIntersection )
+	  solid = new G4IntersectionSolid(name,left,right,0,transform);
+      }
+    }
+
+    if ( !solid ) {
+      string err = "Failed to handle unknown solid shape:" + 
+	name + " of type " + string(shape->IsA()->GetName());
+      throw runtime_error(err);
+    }
+    data().g4Solids[shape] = solid;
+  }
+  return solid;
+}
+
+/// Dump logical volume in GDML format to output stream
+void* Geant4Converter::handleVolume(const string& name, const TGeoVolume* volume)   const   {
+  const TGeoVolume* v =  volume;
+  G4LogicalVolume* vol = data().g4Volumes[v];
+  if ( !vol ) {
+    string      n =  v->GetName();
+    TGeoMedium* m =  v->GetMedium();
+    TGeoShape*  s =  v->GetShape();
+    G4VSolid*   solid  = (G4VSolid*)handleSolid(s->GetName(),s);
+    G4Material* medium = (G4Material*)handleMaterial(m->GetName(),m);
+
+    if ( !solid )   {
+      throw runtime_error("G4Converter: No Geant4 Solid present for volume:"+n);
+    }
+    if ( !medium )   {
+      throw runtime_error("G4Converter: No Geant4 material present for volume:"+n);
+    }
+    vol = new G4LogicalVolume(solid, medium, n);
+    data().g4Volumes[v] = vol;
+  }
+  return vol;
+}
+
+/// Dump volume placement in GDML format to output stream
+void* Geant4Converter::handlePlacement(const std::string& name, const TGeoNode* node) const {
+  G4PVPlacement*     g4pv   = data().g4Placements[node];
+  if ( !g4pv )   {
+    TGeoMatrix*        trafo  = node->GetMatrix();
+    if ( trafo ) {
+      const Double_t*    trans  = trafo->GetTranslation();
+      const Double_t*    rot    = trafo->GetRotationMatrix();
+      int                copy   = node->GetNumber();
+      G4LogicalVolume*   g4vol  = data().g4Volumes[node->GetVolume()];
+      G4LogicalVolume*   g4mot  = data().g4Volumes[node->GetMotherVolume()];
+
+      if ( trafo->IsRotation() )  {
+	MyTransform3D transform;
+	transform.set(rot[0],rot[1],rot[2],trans[0],
+		      rot[3],rot[4],rot[5],trans[1],
+		      rot[6],rot[7],rot[8],trans[3]);
+	g4pv = new G4PVPlacement(transform, // no rotation
+				 g4vol,     // its logical volume
+				 name,      // its name
+				 g4mot,     // its mother (logical) volume
+				 false,     // no boolean operations
+				 copy);     // its copy number
+      }
+      else {
+	G4ThreeVector pos(trans[0],trans[1],trans[2]);
+	g4pv = new G4PVPlacement(0,         // no rotation
+				 pos,       // translation position
+				 g4vol,     // its logical volume
+				 name,      // its name
+				 g4mot,     // its mother (logical) volume
+				 false,     // no boolean operations
+				 copy);     // its copy number
+      }
+      data().g4Placements[node] = g4pv;
+      //  cout << "Created volume placement:" << name << " No:" << copy << endl;
+    }
+  }
+  else {
+    cout << "Attempt to DOUBLE-place physical volume:" << name << " No:" << node->GetNumber() << endl;    
+  }
+  return g4pv;
+}
+
+template <typename O, typename C, typename F> void handle(const O* o, const C& c, F pmf)  {
+  for(typename C::const_iterator i=c.begin(); i != c.end(); ++i) {
+    (o->*pmf)((*i).first, (*i).second);
+  }
+}
+
+static void handleName(const TGeoNode* n)   {
+  TGeoVolume* v = n->GetVolume();
+  TGeoMedium* m = v->GetMedium();
+  TGeoShape*  s = v->GetShape();
+  string nam;
+  cout << "Node:'" << n->GetName() << "' Vol:'" << v->GetName() << "' Shape:'" << s->GetName() << "' Medium:'" << m->GetName() << "'" << endl;
+}
+
+void Geant4Converter::create(DetElement top) {
+  G4GeometryInfo geo;
+  m_dataPtr = &geo;
+  m_data->clear();
+  collect(top,geo);
+
+  handle(this, geo.materials, &Geant4Converter::handleMaterial);
+  handle(this, geo.solids,    &Geant4Converter::handleSolid);
+  handle(this, geo.volumes,   &Geant4Converter::handleVolume);
+
+  for(Data::const_reverse_iterator i=m_data->rbegin(); i != m_data->rend(); ++i)   {
+    const Data::mapped_type& v = (*i).second;
+    for(Data::mapped_type::const_iterator j=v.begin(); j != v.end(); ++j) {
+      handlePlacement((*j)->GetName(),*j);
+      handleName(*j);
+    }
+  }
+}
diff --git a/DDCore/src/Geant4Converter.h b/DDCore/src/Geant4Converter.h
new file mode 100644
index 0000000000000000000000000000000000000000..95fa5d8e159f0c0e37fa8aedcb084843a168ed32
--- /dev/null
+++ b/DDCore/src/Geant4Converter.h
@@ -0,0 +1,100 @@
+// $Id:$
+//====================================================================
+//  AIDA Detector description implementation
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+#ifndef DD4HEP_GEANT4CONVERTER_H
+#define DD4HEP_GEANT4CONVERTER_H
+
+#include "DD4hep/GeoHandler.h"
+#include "DD4hep/LCDD.h"
+#include <set>
+#include <map>
+#include <vector>
+class TGeoVolume;
+class TGeoNode;
+
+struct G4VAny   {  virtual ~G4VAny() {}   };
+
+template <class T> class G4AnyThing : public T {
+ public:
+  G4AnyThing() : T() {}
+  template <class A> G4AnyThing(A) : T() {}
+  template <class A,class B> G4AnyThing(A,B) : T() {}
+  template <class A,class B,class C> G4AnyThing(A,B,C) : T() {}
+  template <class A, class B, class C, class D> G4AnyThing(A,B,C,D) : T() {}
+  template <class A, class B, class C, class D, class E> G4AnyThing(A,B,C,D,E) : T() {}
+  template <class A, class B, class C, class D, class E, class F> G4AnyThing(A,B,C,D,E,F) : T() {}
+  template <class A, class B, class C, class D, class E, class F, class G> G4AnyThing(A,B,C,D,E,F,G) : T() {}
+  template <class A, class B, class C, class D, class E, class F, class G, class H> G4AnyThing(A,B,C,D,E,F,G,H) : T() {}
+  template <class A, class B, class C, class D, class E, class F, class G, class H, class I> G4AnyThing(A,B,C,D,E,F,G,H,I) : T() {}
+  void AddIsotope(void*, double) {}
+  void AddElement(void*, double) {}
+  static G4AnyThing<G4VAny>* GetIsotope(const std::string&, bool) { return 0; }
+  static G4AnyThing<G4VAny>* GetElement(const std::string&, bool) { return 0; }
+  static G4AnyThing<G4VAny>* GetMaterial(const std::string&, bool) { return 0; }
+  int GetNelements() const { return 0; }
+  double GetDensity() const { return 0.0; }
+};
+
+typedef G4VAny G4VSolid;
+typedef G4AnyThing<G4VSolid> G4Box;
+typedef G4AnyThing<G4VSolid> G4Tubs;
+typedef G4AnyThing<G4VSolid> G4Trd;
+typedef G4AnyThing<G4VSolid> G4Paraboloid;
+typedef G4AnyThing<G4VSolid> G4Polycone;
+typedef G4AnyThing<G4VSolid> G4Sphere;
+typedef G4AnyThing<G4VSolid> G4Torus;
+typedef G4AnyThing<G4VSolid> G4UnionSolid;
+typedef G4AnyThing<G4VSolid> G4SubtractionSolid;
+typedef G4AnyThing<G4VSolid> G4IntersectionSolid;
+
+typedef G4AnyThing<G4VAny>   G4LogicalVolume;
+typedef G4AnyThing<G4VAny>   G4Material;
+typedef G4AnyThing<G4VAny>   G4Element;
+typedef G4AnyThing<G4VAny>   G4Isotope;
+typedef G4AnyThing<G4VAny>   G4Transform3D;
+typedef G4AnyThing<G4VAny>   G4ThreeVector;
+typedef G4AnyThing<G4VAny>   G4PVPlacement;
+
+
+namespace DD4hep {
+  namespace Geometry {
+
+    struct Geant4Converter : public GeoHandler  {
+      struct G4GeometryInfo : public GeometryInfo {
+	std::map<const TGeoElement*,G4Element*>       g4Elements;
+	std::map<const TGeoMedium*, G4Material*>      g4Materials;
+	std::map<const TGeoShape*,  G4VSolid*>        g4Solids;
+	std::map<const TGeoVolume*, G4LogicalVolume*> g4Volumes;
+	std::map<const TGeoNode*,   G4PVPlacement*>   g4Placements;
+      };
+      G4GeometryInfo*   m_dataPtr;
+      G4GeometryInfo& data() const { return *m_dataPtr; }
+
+      /// Constructor
+      Geant4Converter() {}
+      /// Standard destructor
+      virtual ~Geant4Converter() {}
+      /// Create geometry dump
+      void create(DetElement top);
+
+      /// Dump material in GDML format to output stream
+      virtual void* handleMaterial(const std::string& name, const TGeoMedium* medium) const;
+      /// Dump element in GDML format to output stream
+      virtual void* handleElement(const std::string& name, const TGeoElement* element) const;
+      /// Dump solid in GDML format to output stream
+      virtual void* handleSolid(const std::string& name, const TGeoShape* volume) const;
+      /// Dump logical volume in GDML format to output stream
+      virtual void* handleVolume(const std::string& name, const TGeoVolume* volume) const;
+      /// Dump volume placement in GDML format to output stream
+      virtual void* handlePlacement(const std::string& name, const TGeoNode* node) const;
+    };
+  }    // End namespace Geometry
+}      // End namespace DD4hep
+
+#endif // DD4HEP_GEANT4CONVERTER_H
+
diff --git a/DDCore/src/GeoHandler.cpp b/DDCore/src/GeoHandler.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4dc91c79622c3a3e7b48ee238a1317c5130bb8f5
--- /dev/null
+++ b/DDCore/src/GeoHandler.cpp
@@ -0,0 +1,116 @@
+// $Id:$
+//====================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+
+#include "DD4hep/LCDD.h"
+#include "DD4hep/GeoHandler.h"
+
+// ROOT includes
+#include "TGeoManager.h"
+#include "TGeoCompositeShape.h"
+#include "TGeoBoolNode.h"
+
+// C/C++ include files
+#include <iostream>
+
+using namespace DD4hep::Geometry;
+using namespace DD4hep;
+using namespace std;
+
+namespace {
+  void collectSolid(GeoHandler::GeometryInfo& geo, const string& name, const string& node, TGeoShape* shape, TGeoMatrix* matrix)     {
+    if ( shape->IsA() == TGeoCompositeShape::Class() ) {
+      const TGeoCompositeShape* s = (const TGeoCompositeShape*)shape;
+      const TGeoBoolNode* boolean = s->GetBoolNode();
+      collectSolid(geo, name+"_left",  name+"_left",  boolean->GetLeftShape(),  boolean->GetLeftMatrix());
+      collectSolid(geo, name+"_right", name+"_right", boolean->GetRightShape(), boolean->GetRightMatrix());
+    }
+    geo.solids.insert(make_pair(name,shape));
+    geo.trafos.push_back(make_pair(node,matrix));
+  }
+}
+
+/// Default constructor
+GeoHandler::GeoHandler() {
+  m_data = new Data();
+}
+
+/// Initializing constructor
+GeoHandler::GeoHandler(Data* ptr) : m_data(ptr) {
+}
+
+/// Default destructor
+GeoHandler::~GeoHandler() {
+  if ( m_data ) delete m_data;
+  m_data = 0;
+}
+
+GeoHandler::Data* GeoHandler::release() {
+  Data* d = m_data;
+  m_data = 0;
+  return d;
+}
+
+GeoHandler& GeoHandler::collect(DetElement element) {
+  m_data->clear();
+  return i_collect(element.placement().ptr(),0);
+}
+
+GeoHandler& GeoHandler::collect(DetElement element, GeometryInfo& info) {
+  m_data->clear();
+  i_collect(element.placement().ptr(),0);
+  for(Data::const_reverse_iterator i=m_data->rbegin(); i != m_data->rend(); ++i)   {
+    int level = (*i).first;
+    const Data::mapped_type& v = (*i).second;
+    for(Data::mapped_type::const_iterator j=v.begin(); j != v.end(); ++j) {
+      const TGeoNode* n = *j;
+      TGeoVolume* v = n->GetVolume();
+      TGeoMedium* m = v->GetMedium();
+      Volume      vol = Handle<>(v);
+      VisAttr     vis = vol.visAttributes();
+
+      info.volumes.insert(make_pair(v->GetName(),v));
+      info.materials[m->GetName()] = m;
+      if ( vis.isValid() ) info.vis[v->GetName()] = vis;
+      collectSolid(info,v->GetName(),n->GetName(),v->GetShape(),n->GetMatrix());
+    }
+  }
+  return *this;
+}
+
+GeoHandler& GeoHandler::i_collect(const TGeoNode* current, int level) {
+  TGeoVolume* volume = current->GetVolume();
+  TObjArray*  nodes  = volume->GetNodes();
+  int   num_children = nodes ? nodes->GetEntriesFast() : 0;
+
+  (*m_data)[level].insert(current);
+  if ( num_children > 0 )   {
+    for(int i=0; i<num_children; ++i)   {
+      TGeoNode* node = (TGeoNode*)nodes->At(i);
+      i_collect(node,level+1);
+    }
+  }
+  return *this;
+}
+
+/// Initializing constructor
+GeoScan::GeoScan(DetElement e) {
+  m_data = GeoHandler().collect(e).release();
+}
+
+/// Default destructor
+GeoScan::~GeoScan() {
+  if ( m_data ) delete m_data;
+  m_data = 0;
+}
+
+/// Work callback
+GeoScan& GeoScan::operator()() {
+  return *this;
+}
+
diff --git a/DDCore/src/GeometryTreeDump.cpp b/DDCore/src/GeometryTreeDump.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e4214b7870b43a18ff5e158315db0ade54b2194e
--- /dev/null
+++ b/DDCore/src/GeometryTreeDump.cpp
@@ -0,0 +1,324 @@
+// $Id:$
+//====================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+
+#include "DD4hep/LCDD.h"
+#include "GeometryTreeDump.h"
+// ROOT includes
+#include "TROOT.h"
+#include "TColor.h"
+#include "TGeoShape.h"
+#include "TGeoCone.h"
+#include "TGeoParaboloid.h"
+#include "TGeoPcon.h"
+#include "TGeoPgon.h"
+#include "TGeoSphere.h"
+#include "TGeoTorus.h"
+#include "TGeoTube.h"
+#include "TGeoTrd1.h"
+#include "TGeoTrd2.h"
+#include "TGeoArb8.h"
+#include "TGeoMatrix.h"
+#include "TGeoBoolNode.h"
+#include "TGeoCompositeShape.h"
+#include "TClass.h"
+#include "TGeoManager.h"
+#include "TMath.h"
+#include <iostream>
+
+using namespace DD4hep::Geometry;
+using namespace DD4hep;
+using namespace std;
+
+namespace {
+  string indent = "";
+
+  /// Reference to output stream
+  std::ostream& m_output = cout;
+
+
+  void getAngles(const Double_t* m, Double_t &phi, Double_t &theta, Double_t &psi)  {
+    // Retreive Euler angles.
+    // Check if theta is 0 or 180.
+    if (TMath::Abs(1.-TMath::Abs(m[8]))<1.e-9) {      
+      theta = TMath::ACos(m[8])*RAD_2_DEGREE;
+      phi = TMath::ATan2(-m[8]*m[1],m[0])*RAD_2_DEGREE;
+      psi = 0.; // convention, phi+psi matters
+      return;
+    }
+    // sin(theta) != 0
+    phi = TMath::ATan2(m[2],-m[5]);
+    Double_t sphi = TMath::Sin(phi);
+    if (TMath::Abs(sphi)<1.e-9) theta = -TMath::ASin(m[5]/TMath::Cos(phi))*RAD_2_DEGREE;
+    else theta = TMath::ASin(m[2]/sphi)*RAD_2_DEGREE;
+    phi *= RAD_2_DEGREE;      
+    psi = TMath::ATan2(m[6],m[7])*RAD_2_DEGREE;
+  }
+}
+
+/// Dump logical volume in GDML format to output stream
+void* GeometryTreeDump::handleVolume(const string& name, const TGeoVolume* volume)   const   {
+  Volume      vol = Handle<>(volume);
+  VisAttr     vis = vol.visAttributes();
+  TGeoShape*  shape  = volume->GetShape();
+  TGeoMedium* medium = volume->GetMedium();
+  int         num    = volume->GetNdaughters();
+
+  m_output << "\t\t<volume name=\"" << name << "\">" << endl;
+  m_output << "\t\t\t<solidref ref=\"" << shape->GetName() << "\"/>" << endl;
+  m_output << "\t\t\t<materialref ref=\"" << medium->GetName() << "\"/>" << endl;
+  if ( vis.isValid() ) {
+    m_output << "\t\t\t<visref ref=\"" << vis.name() << "\"/>" << endl;
+  }
+  if ( num > 0 )   {
+    for(int i=0; i<num; ++i)   {
+      TGeoNode*   n = volume->GetNode(i);
+      TGeoVolume* v = n->GetVolume();
+      TGeoMatrix* m = n->GetMatrix();
+      m_output << "\t\t\t<physvol>" << endl;
+      m_output << "\t\t\t\t<volumeref ref=\"" << v->GetName() << "\"/>" << endl;
+      if ( m ) {
+	if ( m->IsTranslation() ) {
+	  m_output << "\t\t\t\t<positionref ref=\"" << n->GetName() << "_pos\"/>" << endl;
+	}
+	if ( m->IsRotation() ) {
+	  m_output << "\t\t\t\t<rotationref ref=\"" << n->GetName() << "_rot\"/>" << endl;
+	}
+      }
+      m_output << "\t\t\t</physvol>" << endl;
+    }
+  }
+  m_output << "\t\t</volume>" << endl;
+  return 0;
+}
+
+/// Dump solid in GDML format to output stream
+void* GeometryTreeDump::handleSolid(const string& name, const TGeoShape* shape)   const   {
+  if ( shape ) {
+    if ( shape->IsA() == TGeoBBox::Class() ) {
+      const TGeoBBox* s = (const TGeoBBox*)shape;
+      m_output << "\t\t<box name=\"" << name << "_shape\" x=\"" 
+	       << s->GetDX() << "\" y=\"" 
+	       << s->GetDY() << "\" z=\"" 
+	       << s->GetDZ() << "\" lunit=\"cm\"/>" << endl;
+    }
+    else if ( shape->IsA() == TGeoTube::Class() ) {
+      const TGeoTube* s = (const TGeoTube*)shape;
+      m_output << "\t\t<tube name=\"" << name << "_shape\" rmin=\"" 
+	       << s->GetRmin() << "\" rmax=\"" 
+	       << s->GetRmax() << "\" z=\"" 
+	       << s->GetDz() << "\" startphi=\"0.0\" deltaphi=\"360.0\" aunit=\"deg\" lunit=\"cm\"/>" << endl;
+    }
+    else if ( shape->IsA() == TGeoTubeSeg::Class() ) {
+      const TGeoTubeSeg* s = (const TGeoTubeSeg*)shape;
+      m_output << "\t\t<tube name=\"" << name << "_shape\" rmin=\"" 
+	       << s->GetRmin() << "\" rmax=\"" 
+	       << s->GetRmax() << "\" z=\"" 
+	       << s->GetDz()   << "\" startphi=\""
+	       << s->GetPhi1() << "\" deltaphi=\""
+	       << s->GetPhi2() << "\" aunit=\"deg\" lunit=\"cm\"/>" << endl;
+    }
+    else if ( shape->IsA() == TGeoTrd1::Class() ) {
+      const TGeoTrd1* s = (const TGeoTrd1*)shape;
+      m_output << "\t\t<tube name=\"" << name << "_shape\" x1=\""
+	       << s->GetDx1() << "\" x2=\""
+	       << s->GetDx2() << "\" y1=\""
+	       << s->GetDy() << "\" y2=\""
+	       << s->GetDy() << "\" z=\""
+	       << s->GetDz()  << "\" lunit=\"cm\"/>" << endl;
+    }
+    else if ( shape->IsA() == TGeoTrd2::Class() ) {
+      const TGeoTrd2* s = (const TGeoTrd2*)shape;
+      m_output << "\t\t<tube name=\"" << name << "_shape\" x1=\""
+	       << s->GetDx1() << "\" x2=\""
+	       << s->GetDx2() << "\" y1=\""
+	       << s->GetDy1() << "\" y2=\""
+	       << s->GetDy2() << "\" z=\""
+	       << s->GetDz() << "\" lunit=\"cm\"/>" << endl;
+    }
+    else if ( shape->IsA() == TGeoPgon::Class() ) {
+      const TGeoPgon* s = (const TGeoPgon*)shape;
+      m_output << "\t\t<polyhedra name=\"" << name << "_shape\" startphi=\"" 
+	       << s->GetPhi1()     << "\" deltaphi=\"" 
+	       << s->GetDphi()     << "\" numsides=\"" 
+	       << s->GetNedges()   << "\" aunit=\"deg\" lunit=\"cm\">" << endl;
+      for(int i=0; i<s->GetNz(); ++i) {
+	m_output << "\t\t\t<zplane z=\"" << s->GetZ(i)
+		 << "\" rmin=\""   << s->GetRmin(i) 
+		 << "\" rmax=\""   << s->GetRmax(i) 
+		 << "\" lunit=\"cm\"/>" << endl;
+      }
+      m_output << "\t\t</polyhedra>" << endl;
+    }
+    else if ( shape->IsA() == TGeoPcon::Class() ) {
+      const TGeoPcon* s = (const TGeoPcon*)shape;
+      m_output << "\t\t<polycone name=\"" << name << "_shape\" startphi=\"" 
+	       << s->GetPhi1()     << "\" deltaphi=\"" 
+	       << s->GetDphi()     << "\" aunit=\"deg\" lunit=\"cm\">" << endl;
+      for(int i=0; i<s->GetNz(); ++i) {
+	m_output << "\t\t\t<zplane z=\"" << s->GetZ(i)
+		 << "\" rmin=\""   << s->GetRmin(i) 
+		 << "\" rmax=\""   << s->GetRmax(i) 
+		 << "\" lunit=\"cm\"/>" << endl;
+      }
+      m_output << "\t\t</polycone>" << endl;
+    }
+    else if ( shape->IsA() == TGeoCompositeShape::Class() ) {
+      string nn = name;
+      const TGeoCompositeShape* s = (const TGeoCompositeShape*)shape;
+      const TGeoBoolNode* boolean = s->GetBoolNode();
+      TGeoBoolNode::EGeoBoolType oper = boolean->GetBooleanOperator();
+
+      handleSolid(name+"_left", boolean->GetLeftShape());
+      handleSolid(name+"_right",boolean->GetRightShape());
+
+      if (      oper == TGeoBoolNode::kGeoSubtraction )
+	m_output << "\t\t<subtraction name=\"" << nn << "\">" << endl;
+      else if ( oper == TGeoBoolNode::kGeoUnion )
+	m_output << "\t\t<union name=\"" << nn << "\">" << endl;
+      else if ( oper == TGeoBoolNode::kGeoIntersection )
+	m_output << "\t\t<intersection name=\"" << nn << "\">" << endl;
+
+      m_output << "\t\t\t<first ref=\""  << nn << "_left\"/>" << endl;
+      m_output << "\t\t\t<second ref=\"" << nn << "_right\"/>" << endl;
+      indent = "\t";
+      handleTransformation("", boolean->GetRightMatrix());
+      indent = "";
+
+      if (      oper == TGeoBoolNode::kGeoSubtraction )
+	m_output << "\t\t</subtraction>" << endl;
+      else if ( oper == TGeoBoolNode::kGeoUnion )
+	m_output << "\t\t</union>" << endl;
+      else if ( oper == TGeoBoolNode::kGeoIntersection )
+	m_output << "\t\t</intersection>" << endl;
+    }
+    else {
+      cerr << "Failed to handle unknwon solid shape:"
+	   << shape->IsA()->GetName() << endl;
+    }
+  }
+  return 0;
+}
+
+/// Dump structure information in GDML format to output stream
+void GeometryTreeDump::handleStructure(const VolumeSet& volset)   const  {
+  m_output << "\t<structure>" << endl;
+  for(VolumeSet::const_iterator i=volset.begin(); i != volset.end(); ++i)
+    handleVolume((*i).first,(*i).second);
+  m_output << "\t</structure>" << endl;
+}
+
+/// Dump single volume transformation in GDML format to output stream
+void* GeometryTreeDump::handleTransformation(const string& name, const TGeoMatrix* m) const {
+  if ( m ) {
+    if ( m->IsTranslation() ) {
+      const Double_t* f = m->GetTranslation();
+      m_output << indent << "\t\t<position ";
+      if ( !name.empty() ) m_output << "name=\"" << name << "_pos\" ";
+      m_output << "x=\"" << f[0] << "\" "
+	       << "y=\"" << f[1] << "\" "
+	       << "z=\"" << f[2] << "\" unit=\"cm\"/>" << endl;
+    }
+    if ( m->IsRotation() ) {
+      const Double_t* mat = m->GetRotationMatrix();
+      Double_t theta=0.0, phi=0.0, psi=0.0;
+      getAngles(mat, theta, phi, psi);
+      m_output << indent << "\t\t<rotation ";
+      if ( !name.empty() ) m_output << "name=\"" << name << "_rot\" ";
+      m_output << "x=\"" << theta << "\" "
+	       << "y=\"" << psi << "\" "
+	       << "z=\"" << phi << "\" unit=\"deg\"/>" << endl;
+    }
+  }
+  return 0;
+}
+
+/// Dump Transformations in GDML format to output stream
+void GeometryTreeDump::handleTransformations(const TransformSet& trafos)   const {
+  m_output << "\t<define>" << endl;
+  for(TransformSet::const_iterator i=trafos.begin(); i != trafos.end(); ++i)
+    handleTransformation((*i).first, (*i).second);
+  m_output << "\t</define>" << endl;
+}
+
+/// Dump all solids in GDML format to output stream
+void GeometryTreeDump::handleSolids(const SolidSet& solids)   const {
+  m_output << "\t<solids>" << endl;
+  for(SolidSet::const_iterator i=solids.begin(); i != solids.end(); ++i)
+    handleSolid((*i).first, (*i).second);
+  m_output << "\t</solids>" << endl;
+}
+
+/// Dump all constants in GDML format to output stream
+void GeometryTreeDump::handleDefines(const LCDD::HandleMap& defs)   const {
+  m_output << "\t<define>" << endl;
+  for(LCDD::HandleMap::const_iterator i=defs.begin(); i != defs.end(); ++i)
+    m_output << "\t\t<constant name=\"" << (*i).second->GetName() << "\" value=\"" << (*i).second->GetTitle() << "\" />" << endl;
+  m_output << "\t</define>" << endl;
+}
+
+/// Dump all visualisation specs in LCDD format to output stream
+void GeometryTreeDump::handleVisualisation(const LCDD::HandleMap& )   const {
+}
+
+static string _path = "";
+static void dumpStructure(PlacedVolume pv, int level) {
+  TGeoNode*   current = pv.ptr();
+  TGeoVolume* volume  = current->GetVolume();
+  TObjArray*  nodes   = volume->GetNodes();
+  int   num_children  = nodes ? nodes->GetEntriesFast() : 0;
+  char fmt[128];
+
+  _path += "/";
+  _path += current->GetName();
+  ::sprintf(fmt, "%%4d %%%ds %%7s %%s\n",level*2+5);
+  ::printf(fmt,level,"","->LV:  ",volume->GetName());
+  ::printf(fmt,level,"","->PV:  ",current->GetName());
+  ::printf(fmt,level,"","->path:",_path.c_str());
+  if ( num_children > 0 )   {
+    for(int i=0; i<num_children; ++i)   {
+      TGeoNode* node = (TGeoNode*)nodes->At(i);
+      dumpStructure(PlacedVolume(node),level+1);
+    }
+  }
+  _path = _path.substr(0,_path.length()-1-strlen(current->GetName()));
+}
+
+static void dumpDetectors(DetElement parent,int level) {
+  const DetElement::Children& children = parent.children();
+  PlacedVolume pl = parent.placement();
+  char fmt[128];
+
+  _path += "/";
+  _path += parent.name();
+  ::sprintf(fmt, "%%4d %%%ds %%7s %%s\n",level*2+5);
+  ::printf(fmt,level,"","->path:",_path.c_str());
+  if ( pl.isValid() ) {
+    ::printf(fmt,level,"","   ->placement:",parent.placementPath().c_str());
+    ::printf(fmt,level,"","   ->logvol:   ",pl->GetVolume()->GetName());
+    ::printf(fmt,level,"","   ->shape:    ",pl->GetVolume()->GetShape()->GetName());
+  }
+  for(DetElement::Children::const_iterator i=children.begin(); i!=children.end();++i) {
+    dumpDetectors((*i).second,level+1);
+  }
+  _path = _path.substr(0,_path.length()-1-strlen(parent.name()));
+}
+
+void GeometryTreeDump::create(DetElement top) {
+  //PlacedVolume pv = top.placement();
+  dumpDetectors(top,0);
+  dumpStructure(top.placement(),0);
+  //GeometryInfo geo;
+  //collect(top,geo);
+  //handleSetup(LCDD::getInstance().header());
+  //handleDefines(LCDD::getInstance().constants());
+  //handleVisualisation(geo.vis);
+  //handleTransformations(geo.trafos);
+  //handleSolids(geo.solids);
+  //handleStructure(geo.volumes);
+}
diff --git a/DDCore/src/GeometryTreeDump.h b/DDCore/src/GeometryTreeDump.h
new file mode 100644
index 0000000000000000000000000000000000000000..955fbf42ba6d75eede8c2734a02e46f892b238e5
--- /dev/null
+++ b/DDCore/src/GeometryTreeDump.h
@@ -0,0 +1,64 @@
+// $Id:$
+//====================================================================
+//  AIDA Detector description implementation
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+#ifndef DD4HEP_GeometryTreeDump_H
+#define DD4HEP_GeometryTreeDump_H
+
+#include "DD4hep/LCDD.h"
+#include "DD4hep/GeoHandler.h"
+#include <set>
+#include <map>
+#include <vector>
+class TGeoVolume;
+class TGeoNode;
+
+/*
+ *   DD4hep namespace declaration
+ */
+namespace DD4hep {
+
+  /*
+   *   Geometry namespace declaration
+   */
+  namespace Geometry {
+
+    /** @class GeometryTreeDump  GeometryTreeDump.h
+     *
+     * @author  M.Frank
+     * @version 1.0
+     */
+    struct GeometryTreeDump : public GeoHandler  {
+      GeometryTreeDump() {}
+      /// Standard destructor
+      virtual ~GeometryTreeDump() {}
+      /// Main entry point: create required object(s)
+      void create(DetElement top);
+
+      /// Dump logical volume in GDML format to output stream
+      virtual void* handleVolume(const std::string& name, const TGeoVolume* volume) const;
+      /// Dump single volume transformation in GDML format to output stream
+      virtual void* handleTransformation(const std::string& name, const TGeoMatrix* matrix) const;
+      /// Dump solid in GDML format to output stream
+      virtual void* handleSolid(const std::string& name, const TGeoShape* volume) const;
+
+      /// Dump all constants in GDML format to output stream
+      virtual void handleDefines(const LCDD::HandleMap& defs) const;
+      /// Dump all visualisation specs in LCDD format to output stream
+      void handleVisualisation(const LCDD::HandleMap& vis)   const;
+      /// Dump all solids in GDML format to output stream
+      virtual void handleSolids(const SolidSet& solids) const;
+      /// Dump Transformations in GDML format to output stream
+      virtual void handleTransformations(const TransformSet& trafos) const;
+      /// Dump structure information in GDML format to output stream
+      virtual void handleStructure(const VolumeSet& volset)  const;
+    };
+  }    // End namespace Geometry
+}      // End namespace DD4hep
+
+#endif // DD4HEP_GeometryTreeDump_H
+
diff --git a/DDCore/src/Handle.cpp b/DDCore/src/Handle.cpp
index 4634570c8aa5945b5970df8531ee3ca28403fdda..f11a672d6d80952178dba7b764afc3a29adb3128 100644
--- a/DDCore/src/Handle.cpp
+++ b/DDCore/src/Handle.cpp
@@ -171,6 +171,7 @@ INSTANTIATE(TGeoNodeOffset);
 #include "TGeoCone.h"
 #include "TGeoArb8.h"
 #include "TGeoTrd2.h"
+#include "TGeoParaboloid.h"
 #include "TGeoSphere.h"
 #include "TGeoTorus.h"
 #include "TGeoBoolNode.h"
@@ -178,13 +179,14 @@ INSTANTIATE(TGeoNodeOffset);
 #include "TGeoCompositeShape.h"
 INSTANTIATE(TGeoVolume);
 INSTANTIATE(TGeoBBox);
+INSTANTIATE(TGeoCone);
+INSTANTIATE(TGeoParaboloid);
 INSTANTIATE(TGeoPcon);
 INSTANTIATE(TGeoPgon);
 INSTANTIATE(TGeoTube);
 INSTANTIATE(TGeoTubeSeg);
 INSTANTIATE(TGeoTrap);
 INSTANTIATE(TGeoTrd2);
-INSTANTIATE(TGeoCone);
 INSTANTIATE(TGeoSphere);
 INSTANTIATE(TGeoTorus);
 INSTANTIATE(TGeoShape);
diff --git a/DDCore/src/LCDDImp.cpp b/DDCore/src/LCDDImp.cpp
index a61ac1d1fe7d7f9155efeebf3042e6e9de5d2b1f..3e0796bd5a7383f18ab6da5c813b39704efe8efc 100644
--- a/DDCore/src/LCDDImp.cpp
+++ b/DDCore/src/LCDDImp.cpp
@@ -7,14 +7,20 @@
 //
 //====================================================================
 
+#include "DD4hep/GeoHandler.h"
 #include "LCDDImp.h"
 
 // C/C++ include files
 #include <iostream>
 #include <stdexcept>
 
+#include "TGeoCompositeShape.h"
+#include "TGeoBoolNode.h"
 #include "TGeoManager.h"
 #include "TGeoMatrix.h"
+#include "TGeoVolume.h"
+#include "TGeoShape.h"
+#include "TClass.h"
 
 #if DD4HEP_USE_PYROOT
   #include "TPython.h"
@@ -27,26 +33,27 @@ namespace DD4hep  { namespace Geometry { struct Compact; }}
 using namespace DD4hep::Geometry;
 using namespace DD4hep;
 using namespace std;
+namespace {
+  struct TopDetElement : public DetElement {
+    TopDetElement(const std::string& nam, Volume vol) : DetElement(nam,0) { _data().volume = vol;    }
+  };
+}
 
 LCDD& LCDD::getInstance() {
   static LCDD* s_lcdd = new LCDDImp();
   return *s_lcdd; 
 }
 
-LCDDImp::LCDDImp() : m_worldVol(), m_trackingVol()  {
+LCDDImp::LCDDImp() : m_world(), m_trackers(), m_worldVol(), m_trackingVol()  {
 }
 
 Volume LCDDImp::pickMotherVolume(const DetElement&) const  {     // throw if not existing
   return m_worldVol;
 }
 
-LCDD& LCDDImp::addVolume(const Ref_t& x)    {
-  m_structure.append<TGeoVolume>(x,false);
-  return *this;
-}
-
-LCDD& LCDDImp::addSolid(const Ref_t& x)    {
-  m_structure.append<TGeoShape>(x,false);
+LCDD& LCDDImp::addDetector(const Ref_t& x)    { 
+  m_detectors.append_noCheck(x);
+  m_world.add(DetElement(x));
   return *this;
 }
 
@@ -54,10 +61,6 @@ void LCDDImp::convertMaterials(const string& fname)  {
   //convertMaterials(XML::DocumentHandler().load(fname).root());
 }
 
-//void LCDDImp::convertMaterials(XML::Handle_t materials)  {
-//  Converter<Materials>(*this)(materials);
-//}
-
 void LCDDImp::addStdMaterials()   {
   convertMaterials("file:../cmt/elements.xml");
   convertMaterials("file:../cmt/materials.xml");
@@ -74,33 +77,79 @@ Handle<TObject> LCDDImp::getRefChild(const HandleMap& e, const std::string& name
   }
   return 0;
 }
+namespace {
+  struct ShapePatcher : public GeoScan {
+    ShapePatcher(DetElement e) : GeoScan(e) {}
+    GeoScan& operator()()  {
+      GeoHandler::Data& data = *m_data;
+      string nam;
+      for(GeoHandler::Data::const_reverse_iterator i=data.rbegin(); i != data.rend(); ++i)   {
+	const GeoHandler::Data::mapped_type& v = (*i).second;
+	for(GeoHandler::Data::mapped_type::const_iterator j=v.begin(); j != v.end(); ++j) {
+	  const TGeoNode* n = *j;
+	  TGeoVolume* v = n->GetVolume();
+	  TGeoShape*  s = v->GetShape();
+	  if ( 0 == ::strcmp(s->GetName(),s->IsA()->GetName()) ) {
+	    nam = v->GetName();
+	    nam += "_shape";
+	    s->SetName(nam.c_str());
+	  }
+	  else {
+	    nam = s->GetName();
+	  }
+	  if ( s->IsA()->Class() == TGeoCompositeShape::Class() ) {
+	    TGeoCompositeShape* c = (TGeoCompositeShape*)s;
+	    const TGeoBoolNode* boolean = c->GetBoolNode();
+	    s = boolean->GetLeftShape();
+	    if ( 0 == ::strcmp(s->GetName(),s->IsA()->GetName()) ) {
+	      nam = v->GetName();
+	      nam += "_left";
+	      s->SetName(nam.c_str());
+	    }
+	    s = boolean->GetRightShape();
+	    if ( 0 == ::strcmp(s->GetName(),s->IsA()->GetName()) ) {
+	      nam = v->GetName();
+	      nam += "_right";
+	      s->SetName(nam.c_str());
+	    }
+	  }
+	}
+      }  
+    }
+  };
+}
 
 void LCDDImp::endDocument()  {
   LCDD& lcdd = *this;
-  Volume world  = volume("world_volume");
-  Volume trkVol = volume("tracking_volume");
   Material  air = material("Air");
 
-  world.setMaterial(air);
-  trkVol.setMaterial(air);
+  m_worldVol.setMaterial(air);
+  m_trackingVol.setMaterial(air);
 
   Region trackingRegion(lcdd,"TrackingRegion");
   trackingRegion.setThreshold(1);
   trackingRegion.setStoreSecondaries(true);
   add(trackingRegion);
-  trkVol.setRegion(trackingRegion);
+  m_trackingVol.setRegion(trackingRegion);
     
   // Set the world volume to invisible.
   VisAttr worldVis(lcdd,"WorldVis");
   worldVis.setVisible(false);
-  world.setVisAttributes(worldVis);
+  m_worldVol.setVisAttributes(worldVis);
   add(worldVis);
   
   // Set the tracking volume to invisible.
   VisAttr trackingVis(lcdd,"TrackingVis");
   trackingVis.setVisible(false);               
-  trkVol.setVisAttributes(trackingVis);
+  m_trackingVol.setVisAttributes(trackingVis);
   add(trackingVis); 
+
+  /// Since we allow now for anonymous shapes,
+  /// we will rename them to use the name of the volume they are assigned to
+  TGeoManager* mgr = gGeoManager;
+  mgr->CloseGeometry();
+  m_world.setPlacement(PlacedVolume(mgr->GetTopNode()));
+  ShapePatcher(m_world)();
 }
 
 void LCDDImp::create()  {
@@ -109,23 +158,22 @@ void LCDDImp::create()  {
 
 void LCDDImp::init()  {
   LCDD& lcdd = *this;
-  Box worldSolid(lcdd,"world_box","world_x","world_y","world_z");
+  Box worldSolid("world_box","world_x","world_y","world_z");
   Material vacuum = material("Vacuum");
-  Volume world(lcdd,"world_volume",worldSolid,vacuum);
-
-  Tube trackingSolid(lcdd,"tracking_cylinder",
+  Volume world("world_volume",worldSolid,vacuum);
+  Tube trackingSolid("tracking_cylinder",
 		     0.,
 		     _toDouble("tracking_region_radius"),
 		     _toDouble("2*tracking_region_zmax"),2*M_PI);
-  Volume tracking(lcdd,"tracking_volume",trackingSolid, vacuum);
-  //-->world.placeVolume(tracking);
-
-  //Ref_t ref_world(lcdd,"world",world.refName());
-  //m_setup.append(ref_world);
+  Volume tracking("tracking_volume",trackingSolid, vacuum);
+  m_world          = TopDetElement("world",world);
+  m_trackers       = TopDetElement("tracking",tracking);
   m_worldVol       = world;
   m_trackingVol    = tracking;
   m_materialAir    = material("Air");
   m_materialVacuum = material("Vacuum");
+  m_detectors.append_noCheck(m_world);
+  m_world.add(m_trackers);
   gGeoManager->SetTopVolume(m_worldVol);
 }
 
@@ -155,164 +203,18 @@ void LCDDImp::fromCompact(const std::string& xmlfile) {
 void LCDDImp::applyAlignment()   {
 }
 
-static void dumpChildren(const DetElement& e, int level) {
-#if 0
-  cout << "[" << level << " , " << e.placements().size() << "] ";
-  for(int j=0; j<level; ++j) cout << "...";
-  cout << e.path() << endl;
-#endif
-  for(DetElement::Children::const_iterator i=e.children().begin(); i != e.children().end(); ++i)
-    dumpChildren(DetElement((*i).second),level+1);
-}
-
-#if 0
-#include "TGeoNode.h"
+#include "SimpleGDMLWriter.h"
+#include "Geant4Converter.h"
+#include "GeometryTreeDump.h"
 
-static void dumpGeometry(vector<TGeoNode*>& globals, vector<TGeoNode*>& locals, TGeoNode* current) {
-  typedef Value<TGeoNodeMatrix,PlacedVolume::Object> _P;
-  TGeoMatrix* matrix = current->GetMatrix();
-  TGeoVolume* volume = current->GetVolume();
-  TObjArray*  nodes  = volume->GetNodes();
-  int   num_children = nodes ? nodes->GetEntriesFast() : 0;
-  _P*   val = dynamic_cast<_P*>(current);
-  static vector<DetElement> det_cache;
-  vector<TGeoNode*>   loc_cache;
-  vector<TGeoNode*>*  ptrloc_cache = &locals;
-  const char* tag = val ? "Yes" : "No ";
-  bool valid_det = false;
-  bool prt = false;
-  for(size_t i=0; i<globals.size(); ++i) {
-    if(strncmp(globals[i]->GetName(),"Muon",4)==0) { prt = true; break;}
-  }
-
-  if ( val ) {
-    DetElement d = val->detector;
-    if ( d.isValid() )   {
-      valid_det = true;
-      det_cache.push_back(d);
-      ptrloc_cache = &loc_cache;
-    }
-  }
-  if ( prt ) {
-    cout << "[" << int(globals.size()) << " , " << tag << "] \t" << (void*)current << "\t" 
-	 << char(valid_det ? '*' : ' ')
-	 << current->GetName();
-    if ( num_children > 0 )
-      cout << " #Children:" << num_children << ".";
-    else
-      cout << " No Children.";
-    cout << "\t Vol:" << volume->GetName();
-    if ( valid_det ) {
-      DetElement d = val->detector;
-      cout << " DetElement:" << d->GetName();
-      //cout << " Vol:" << d.volume().name();
-      cout << " DetTrafos:" << locals.size();
-    }
-    else  {
-      cout << " Trafos:" << locals.size();
-      for(size_t i=0; i<locals.size(); ++i)
-	cout << " " << (void*)locals[i];
-    }
-    cout << endl;
-  }
-  if ( num_children > 0 )   {
-    globals.push_back(current);
-    for(int i=0; i<num_children; ++i)   {
-      TGeoNode* node = (TGeoNode*)nodes->At(i);
-      ptrloc_cache->push_back(node);
-      dumpGeometry(globals,*ptrloc_cache,node);
-      ptrloc_cache->pop_back();
-    }
-    globals.pop_back();
-  }
-  if ( valid_det ) det_cache.pop_back();
-}
-
-vector<TGeoMatrix*>          Transformations;
-vector<TGeoSolid*>           Volumes;
-map<int, vector<TGeoNode*> > Placements;
-
-
-static void dumpGeo(TGeoNode* current) {
-
-  typedef Value<TGeoNodeMatrix,PlacedVolume::Object> _P;
-  TGeoMatrix* matrix = current->GetMatrix();
-  TGeoVolume* volume = current->GetVolume();
-  TObjArray*  nodes  = volume->GetNodes();
-  int   num_children = nodes ? nodes->GetEntriesFast() : 0;
-  _P*   val = dynamic_cast<_P*>(current);
-  static vector<DetElement> det_cache;
-  vector<TGeoNode*>   loc_cache;
-  vector<TGeoNode*>*  ptrloc_cache = &locals;
-  const char* tag = val ? "Yes" : "No ";
-  bool valid_det = false;
-  bool prt = false;
-  for(size_t i=0; i<globals.size(); ++i) {
-    if(strncmp(globals[i]->GetName(),"Muon",4)==0) { prt = true; break;}
-  }
-
-  if ( val ) {
-    DetElement d = val->detector;
-    if ( d.isValid() )   {
-      valid_det = true;
-      det_cache.push_back(d);
-      ptrloc_cache = &loc_cache;
-    }
-  }
-  if ( prt ) {
-    cout << "[" << int(globals.size()) << " , " << tag << "] \t" << (void*)current << "\t" 
-	 << char(valid_det ? '*' : ' ')
-	 << current->GetName();
-    if ( num_children > 0 )
-      cout << " #Children:" << num_children << ".";
-    else
-      cout << " No Children.";
-    cout << "\t Vol:" << volume->GetName();
-    if ( valid_det ) {
-      DetElement d = val->detector;
-      cout << " DetElement:" << d->GetName();
-      //cout << " Vol:" << d.volume().name();
-      cout << " DetTrafos:" << locals.size();
-    }
-    else  {
-      cout << " Trafos:" << locals.size();
-      for(size_t i=0; i<locals.size(); ++i)
-	cout << " " << (void*)locals[i];
-    }
-    cout << endl;
-  }
-  if ( num_children > 0 )   {
-    globals.push_back(current);
-    for(int i=0; i<num_children; ++i)   {
-      TGeoNode* node = (TGeoNode*)nodes->At(i);
-      ptrloc_cache->push_back(node);
-      dumpGeometry(globals,*ptrloc_cache,node);
-      ptrloc_cache->pop_back();
-    }
-    globals.pop_back();
-  }
-  if ( valid_det ) det_cache.pop_back();
-}
-#endif
 void LCDDImp::dump() const  {
   TGeoManager* mgr = gGeoManager;
-  mgr->CloseGeometry();
   mgr->SetVisLevel(4);
   mgr->SetVisOption(1);
   m_worldVol->Draw("ogl");
-  cout << "Total number of object verifications:" << num_object_validations() << endl;
-  //Printer<const LCDD*>(*this,cout)(this);
-  for(HandleMap::const_iterator i=detectors().begin(); i != detectors().end(); ++i) {
-    DetElement e((*i).second);
-    dumpChildren(e,0);
-    //cout << "Detector: " << (*i).first << " : " << e.name() << endl;
-  }
-#if 0
-  TGeoNode* top = mgr->GetTopNode();
-  vector<TGeoNode*> globals;
-  vector<TGeoNode*> locals;
-  //dumpGeometry(globals,locals,top);
-  //dumpGeo(top);
-#endif
-}
 
+  // SimpleGDMLWriter handler(cout);
+  // Geant4Converter handler;
+  //GeometryTreeDump handler;
+  //handler.create(m_world);
+}
diff --git a/DDCore/src/LCDDImp.h b/DDCore/src/LCDDImp.h
index 1c87cdb58afc19afb5e5da5f91b087dfad94067d..58775a4e4252af68e990e17d1f3ed01c1d64e7c7 100644
--- a/DDCore/src/LCDDImp.h
+++ b/DDCore/src/LCDDImp.h
@@ -26,9 +26,7 @@ namespace DD4hep {
    *   XML namespace declaration
    */
   namespace Geometry  {
-    
-    struct Materials {};
-    
+
     class LCDDImp : public LCDD  {
     public:
       struct InvalidObjectError : public std::runtime_error {
@@ -79,26 +77,23 @@ namespace DD4hep {
       ObjectHandleMap     m_fields;
       
       // GDML fields
-      ObjectHandleMap     m_gdml;
       ObjectHandleMap     m_define;
-      ObjectHandleMap     m_structure;
       ObjectHandleMap     m_materials;
-      ObjectHandleMap     m_solids;
-      
       
+      DetElement          m_world;
+      DetElement          m_trackers;
       Volume              m_worldVol;
       Volume              m_trackingVol;
       
       Material            m_materialAir;
       Material            m_materialVacuum;
       
-      Ref_t          m_setup;
+      Ref_t               m_setup;
       
       void convertMaterials(const std::string& uri);
-      //void convertMaterials(XML::Handle_t doc_element);
-      
       LCDDImp();
 
+		      
       /// Read compact geometry description or alignment file
       virtual void fromCompact(const std::string& fname);
       /// Apply & lock realigments
@@ -110,13 +105,15 @@ namespace DD4hep {
       virtual void endDocument();
       
       void dump() const;
-      
-      virtual Handle<TObject>  getRefChild(const HandleMap& e, const std::string& name, bool throw_if_not=true)  const;
-      virtual Volume         pickMotherVolume(const DetElement& sd) const;
-      virtual Volume         worldVolume() const      { return m_worldVol;          }
-      virtual Volume         trackingVolume() const   { return m_trackingVol;       }
-      virtual Material       air() const              { return m_materialVacuum;    }
-      virtual Material       vacuum() const           { return m_materialAir;       }
+
+      virtual Handle<TObject> getRefChild(const HandleMap& e, const std::string& name, bool throw_if_not=true)  const;
+      virtual Volume          pickMotherVolume(const DetElement& sd) const;
+      virtual DetElement      world() const            { return m_world;            }
+      virtual DetElement      trackers() const         { return m_trackers;         }
+      virtual Volume          worldVolume() const      { return m_worldVol;         }
+      virtual Volume          trackingVolume() const   { return m_trackingVol;      }
+      virtual Material        air() const              { return m_materialVacuum;   }
+      virtual Material        vacuum() const           { return m_materialAir;      }
       
       virtual LimitSet limitSet(const std::string& name)  const
       {  return getRefChild(m_limits,name);                                         }  
@@ -128,10 +125,6 @@ namespace DD4hep {
       {  return getRefChild(m_regions,name);                                        }
       virtual Ref_t  idSpec(const std::string& name)  const
       {  return getRefChild(m_idDict,name);                                         }
-      virtual Volume      volume(const std::string& name)  const
-      {  return getRefChild(m_structure,name);                                      }
-      virtual Solid       solid(const std::string& name) const 
-      {  return getRefChild(solids(),name);                                         }
       virtual Constant    constant(const std::string& name) const 
       {  return getRefChild(m_define,name);                                         }
       virtual Readout     readout(const std::string& name)  const
@@ -144,8 +137,6 @@ namespace DD4hep {
       virtual const HandleMap& header()  const        { return m_header;            }
       virtual const HandleMap& constants() const      { return m_define;            }
       virtual const HandleMap& visAttributes() const  { return m_display;           }
-      virtual const HandleMap& structure()  const     { return m_structure;         }
-      virtual const HandleMap& solids()  const        { return m_solids;            }
       virtual const HandleMap& limitsets()  const     { return m_limits;            }
       virtual const HandleMap& regions() const        { return m_regions;           }
       virtual const HandleMap& materials()  const     { return m_materials;         }
@@ -154,8 +145,6 @@ namespace DD4hep {
       virtual const HandleMap& alignments()  const    { return m_alignments;        }
       
       virtual LCDD& add(const Constant& x)            { return addConstant(x);      }
-      virtual LCDD& add(const Solid& x)               { return addSolid(x);         }
-      virtual LCDD& add(const Volume& x)              { return addVolume(x);        }
       virtual LCDD& add(const Material& x)            { return addMaterial(x);      }
       virtual LCDD& add(const LimitSet& x)            { return addLimitSet(x);      }
       virtual LCDD& add(const Region& x)              { return addRegion(x);        }
@@ -165,10 +154,6 @@ namespace DD4hep {
       virtual LCDD& add(const DetElement& x)          { return addDetector(x);      }
       
 #define __R  return *this
-      // These are manager by the TGeoManager
-      virtual LCDD& addSolid(const Ref_t& x);       //  { m_solids.append(x);     __R;}
-      virtual LCDD& addVolume(const Ref_t& x);      //  { m_structure.append(x);  __R;}
-      
       // These not:
       virtual LCDD& addConstant(const Ref_t& x)         { m_define.append(x,false);     __R;}
       virtual LCDD& addMaterial(const Ref_t& x)         { m_materials.append(x);  __R;}
@@ -178,7 +163,7 @@ namespace DD4hep {
       virtual LCDD& addReadout(const Ref_t& x)          { m_readouts.append(x);   __R;}
       virtual LCDD& addVisAttribute(const Ref_t& x)     { m_display.append(x);    __R;}
       virtual LCDD& addSensitiveDetector(const Ref_t& x){ m_sensitive.append(x);  __R;}
-      virtual LCDD& addDetector(const Ref_t& x)         { m_detectors.append_noCheck(x);  __R;}
+      virtual LCDD& addDetector(const Ref_t& x);    //  { m_detectors.append_noCheck(x);  __R;}
 
       virtual LCDD& addAlignment(const Ref_t& x)        { m_alignments.append(x); __R;}
 #undef __R
diff --git a/DDCore/src/Objects.cpp b/DDCore/src/Objects.cpp
index 59b6a22f1d2f75fa521ba7363752041c979fa1a3..b879c72d96a6cc07e3d7c32d8d1314d007c93f8a 100644
--- a/DDCore/src/Objects.cpp
+++ b/DDCore/src/Objects.cpp
@@ -114,35 +114,81 @@ VisAttr::VisAttr(LCDD& /* lcdd */, const string& name)    {
   setAlpha(0.1f);
 }
 
+/// Get Flag to show/hide daughter elements
+bool VisAttr::showDaughters() const  {
+  return _data().showDaughters;
+}
+
 /// Set Flag to show/hide daughter elements
 void VisAttr::setShowDaughters(bool value)   {
   _data().showDaughters = value;
 }
 
+/// Get visibility flag
+bool VisAttr::visible() const   {
+  return _data().visible;
+}
+
 /// Set visibility flag
 void VisAttr::setVisible(bool value)   {
   _data().visible = value;
 }
 
+/// Get line style
+int VisAttr::lineStyle()  const {
+  return _data().lineStyle;
+}
+
 /// Set line style
 void VisAttr::setLineStyle(LineStyle value)  {
   _data().lineStyle = value;
 }
 
+/// Get drawing style
+int VisAttr::drawingStyle()  const {
+  return _data().drawingStyle;
+}
+
 /// Set drawing style
 void VisAttr::setDrawingStyle(DrawingStyle value)   {
   _data().drawingStyle = value;
 }
 
+/// Get alpha value
+float VisAttr::alpha() const  {
+  //TNamed* obj = first_value<TNamed>(*this);
+  //obj->SetAlpha(value);
+  return _data().alpha;
+}
+
 /// Set alpha value
-void VisAttr::setAlpha(float /* value */)   {
+void VisAttr::setAlpha(float value)   {
+  _data().alpha = value;
   //TNamed* obj = first_value<TNamed>(*this);
   //obj->SetAlpha(value);
 }
 
+/// Get object color
+int VisAttr::color()   const  {
+  return _data().color;
+}
+
 /// Set object color
 void VisAttr::setColor(float red, float green, float blue)   {
-  _data().color = TColor::GetColor(red,green,blue);
+  Object& o = _data();
+  o.color = TColor::GetColor(red,green,blue);
+  o.col   = gROOT->GetColor(o.color);
+}
+
+/// Get RGB values of the color (if valid)
+bool VisAttr::rgb(float& red, float& green, float& blue) const {
+  Object& o = _data();
+  if ( o.col ) {
+    TColor* c = (TColor*)o.col;
+    c->GetRGB(red,green,blue);
+    return true;
+  }
+  return false;
 }
 
 /// String representation of this object
diff --git a/DDCore/src/Shapes.cpp b/DDCore/src/Shapes.cpp
index 44988ab11eae82469afa4c374da41e599d4550b4..2ca533179acd7a94bafc444cbec67603d83987ef 100644
--- a/DDCore/src/Shapes.cpp
+++ b/DDCore/src/Shapes.cpp
@@ -21,6 +21,9 @@
 #include "TGeoTube.h"
 #include "TGeoTrd2.h"
 #include "TGeoArb8.h"
+#include "TGeoParaboloid.h"
+#include "TGeoSphere.h"
+#include "TGeoTorus.h"
 #include "TGeoMatrix.h"
 #include "TGeoBoolNode.h"
 #include "TGeoCompositeShape.h"
@@ -35,10 +38,10 @@ template<typename T> void Solid_type<T>::_setDimensions(double* param) {
 
 /// Assign pointrs and register solid to geometry
 template<typename T> 
-void Solid_type<T>::_assign(LCDD& lcdd, T* n, const string& nam, const string& tit, bool cbbox) {
+void Solid_type<T>::_assign(T* n, const string& nam, const string& tit, bool cbbox) {
   this->assign(n,nam,tit);
   if ( cbbox ) n->ComputeBBox();
-  lcdd.addSolid(Solid(this->ptr()));
+  //lcdd.addSolid(Solid(this->ptr()));
 }
 
 /// Access to shape name
@@ -46,8 +49,8 @@ template<typename T> const char* Solid_type<T>::name() const {
   return this->ptr()->GetName();
 }
 
-void Box::make(LCDD& lcdd, const string& name, double x, double y, double z)  {
-  _assign(lcdd,new TGeoBBox(x,y,z),name,"box");
+void Box::make(const string& name, double x, double y, double z)  {
+  _assign(new TGeoBBox(x,y,z),name,"box");
 }
 
 /// Set the box dimensions
@@ -57,18 +60,23 @@ Box& Box::setDimensions(double x, double y, double z)   {
   return *this;
 }
 
-/// Constructor to be used when creating a new DOM tree
-Polycone::Polycone(LCDD& lcdd, const string& name)   {
-  _assign(lcdd,new TGeoPcon(0,RAD_2_DEGREE * (2.*M_PI),0),name,"polycone",false);
+/// Constructor to be used when creating a new object
+Polycone::Polycone(const string& name)   {
+  _assign(new TGeoPcon(0,RAD_2_DEGREE * (2.*M_PI),0),name,"polycone",false);
+}
+
+/// Constructor to be used when creating a new object
+Polycone::Polycone(double start, double delta)   {
+  _assign(new TGeoPcon(RAD_2_DEGREE*start,RAD_2_DEGREE*delta,0),"","polycone",false);
 }
 
-/// Constructor to be used when creating a new DOM tree
-Polycone::Polycone(LCDD& lcdd, const string& name, double start, double delta)   {
-  _assign(lcdd,new TGeoPcon(RAD_2_DEGREE*start,RAD_2_DEGREE*delta,0),name,"polycone",false);
+/// Constructor to be used when creating a new object
+Polycone::Polycone(const string& name, double start, double delta)   {
+  _assign(new TGeoPcon(RAD_2_DEGREE*start,RAD_2_DEGREE*delta,0),name,"polycone",false);
 }
 
 /// Constructor to be used when creating a new polycone object. Add at the same time all Z planes
-Polycone::Polycone(LCDD& lcdd, const string& name, double start, double delta, const vector<double>& rmin, const vector<double>& rmax, const vector<double>& z)
+Polycone::Polycone(double start, double delta, const vector<double>& rmin, const vector<double>& rmax, const vector<double>& z)
 {
   vector<double> params;
   if ( rmin.size() < 2 )  {
@@ -82,7 +90,25 @@ Polycone::Polycone(LCDD& lcdd, const string& name, double start, double delta, c
     params.push_back(rmin[i]);
     params.push_back(rmax[i]);
   }
-  _assign(lcdd, new TGeoPcon(&params[0]),name,"polycone");
+  _assign( new TGeoPcon(&params[0]),"","polycone");
+}
+
+/// Constructor to be used when creating a new polycone object. Add at the same time all Z planes
+Polycone::Polycone(const string& name, double start, double delta, const vector<double>& rmin, const vector<double>& rmax, const vector<double>& z)
+{
+  vector<double> params;
+  if ( rmin.size() < 2 )  {
+    throw runtime_error("PolyCone::addZPlanes> Not enough Z planes. minimum is 2!");
+  }
+  params.push_back(RAD_2_DEGREE * start);
+  params.push_back(RAD_2_DEGREE * delta);
+  params.push_back(rmin.size());
+  for( size_t i=0; i<rmin.size(); ++i )  {
+    params.push_back(z[i]);
+    params.push_back(rmin[i]);
+    params.push_back(rmax[i]);
+  }
+  _assign( new TGeoPcon(&params[0]),name,"polycone");
 }
 
 /// Add Z-planes to the Polycone
@@ -109,10 +135,10 @@ void Polycone::addZPlanes(const vector<double>& rmin, const vector<double>& rmax
   _setDimensions(&params[0]);
 }
 
-/// Constructor to be used when creating a new DOM tree with attribute initialization
-void Tube::make(LCDD& lcdd, const string& name, double rmin, double rmax, double z, double deltaPhi)
+/// Constructor to be used when creating a new object with attribute initialization
+void Tube::make(const string& name, double rmin, double rmax, double z, double deltaPhi)
 {
-  _assign(lcdd,new TGeoTubeSeg(rmin,rmax,z,0.,RAD_2_DEGREE*deltaPhi),name,"tube");
+  _assign(new TGeoTubeSeg(rmin,rmax,z,0.,RAD_2_DEGREE*deltaPhi),name,"tube");
 }
 
 /// Set the tube dimensions
@@ -123,15 +149,15 @@ Tube& Tube::setDimensions(double rmin, double rmax, double z, double deltaPhi)
   return *this;
 }
 
-/// Constructor to be used when creating a new DOM tree with attribute initialization
-void Cone::make(LCDD&  lcdd, const string& name,
+/// Constructor to be used when creating a new object with attribute initialization
+void Cone::make(const string& name,
 		double z,
 		double rmin1,
 		double rmax1,
 		double rmin2,
 		double rmax2)
 {
-  _assign(lcdd,new TGeoCone(z,rmin1,rmax1,rmin2,rmax2),name,"cone");
+  _assign(new TGeoCone(z,rmin1,rmax1,rmin2,rmax2),name,"cone");
 }
 
 Cone& Cone::setDimensions(double z,double rmin1,double rmax1,double rmin2,double rmax2)  {
@@ -140,25 +166,106 @@ Cone& Cone::setDimensions(double z,double rmin1,double rmax1,double rmin2,double
   return *this;
 }
 
-/// Constructor to be used when creating a new DOM tree
-Trapezoid::Trapezoid(LCDD& lcdd, const string& name)  {
-  _assign(lcdd,new TGeoTrd2(0,0,0,0,0),name,"trd2");
+/// Constructor to be used when creating a new object
+Trapezoid::Trapezoid(const string& name)  {
+  _assign(new TGeoTrd2(0,0,0,0,0),name,"trd2");
 }
 
-/// Constructor to be used when creating a new DOM tree with attribute initialization
-Trapezoid::Trapezoid(LCDD& lcdd, const string& name, double x1, double x2, double y1, double y2, double z)  {
-  _assign(lcdd,new TGeoTrd2(x1,x2,y1,y2,z),name,"trd2");
+/// Constructor to be used when creating a new object with attribute initialization
+Trapezoid::Trapezoid(const string& name, double x1, double x2, double y1, double y2, double z)  {
+  _assign(new TGeoTrd2(x1,x2,y1,y2,z),name,"trd2");
+}
+
+/// Constructor to be used when creating a new object with attribute initialization
+Trapezoid::Trapezoid(double x1, double x2, double y1, double y2, double z)  {
+  _assign(new TGeoTrd2(x1,x2,y1,y2,z),"","trd2");
 }
 
 /// Set the Trapezoid dimensions
-Trapezoid& Trapezoid::setDimensions(double x1, double x2, double y1, double y2, double z)
-{
+Trapezoid& Trapezoid::setDimensions(double x1, double x2, double y1, double y2, double z)  {
   double params[] = {x1,x2,y1,y2,z};
   _setDimensions(params);
   return *this;
 }
 
-Trap::Trap( LCDD&  lcdd, const string& name,
+/// Constructor to be used when creating a new object
+Paraboloid::Paraboloid(const string& name)  {
+  _assign(new TGeoParaboloid(0,0,0),name,"paraboloid");
+}
+
+/// Constructor to be used when creating a new identified object with attribute initialization
+Paraboloid::Paraboloid(const string& name, double r_low, double r_high, double delta_z)  {
+  _assign(new TGeoParaboloid(r_low,r_high,delta_z),name,"paraboloid");
+}
+
+/// Constructor to be used when creating a new object with attribute initialization
+Paraboloid::Paraboloid(double r_low, double r_high, double delta_z)  {
+  _assign(new TGeoParaboloid(r_low,r_high,delta_z),"","paraboloid");
+}
+
+/// Set the Paraboloid dimensions
+Paraboloid& Paraboloid::setDimensions(double r_low, double r_high, double delta_z)  {
+  double params[] = {r_low,r_high,delta_z};
+  _setDimensions(params);
+  return *this;
+}
+
+/// Constructor to be used when creating a new anonymous object
+Sphere::Sphere()  {
+  _assign(new TGeoSphere(0,0),"","sphere");
+}
+
+/// Constructor to be used when creating a new identified object
+Sphere::Sphere(const string& name)  {
+  _assign(new TGeoSphere(0,0),name,"sphere");
+}
+
+/// Constructor to be used when creating a new identified object with attribute initialization
+Sphere::Sphere(const string& name, double rmin, double rmax, double theta, double delta_theta, double phi, double delta_phi)  {
+  _assign(new TGeoSphere(rmin,rmax,theta,delta_theta,phi,delta_phi),name,"sphere");
+}
+
+/// Constructor to be used when creating a new object with attribute initialization
+Sphere::Sphere(double rmin, double rmax, double theta, double delta_theta, double phi, double delta_phi)  {
+  _assign(new TGeoSphere(rmin,rmax,theta,delta_theta,phi,delta_phi),"","sphere");
+}
+
+/// Set the Sphere dimensions
+Sphere& Sphere::setDimensions(double rmin, double rmax, double theta, double delta_theta, double phi, double delta_phi)  {
+  double params[] = {rmin,rmax,theta,delta_theta,phi,delta_phi};
+  _setDimensions(params);
+  return *this;
+}
+
+/// Constructor to be used when creating a new object
+Torus::Torus()  {
+  _assign(new TGeoTorus(0,0,0),"","torus");
+}
+
+/// Constructor to be used when creating a new object
+Torus::Torus(const string& name)  {
+  _assign(new TGeoTorus(0,0,0),name,"torus");
+}
+
+/// Constructor to be used when creating a new identified object with attribute initialization
+Torus::Torus(const string& name, double r, double rmin, double rmax, double phi, double delta_phi)  {
+  _assign(new TGeoTorus(r,rmin,rmax,phi,delta_phi),name,"torus");
+}
+
+/// Constructor to be used when creating a new object with attribute initialization
+Torus::Torus(double r, double rmin, double rmax, double phi, double delta_phi)  {
+  _assign(new TGeoTorus(r,rmin,rmax,phi,delta_phi),"","torus");
+}
+
+/// Set the Torus dimensions
+Torus& Torus::setDimensions(double r, double rmin, double rmax, double phi, double delta_phi)  {
+  double params[] = {r,rmin,rmax,phi,delta_phi};
+  _setDimensions(params);
+  return *this;
+}
+
+/// Constructor to be used when creating a new identified object with attribute initialization
+Trap::Trap( const string& name,
             double z,
             double theta,
             double phi,
@@ -171,7 +278,23 @@ Trap::Trap( LCDD&  lcdd, const string& name,
             double x4,
             double alpha2)
 {
-  _assign(lcdd,new TGeoTrap(z,RAD_2_DEGREE*theta,RAD_2_DEGREE*phi,y1,x1,x2,alpha1,y2,x3,x4,alpha2),name,"trap");
+  _assign(new TGeoTrap(z,RAD_2_DEGREE*theta,RAD_2_DEGREE*phi,y1,x1,x2,alpha1,y2,x3,x4,alpha2),name,"trap");
+}
+
+/// Constructor to be used when creating a new anonymous object with attribute initialization
+Trap::Trap( double z,
+            double theta,
+            double phi,
+            double y1,
+            double x1,
+            double x2,
+            double alpha1,
+            double y2,
+            double x3,
+            double x4,
+            double alpha2)
+{
+  _assign(new TGeoTrap(z,RAD_2_DEGREE*theta,RAD_2_DEGREE*phi,y1,x1,x2,alpha1,y2,x3,x4,alpha2),"","trap");
 }
 
 /// Set the trap dimensions
@@ -183,14 +306,14 @@ Trap& Trap::setDimensions(double z,double theta,double phi,
   return *this;
 }
 
-/// Constructor to be used when creating a new DOM tree
-PolyhedraRegular::PolyhedraRegular(LCDD& lcdd, const string& name, int nsides, double rmin, double rmax, double zlen)  
+/// Constructor to be used when creating a new object
+PolyhedraRegular::PolyhedraRegular(const string& name, int nsides, double rmin, double rmax, double zlen)  
 {
   if ( rmin<0e0 || rmin>rmax )
     throw runtime_error("PolyhedraRegular: Illegal argument rmin:<"+_toString(rmin)+"> is invalid!");
   else if ( rmax<0e0 )
     throw runtime_error("PolyhedraRegular: Illegal argument rmax:<"+_toString(rmax)+"> is invalid!");
-  _assign(lcdd,new TGeoPgon(),name,"polyhedra",false);
+  _assign(new TGeoPgon(),name,"polyhedra",false);
   double params[] = {
     RAD_2_DEGREE * 2 * M_PI,
     RAD_2_DEGREE * 2 * M_PI,
@@ -202,26 +325,72 @@ PolyhedraRegular::PolyhedraRegular(LCDD& lcdd, const string& name, int nsides, d
   _setDimensions(&params[0]);
 }
 
-/// Constructor to be used when creating a new DOM tree
-BooleanSolid::BooleanSolid(LCDD& lcdd, const string& name, const string& type, const string& expr)
+/// Constructor to be used when creating a new object
+PolyhedraRegular::PolyhedraRegular(int nsides, double rmin, double rmax, double zlen)  
 {
-  _assign(lcdd,new TGeoCompositeShape(expr.c_str()),name,type);
+  if ( rmin<0e0 || rmin>rmax )
+    throw runtime_error("PolyhedraRegular: Illegal argument rmin:<"+_toString(rmin)+"> is invalid!");
+  else if ( rmax<0e0 )
+    throw runtime_error("PolyhedraRegular: Illegal argument rmax:<"+_toString(rmax)+"> is invalid!");
+  _assign(new TGeoPgon(),"","polyhedra",false);
+  double params[] = {
+    RAD_2_DEGREE * 2 * M_PI,
+    RAD_2_DEGREE * 2 * M_PI,
+    double(nsides),
+    2e0,
+    zlen/2e0,rmin,rmax,
+    -zlen/2e0,rmin,rmax
+  };
+  _setDimensions(&params[0]);
 }
 
 /// Constructor to be used when creating a new object
-SubtractionSolid::SubtractionSolid(LCDD& lcdd, const string& name, const string& expr)
-  : BooleanSolid(lcdd, name, "subtraction", expr)
+SubtractionSolid::SubtractionSolid(const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot)
 {
+  static TGeoRotation inverse_identity_rot(TGeoRotation("",0,0,0).Inverse());
+  TGeoRotation rotation("",rot.phi*RAD_2_DEGREE,rot.theta*RAD_2_DEGREE,rot.psi*RAD_2_DEGREE);
+  TGeoCombiTrans* first  = new TGeoCombiTrans("_first",0,0,0,&inverse_identity_rot);
+  TGeoCombiTrans* second = new TGeoCombiTrans("_secnd",pos.x,pos.y,pos.z,0);
+  second->SetRotation(rotation.Inverse());
+
+  TGeoSubtraction*    sub  = new TGeoSubtraction(shape1,shape2,first,second);
+  TGeoCompositeShape* comp = new TGeoCompositeShape("",sub);
+  comp->ComputeBBox();
+  _assign( comp, "", "subtraction");
 }
 
-/// Constructor to be used when creating a new DOM tree
-SubtractionSolid::SubtractionSolid(LCDD& lcdd, const string& name, const Solid& shape1, const Solid& shape2)
-  : BooleanSolid(lcdd, name, "subtraction", shape1.name()+string("-")+shape2.name())
+/// Constructor to be used when creating a new object
+SubtractionSolid::SubtractionSolid(const string& name, const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot)
 {
+  static TGeoRotation inverse_identity_rot(TGeoRotation("",0,0,0).Inverse());
+  TGeoRotation rotation("",rot.phi*RAD_2_DEGREE,rot.theta*RAD_2_DEGREE,rot.psi*RAD_2_DEGREE);
+  TGeoCombiTrans* first  = new TGeoCombiTrans((name+"_first").c_str(),0,0,0,&inverse_identity_rot);
+  TGeoCombiTrans* second = new TGeoCombiTrans((name+"_secnd").c_str(),pos.x,pos.y,pos.z,0);
+  second->SetRotation(rotation.Inverse());
+
+  TGeoSubtraction*    sub  = new TGeoSubtraction(shape1,shape2,first,second);
+  TGeoCompositeShape* comp = new TGeoCompositeShape(name.c_str(),sub);
+  comp->ComputeBBox();
+  _assign( comp, "", "subtraction");
 }
 
 /// Constructor to be used when creating a new object
-SubtractionSolid::SubtractionSolid(LCDD& lcdd, const string& name, const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot)
+UnionSolid::UnionSolid(const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot)
+{
+  static TGeoRotation inverse_identity_rot(TGeoRotation("",0,0,0).Inverse());
+  TGeoRotation rotation("",rot.phi*RAD_2_DEGREE,rot.theta*RAD_2_DEGREE,rot.psi*RAD_2_DEGREE);
+  TGeoCombiTrans* first  = new TGeoCombiTrans("_first",0,0,0,&inverse_identity_rot);
+  TGeoCombiTrans* second = new TGeoCombiTrans("_secnd",pos.x,pos.y,pos.z,0);
+  second->SetRotation(rotation.Inverse());
+
+  TGeoUnion* sub = new TGeoUnion(shape1,shape2,first,second);
+  TGeoCompositeShape* comp = new TGeoCompositeShape("",sub);
+  comp->ComputeBBox();
+  _assign( comp, "", "union");
+}
+
+/// Constructor to be used when creating a new object
+UnionSolid::UnionSolid(const string& name, const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot)
 {
   static TGeoRotation inverse_identity_rot(TGeoRotation("",0,0,0).Inverse());
   TGeoRotation rotation("",rot.phi*RAD_2_DEGREE,rot.theta*RAD_2_DEGREE,rot.psi*RAD_2_DEGREE);
@@ -229,25 +398,54 @@ SubtractionSolid::SubtractionSolid(LCDD& lcdd, const string& name, const Solid&
   TGeoCombiTrans* second = new TGeoCombiTrans((name+"_secnd").c_str(),pos.x,pos.y,pos.z,0);
   second->SetRotation(rotation.Inverse());
 
-  TGeoSubtraction*    sub  = new TGeoSubtraction(shape1,shape2,first,second);
+  TGeoUnion* sub = new TGeoUnion(shape1,shape2,first,second);
+  TGeoCompositeShape* comp = new TGeoCompositeShape(name.c_str(),sub);
+  comp->ComputeBBox();
+  _assign( comp, "", "union");
+}
+
+/// Constructor to be used when creating a new object
+IntersectionSolid::IntersectionSolid(const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot)
+{
+  static TGeoRotation inverse_identity_rot(TGeoRotation("",0,0,0).Inverse());
+  TGeoRotation rotation("",rot.phi*RAD_2_DEGREE,rot.theta*RAD_2_DEGREE,rot.psi*RAD_2_DEGREE);
+  TGeoCombiTrans* first  = new TGeoCombiTrans("_first",0,0,0,&inverse_identity_rot);
+  TGeoCombiTrans* second = new TGeoCombiTrans("_secnd",pos.x,pos.y,pos.z,0);
+  second->SetRotation(rotation.Inverse());
+
+  TGeoIntersection*    sub = new TGeoIntersection(shape1,shape2,first,second);
+  TGeoCompositeShape* comp = new TGeoCompositeShape("",sub);
+  comp->ComputeBBox();
+  _assign( comp, "", "intersection");
+}
+
+/// Constructor to be used when creating a new object
+IntersectionSolid::IntersectionSolid(const string& name, const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot)
+{
+  static TGeoRotation inverse_identity_rot(TGeoRotation("",0,0,0).Inverse());
+  TGeoRotation rotation("",rot.phi*RAD_2_DEGREE,rot.theta*RAD_2_DEGREE,rot.psi*RAD_2_DEGREE);
+  TGeoCombiTrans* first  = new TGeoCombiTrans((name+"_first").c_str(),0,0,0,&inverse_identity_rot);
+  TGeoCombiTrans* second = new TGeoCombiTrans((name+"_secnd").c_str(),pos.x,pos.y,pos.z,0);
+  second->SetRotation(rotation.Inverse());
+
+  TGeoIntersection*    sub = new TGeoIntersection(shape1,shape2,first,second);
   TGeoCompositeShape* comp = new TGeoCompositeShape(name.c_str(),sub);
   comp->ComputeBBox();
-  _assign(lcdd, comp, "", "subtraction");
+  _assign( comp, "", "intersection");
 }
 
 #define INSTANTIATE(X) template class DD4hep::Geometry::Solid_type<X>
 
-#include "TGeoSphere.h"
-#include "TGeoTorus.h"
 INSTANTIATE(TGeoShape);
 INSTANTIATE(TGeoBBox);
+INSTANTIATE(TGeoCone);
+INSTANTIATE(TGeoParaboloid);
 INSTANTIATE(TGeoPcon);
 INSTANTIATE(TGeoPgon);
+INSTANTIATE(TGeoSphere);
+INSTANTIATE(TGeoTorus);
 INSTANTIATE(TGeoTube);
 INSTANTIATE(TGeoTubeSeg);
 INSTANTIATE(TGeoTrap);
 INSTANTIATE(TGeoTrd2);
-INSTANTIATE(TGeoCone);
 INSTANTIATE(TGeoCompositeShape);
-INSTANTIATE(TGeoSphere);
-INSTANTIATE(TGeoTorus);
diff --git a/DDCore/src/SimpleGDMLWriter.cpp b/DDCore/src/SimpleGDMLWriter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bb2f5f5f4d45c5709ed07b8c43cfb54b8e64c0b8
--- /dev/null
+++ b/DDCore/src/SimpleGDMLWriter.cpp
@@ -0,0 +1,311 @@
+// $Id:$
+//====================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+
+#include "DD4hep/LCDD.h"
+#include "SimpleGDMLWriter.h"
+// ROOT includes
+#include "TROOT.h"
+#include "TColor.h"
+#include "TGeoShape.h"
+#include "TGeoCone.h"
+#include "TGeoParaboloid.h"
+#include "TGeoPcon.h"
+#include "TGeoPgon.h"
+#include "TGeoSphere.h"
+#include "TGeoTorus.h"
+#include "TGeoTube.h"
+#include "TGeoTrd1.h"
+#include "TGeoTrd2.h"
+#include "TGeoArb8.h"
+#include "TGeoMatrix.h"
+#include "TGeoBoolNode.h"
+#include "TGeoCompositeShape.h"
+#include "TClass.h"
+#include "TMath.h"
+#include <iostream>
+
+using namespace DD4hep::Geometry;
+using namespace DD4hep;
+using namespace std;
+
+namespace {
+  string indent = "";
+
+  void getAngles(const Double_t* m, Double_t &phi, Double_t &theta, Double_t &psi)  {
+    // Retreive Euler angles.
+    // Check if theta is 0 or 180.
+    if (TMath::Abs(1.-TMath::Abs(m[8]))<1.e-9) {      
+      theta = TMath::ACos(m[8])*RAD_2_DEGREE;
+      phi = TMath::ATan2(-m[8]*m[1],m[0])*RAD_2_DEGREE;
+      psi = 0.; // convention, phi+psi matters
+      return;
+    }
+    // sin(theta) != 0
+    phi = TMath::ATan2(m[2],-m[5]);
+    Double_t sphi = TMath::Sin(phi);
+    if (TMath::Abs(sphi)<1.e-9) theta = -TMath::ASin(m[5]/TMath::Cos(phi))*RAD_2_DEGREE;
+    else theta = TMath::ASin(m[2]/sphi)*RAD_2_DEGREE;
+    phi *= RAD_2_DEGREE;      
+    psi = TMath::ATan2(m[6],m[7])*RAD_2_DEGREE;
+  }
+}
+
+/// Dump logical volume in GDML format to output stream
+void* SimpleGDMLWriter::handleVolume(const string& name, const TGeoVolume* volume)   const   {
+  Volume      vol = Handle<>(volume);
+  VisAttr     vis = vol.visAttributes();
+  TGeoShape*  shape  = volume->GetShape();
+  TGeoMedium* medium = volume->GetMedium();
+  int         num    = volume->GetNdaughters();
+
+  m_output << "\t\t<volume name=\"" << name << "\">" << endl;
+  m_output << "\t\t\t<solidref ref=\"" << shape->GetName() << "\"/>" << endl;
+  m_output << "\t\t\t<materialref ref=\"" << medium->GetName() << "\"/>" << endl;
+  if ( vis.isValid() ) {
+    m_output << "\t\t\t<visref ref=\"" << vis.name() << "\"/>" << endl;
+  }
+  if ( num > 0 )   {
+    for(int i=0; i<num; ++i)   {
+      TGeoNode*   n = volume->GetNode(i);
+      TGeoVolume* v = n->GetVolume();
+      TGeoMatrix* m = n->GetMatrix();
+      m_output << "\t\t\t<physvol>" << endl;
+      m_output << "\t\t\t\t<volumeref ref=\"" << v->GetName() << "\"/>" << endl;
+      if ( m ) {
+	if ( m->IsTranslation() ) {
+	  m_output << "\t\t\t\t<positionref ref=\"" << n->GetName() << "_pos\"/>" << endl;
+	}
+	if ( m->IsRotation() ) {
+	  m_output << "\t\t\t\t<rotationref ref=\"" << n->GetName() << "_rot\"/>" << endl;
+	}
+      }
+      m_output << "\t\t\t</physvol>" << endl;
+    }
+  }
+  m_output << "\t\t</volume>" << endl;
+  return 0;
+}
+
+/// Dump solid in GDML format to output stream
+void* SimpleGDMLWriter::handleSolid(const string& name, const TGeoShape* shape)   const   {
+  if ( shape ) {
+    if ( shape->IsA() == TGeoBBox::Class() ) {
+      const TGeoBBox* s = (const TGeoBBox*)shape;
+      m_output << "\t\t<box name=\"" << name << "_shape\" x=\"" 
+	       << s->GetDX() << "\" y=\"" 
+	       << s->GetDY() << "\" z=\"" 
+	       << s->GetDZ() << "\" lunit=\"cm\"/>" << endl;
+    }
+    else if ( shape->IsA() == TGeoTube::Class() ) {
+      const TGeoTube* s = (const TGeoTube*)shape;
+      m_output << "\t\t<tube name=\"" << name << "_shape\" rmin=\"" 
+	       << s->GetRmin() << "\" rmax=\"" 
+	       << s->GetRmax() << "\" z=\"" 
+	       << s->GetDz() << "\" startphi=\"0.0\" deltaphi=\"360.0\" aunit=\"deg\" lunit=\"cm\"/>" << endl;
+    }
+    else if ( shape->IsA() == TGeoTubeSeg::Class() ) {
+      const TGeoTubeSeg* s = (const TGeoTubeSeg*)shape;
+      m_output << "\t\t<tube name=\"" << name << "_shape\" rmin=\"" 
+	       << s->GetRmin() << "\" rmax=\"" 
+	       << s->GetRmax() << "\" z=\"" 
+	       << s->GetDz()   << "\" startphi=\""
+	       << s->GetPhi1() << "\" deltaphi=\""
+	       << s->GetPhi2() << "\" aunit=\"deg\" lunit=\"cm\"/>" << endl;
+    }
+    else if ( shape->IsA() == TGeoTrd1::Class() ) {
+      const TGeoTrd1* s = (const TGeoTrd1*)shape;
+      m_output << "\t\t<tube name=\"" << name << "_shape\" x1=\""
+	       << s->GetDx1() << "\" x2=\""
+	       << s->GetDx2() << "\" y1=\""
+	       << s->GetDy() << "\" y2=\""
+	       << s->GetDy() << "\" z=\""
+	       << s->GetDz()  << "\" lunit=\"cm\"/>" << endl;
+    }
+    else if ( shape->IsA() == TGeoTrd2::Class() ) {
+      const TGeoTrd2* s = (const TGeoTrd2*)shape;
+      m_output << "\t\t<tube name=\"" << name << "_shape\" x1=\""
+	       << s->GetDx1() << "\" x2=\""
+	       << s->GetDx2() << "\" y1=\""
+	       << s->GetDy1() << "\" y2=\""
+	       << s->GetDy2() << "\" z=\""
+	       << s->GetDz() << "\" lunit=\"cm\"/>" << endl;
+    }
+    else if ( shape->IsA() == TGeoPgon::Class() ) {
+      const TGeoPgon* s = (const TGeoPgon*)shape;
+      m_output << "\t\t<polyhedra name=\"" << name << "_shape\" startphi=\"" 
+	       << s->GetPhi1()     << "\" deltaphi=\"" 
+	       << s->GetDphi()     << "\" numsides=\"" 
+	       << s->GetNedges()   << "\" aunit=\"deg\" lunit=\"cm\">" << endl;
+      for(int i=0; i<s->GetNz(); ++i) {
+	m_output << "\t\t\t<zplane z=\"" << s->GetZ(i)
+		 << "\" rmin=\""   << s->GetRmin(i) 
+		 << "\" rmax=\""   << s->GetRmax(i) 
+		 << "\" lunit=\"cm\"/>" << endl;
+      }
+      m_output << "\t\t</polyhedra>" << endl;
+    }
+    else if ( shape->IsA() == TGeoPcon::Class() ) {
+      const TGeoPcon* s = (const TGeoPcon*)shape;
+      m_output << "\t\t<polycone name=\"" << name << "_shape\" startphi=\"" 
+	       << s->GetPhi1()     << "\" deltaphi=\"" 
+	       << s->GetDphi()     << "\" aunit=\"deg\" lunit=\"cm\">" << endl;
+      for(int i=0; i<s->GetNz(); ++i) {
+	m_output << "\t\t\t<zplane z=\"" << s->GetZ(i)
+		 << "\" rmin=\""   << s->GetRmin(i) 
+		 << "\" rmax=\""   << s->GetRmax(i) 
+		 << "\" lunit=\"cm\"/>" << endl;
+      }
+      m_output << "\t\t</polycone>" << endl;
+    }
+    else if ( shape->IsA() == TGeoCompositeShape::Class() ) {
+      string nn = name;
+      const TGeoCompositeShape* s = (const TGeoCompositeShape*)shape;
+      const TGeoBoolNode* boolean = s->GetBoolNode();
+      TGeoBoolNode::EGeoBoolType oper = boolean->GetBooleanOperator();
+
+      handleSolid(name+"_left", boolean->GetLeftShape());
+      handleSolid(name+"_right",boolean->GetRightShape());
+
+      if (      oper == TGeoBoolNode::kGeoSubtraction )
+	m_output << "\t\t<subtraction name=\"" << nn << "\">" << endl;
+      else if ( oper == TGeoBoolNode::kGeoUnion )
+	m_output << "\t\t<union name=\"" << nn << "\">" << endl;
+      else if ( oper == TGeoBoolNode::kGeoIntersection )
+	m_output << "\t\t<intersection name=\"" << nn << "\">" << endl;
+
+      m_output << "\t\t\t<first ref=\""  << nn << "_left\"/>" << endl;
+      m_output << "\t\t\t<second ref=\"" << nn << "_right\"/>" << endl;
+      indent = "\t";
+      handleTransformation("", boolean->GetRightMatrix());
+      indent = "";
+
+      if (      oper == TGeoBoolNode::kGeoSubtraction )
+	m_output << "\t\t</subtraction>" << endl;
+      else if ( oper == TGeoBoolNode::kGeoUnion )
+	m_output << "\t\t</union>" << endl;
+      else if ( oper == TGeoBoolNode::kGeoIntersection )
+	m_output << "\t\t</intersection>" << endl;
+    }
+    else {
+      cerr << "Failed to handle unknwon solid shape:"
+	   << shape->IsA()->GetName() << endl;
+    }
+  }
+  return 0;
+}
+
+/// Dump structure information in GDML format to output stream
+void SimpleGDMLWriter::handleStructure(const VolumeSet& volset)   const  {
+  m_output << "\t<structure>" << endl;
+  for(VolumeSet::const_iterator i=volset.begin(); i != volset.end(); ++i)
+    handleVolume((*i).first,(*i).second);
+  m_output << "\t</structure>" << endl;
+}
+
+/// Dump single volume transformation in GDML format to output stream
+void* SimpleGDMLWriter::handleTransformation(const string& name, const TGeoMatrix* m) const {
+  if ( m ) {
+    if ( m->IsTranslation() ) {
+      const Double_t* f = m->GetTranslation();
+      m_output << indent << "\t\t<position ";
+      if ( !name.empty() ) m_output << "name=\"" << name << "_pos\" ";
+      m_output << "x=\"" << f[0] << "\" "
+	       << "y=\"" << f[1] << "\" "
+	       << "z=\"" << f[2] << "\" unit=\"cm\"/>" << endl;
+    }
+    if ( m->IsRotation() ) {
+      const Double_t* mat = m->GetRotationMatrix();
+      Double_t theta=0.0, phi=0.0, psi=0.0;
+      getAngles(mat, theta, phi, psi);
+      m_output << indent << "\t\t<rotation ";
+      if ( !name.empty() ) m_output << "name=\"" << name << "_rot\" ";
+      m_output << "x=\"" << theta << "\" "
+	       << "y=\"" << psi << "\" "
+	       << "z=\"" << phi << "\" unit=\"deg\"/>" << endl;
+    }
+  }
+  return 0;
+}
+
+/// Dump Transformations in GDML format to output stream
+void SimpleGDMLWriter::handleTransformations(const TransformSet& trafos)   const {
+  m_output << "\t<define>" << endl;
+  for(TransformSet::const_iterator i=trafos.begin(); i != trafos.end(); ++i)
+    handleTransformation((*i).first, (*i).second);
+  m_output << "\t</define>" << endl;
+}
+
+/// Dump all solids in GDML format to output stream
+void SimpleGDMLWriter::handleSolids(const SolidSet& solids)   const {
+  m_output << "\t<solids>" << endl;
+  for(SolidSet::const_iterator i=solids.begin(); i != solids.end(); ++i)
+    handleSolid((*i).first, (*i).second);
+  m_output << "\t</solids>" << endl;
+}
+
+/// Dump all constants in GDML format to output stream
+void SimpleGDMLWriter::handleDefines(const LCDD::HandleMap& defs)   const {
+  m_output << "\t<define>" << endl;
+  for(LCDD::HandleMap::const_iterator i=defs.begin(); i != defs.end(); ++i)
+    m_output << "\t\t<constant name=\"" << (*i).second->GetName() << "\" value=\"" << (*i).second->GetTitle() << "\" />" << endl;
+  m_output << "\t</define>" << endl;
+}
+
+/// Dump all visualisation specs in LCDD format to output stream
+void SimpleGDMLWriter::handleVisualisation(const LCDD::HandleMap& vis)   const {
+  m_output << "\t<display>" << endl;
+  for(LCDD::HandleMap::const_iterator i=vis.begin(); i != vis.end(); ++i) {
+    VisAttr v = (*i).second;
+    if ( v.isValid() ) {
+      float r=1., g=1., b=1., alpha=1.;
+      TColor *color = gROOT->GetColor(v.color());
+      if ( color ) {
+	color->GetRGB(r,g,b);
+	alpha = color->GetAlpha();
+      }
+      const char* line_style=0, *draw_style=0;
+      switch(v.lineStyle()) {
+      case VisAttr::DASHED:
+	line_style = "broken";
+	break;
+      case VisAttr::SOLID: 
+      default:
+	line_style = "unbroken";
+	break;
+      }
+      switch(v.drawingStyle()) {
+      case VisAttr::WIREFRAME:
+	draw_style = "wireframe";
+	break;
+      default:
+	break;
+      }
+
+      m_output << "\t\t<vis name=\""  << v.name() << "\" ";
+      if ( line_style ) m_output << "linestyle=\""      << line_style << "\" ";
+      if ( draw_style ) m_output << "drawingStyle=\""   << draw_style << "\" ";
+      m_output << "show_daughters=\"" << (const char*)(v.showDaughters() ? "true" : "false") << "\" "
+	       << "visible=\""        << (const char*)(v.visible() ? "true" : "false") << "\" >" << endl
+	       << "\t\t\t<color R=\"" << r << "\" G=\"" << g << "\" B=\"" << b << "\" alpha=\"" << alpha << "\" />" << endl
+	       << "\t\t</vis>" << endl;
+    }
+  }
+  m_output << "\t</display>" << endl;
+}
+
+void SimpleGDMLWriter::create(DetElement top) {
+  GeometryInfo geo;
+  collect(top,geo);
+  //handleSetup(LCDD::getInstance().header());
+  //handleDefines(LCDD::getInstance().constants());
+  handleVisualisation(geo.vis);
+  //handleTransformations(geo.trafos);
+  //handleSolids(geo.solids);
+  //handleStructure(geo.volumes);
+}
diff --git a/DDCore/src/SimpleGDMLWriter.h b/DDCore/src/SimpleGDMLWriter.h
new file mode 100644
index 0000000000000000000000000000000000000000..1f1635c32596603f5f0535995d7f17294f28fbbf
--- /dev/null
+++ b/DDCore/src/SimpleGDMLWriter.h
@@ -0,0 +1,68 @@
+// $Id:$
+//====================================================================
+//  AIDA Detector description implementation
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+#ifndef DD4HEP_SIMPLEGDMLWRITER_H
+#define DD4HEP_SIMPLEGDMLWRITER_H
+
+#include "DD4hep/LCDD.h"
+#include "DD4hep/GeoHandler.h"
+#include <set>
+#include <map>
+#include <vector>
+class TGeoVolume;
+class TGeoNode;
+
+/*
+ *   DD4hep namespace declaration
+ */
+namespace DD4hep {
+
+  /*
+   *   Geometry namespace declaration
+   */
+  namespace Geometry {
+
+    /** @class SimpleGDMLWriter  SimpleGDMLWriter.h
+     *
+     * @author  M.Frank
+     * @version 1.0
+     */
+    struct SimpleGDMLWriter : public GeoHandler  {
+
+      /// Reference to output stream
+      std::ostream& m_output;
+
+      SimpleGDMLWriter(std::ostream& os) : m_output(os) {}
+      /// Standard destructor
+      virtual ~SimpleGDMLWriter() {}
+      /// Main entry point: create required object(s)
+      void create(DetElement top);
+
+      /// Dump logical volume in GDML format to output stream
+      virtual void* handleVolume(const std::string& name, const TGeoVolume* volume) const;
+      /// Dump single volume transformation in GDML format to output stream
+      virtual void* handleTransformation(const std::string& name, const TGeoMatrix* matrix) const;
+      /// Dump solid in GDML format to output stream
+      virtual void* handleSolid(const std::string& name, const TGeoShape* volume) const;
+
+      /// Dump all constants in GDML format to output stream
+      virtual void handleDefines(const LCDD::HandleMap& defs) const;
+      /// Dump all visualisation specs in LCDD format to output stream
+      void handleVisualisation(const LCDD::HandleMap& vis)   const;
+      /// Dump all solids in GDML format to output stream
+      virtual void handleSolids(const SolidSet& solids) const;
+      /// Dump Transformations in GDML format to output stream
+      virtual void handleTransformations(const TransformSet& trafos) const;
+      /// Dump structure information in GDML format to output stream
+      virtual void handleStructure(const VolumeSet& volset)  const;
+    };
+  }    // End namespace Geometry
+}      // End namespace DD4hep
+
+#endif // DD4HEP_SIMPLEGDMLWRITER_H
+
diff --git a/DDCore/src/Volumes.cpp b/DDCore/src/Volumes.cpp
index ad18e0d0619f22f535593e1bf04e5eefe9a697a6..36df53df14d92e68a6cc81aaa8e9383303a69b64 100644
--- a/DDCore/src/Volumes.cpp
+++ b/DDCore/src/Volumes.cpp
@@ -239,16 +239,14 @@ string PlacedVolume::toString() const {
 }
 
 /// Constructor to be used when creating a new geometry tree.
-Volume::Volume(LCDD& lcdd, const string& name)    {
+Volume::Volume(const string& name)    {
   m_element = new Value<TGeoVolume,Volume::Object>(name.c_str());
-  lcdd.addVolume(*this);
 }
 
 /// Constructor to be used when creating a new geometry tree. Also sets materuial and solid attributes
-Volume::Volume(LCDD& lcdd, const string& name, const Solid& s, const Material& m) {
+Volume::Volume(const string& name, const Solid& s, const Material& m) {
   m_element = new Value<TGeoVolume,Volume::Object>(name.c_str(),s);
   setMaterial(m);
-  lcdd.addVolume(*this);
 }
 
 /// Set the volume's material
@@ -413,8 +411,7 @@ LimitSet Volume::limitSet() const
 {  return data<Object>()->limits;                           }
 
 /// Constructor to be used when creating a new geometry tree.
-Assembly::Assembly(LCDD& lcdd, const std::string& name) {
+Assembly::Assembly(const std::string& name) {
   m_element = new Value<TGeoVolumeAssembly,Volume::Object>(name.c_str());
-  lcdd.addVolume(*this);
 }
 
diff --git a/DDCore/src/compact/Compact2Objects.cpp b/DDCore/src/compact/Compact2Objects.cpp
index 3df518b4e4600cded6cebf441daac09f2ddfe9fc..3687af7ff94d4d47e32b3d310d20f4e952716f5d 100644
--- a/DDCore/src/compact/Compact2Objects.cpp
+++ b/DDCore/src/compact/Compact2Objects.cpp
@@ -359,6 +359,17 @@ namespace DD4hep { namespace Geometry {
   template <> void Converter<LimitSet>::operator()(const xml_h& element)  const {
     lcdd.addLimitSet(toRefObject<to_type>(lcdd,element));
   }
+  void setChildTitles(const pair<string,DetElement>& e) {
+    DetElement parent = e.second.parent();
+    const DetElement::Children& children = e.second.children();
+    if ( strlen(e.second->GetTitle()) == 0 ) {
+      e.second->SetTitle(parent.isValid() ? parent.type().c_str() : e.first.c_str());
+    }
+    else {
+      cout << "Title present: " << e.second->GetTitle() << endl;
+    }
+    for_each(children.begin(),children.end(),setChildTitles);
+  }
   template <> void Converter<DetElement>::operator()(const xml_h& element)  const {
     static const char* req_dets = ::getenv("REQUIRED_DETECTORS");
     static const char* req_typs = ::getenv("REQUIRED_DETECTOR_TYPES");
@@ -376,12 +387,15 @@ namespace DD4hep { namespace Geometry {
       SensitiveDetector  sd = toRefObject<SensitiveDetector>(lcdd,element);
       DetElement det(Handle<TNamed>(ROOT::Reflex::PluginService::Create<TNamed*>(type,&lcdd,&element,&sd)));
       
-      if ( det.isValid() && element.hasAttr(_A(readout)) )  {
-        string rdo = element.attr<string>(_A(readout));
-        det.setReadout(lcdd.readout(rdo));
+      if ( det.isValid() )  {
+	setChildTitles(make_pair(name,det));
+	if ( element.hasAttr(_A(readout)) )  {
+	  string rdo = element.attr<string>(_A(readout));
+	  det.setReadout(lcdd.readout(rdo));
+	}
       }
       cout << (det.isValid() ? "Converted" : "FAILED    ")
-      << " subdetector:" << name << " of type " << type << endl;
+	   << " subdetector:" << name << " of type " << type << endl;
       lcdd.addDetector(det);
     }
     catch(const exception& e) {
diff --git a/DDExamples/AlignDet/src/BoxDetector_geo.cpp b/DDExamples/AlignDet/src/BoxDetector_geo.cpp
index 6aa54616ebde58d33886cda376e27174a9b24fb1..d8d82dfa170d789727ccd9bcd11d71c157e828c2 100644
--- a/DDExamples/AlignDet/src/BoxDetector_geo.cpp
+++ b/DDExamples/AlignDet/src/BoxDetector_geo.cpp
@@ -15,19 +15,18 @@ using namespace DD4hep::Geometry;
 static Ref_t create_element(LCDD& lcdd, const xml_h& e, SensitiveDetector&)  {
   xml_det_t   x_det = e;
   string      name  = x_det.nameStr();
-  xml_comp_t  x_box  (x_det.child(_X(box)));
-  xml_dim_t   x_pos  (x_det.child(_X(position)));
-  xml_dim_t   x_rot  (x_det.child(_X(rotation)));
+  xml_comp_t  box    (x_det.child(_X(box)));
+  xml_dim_t   pos    (x_det.child(_X(position)));
+  xml_dim_t   rot    (x_det.child(_X(rotation)));
   Material    mat    (lcdd.material(x_det.materialStr()));
-  DetElement  det    (lcdd,name,x_det.typeStr(),x_det.id());
-  Box         det_box(lcdd,name,x_box.x(),x_box.y(),x_box.z());
-  Volume      det_vol(lcdd,name+"_vol",det_box, mat);
+  DetElement  det    (name,x_det.id());
+  Volume      det_vol(name+"_vol",Box(box.x(),box.y(),box.z()), mat);
   Volume      mother = lcdd.pickMotherVolume(det);
 
   det_vol.setVisAttributes(lcdd, x_det.visStr());
-  PlacedVolume phv = mother.placeVolume(det_vol,Position(x_pos.x(),x_pos.y(),x_pos.z()),
-					Rotation(x_rot.x(),x_rot.y(),x_rot.z()));
-  phv.addPhysVolID(_A(id),x_det.id());
+  PlacedVolume phv = mother.placeVolume(det_vol,Position(pos.x(),pos.y(),pos.z()),
+					Rotation(rot.x(),rot.y(),rot.z()));
+  phv.addPhysVolID("id",x_det.id());
   det.setPlacement(phv);
   return det;
 }
diff --git a/DDExamples/CLICSiD/src/CylindricalBarrelCalorimeter_geo.cpp b/DDExamples/CLICSiD/src/CylindricalBarrelCalorimeter_geo.cpp
index 71cd5d47e2e56a6e6bea16be238e19c80404617e..ab498b7030970923a85f4f95b40417177ef15035 100644
--- a/DDExamples/CLICSiD/src/CylindricalBarrelCalorimeter_geo.cpp
+++ b/DDExamples/CLICSiD/src/CylindricalBarrelCalorimeter_geo.cpp
@@ -18,8 +18,8 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
   Material   air       = lcdd.air();
   string     det_name  = x_det.nameStr();
   string     det_type  = x_det.typeStr();
-  Tube       envelope   (lcdd,det_name);
-  Volume     envelopeVol(lcdd,det_name,envelope,air);
+  Tube       envelope;
+  Volume     envelopeVol(det_name,envelope,air);
   DetElement sdet       (det_name,det_type,x_det.id());
   double     z         = dim.outer_z();
   double     rmin      = dim.inner_r();
@@ -30,20 +30,19 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
     xml_comp_t x_layer = c;
     for(int i=0, m=0, repeat=x_layer.repeat(); i<repeat; ++i, m=0)  {
       string layer_name = det_name + _toString(n,"_layer%d");
-      Tube   layer_tub(lcdd,layer_name);
-      Volume layer_vol(lcdd,layer_name,layer_tub,air);
+      Tube   layer_tub;
+      Volume layer_vol(layer_name,layer_tub,air);
       double rlayer = r;
         
       for(xml_coll_t l(x_layer,_X(slice)); l; ++l, ++m)  {
 	xml_comp_t x_slice = l;
+	double     router = r + x_slice.thickness();
 	Material   slice_mat  = lcdd.material(x_slice.materialStr());
 	string     slice_name = layer_name + _toString(m,"slice%d");
-	Tube       slice_tube(lcdd,slice_name);
-	Volume     slice_vol (lcdd,slice_name,slice_tube,slice_mat);
-	double     router = r + x_slice.thickness();
+	Tube       slice_tube(r,router,z * 2);
+	Volume     slice_vol (slice_name,slice_tube,slice_mat);
           
 	if ( x_slice.isSensitive() ) slice_vol.setSensitiveDetector(sens);
-	slice_tube.setDimensions(r,router,z * 2);
 	r = router;
 	slice_vol.setAttributes(lcdd,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr());
 	// Instantiate physical volume
diff --git a/DDExamples/CLICSiD/src/CylindricalEndcapCalorimeter_geo.cpp b/DDExamples/CLICSiD/src/CylindricalEndcapCalorimeter_geo.cpp
index a05c968acf403dd3cd0f6cda063de8dbfa8c720a..9282af5095cc36babbe1e31aaa6c09cd45869305 100644
--- a/DDExamples/CLICSiD/src/CylindricalEndcapCalorimeter_geo.cpp
+++ b/DDExamples/CLICSiD/src/CylindricalEndcapCalorimeter_geo.cpp
@@ -18,9 +18,8 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
   xml_dim_t  dim       = x_det.dimensions();
   Material   air       = lcdd.air();
   string     det_name  = x_det.nameStr();
-  string     det_type  = x_det.typeStr();
-  Tube       envelope   (lcdd,det_name);
-  Volume     envelopeVol(lcdd,det_name,envelope,air);
+  Tube       envelope;
+  Volume     envelopeVol(det_name,envelope,air);
   bool       reflect   = dim.reflect();
   double     zmin      = dim.inner_z();
   double     rmin      = dim.inner_r();
@@ -37,16 +36,14 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
     for(int i=0, m=0, repeat=x_layer.repeat(); i<repeat; ++i, m=0)  {
       double     zlayer = z;
       string     layer_name = det_name + _toString(n,"_layer%d");
-      Tube       layer_tub(lcdd,layer_name,rmin,rmax,layerWidth);
-      Volume     layer_vol(lcdd,layer_name,layer_tub,air);
+      Volume     layer_vol(layer_name,Tube(rmin,rmax,layerWidth),air);
         
       for(xml_coll_t l(x_layer,_X(slice)); l; ++l, ++m)  {
 	xml_comp_t x_slice = l;
 	double     w = x_slice.thickness();
 	string     slice_name = layer_name + _toString(m,"slice%d");
 	Material   slice_mat  = lcdd.material(x_slice.materialStr());
-	Tube       slice_tube(lcdd,slice_name, rmin,rmax,w);
-	Volume     slice_vol (lcdd,slice_name, slice_tube, slice_mat);
+	Volume     slice_vol (slice_name,Tube(rmin,rmax,w),slice_mat);
           
 	if ( x_slice.isSensitive() ) slice_vol.setSensitiveDetector(sens);
           
@@ -66,10 +63,10 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
   envelope.setDimensions(rmin,rmax,totWidth,2.*M_PI);
   // Set attributes of slice
   envelopeVol.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det.visStr());
-    
-  DetElement sdet(det_name,det_type,x_det.id());
+
+  DetElement sdet(det_name,x_det.id());
   Volume     motherVol = lcdd.pickMotherVolume(sdet);
-  PlacedVolume phv=motherVol.placeVolume(envelopeVol,Position(0,0,zmin+totWidth/2));
+  PlacedVolume phv = motherVol.placeVolume(envelopeVol,Position(0,0,zmin+totWidth/2));
   phv.addPhysVolID(_A(system),sdet.id())
     .addPhysVolID(_A(barrel),1);
   sdet.setPlacement(phv);
diff --git a/DDExamples/CLICSiD/src/DiskTracker_geo.cpp b/DDExamples/CLICSiD/src/DiskTracker_geo.cpp
index d1756bb4fc2628e7527d2bee51622005126355a3..388504eeef633af9b114f765029aec720643b5da 100644
--- a/DDExamples/CLICSiD/src/DiskTracker_geo.cpp
+++ b/DDExamples/CLICSiD/src/DiskTracker_geo.cpp
@@ -16,9 +16,8 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
   xml_det_t  x_det     = e;
   Material   air       = lcdd.air();
   string     det_name  = x_det.nameStr();
-  string     det_type  = x_det.typeStr();
   bool       reflect   = x_det.reflect();
-  DetElement sdet(det_name,det_type,x_det.id());
+  DetElement sdet(det_name,x_det.id());
   Volume     motherVol = lcdd.pickMotherVolume(sdet);
   int l_num = 0;
     
@@ -35,16 +34,15 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
       double thickness = xml_comp_t(j).thickness();
       layerWidth += thickness;
     }
-    Tube    l_tub(lcdd,l_nam,rmin,rmax,layerWidth,2*M_PI);
-    Volume  l_vol(lcdd,l_nam,l_tub,air);
+    Tube    l_tub(rmin,rmax,layerWidth,2*M_PI);
+    Volume  l_vol(l_nam,l_tub,air);
     l_vol.setVisAttributes(lcdd,x_layer.visStr());
     for(xml_coll_t j(x_layer,_X(slice)); j; ++j, ++s_num)  {
       xml_comp_t x_slice = j;
       double thick = x_slice.thickness();
       Material mat = lcdd.material(x_slice.materialStr());
       string s_nam = l_nam+_toString(s_num,"_slice%d");
-      Tube   s_tub(lcdd,s_nam, rmin,rmax,thick);
-      Volume s_vol(lcdd,s_nam, s_tub, mat);
+      Volume s_vol(s_nam, Tube(rmin,rmax,thick), mat);
         
       if ( x_slice.isSensitive() ) s_vol.setSensitiveDetector(sens);
       s_vol.setAttributes(lcdd,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr());
@@ -57,8 +55,8 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
     PlacedVolume lpv = motherVol.placeVolume(l_vol,Position(0,0,zmin+layerWidth/2.));
     lpv.addPhysVolID(_X(system),sdet.id());
     lpv.addPhysVolID(_X(barrel),1);
-    DetElement layer(l_nam,det_type+"/Layer",l_num);
-    sdet.add(layer.setPlacement(lpv));
+    DetElement layer(sdet,l_nam,l_num);
+    layer.setPlacement(lpv);
     if ( reflect )  {
       PlacedVolume lpvR = motherVol.placeVolume(l_vol,Position(0,0,-zmin-layerWidth/2),ReflectRot());
       lpvR.addPhysVolID(_X(system),sdet.id());
diff --git a/DDExamples/CLICSiD/src/EcalBarrel_geo.cpp b/DDExamples/CLICSiD/src/EcalBarrel_geo.cpp
index 58ddd23511e0167a174f026864f8f5159b9f699f..0987eb3fff6521ca77beaf99c9fba52f29493f86 100644
--- a/DDExamples/CLICSiD/src/EcalBarrel_geo.cpp
+++ b/DDExamples/CLICSiD/src/EcalBarrel_geo.cpp
@@ -22,7 +22,6 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
   Material      vacuum    = lcdd.vacuum();
   int           det_id    = x_det.id();
   string        det_name  = x_det.nameStr();
-  string        det_type  = x_det.typeStr();
   xml_comp_t    x_staves  = x_det.child(_X(staves));
   xml_comp_t    x_dim     = x_det.child(_X(dimensions));
   int           nsides    = x_dim.numsides();
@@ -32,17 +31,17 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
   double        mod_z     = layering.totalThickness();
   double        outer_r   = inner_r + mod_z;
   double        totThick  = mod_z;
-  DetElement    sdet      (det_name,det_type,det_id);
+  DetElement    sdet      (det_name,det_id);
   Volume        motherVol = lcdd.pickMotherVolume(sdet);
-  PolyhedraRegular hedra(lcdd,det_name,nsides,inner_r,inner_r+totThick+tolerance*2e0,x_dim.z());
-  Volume        envelope  (lcdd,det_name,hedra,air);
+  PolyhedraRegular hedra(nsides,inner_r,inner_r+totThick+tolerance*2e0,x_dim.z());
+  Volume        envelope  (det_name,hedra,air);
   PlacedVolume  env_phv   = motherVol.placeVolume(envelope,Rotation(0,0,M_PI/nsides));
 
   env_phv.addPhysVolID("system",det_id);
   env_phv.addPhysVolID("barrel",0);
   sdet.setPlacement(env_phv);
 
-  DetElement    stave_det(det_name+"_stave0",det_type,det_id);
+  DetElement    stave_det("stave0",det_id);
   double dx        = mod_z / std::sin(dphi); // dx per layer
   dx = 0;
     
@@ -54,14 +53,13 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
   double trd_z  = mod_z/2 - tolerance;
 		
   // Create the trapezoid for the stave.
-  Trapezoid trd(lcdd,det_name + "_module_trd", 
-		trd_x1, // Outer side, i.e. the "short" X side.
+  Trapezoid trd(trd_x1, // Outer side, i.e. the "short" X side.
 		trd_x2, // Inner side, i.e. the "long"  X side.
 		trd_y1, // Corresponds to subdetector (or module) Z.
 		trd_y2, //
 		trd_z); // Thickness, in Y for top stave, when rotated.
 
-  Volume mod_vol(lcdd,det_name+"_module",trd,air);
+  Volume mod_vol(det_name+"_module",trd,air);
 
   { // =====  buildBarrelStave(lcdd, sens, module_volume) =====
     // Parameters for computing the layer X dimension:
@@ -80,54 +78,51 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
       int repeat = x_layer.repeat();
       // Loop over number of repeats for this layer.
       for (int j=0; j<repeat; j++)    {
-	string l_name = det_name + _toString(l_num,"_layer%d");
+	string l_name = _toString(l_num,"layer%d");
 	double l_thickness = layering.layer(l_num)->thickness();  // Layer's thickness.
 	double xcut = (l_thickness / tan_beta);                   // X dimension for this layer.
 	l_dim_x -= xcut/2;
 
 	Position   l_pos(0,0,l_pos_z+l_thickness/2);      // Position of the layer.
-	Box        l_box(lcdd,l_name,l_dim_x*2-tolerance,stave_z*2-tolerance,l_thickness-tolerance);
-	Volume     l_vol(lcdd,l_name,l_box,air);
-	DetElement layer(l_name,det_type+"/Layer",det_id);
+	Box        l_box(l_dim_x*2-tolerance,stave_z*2-tolerance,l_thickness-tolerance);
+	Volume     l_vol(det_name+"_"+l_name,l_box,air);
+	DetElement layer(stave_det, l_name, det_id);
 
-	stave_det.add(layer);
 	// Loop over the sublayers or slices for this layer.
 	int s_num = 0;
 	double s_pos_z = -(l_thickness / 2);
 	for(xml_coll_t si(x_layer,_X(slice)); si; ++si)  {
 	  xml_comp_t x_slice = si;
-	  string     s_name  = l_name + _toString(s_num,"_slice%d");
+	  string     s_name  =  _toString(s_num,"slice%d");
 	  double     s_thick = x_slice.thickness();
-	  Box        s_box(lcdd,s_name,l_dim_x*2-tolerance,stave_z*2-tolerance,s_thick-tolerance);
-	  Volume     s_vol(lcdd,s_name,s_box,lcdd.material(x_slice.materialStr()));
-	  DetElement slice(s_name,det_type+"/Layer/Slice",det_id);
-
-	  layer.add(slice);
-	  if ( x_slice.isSensitive() ) s_vol.setSensitiveDetector(sens);
-	    
-	  slice.setAttributes(lcdd,s_vol,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr());
-
-	  // Slice placement.
-	  PlacedVolume slice_phv = l_vol.placeVolume(s_vol,Position(0,0,s_pos_z+s_thick/2));					
-	  slice_phv.addPhysVolID("layer", l_num);
-	  slice_phv.addPhysVolID("slice", s_num);
-	  slice.setPlacement(slice_phv);
-	  // Increment Z position of slice.
-	  s_pos_z += s_thick;
-					
-	  // Increment slice number.
-	  ++s_num;
-	}	
-
-	// Set region, limitset, and vis of layer.
-	layer.setAttributes(lcdd,l_vol,x_layer.regionStr(),x_layer.limitsStr(),x_layer.visStr());
-
-	PlacedVolume layer_phv = mod_vol.placeVolume(l_vol,l_pos);
-	layer_phv.addPhysVolID("layer", l_num);
-	layer.setPlacement(layer_phv);
-	// Increment to next layer Z position.
-	l_pos_z += l_thickness;	  
-	++l_num;
+	  Box        s_box(l_dim_x*2-tolerance,stave_z*2-tolerance,s_thick-tolerance);
+	  Volume     s_vol(det_name+"_"+l_name+"_"+s_name,s_box,lcdd.material(x_slice.materialStr()));
+          DetElement slice(layer,s_name,det_id);
+
+          if ( x_slice.isSensitive() ) s_vol.setSensitiveDetector(sens);            
+          slice.setAttributes(lcdd,s_vol,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr());
+
+          // Slice placement.
+          PlacedVolume slice_phv = l_vol.placeVolume(s_vol,Position(0,0,s_pos_z+s_thick/2));                                        
+          slice_phv.addPhysVolID("layer", l_num);
+          slice_phv.addPhysVolID("slice", s_num);
+          slice.setPlacement(slice_phv);
+          // Increment Z position of slice.
+          s_pos_z += s_thick;
+                                        
+          // Increment slice number.
+          ++s_num;
+        }        
+
+        // Set region, limitset, and vis of layer.
+        layer.setAttributes(lcdd,l_vol,x_layer.regionStr(),x_layer.limitsStr(),x_layer.visStr());
+
+        PlacedVolume layer_phv = mod_vol.placeVolume(l_vol,l_pos);
+        layer_phv.addPhysVolID("layer", l_num);
+        layer.setPlacement(layer_phv);
+        // Increment to next layer Z position.
+        l_pos_z += l_thickness;          
+        ++l_num;
       }
     }
   }
@@ -143,18 +138,18 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
 
   // Create nsides staves.
   for (int i = 0; i < nsides; i++, phi -= dphi)      { // i is module number
-    DetElement stave_det(det_name+_toString(i,"_stave%d"),det_type,x_det.id());
     // Compute the stave position
     double m_pos_x = mod_x_off * std::cos(phi) - mod_y_off * std::sin(phi);
     double m_pos_y = mod_x_off * std::sin(phi) + mod_y_off * std::cos(phi);
     PlacedVolume pv = envelope.placeVolume(mod_vol,
-					   Position(-m_pos_x,-m_pos_y,0),
-					   Rotation(M_PI*0.5,phi,0));
+                                           Position(-m_pos_x,-m_pos_y,0),
+                                           Rotation(M_PI*0.5,phi,0));
     pv.addPhysVolID("module",i);
     pv.addPhysVolID("system",det_id);
     pv.addPhysVolID("barrel",0);
-    sdet.add(i==0 ? stave_det : stave_det.clone(det_name+_toString(i,"_stave%d")));
-    stave_det.setPlacement(pv);
+    DetElement sd = i==0 ? stave_det : stave_det.clone(_toString(i,"stave%d"));
+    sd.setPlacement(pv);
+    sdet.add(sd);
   }
 
   // Set envelope volume attributes.
diff --git a/DDExamples/CLICSiD/src/ForwardDetector_geo.cpp b/DDExamples/CLICSiD/src/ForwardDetector_geo.cpp
index 3d49bea23620eb2f6505f955ed8e8b3cdba34be6..8c7699e65721a32f05e7d0c651248daf2977dec2 100644
--- a/DDExamples/CLICSiD/src/ForwardDetector_geo.cpp
+++ b/DDExamples/CLICSiD/src/ForwardDetector_geo.cpp
@@ -19,10 +19,9 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
   bool        reflect    = x_det.reflect();
   xml_comp_t  beam       = x_det.child(_X(beampipe));
   string      det_name   = x_det.nameStr();
-  string      det_type   = x_det.typeStr();
   int         id         = x_det.id();
   Material    air        = lcdd.air();
-  DetElement  sdet       (det_name,det_type,id);
+  DetElement  sdet       (det_name,id);
   Layering    layering(x_det);
 
   Volume      motherVol  = lcdd.pickMotherVolume(sdet);
@@ -36,16 +35,15 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
   double      xangleHalf = xangle / 2;
   double      thickness  = layering.totalThickness();
   double      zpos       = zinner + (thickness / 2);
-  //double      zouter     = zinner + thickness;
   // Beampipe position in envelope.
   double      beamPosX   = std::tan(xangleHalf) * zpos;
 
   // Detector envelope solid. 
-  Tube envelopeTube(lcdd,det_name,rmin,rmax,thickness);
+  Tube envelopeTube(rmin,rmax,thickness);
 
   // First envelope bool subtracion of outgoing beampipe.
   // Incoming beampipe solid.
-  Tube beamInTube(lcdd,det_name + "_beampipe_incoming",0,outgoingR,thickness * 2);
+  Tube beamInTube(0,outgoingR,thickness * 2);
   // Position of incoming beampipe.
   Position beamInPos(beamPosX,0,0);
   /// Rotation of incoming beampipe.
@@ -53,20 +51,18 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
 
   // Second envelope bool subtracion of outgoing beampipe.
   // Outgoing beampipe solid.
-  Tube     beamOutTube(lcdd,det_name + "_beampipe_outgoing",0,incomingR,thickness * 2);
+  Tube     beamOutTube(0,incomingR,thickness * 2);
   // Position of outgoing beampipe.
   Position beamOutPos(-beamPosX,0,0);
   // Rotation of outgoing beampipe.
   Rotation beamOutRot(0,-xangleHalf,0);
 
   // First envelope bool subtraction of incoming beampipe.
-  SubtractionSolid envelopeSubtraction1(lcdd,det_name+"_subtraction1_tube",
-					envelopeTube,beamInTube,beamInPos,beamInRot);
-  SubtractionSolid envelopeSubtraction2(lcdd,det_name+"_subtraction2_tube",
-					envelopeSubtraction1,beamOutTube,beamOutPos,beamOutRot);
+  SubtractionSolid envelopeSubtraction1(envelopeTube,beamInTube,beamInPos,beamInRot);
+  SubtractionSolid envelopeSubtraction2(envelopeSubtraction1,beamOutTube,beamOutPos,beamOutRot);
 
   // Final envelope bool volume.
-  Volume envelopeVol(lcdd,det_name, envelopeSubtraction2, air);
+  Volume envelopeVol(det_name, envelopeSubtraction2, air);
 
   // Process each layer element.
   double layerPosZ   = -thickness / 2;
@@ -77,28 +73,26 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
 
     // Create tube envelope for this layer, which can be reused in bool definition
     // in the repeat loop below.
-    Tube layerTube(lcdd, det_name + "_layer",rmin,rmax,layerThickness);
+    Tube layerTube(rmin,rmax,layerThickness);
 
     for(int i=0, m=0, repeat=x_layer.repeat(); i<repeat; ++i, m=0)  {
-      string layer_nam = det_name + _toString(i,"_layer%d");
+      string layer_nam = _toString(i,"layer%d");
       // Increment to new layer position.
       layerDisplZ += layerThickness / 2;
       layerPosZ   += layerThickness / 2;
 
       // First layer subtraction solid.
-      DetElement  layer(layer_nam,"ForwardDetector/Layer",sdet.id());
+      DetElement  layer(sdet,layer_nam,sdet.id());
       double      layerGlobalZ = zinner + layerDisplZ;
       double      layerPosX    = tan(xangleHalf) * layerGlobalZ;
       Position    layerSubtraction1Pos( layerPosX,0,0);
       Position    layerSubtraction2Pos(-layerPosX,0,0);
 
-      SubtractionSolid layerSubtraction1(lcdd,layer_nam + "_subtraction1",
-					 layerTube,beamInTube,layerSubtraction1Pos,beamInRot);
+      SubtractionSolid layerSubtraction1(layerTube,beamInTube,layerSubtraction1Pos,beamInRot);
       // Second layer subtraction solid.
-      SubtractionSolid layerSubtraction2(lcdd,layer_nam + "_subtraction2",
-					 layerSubtraction1,beamOutTube,layerSubtraction2Pos,beamOutRot);
+      SubtractionSolid layerSubtraction2(layerSubtraction1,beamOutTube,layerSubtraction2Pos,beamOutRot);
       // Layer LV.
-      Volume layerVol(lcdd,layer_nam, layerSubtraction2, air);
+      Volume layerVol(det_name+"_"+layer_nam,layerSubtraction2,air);
       
       // Slice loop.
       int sliceCount = 0;
@@ -106,7 +100,7 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
       double sliceDisplZ = 0;
       for(xml_coll_t l(x_layer,XML::Tag_slice); l; ++l, ++m)  {
 	xml_comp_t x_slice = l;
-	string slice_nam = layer_nam + _toString(sliceCount,"_slice%d");
+	string slice_nam = _toString(sliceCount,"slice%d");
 	/** Get slice parameters. */
 	double sliceThickness = x_slice.thickness();
 	Material slice_mat = lcdd.material(x_slice.materialStr());
@@ -116,27 +110,24 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
 	slicePosZ   += sliceThickness / 2;
 
 	// Slice's basic tube.
-	Tube sliceTube(lcdd, slice_nam + "_tube", rmin,rmax,sliceThickness);
-	DetElement slice(slice_nam,"ForwardDetector/Layer/Slice",sdet.id());
+	Tube sliceTube(rmin,rmax,sliceThickness);
+	DetElement slice(layer,slice_nam,sdet.id());
 	double sliceGlobalZ = zinner + (layerDisplZ - layerThickness / 2) + sliceDisplZ;
 	double slicePosX    = std::tan(xangleHalf) * sliceGlobalZ;
 
 	// First slice subtraction solid.
-	SubtractionSolid sliceSubtraction1(lcdd,slice_nam + "_subtraction1",
-					   sliceTube,beamInTube,Position(slicePosX,0,0),beamInRot);
+	SubtractionSolid sliceSubtraction1(sliceTube,beamInTube,Position(slicePosX,0,0),beamInRot);
 	// Second slice subtraction solid.
-	SubtractionSolid sliceSubtraction2(lcdd,slice_nam + "_subtraction2",
-					   sliceSubtraction1,beamOutTube,Position(-slicePosX,0,0),beamOutRot); 
+	SubtractionSolid sliceSubtraction2(sliceSubtraction1,beamOutTube,Position(-slicePosX,0,0),beamOutRot); 
 	// Slice LV.
-	Volume sliceVol(lcdd,slice_nam, sliceSubtraction2, slice_mat);
-        
+	Volume sliceVol(det_name+"_"+layer_nam+"_"+slice_nam, sliceSubtraction2, slice_mat);
+
 	if ( x_slice.isSensitive() ) sliceVol.setSensitiveDetector(sens);
 	// Set attributes of slice
 	slice.setAttributes(lcdd, sliceVol, x_slice.regionStr(), x_slice.limitsStr(), x_slice.visStr());
 
 	// Place volume in layer
 	slice.setPlacement(layerVol.placeVolume(sliceVol,Position(0,0,slicePosZ)));
-	layer.add(slice);
 
 	// Start of next slice.
 	sliceDisplZ += sliceThickness / 2;
@@ -150,7 +141,6 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
       PlacedVolume layerPV = envelopeVol.placeVolume(layerVol,Position(0,0,layerPosZ));
       layerPV.addPhysVolID(_X(layer), i);
       layer.setPlacement(layerPV);
-      sdet.add(layer);
 
       // Increment to start of next layer.
       layerDisplZ += layerThickness / 2;
@@ -168,7 +158,7 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
     env_phv = motherVol.placeVolume(envelopeVol,Position(0,0,-zpos),ReflectRot());
     env_phv.addPhysVolID(_X(system), id);
     env_phv.addPhysVolID(_X(barrel), 2);
-    DetElement rdet(det_name+"_reflect",det_type,x_det.id());
+    DetElement rdet(det_name+"_reflect",x_det.id());
     rdet.setPlacement(env_phv);
   }
   return sdet;
diff --git a/DDExamples/CLICSiD/src/MultiLayerTracker_geo.cpp b/DDExamples/CLICSiD/src/MultiLayerTracker_geo.cpp
index 9c3420612056996e5ca7106247d2ca10fc0cc96d..72c70e76ba8a264b4346f0952d7c4811dbf70a2c 100644
--- a/DDExamples/CLICSiD/src/MultiLayerTracker_geo.cpp
+++ b/DDExamples/CLICSiD/src/MultiLayerTracker_geo.cpp
@@ -17,16 +17,16 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
   string     det_name  = x_det.nameStr();
   string     det_type  = x_det.typeStr();
   Material   air       = lcdd.air();
-  DetElement sdet(det_name,det_type,x_det.id());
+  DetElement sdet(det_name,x_det.id());
   Volume     motherVol = lcdd.pickMotherVolume(sdet);
   int n = 0;
     
   for(xml_coll_t i(x_det,_X(layer)); i; ++i, ++n)  {
     xml_comp_t x_layer = i;
     string  l_name = det_name+_toString(n,"_layer%d");
-    DetElement layer(l_name,"MultiLayerTracker/Layer",x_layer.id());
-    Tube    l_tub(lcdd,l_name);
-    Volume  l_vol(lcdd,l_name,l_tub,air);
+    DetElement layer(sdet,_toString(n,"layer%d"),x_layer.id());
+    Tube    l_tub;
+    Volume  l_vol(l_name,l_tub,air);
     double  z    = x_layer.outer_z();
     double  rmin = x_layer.inner_r();
     double  r    = rmin;
@@ -36,8 +36,8 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
       xml_comp_t x_slice = j;
       Material mat = lcdd.material(x_slice.materialStr());
       string s_name= l_name+_toString(m,"_slice%d");
-      Tube   s_tub(lcdd,s_name);
-      Volume s_vol(lcdd,s_name, s_tub, mat);
+      Tube   s_tub;
+      Volume s_vol(s_name, s_tub, mat);
         
       r += x_slice.thickness();
       s_tub.setDimensions(r,r,2*z,2*M_PI);
@@ -53,7 +53,7 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
       
     PlacedVolume lpv = motherVol.placeVolume(l_vol,IdentityPos());
     lpv.addPhysVolID(_X(system),sdet.id()).addPhysVolID(_X(barrel),0);
-    sdet.add(layer.setPlacement(lpv));
+    layer.setPlacement(lpv);
   }
   sdet.setCombineHits(x_det.attr<bool>(_A(combineHits)),sens);
   return sdet;
diff --git a/DDExamples/CLICSiD/src/PolyconeSupport_geo.cpp b/DDExamples/CLICSiD/src/PolyconeSupport_geo.cpp
index 103f41475c58029a816445a36953cd11bafff145..63cb370003821a2caa1461136cffe011cdc641d5 100644
--- a/DDExamples/CLICSiD/src/PolyconeSupport_geo.cpp
+++ b/DDExamples/CLICSiD/src/PolyconeSupport_geo.cpp
@@ -15,10 +15,8 @@ using namespace DD4hep::Geometry;
 static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector&)  {
   xml_det_t  x_det   = e;
   string     name    = x_det.nameStr();
-  DetElement sdet   (name,x_det.typeStr(),x_det.id());
-  Polycone   cone   (lcdd,name);
+  DetElement sdet   (name,x_det.id());
   Material   mat    (lcdd.material(x_det.materialStr()));
-  Volume     volume (lcdd,name, cone, mat);
   vector<double> rmin,rmax,z;
   int num = 0;
 
@@ -31,7 +29,8 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector&)  {
   if ( num < 2 )  {
     throw runtime_error("PolyCone["+name+"]> Not enough Z planes. minimum is 2!");
   }
-  cone.addZPlanes(rmin,rmax,z);
+  Polycone   cone   (0.,2.*M_PI,rmin,rmax,z);
+  Volume     volume (name, cone, mat);
   volume.setVisAttributes(lcdd, x_det.visStr());
   sdet.setPlacement(lcdd.pickMotherVolume(sdet).placeVolume(volume));
   return sdet;
diff --git a/DDExamples/CLICSiD/src/PolyhedraBarrelCalorimeter2_geo.cpp b/DDExamples/CLICSiD/src/PolyhedraBarrelCalorimeter2_geo.cpp
index c886f4f2caad3857e195491c6178c071a8276378..2768393193b34f0531eb1da6688a62e28baa43b8 100644
--- a/DDExamples/CLICSiD/src/PolyhedraBarrelCalorimeter2_geo.cpp
+++ b/DDExamples/CLICSiD/src/PolyhedraBarrelCalorimeter2_geo.cpp
@@ -30,10 +30,8 @@ static void placeStaves(DetElement&   parent,
   double posX = -sectCenterRadius  * std::sin(rotY);
   double posY =  sectCenterRadius  * std::cos(rotY);
   for (int module = 0; module < numsides; ++module)  {
-    string nam = stave.name();
-    nam = nam.substr(0,nam.length()-1)+_toString(module,"%d");
-    DetElement det = module>0 ? stave.clone(nam) : stave;
-    PlacedVolume pv=envelopeVolume.placeVolume(sectVolume,Position(-posX,-posY,0),Rotation(rotX,rotY,0));
+    DetElement det  = module>0 ? stave.clone(_toString(module,"stave%d")) : stave;
+    PlacedVolume pv = envelopeVolume.placeVolume(sectVolume,Position(-posX,-posY,0),Rotation(rotX,rotY,0));
     pv.addPhysVolID(_X(stave), 0);
     pv.addPhysVolID(_X(module),module);
     det.setPlacement(pv);
@@ -60,11 +58,11 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
   int         numSides    = dim.numsides();
   double      detZ        = dim.z();
   double      rmin        = dim.rmin();
-  DetElement  sdet(det_name,det_type,x_det.id());
-  DetElement  stave(det_name+"_stave0",det_type,x_det.id());
+  DetElement  sdet(det_name,x_det.id());
+  DetElement  stave("stave0",x_det.id());
   Volume      motherVol = lcdd.pickMotherVolume(sdet);
 
-  cout << det_name << "  Gap:" << gap << endl;
+  //cout << det_name << "  Gap:" << gap << endl;
 
   for(xml_coll_t c(x_det,_X(layer)); c; ++c)  {
     xml_comp_t x_layer = c;
@@ -73,8 +71,8 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
     totalSlices += x_layer.numChildren(_X(slice));
   }
 
-  PolyhedraRegular polyhedra(lcdd,det_name,numSides,rmin,rmin+totalThickness,detZ);
-  Volume           envelopeVol(lcdd,det_name,polyhedra,air);
+  PolyhedraRegular polyhedra(numSides,rmin,rmin+totalThickness,detZ);
+  Volume           envelopeVol(det_name,polyhedra,air);
 
   // Add the subdetector envelope to the structure.
   double innerAngle     = 2*M_PI/numSides;
@@ -84,13 +82,11 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
   double outerFaceLen   = (rmin+totalThickness) * tan_inner;
   double staveThickness = totalThickness;
 
-  Trapezoid staveTrdOuter(lcdd,det_name+"_stave_trapezoid_outer",
-			  innerFaceLen/2,outerFaceLen/2,detZ/2,detZ/2,staveThickness/2);
-  Volume staveOuterVol(lcdd,det_name+"_stave",staveTrdOuter,air);
+  Trapezoid staveTrdOuter(innerFaceLen/2,outerFaceLen/2,detZ/2,detZ/2,staveThickness/2);
+  Volume staveOuterVol(det_name+"_stave",staveTrdOuter,air);
 
-  Trapezoid staveTrdInner(lcdd,det_name+"_stave_trapezoid_inner",
-			  innerFaceLen/2-gap,outerFaceLen/2-gap,detZ/2,detZ/2,staveThickness/2);
-  Volume staveInnerVol(lcdd,det_name+"_inner",staveTrdInner,air);
+  Trapezoid staveTrdInner(innerFaceLen/2-gap,outerFaceLen/2-gap,detZ/2,detZ/2,staveThickness/2);
+  Volume staveInnerVol(det_name+"_inner",staveTrdInner,air);
 
   double layerOuterAngle = (M_PI-innerAngle)/2;
   double layerInnerAngle = (M_PI/2 - layerOuterAngle);
@@ -107,34 +103,30 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
     const Layer* lay    = layering.layer(layer_num); // Get the layer from the layering engine.
     // Loop over repeats for this layer.
     for (int j = 0; j < repeat; j++)    {
-      //string layer_name      = det_name+_toString(layer_num,"_stave_layer%d");
-      string layer_name      = _toString(layer_num,"stave_layer%d");
+      string layer_name      = det_name+_toString(layer_num,"_layer%d");
       double layer_thickness = lay->thickness();
-      DetElement  layer(layer_name,det_name+"/Layer",x_det.id());
+      DetElement  layer(stave,_toString(layer_num,"layer%d"),x_det.id());
 
       // Layer position in Z within the stave.
       layer_pos_z += layer_thickness / 2;
       // Layer box & volume
-      Box    layer_box(lcdd,"layer", layer_dim_x, detZ/2, layer_thickness);
-      Volume layer_vol(lcdd,"layer", layer_box, air);
+      Volume layer_vol(layer_name, Box(layer_dim_x,detZ/2,layer_thickness), air);
 
       // Create the slices (sublayers) within the layer.
       double slice_pos_z = -(layer_thickness / 2);
       int slice_number = 0;
       for(xml_coll_t k(x_layer,_X(slice)); k; ++k)  {
 	xml_comp_t x_slice = k;
-	//string   slice_name      = layer_name + _toString(slice_number,"_slice%d");
-	string   slice_name      = _toString(slice_number,"slice%d");
+	string   slice_name      = layer_name + _toString(slice_number,"_slice%d");
 	double   slice_thickness = x_slice.thickness();
 	Material slice_material  = lcdd.material(x_slice.materialStr());
-	DetElement slice(slice_name,det_name+"/Layer/Slice",x_det.id());
+	DetElement slice(layer,_toString(slice_number,"slice%d"),x_det.id());
 
 	slice_pos_z += slice_thickness / 2;
-	// Slice box. 
-	Box slice_box(lcdd,"slice",layer_dim_x,detZ/2,slice_thickness);
 
-	// Slice volume.
-	Volume slice_vol(lcdd,"slice",slice_box,slice_material);
+	// Slice volume & box
+	Volume slice_vol(slice_name,Box(layer_dim_x,detZ/2,slice_thickness),slice_material);
+
 	if ( x_slice.isSensitive() ) slice_vol.setSensitiveDetector(sens);
 	// Set region, limitset, and vis.
 	slice_vol.setAttributes(lcdd,x_slice.regionStr(),x_slice.limitsStr(),x_slice.visStr());
@@ -142,7 +134,7 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
 	PlacedVolume slice_phv = layer_vol.placeVolume(slice_vol,Position(0,0,slice_pos_z));
 	slice_phv.addPhysVolID(_X(slice),slice_number);
 
-	layer.add(slice);
+	slice.setPlacement(slice_phv);
 	// Increment Z position for next slice.
 	slice_pos_z += slice_thickness / 2;
 	// Increment slice number.
@@ -154,8 +146,7 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
       // Layer physical volume.
       PlacedVolume layer_phv = staveInnerVol.placeVolume(layer_vol,Position(0,0,layer_pos_z));
       layer_phv.addPhysVolID(_X(layer),layer_num);
-
-      stave.add(layer);
+      layer.setPlacement(layer_phv);
 
       // Increment the layer X dimension.
       layer_dim_x += layer_thickness * std::tan(layerInnerAngle);// * 2;
@@ -168,10 +159,8 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
 
   // Add stave inner physical volume to outer stave volume.
   staveOuterVol.placeVolume(staveInnerVol,IdentityPos());
-
   // Set the vis attributes of the outer stave section.
   stave.setVisAttributes(lcdd,staves.visStr(),staveOuterVol);
-
   // Place the staves.
   placeStaves(sdet,stave,rmin,numSides,totalThickness,envelopeVol,innerAngle,staveOuterVol);
 
diff --git a/DDExamples/CLICSiD/src/PolyhedraEndcapCalorimeter2_geo.cpp b/DDExamples/CLICSiD/src/PolyhedraEndcapCalorimeter2_geo.cpp
index de179d778db72a22ff768dba583bada7f7fcf631..260aa2731b68be7788228e7cdae46e51e2c6ed53 100644
--- a/DDExamples/CLICSiD/src/PolyhedraEndcapCalorimeter2_geo.cpp
+++ b/DDExamples/CLICSiD/src/PolyhedraEndcapCalorimeter2_geo.cpp
@@ -18,7 +18,6 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
   xml_dim_t   dim       = x_det.dimensions();
   int         det_id    = x_det.id();
   string      det_name  = x_det.nameStr();
-  string      det_type  = x_det.typeStr();
   bool        reflect   = x_det.reflect(true);
   Material    air       = lcdd.air();
   int         numsides  = dim.numsides();
@@ -27,9 +26,7 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
   double      zmin      = dim.zmin();
   Layering    layering(x_det);
   double      totalThickness = layering.totalThickness();
-    
-  PolyhedraRegular polyhedra(lcdd,det_name,numsides,rmin,rmax,totalThickness);
-  Volume           envelopeVol(lcdd,det_name,polyhedra,air);
+  Volume      envelopeVol(det_name,PolyhedraRegular(numsides,rmin,rmax,totalThickness),air);
     
   int l_num = 0;
   int layerType   = 0;
@@ -40,8 +37,7 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
     double           l_thick  = layering.layer(l_num)->thickness();
     string           l_name   = det_name + _toString(layerType,"_layer%d");
     int              l_repeat = x_layer.repeat();
-    PolyhedraRegular l_solid(lcdd,l_name,numsides,rmin,rmax,l_thick);
-    Volume           l_vol  (lcdd,l_name, l_solid, air);
+    Volume           l_vol(l_name,PolyhedraRegular(numsides,rmin,rmax,l_thick),air);
       
     int s_num = 0;
     double sliceZ = -l_thick/2;
@@ -50,8 +46,7 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
       string     s_name  = l_name + _toString(s_num,"_slice%d");
       double     s_thick = x_slice.thickness();
       Material   s_mat   = lcdd.material(x_slice.materialStr());
-      PolyhedraRegular s_solid(lcdd,s_name,numsides,rmin,rmax,s_thick);
-      Volume           s_vol  (lcdd,s_name,s_solid,s_mat);
+      Volume     s_vol(s_name,PolyhedraRegular(numsides,rmin,rmax,s_thick),s_mat);
         
       if ( x_slice.isSensitive() ) s_vol.setSensitiveDetector(sens);
       s_vol.setVisAttributes(lcdd.visAttributes(x_slice.visStr()));
@@ -74,7 +69,7 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
   }
     
   envelopeVol.setAttributes(lcdd,x_det.regionStr(),x_det.limitsStr(),x_det.visStr());
-  DetElement sdet    (det_name,det_type,x_det.id());
+  DetElement sdet    (det_name,x_det.id());
   Volume motherVol = lcdd.pickMotherVolume(sdet);
   PlacedVolume  physvol = motherVol.placeVolume(envelopeVol,
 						Position(0,0,zmin+totalThickness/2),
@@ -89,7 +84,7 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
 				    Rotation(M_PI,0,M_PI/numsides));
     physvol.addPhysVolID("system",det_id);
     physvol.addPhysVolID("barrel",2);
-    DetElement rdet(det_name+"_reflect",det_type,x_det.id());
+    DetElement rdet(det_name+"_reflect",x_det.id());
     rdet.setPlacement(physvol);
   }
   return sdet;
diff --git a/DDExamples/CLICSiD/src/SiTrackerBarrel_geo.cpp b/DDExamples/CLICSiD/src/SiTrackerBarrel_geo.cpp
index 3834c51790aa69e6819b670226c0db326e599cbb..ba5d58fb3401b4a951ca8b170f2718e8989083fe 100644
--- a/DDExamples/CLICSiD/src/SiTrackerBarrel_geo.cpp
+++ b/DDExamples/CLICSiD/src/SiTrackerBarrel_geo.cpp
@@ -17,28 +17,28 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
   Material    air       = lcdd.air();
   int         det_id    = x_det.id();
   string      det_name  = x_det.nameStr();
-  string      det_type  = x_det.typeStr();
-  DetElement  sdet       (det_name,det_type,det_id);
+  DetElement  sdet       (det_name,det_id);
   Volume      motherVol = lcdd.pickMotherVolume(sdet);
-    
+  map<string, Volume> volumes;
+
   for(xml_coll_t mi(x_det,_X(module)); mi; ++mi)  {
     xml_comp_t x_mod  = mi;
     xml_comp_t m_env  = x_mod.child(_X(module_envelope));
-    string     m_nam  = det_name+"_"+x_mod.nameStr();
-    Box        m_box (lcdd,m_nam+"_box",m_env.width(),m_env.length(),m_env.thickness());
-    Volume     m_vol (lcdd,m_nam,m_box,air);
-    DetElement m_elt (m_nam,det_type+"/Module",det_id);
+    string     m_nam  = x_mod.nameStr();
+    Volume     m_vol(m_nam,Box(m_env.width(),m_env.length(),m_env.thickness()),air);
+    DetElement m_elt(sdet, m_nam, det_id);
     int        ncomponents = 0, sensor_number = 0;
+
+    volumes[m_nam] = m_vol;
     for(xml_coll_t ci(x_mod,_X(module_component)); ci; ++ci, ++ncomponents)  {
       xml_comp_t x_comp = ci;
       xml_comp_t x_pos  = x_comp.child(_X(position),false);
       xml_comp_t x_rot  = x_comp.child(_X(rotation),false);	
-      string     c_nam  = m_nam + _toString(ncomponents,"_component%d");
-      Box        c_box (lcdd,c_nam,x_comp.width(),x_comp.length(),x_comp.thickness());
-      Volume     c_vol (lcdd,c_nam,c_box,lcdd.material(x_comp.materialStr()));
-      DetElement c_elt (c_nam,det_type+"/Module/Component",det_id);
+      string     c_nam  = _toString(ncomponents,"component%d");
+      Box        c_box (x_comp.width(),x_comp.length(),x_comp.thickness());
+      Volume     c_vol (c_nam,c_box,lcdd.material(x_comp.materialStr()));
       PlacedVolume c_phv;
-        
+
       if ( x_pos && x_rot ) {
 	Position   c_pos(x_pos.x(0),x_pos.y(0),x_pos.z(0));
 	Rotation   c_rot(x_rot.x(0),x_rot.y(0),x_rot.z(0));
@@ -57,11 +57,11 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
 	c_phv.addPhysVolID(_X(sensor),sensor_number++);
 	c_vol.setSensitiveDetector(sens);
       }
+      DetElement c_elt(m_elt,c_nam,det_id);
       c_elt.setAttributes(lcdd,c_vol,x_comp.regionStr(),x_comp.limitsStr(),x_comp.visStr());
-      m_elt.add(c_elt);
+      c_elt.setPlacement(c_phv);
     }
     m_vol.setVisAttributes(lcdd.visAttributes(x_mod.visStr()));
-    sdet.add(m_elt);
   }
   for(xml_coll_t li(x_det,_X(layer)); li; ++li)  {
     xml_comp_t x_layer  = li;
@@ -69,23 +69,23 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
     xml_comp_t x_layout = x_layer.child(_X(rphi_layout));
     xml_comp_t z_layout = x_layer.child(_X(z_layout));      // Get the <z_layout> element.
     int        lay_id   = x_layer.id();
-    string     m_nam    = det_name+"_"+x_layer.moduleStr();
+    string     m_nam    = x_layer.moduleStr();
     DetElement m_elt    = sdet.child(m_nam);
-    Volume     m_env    = lcdd.volume(m_nam);
+    Volume     m_env    = volumes[m_nam];
     string     lay_nam  = det_name+_toString(lay_id,"_layer%d");
-    Tube       lay_tub   (lcdd,lay_nam,x_barrel.inner_r(),x_barrel.outer_r(),x_barrel.z_length());
-    Volume     lay_vol   (lcdd,lay_nam,lay_tub,air);  // Create the layer envelope volume.
-    double     phi0     = x_layout.phi0();      // Starting phi of first module.
-    double     phi_tilt = x_layout.phi_tilt();  // Phi tilt of a module.
-    double     rc       = x_layout.rc();        // Radius of the module center.
-    int        nphi     = x_layout.nphi();      // Number of modules in phi.
-    double     rphi_dr  = x_layout.dr();        // The delta radius of every other module.
-    double     phi_incr = (M_PI * 2) / nphi;    // Phi increment for one module.
-    double     phic     = phi0;                 // Phi of the module center.
-    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.
-      
+    Tube       lay_tub   (x_barrel.inner_r(),x_barrel.outer_r(),x_barrel.z_length());
+    Volume     lay_vol   (lay_nam,lay_tub,air);       // Create the layer envelope volume.
+    double     phi0     = x_layout.phi0();            // Starting phi of first module.
+    double     phi_tilt = x_layout.phi_tilt();        // Phi tilt of a module.
+    double     rc       = x_layout.rc();              // Radius of the module center.
+    int        nphi     = x_layout.nphi();            // Number of modules in phi.
+    double     rphi_dr  = x_layout.dr();              // The delta radius of every other module.
+    double     phi_incr = (M_PI * 2) / nphi;          // Phi increment for one module.
+    double     phic     = phi0;                       // Phi of the module center.
+    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.
+
     // Z increment for module placement along Z axis.
     // Adjust for z0 at center of module rather than
     // the end of cylindrical envelope.
@@ -103,8 +103,6 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
         
       // Loop over the number of modules in z.
       for (int j = 0; j < nz; j++)	  {
-	// Create a unique name for the module in this logical volume, layer, phi, and z.
-	string m_place = lay_nam + _toString(ii,"_phi%d") + _toString(j,"_z%d");
 	// Module PhysicalVolume.
 	PlacedVolume  m_physvol = 
           lay_vol.placeVolume(m_env,Position(x,y,module_z),
@@ -124,12 +122,13 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
       rphi_dr *= -1;            // Flip sign of dr parameter.
       module_z = -z0;           // Reset the Z placement parameter for module.
     }
-    m_elt.setAttributes(lcdd,lay_vol,x_layer.regionStr(),x_layer.limitsStr(),x_layer.visStr());
     // Create the PhysicalVolume for the layer.
     PlacedVolume lpv = motherVol.placeVolume(lay_vol); // Place layer in mother
     lpv.addPhysVolID("system", det_id);      // Set the subdetector system ID.
     lpv.addPhysVolID("barrel", 0);           // Flag this as a barrel subdetector.
     lpv.addPhysVolID("layer", lay_id);       // Set the layer ID.
+    m_elt.setAttributes(lcdd,lay_vol,x_layer.regionStr(),x_layer.limitsStr(),x_layer.visStr());
+    m_elt.setPlacement(lpv);
   }
   return sdet;
 }
diff --git a/DDExamples/CLICSiD/src/SiTrackerEndcap2_geo.cpp b/DDExamples/CLICSiD/src/SiTrackerEndcap2_geo.cpp
index 8e1d3e520328dee236ba6a5350fdf26d2055579f..8d3d712dc62a2afbcdf5218a3beee53baa1f1b6d 100644
--- a/DDExamples/CLICSiD/src/SiTrackerEndcap2_geo.cpp
+++ b/DDExamples/CLICSiD/src/SiTrackerEndcap2_geo.cpp
@@ -20,9 +20,8 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
   Material    vacuum    = lcdd.vacuum();
   int         det_id    = x_det.id();
   string      det_name  = x_det.nameStr();
-  string      det_type  = x_det.typeStr();
   bool        reflect   = x_det.reflect();
-  DetElement  sdet       (det_name,det_type,det_id);
+  DetElement  sdet       (det_name,det_id);
   Volume      motherVol = lcdd.trackingVolume();
   int         m_id=0, c_id=0, n_sensor=0;
   double      posY;
@@ -31,7 +30,6 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
   for(xml_coll_t mi(x_det,_X(module)); mi; ++mi, ++m_id)  {
     xml_comp_t x_mod   = mi;
     string     m_nam   = x_mod.nameStr();
-    string     vol_nam = m_nam+"Volume";
     xml_comp_t trd     = x_mod.child(_X(trd));
     double     x1      = trd.x1();
     double     x2      = trd.x2();
@@ -42,21 +40,17 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
       total_thickness += xml_comp_t(ci).thickness();
       
     y1 = y2 = total_thickness / 2;
-    Trapezoid m_envelope(lcdd, m_nam+"Trd", x1, x2, y1, y2, z);
-    Volume    m_volume(lcdd, vol_nam, m_envelope, vacuum);
-      
+    Volume  m_volume(det_name+"_"+m_nam, Trapezoid(x1, x2, y1, y2, z), vacuum);      
     m_volume.setVisAttributes(lcdd.visAttributes(x_mod.visStr()));
       
     for(ci.reset(), n_sensor=0, 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_nam + _toString(c_id,"_component%d");
-      Trapezoid trd(lcdd, c_name, x1, x2, c_thick/2e0, c_thick/2e0, z);
-      Volume    vol(lcdd, c_name, trd, c_mat);
-        
+      string     c_name  = m_volume.name() + _toString(c_id,"_component%d");
+      Volume vol(c_name, Trapezoid(x1,x2,c_thick/2e0,c_thick/2e0,z), c_mat);
+
       vol.setVisAttributes(lcdd.visAttributes(c.visStr()));
-        
       PlacedVolume phv = m_volume.placeVolume(vol,Position(0,posY+c_thick/2,0));
       phv.addPhysVolID(_X(component),c_id);
       if ( c.isSensitive() ) {
@@ -70,8 +64,8 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
     modules[m_nam] = m_volume;
   }
   for(xml_coll_t li(x_det,_X(layer)); li; ++li)  {
-    xml_comp_t x_layer(li);
-    int l_id = x_layer.id();
+    xml_comp_t  x_layer(li);
+    int l_id    = x_layer.id();
     int mod_num = 0;
     for(xml_coll_t ri(x_layer,_X(ring)); ri; ++ri)  {
       xml_comp_t x_ring = ri;
@@ -82,33 +76,30 @@ static Ref_t create_detector(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens
       int    nmodules = x_ring.attr<int>(_A(nmodules));
       string m_nam    = x_ring.moduleStr();
       Volume m_vol    = modules[m_nam];
-        
       double iphi     = 2*M_PI/nmodules;
-      double phi = phi0;
+      double phi      = phi0;
+
       for(int k=0; k<nmodules; ++k) {
-	string m_base = det_name + _toString(l_id,"_layer%d") + _toString(mod_num,"_module%d");
+	string m_base = _toString(l_id,"layer%d") + _toString(mod_num,"_module%d");
 	double x = r*std::cos(phi);
 	double y = r*std::sin(phi);
+	DetElement module(sdet,m_base,det_id);
 	PlacedVolume pv = motherVol.placeVolume(m_vol,
 						Position(x,y,zstart+dz),
 						Rotation(-M_PI/2,-M_PI/2-phi,0));
 	pv.addPhysVolID("system",det_id).addPhysVolID("barrel",1);
 	pv.addPhysVolID("layer", l_id).addPhysVolID("module",mod_num);
-	DetElement module (m_base,det_type+"/Module",det_id);
 	module.setPlacement(pv);
-	sdet.add(module);
-          
 	if ( reflect ) {
 	  pv = motherVol.placeVolume(m_vol,
 				     Position(x,y,-zstart-dz),
 				     Rotation(-M_PI/2,-M_PI/2-phi,M_PI));
 	  pv.addPhysVolID("system",det_id).addPhysVolID("barrel",2);
 	  pv.addPhysVolID("layer", l_id).addPhysVolID("module",mod_num);
-	  DetElement r_module (m_base+"_reflect",det_type+"/Module",det_id);
+	  DetElement r_module(sdet,m_base+"_reflect",det_id);
 	  r_module.setPlacement(pv);
-	  sdet.add(r_module);
 	}
-	dz = -dz;
+	dz   = -dz;
 	phi += iphi;
 	++mod_num;
       }
diff --git a/DDExamples/CLICSiD/src/TubeSegment_geo.cpp b/DDExamples/CLICSiD/src/TubeSegment_geo.cpp
index b8e17308af4b173013f746795e9df56f483b9a4c..28e94d1aa30187ca34289ef441dc84ca92e8c1d3 100644
--- a/DDExamples/CLICSiD/src/TubeSegment_geo.cpp
+++ b/DDExamples/CLICSiD/src/TubeSegment_geo.cpp
@@ -15,19 +15,19 @@ using namespace DD4hep::Geometry;
 static Ref_t create_element(LCDD& lcdd, const xml_h& e, SensitiveDetector&)  {
   xml_det_t  x_det  (e);
   xml_comp_t x_tube (x_det.child(_X(tubs)));
-  xml_dim_t  x_pos  (x_det.child(_X(position)));
-  xml_dim_t  x_rot  (x_det.child(_X(rotation)));
-  string     name   = x_det.nameStr();
-  Tube       tub    (lcdd,name,x_tube.rmin(),x_tube.rmax(),x_tube.zhalf());
-  Volume     vol    (lcdd,name,tub,lcdd.material(x_det.materialStr()));
-    
+  xml_dim_t  pos    (x_det.child(_X(position)));
+  xml_dim_t  rot    (x_det.child(_X(rotation)));
+  string     name  = x_det.nameStr();
+  Tube       tub    (x_tube.rmin(),x_tube.rmax(),x_tube.zhalf());
+  Volume     vol    (name,tub,lcdd.material(x_det.materialStr()));
+
   vol.setVisAttributes(lcdd, x_det.visStr());
     
-  DetElement   sdet(name,x_det.typeStr(),x_det.id());
+  DetElement   sdet(name,x_det.id());
   Volume       mother = lcdd.pickMotherVolume(sdet);
   PlacedVolume phv = 
-    mother.placeVolume(vol,Position(x_pos.x(),x_pos.y(),x_pos.z()),
-                       Rotation(x_rot.x(),x_rot.y(),x_rot.z()));
+    mother.placeVolume(vol,Position(pos.x(),pos.y(),pos.z()),
+                       Rotation(rot.x(),rot.y(),rot.z()));
   phv.addPhysVolID(_A(id),x_det.id());
   sdet.setPlacement(phv);
   return sdet;
diff --git a/DDExamples/ILDExDet/include/ILDExTPC.h b/DDExamples/ILDExDet/include/ILDExTPC.h
index 071fab2f296ea595a4385334ad15e86976380dd0..b914d6da54aa7db8d45e103a3676e09b03e30c45 100644
--- a/DDExamples/ILDExDet/include/ILDExTPC.h
+++ b/DDExamples/ILDExDet/include/ILDExTPC.h
@@ -15,7 +15,7 @@ namespace DD4hep {
   struct ILDExTPC : public Geometry::DetElement {
     typedef Geometry::Ref_t Ref_t;
     ILDExTPC(const Ref_t& e) : Geometry::DetElement(e) {}
-    ILDExTPC(const Geometry::LCDD& lcdd, const std::string& name, const std::string& type, int id);
+    ILDExTPC(const std::string& name, const std::string& type, int id);
     void setInnerWall(Ref_t obj);
     void setOuterWall(Ref_t obj);
     void setGasVolume(Ref_t obj);
diff --git a/DDExamples/ILDExDet/include/ILDExVXD.h b/DDExamples/ILDExDet/include/ILDExVXD.h
index 3fdf50a6cbeebaafc71d6cf4d879e82ce4cd6437..133745ac671682aef044bbc6074118678bfff005 100644
--- a/DDExamples/ILDExDet/include/ILDExVXD.h
+++ b/DDExamples/ILDExDet/include/ILDExVXD.h
@@ -13,8 +13,9 @@
 
 namespace DD4hep {
   struct ILDExVXD : public Geometry::DetElement {
-    ILDExVXD(const Geometry::LCDD& lcdd, const std::string& name, const std::string& type, int id)
-      : Geometry::DetElement(lcdd,name,type,id) {}
+    ILDExVXD(const Geometry::Ref_t& e) : Geometry::DetElement(e) {}
+    ILDExVXD(const std::string& name, const std::string& type, int id)
+      : Geometry::DetElement(name,type,id) {}
   };
 }
 #endif // DD4hep_ILDEXVXD_H
diff --git a/DDExamples/ILDExDet/include/TPCModule.h b/DDExamples/ILDExDet/include/TPCModule.h
index 9926b8536affcde02e9b690995b49278340325ce..8eff9bef46c345a964daa56234902c65ac36cfe4 100644
--- a/DDExamples/ILDExDet/include/TPCModule.h
+++ b/DDExamples/ILDExDet/include/TPCModule.h
@@ -21,7 +21,7 @@ namespace DD4hep {
     TPCModule() {}
     TPCModule(const Ref_t& e) : Geometry::DetElement(e) {}
     TPCModule(const Geometry::DetElement& e) : Geometry::DetElement(e) {}
-    TPCModule(const Geometry::LCDD& lcdd, const std::string& name, const std::string& type, int id);
+    TPCModule(const std::string& name, const std::string& type, int id);
     /** ID of this module.
      */
     int getID() const;
diff --git a/DDExamples/ILDExDet/src/ILDExTPC.cpp b/DDExamples/ILDExDet/src/ILDExTPC.cpp
index 8a66d39066791b6781fe0788f5515d9780ba535e..6d4e3468b754bd6bdbe8fd176e4527f2b1e80cae 100644
--- a/DDExamples/ILDExDet/src/ILDExTPC.cpp
+++ b/DDExamples/ILDExDet/src/ILDExTPC.cpp
@@ -8,7 +8,7 @@ namespace DD4hep {
   
   using namespace Geometry;
   
-  ILDExTPC::ILDExTPC(const LCDD&, const string& name, const string& type, int id)
+  ILDExTPC::ILDExTPC(const string& name, const string& type, int id)
   {
     Value<TNamed,TPCData>* p = new Value<TNamed,TPCData>();
     assign(p,name, type);
diff --git a/DDExamples/ILDExDet/src/TPCModule.cpp b/DDExamples/ILDExDet/src/TPCModule.cpp
index 3bb15632f4762ec54a60c5485e86e8dddac8549a..f484351a53d81ad42f15de6b63dae0ad1697ea79 100644
--- a/DDExamples/ILDExDet/src/TPCModule.cpp
+++ b/DDExamples/ILDExDet/src/TPCModule.cpp
@@ -25,7 +25,7 @@ namespace DD4hep {
   
   using namespace Geometry;
   
-  TPCModule::TPCModule(const LCDD&, const string& name, const string& type, int id)
+  TPCModule::TPCModule(const string& name, const string& type, int id)
   {
     Value<TNamed,TPCModuleData>* p = new Value<TNamed,TPCModuleData>();
     assign(p,name, type);
diff --git a/DDExamples/ILDExDet/src/compact/ILDExTPC_geo.cpp b/DDExamples/ILDExDet/src/compact/ILDExTPC_geo.cpp
index a824ab9fb2258de7b994f12c5d165542d375be3a..27e5e7aa6b5fc7cf751e524219401ff1e4ed231f 100644
--- a/DDExamples/ILDExDet/src/compact/ILDExTPC_geo.cpp
+++ b/DDExamples/ILDExDet/src/compact/ILDExTPC_geo.cpp
@@ -25,9 +25,9 @@ static Ref_t create_element(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens)
   //     DetElement tpc(tpcData, name, x_det.typeStr());
   //     tpcData->id = x_det.id();
   //else do this
-  DetElement    tpc    (lcdd,name,x_det.typeStr(),x_det.id());
-  Tube        tpc_tub(lcdd,name+"_envelope",x_tube.rmin(),x_tube.rmax(),x_tube.zhalf());
-  Volume      tpc_vol(lcdd,name+"_envelope_volume", tpc_tub, mat);
+  DetElement    tpc  (name,x_det.typeStr(),x_det.id());
+  Tube        tpc_tub(x_tube.rmin(),x_tube.rmax(),x_tube.zhalf());
+  Volume      tpc_vol(name+"_envelope_volume", tpc_tub, mat);
 
   for(xml_coll_t c(e,_X(detector)); c; ++c)  {
     xml_comp_t  px_det  (c);
@@ -37,9 +37,9 @@ static Ref_t create_element(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens)
     xml_comp_t  px_mat  (px_det.child(_X(material)));
     string      part_nam(px_det.nameStr());
     Material    part_mat(lcdd.material(px_mat.nameStr()));
-    DetElement  part_det(lcdd,part_nam,px_det.typeStr(),px_det.id());
-    Tube        part_tub(lcdd,part_nam+"_tube",px_tube.rmin(),px_tube.rmax(),px_tube.zhalf());
-    Volume      part_vol(lcdd,part_nam,part_tub,part_mat);
+    DetElement  part_det(part_nam,px_det.typeStr(),px_det.id());
+    Tube        part_tub(px_tube.rmin(),px_tube.rmax(),px_tube.zhalf());
+    Volume      part_vol(part_nam,part_tub,part_mat);
     Position    part_pos(px_pos.x(),px_pos.y(),px_pos.z());
     Rotation    part_rot(px_rot.x(),px_rot.y(),px_rot.z());
     bool        reflect   = px_det.reflect();
@@ -63,15 +63,14 @@ static Ref_t create_element(LCDD& lcdd, const xml_h& e, SensitiveDetector& sens)
 	  double DeltaPhi=(2*M_PI-nmodules*(row.modulePitch()/(rmin+(rmax-rmin)/2)))/nmodules;
 	  double zhalf=px_tube.zhalf();
 	  string      mr_nam=m_name+_toString(rowID,"_Row%d");
-	  Tube        mr_tub(lcdd,mr_nam+"_tube",rmin,rmax,zhalf,DeltaPhi);
-	  Volume      mr_vol(lcdd,mr_nam,mr_tub,part_mat);
+	  Volume      mr_vol(mr_nam,Tube(rmin,rmax,zhalf,DeltaPhi),part_mat);
 	  Material    mr_mat(lcdd.material(px_mat.nameStr()));
 	  Readout xml_pads(lcdd.readout(row.padType()));
 	  		
 	 //placing modules
 	  for(int md=0;md<nmodules;md++){
 	    string      m_nam=m_name+_toString(rowID,"_Row%d")+_toString(md,"_M%d");
-	    DetElement  module (lcdd,m_nam,row.typeStr(),mdcount);
+	    DetElement  module(m_nam,row.typeStr(),mdcount);
 	    //data of module, e.g. Readout
 	    // Value<TNamed,TPCModuleData>* tpcModData = new Value<TNamed,TPCModuleData>();
 	    // tpcModData->id = mdcount;
diff --git a/DDExamples/ILDExDet/src/compact/ILDExVXD_geo.cpp b/DDExamples/ILDExDet/src/compact/ILDExVXD_geo.cpp
index 82be5eba2258533f8e70c7e31b2272567ac752ac..b7f2b67e285f7e0544ce7ead1e3bcf594c7b4557 100644
--- a/DDExamples/ILDExDet/src/compact/ILDExVXD_geo.cpp
+++ b/DDExamples/ILDExDet/src/compact/ILDExVXD_geo.cpp
@@ -18,7 +18,7 @@ namespace DD4hep { namespace Geometry {
   template <> Ref_t DetElementFactory<ILDExVXD>::create(LCDD& lcdd, const xml_h& e, SensitiveDetector&)  {
     xml_det_t   x_det = e;
     string      name  = x_det.nameStr();
-    ILDExVXD    vxd    (lcdd,name,x_det.typeStr(),x_det.id());
+    ILDExVXD    vxd    (name,x_det.typeStr(),x_det.id());
     Volume      mother= lcdd.pickMotherVolume(vxd);
     
     for(xml_coll_t c(e,_X(layer)); c; ++c)  {
@@ -37,12 +37,12 @@ namespace DD4hep { namespace Geometry {
       double      width      = 2.*tan(dphi/2.)*(sens_radius-sens_thick/2.);
       Material    sens_mat   = lcdd.material(x_ladder.materialStr());
       Material    supp_mat   = lcdd.material(x_support.materialStr());
-      Box         ladderbox (lcdd,layername+"_ladder_solid",  (sens_thick+supp_thick)/2.,width/2.,zhalf);
-      Volume      laddervol (lcdd,layername+"_ladder_volume",  ladderbox,sens_mat);
-      Box         sensbox   (lcdd,layername+"_sens_solid",     sens_thick/2.,width/2.,zhalf);
-      Volume      sensvol   (lcdd,layername+"_sens_volume",    sensbox,sens_mat);
-      Box         suppbox   (lcdd,layername+"_supp_solid",     supp_thick/2.,width/2.,zhalf);
-      Volume      suppvol   (lcdd,layername+"_supp_volume",    suppbox,supp_mat);
+      Box         ladderbox ((sens_thick+supp_thick)/2.,width/2.,zhalf);
+      Volume      laddervol (layername+"_ladder_volume",  ladderbox,sens_mat);
+      Box         sensbox   (sens_thick/2.,width/2.,zhalf);
+      Volume      sensvol   (layername+"_sens_volume",    sensbox,sens_mat);
+      Box         suppbox   (supp_thick/2.,width/2.,zhalf);
+      Volume      suppvol   (layername+"_supp_volume",    suppbox,supp_mat);
       Position    senspos   (-(sens_thick+supp_thick)/2.+sens_thick/2.,0,0);
       Position    supppos   (-(sens_thick+supp_thick)/2.+sens_thick/2.+supp_thick/2.,0,0);