diff --git a/DDCore/include/DD4hep/GeoHandler.h b/DDCore/include/DD4hep/GeoHandler.h
index ed8de7473bd0c43308c913b7f5f8c1e33512f002..5416f2824883e469b5aca0598d73b3c59e2b49d4 100644
--- a/DDCore/include/DD4hep/GeoHandler.h
+++ b/DDCore/include/DD4hep/GeoHandler.h
@@ -46,6 +46,7 @@ namespace DD4hep {
     public:
 
       typedef std::set<TGeoVolume*>                              VolumeSet;
+      typedef std::vector<TGeoVolume*>                           VolumeVector;
       typedef std::set<const TGeoVolume*>                        ConstVolumeSet;
       typedef std::vector<std::pair<std::string, TGeoMatrix*> >  TransformSet;
       typedef std::set<TGeoShape*>                               SolidSet;
@@ -61,7 +62,8 @@ namespace DD4hep {
 
       struct GeometryInfo   {
 	SolidSet           solids;
-	VolumeSet          volumes;
+	VolumeSet          volumeSet;
+	VolumeVector       volumes;
 	TransformSet       trafos;
 	VisRefs            vis;
 	Fields             fields;
diff --git a/DDCore/include/DD4hep/Shapes.h b/DDCore/include/DD4hep/Shapes.h
index ede1603ce17e46d62aa6e9659050b807bcde9004..82183a724ab404ddde39a21062700d366e635c2d 100644
--- a/DDCore/include/DD4hep/Shapes.h
+++ b/DDCore/include/DD4hep/Shapes.h
@@ -213,7 +213,7 @@ namespace DD4hep {
       double GetRmin() const { return GetRmin1(); }
       double GetRmax() const { return GetRmax1(); }
     };
-    struct Tube : public Solid_type</*TGeoTubeSeg */ MyConeSeg>  {
+    struct Tube : public Solid_type<TGeoTubeSeg /* MyConeSeg */>  {
       protected:
       void make(const std::string& name,double rmin,double rmax,double z,double startPhi,double deltaPhi);
 
@@ -449,6 +449,11 @@ namespace DD4hep {
      *   @version 1.0
      */
     struct PolyhedraRegular : public Solid_type<TGeoPgon>  {
+      protected:
+      /// Helper function to create holy hedron
+      void _create(const std::string& name, int nsides, double rmin, double rmax, 
+		   double zpos, double zneg, double start, double delta);
+      public:
       /// Constructor to be used when reading the already parsed object
       template <typename Q> 
       PolyhedraRegular(const Handle<Q>& e) : Solid_type<Implementation>(e) {}
diff --git a/DDCore/include/XML/DocumentHandler.h b/DDCore/include/XML/DocumentHandler.h
index 85c038d6721618313c476fa188aa6c77ad556840..c7f9a74932e5fe06be2958100a754b5ff5225c73 100644
--- a/DDCore/include/XML/DocumentHandler.h
+++ b/DDCore/include/XML/DocumentHandler.h
@@ -41,6 +41,8 @@ namespace DD4hep {
       DocumentHandler();
       /// Default destructor
       virtual ~DocumentHandler();
+      // Create new XML document by parsing empty xml buffer
+      Document create(const char* tag, const char* comment=0)  const;
       /// Load XML file and parse it.
       virtual Document load(const std::string& fname) const;
       /// Load secondary XML file with relative addressing with respect to handle
diff --git a/DDCore/include/XML/UnicodeValues.h b/DDCore/include/XML/UnicodeValues.h
index 138a4ea454bf511137069029a87d66e26f45c2db..c571231bd5f3ba56f8787da88cde548b210a791c 100644
--- a/DDCore/include/XML/UnicodeValues.h
+++ b/DDCore/include/XML/UnicodeValues.h
@@ -7,11 +7,6 @@ namespace DD4hep   { namespace XML  {
     extern const Tag_t Unicode_PI;
     extern const Tag_t Unicode_TWOPI;
 
-  UNICODE(value);
-  UNICODE(radian);
-  UNICODE(ref);
-
-
   UNICODE(0);
   UNICODE(1);
   UNICODE(2);
@@ -35,6 +30,7 @@ namespace DD4hep   { namespace XML  {
   UNICODE(alpha2);
   UNICODE(alpha3);
   UNICODE(alpha4);
+  UNICODE(arb8);
   UNICODE(assembly);
   UNICODE(atom);
   UNICODE(attributes);
@@ -43,11 +39,11 @@ namespace DD4hep   { namespace XML  {
 
   UNICODE(b);
   UNICODE(B);
-  UNICODE(box);
   UNICODE(barrel);
   UNICODE(barrel_envelope);
   UNICODE(beampipe);
   UNICODE(beta);
+  UNICODE(box);
 
   UNICODE(c);
   UNICODE(C);
@@ -72,6 +68,7 @@ namespace DD4hep   { namespace XML  {
   UNICODE(d);
   UNICODE(D);
   UNICODE(define);
+  UNICODE(delta);
   UNICODE(deltaphi);
   UNICODE(deltatheta);
   UNICODE(depth);
@@ -104,6 +101,7 @@ namespace DD4hep   { namespace XML  {
   UNICODE(end_modules);
   UNICODE(endcap);
   UNICODE(endphi);
+  UNICODE(epsilon);
   UNICODE(eunit);
   UNICODE(end_x);
   UNICODE(end_y);
@@ -152,6 +150,7 @@ namespace DD4hep   { namespace XML  {
   UNICODE(header);
   UNICODE(height);
   UNICODE(hits_collection);
+  UNICODE(hype);
 
   UNICODE(i);
   UNICODE(I);
@@ -240,6 +239,7 @@ namespace DD4hep   { namespace XML  {
   UNICODE(outer_radius);
   UNICODE(outer_z);
   UNICODE(outgoing_r);
+  UNICODE(outst);
 
   UNICODE(p);
   UNICODE(P);
@@ -273,12 +273,15 @@ namespace DD4hep   { namespace XML  {
   UNICODE(R);
   UNICODE(r_size);
   UNICODE(r0);
+  UNICODE(rad);
+  UNICODE(radian);
   UNICODE(radius);
   UNICODE(radiator);
   UNICODE(rbg);
   UNICODE(rc);
   UNICODE(readout);
   UNICODE(readouts);
+  UNICODE(ref);
   UNICODE(reflect);
   UNICODE(reflect_rot);
   UNICODE(region);
@@ -371,7 +374,24 @@ namespace DD4hep   { namespace XML  {
 
   UNICODE(v);
   UNICODE(V);
+  UNICODE(v1x);
+  UNICODE(v1y);
+  UNICODE(v2x);
+  UNICODE(v2y);
+  UNICODE(v3x);
+  UNICODE(v3y);
+  UNICODE(v4x);
+  UNICODE(v4y);
+  UNICODE(v5x);
+  UNICODE(v5y);
+  UNICODE(v6x);
+  UNICODE(v6y);
+  UNICODE(v7x);
+  UNICODE(v7y);
+  UNICODE(v8x);
+  UNICODE(v8y);
   UNICODE(Vacuum);
+  UNICODE(value);
   UNICODE(verbose);
   UNICODE(version);
   UNICODE(vis);
diff --git a/DDCore/include/XML/XMLDetector.h b/DDCore/include/XML/XMLDetector.h
index cd666d4bb55fdf7f0b0206bf535fdad2308aa8ae..c36db45b6c7e478f14eebe73abd73934c6597101 100644
--- a/DDCore/include/XML/XMLDetector.h
+++ b/DDCore/include/XML/XMLDetector.h
@@ -62,6 +62,16 @@ namespace DD4hep {
 
       /// Access rotation constants: angle
       double angle() const;
+      /// Access rotation constants: angle
+      double alpha() const;
+      /// Access rotation constants: angle
+      double beta() const;
+      /// Access rotation constants: angle
+      double gamma() const;
+      /// Access rotation constants: angle
+      double delta() const;
+      /// Access rotation constants: angle
+      double epsilon() const;
       /// Access rotation constants: theta
       double theta() const;
       /// Access rotation constants: thetaBins
@@ -83,6 +93,15 @@ namespace DD4hep {
       /// Access Tube parameters: deltaphi
       double deltaphi() const;
 
+      /// Access parameters: b
+      double b()  const;
+      /// Access parameters: B
+      double B()  const;
+      /// Access parameters: g
+      double g()  const;
+      /// Access parameters: G
+      double G()  const;
+
       /// Access parameters: r
       double r()  const;
       /// Access parameters: r, if not present returns default
@@ -288,6 +307,11 @@ namespace DD4hep {
       /// Access attribute values: outer_field
       double outer_field() const;
 
+      /// Access attribute values: visible
+      bool visible() const;
+      /// Access attribute values: show_daughters
+      bool show_daughters() const;
+      
       /// Access child element with tag "dimensions" as Dimension object
       Dimension dimensions(bool throw_if_not_present=true)  const;
       /// Child access: position
@@ -305,6 +329,8 @@ namespace DD4hep {
 
       /// Access name attribute as STL string
       std::string   nameStr() const;
+      /// Access ref attribute as a string
+      std::string   refStr()  const;
       /// Access type attribute as STL string
       std::string   typeStr() const;
       /// Access module attribute as STL string
@@ -349,7 +375,7 @@ namespace DD4hep {
     struct DetElement : public Dimension  {
       /// Constructor from Handle
       DetElement(Handle_t e) : Dimension(e)  {}
-      /// Access undrlying XML handle object
+      /// Access underlying XML handle object
       Handle_t handle()  const { return m_element; }
       
       /// Access parameters: id
diff --git a/DDCore/include/XML/XMLElements.h b/DDCore/include/XML/XMLElements.h
index 7916eaba459b9717181343acc2463788867b542e..28393cf8ac66e44b160633bf4c655fcd206cf6f2 100644
--- a/DDCore/include/XML/XMLElements.h
+++ b/DDCore/include/XML/XMLElements.h
@@ -374,6 +374,8 @@ namespace DD4hep {
 
       /// Add reference child as a new child node. The obj must have the "name" attribute!
       Handle_t setRef(const XmlChar* tag, const XmlChar* ref);
+      /// Add reference child as a new child node. The obj must have the "name" attribute!
+      Handle_t setRef(const XmlChar* tag, const std::string& ref);
 
       /*** DOM Element child handling 
        */
@@ -606,8 +608,12 @@ namespace DD4hep {
       bool hasChild(const XmlChar* tag) const                   {  return m_element.hasChild(tag);        }
       /// Set the reference attribute to the node (adds attribute ref="ref-name")
       Attribute setRef(const XmlChar* tag, const XmlChar* refname)  const;
+      /// Set the reference attribute to the node (adds attribute ref="ref-name")
+      Attribute setRef(const XmlChar* tag, const std::string& refname)  const;
       /// Access the value of the reference attribute of the node (attribute ref="ref-name")
       const XmlChar* getRef(const XmlChar* tag)  const;
+      /// Add comment node to the element
+      void addComment(const char* text) const;
     };
 
     /** @class RefElement XMLElements.h XML/XMLElements.h
diff --git a/DDCore/include/XML/config.h b/DDCore/include/XML/config.h
index 81dd70ede4bd67e58b4a6e119bad80972be8c2b3..f36432d0f677a2563e66bc26dcd8c6960e9a4825 100644
--- a/DDCore/include/XML/config.h
+++ b/DDCore/include/XML/config.h
@@ -36,10 +36,7 @@ namespace DD4hep { namespace XML {
 
 #ifdef  __TIXML__
 #define XML_IMPLEMENTATION_TYPE " TinyXML DOM mini-parser   "
-#define XML_HEADER_DECLARATION  "<?xml version=\"1.0\" encoding=\"UTF-8\">\n"
 #else   // Xerces-C
 #define XML_IMPLEMENTATION_TYPE " Apache Xerces-C DOM Parser"
-#define XML_HEADER_DECLARATION
 #endif  // __TIXML__
-
 #endif // DD4HEP_XML_CONFIG_H
diff --git a/DDCore/src/GeoHandler.cpp b/DDCore/src/GeoHandler.cpp
index f41acade92fd6c464665b83e83d382d7bfd07f53..0740c9abb331eff5ccb4944135088e6edaea43db 100644
--- a/DDCore/src/GeoHandler.cpp
+++ b/DDCore/src/GeoHandler.cpp
@@ -82,7 +82,10 @@ GeoHandler& GeoHandler::collect(DetElement element, GeometryInfo& info) {
       //SensitiveDetector det = vol.sensitiveDetector();
 
       // Note : assemblies and the world do not have a real volume nor a material
-      if ( v ) info.volumes.insert(v);
+      if ( v && info.volumeSet.find(v) == info.volumeSet.end() )   {
+	info.volumeSet.insert(v);
+	info.volumes.push_back(v);
+      }
       if ( m ) info.materials.insert(m);
       if ( dynamic_cast<Volume::Object*>(v) ) {
 	if ( vis.isValid() ) info.vis.insert(vis.ptr());
diff --git a/DDCore/src/LCDDImp.cpp b/DDCore/src/LCDDImp.cpp
index 26eb3c3b492a6bd2c82a4725a2bcb2d7b7a93a1c..24d48e7792a2889b80beb2dfd3bf94e5ec8b8b3a 100644
--- a/DDCore/src/LCDDImp.cpp
+++ b/DDCore/src/LCDDImp.cpp
@@ -137,34 +137,47 @@ namespace {
     GeoScan& operator()()  {
       GeoHandler::Data& data = *m_data;
       string nam;
+      cout << "++ Patching names of anonymous shapes...." << endl;
       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()) ) {
+          TGeoVolume* v     = n->GetVolume();
+          TGeoShape*  s     = v->GetShape();
+	  const char* sn    = s->GetName();
+          if ( 0 == sn || 0 == ::strlen(sn) ) {
             nam = v->GetName();
             nam += "_shape";
             s->SetName(nam.c_str());
           }
-          else {
-            nam = s->GetName();
+          else if ( 0 == ::strcmp(sn,s->IsA()->GetName()) ) {
+            nam = v->GetName();
+            nam += "_shape";
+            s->SetName(nam.c_str());
           }
-          if ( s->IsA()->Class() == TGeoCompositeShape::Class() ) {
+	  else {
+	    nam = sn;
+	    if ( nam.find("_shape") == string::npos ) nam += "_shape";
+            s->SetName(nam.c_str());
+	  }
+          if ( s->IsA() == 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());
+            s  = boolean->GetLeftShape();
+	    sn = s->GetName();
+	    if ( 0 == sn || 0 == ::strlen(sn) ) {
+              s->SetName((nam+"_left").c_str());
+	    }
+            else if ( 0 == ::strcmp(sn,s->IsA()->GetName()) ) {
+              s->SetName((nam+"_left").c_str());
+	    }
+            s  = boolean->GetRightShape();
+	    sn = s->GetName();
+	    if ( 0 == sn || 0 == ::strlen(sn) ) {
+              s->SetName((nam+"_right").c_str());
+	    }
+            else if ( 0 == ::strcmp(s->GetName(),s->IsA()->GetName()) ) {
+              s->SetName((nam+"_right").c_str());
             }
           }
         }
@@ -206,7 +219,8 @@ void LCDDImp::endDocument()  {
     //gGeoManager->SetTopVolume(m_worldVol);
     mgr->CloseGeometry();
     m_world.setPlacement(PlacedVolume(mgr->GetTopNode()));
-    ShapePatcher(m_world)();
+    ShapePatcher patcher(m_world);
+    patcher();
   }
 }
 
diff --git a/DDCore/src/Objects.cpp b/DDCore/src/Objects.cpp
index 9a506f65bbc299278be2c3fa66584633e2a3e346..6aa2598bed561a2db552b2944e12f075a5458a2b 100644
--- a/DDCore/src/Objects.cpp
+++ b/DDCore/src/Objects.cpp
@@ -169,7 +169,7 @@ VisAttr::VisAttr(const string& name)    {
   assign(obj, name, "vis");
   obj->color  = 2;
   setLineStyle(SOLID);
-  setDrawingStyle(WIREFRAME);
+  setDrawingStyle(SOLID);
   setShowDaughters(true);
   setAlpha(0.1f);
 }
diff --git a/DDCore/src/Shapes.cpp b/DDCore/src/Shapes.cpp
index caecf029c7aaf9b5f5f2d5d61894a59294327031..7545fbadf07eb148db189b162dd98d3c8894c797 100644
--- a/DDCore/src/Shapes.cpp
+++ b/DDCore/src/Shapes.cpp
@@ -186,17 +186,17 @@ ConeSegment& ConeSegment::setDimensions(double dz, double rmin1, double rmax1, d
 void Tube::make(const string& name, double rmin, double rmax, double z, double startPhi, double deltaPhi)
 {
   //_assign((TGeoTubeSeg*)new TGeoTube(rmin,rmax,z),name,"tube");
-  //_assign(new TGeoTubeSeg(rmin,rmax,z,RAD_2_DEGREE*startPhi,RAD_2_DEGREE*deltaPhi),name,"tube");
-  MyConeSeg* s = new MyConeSeg();
-  _assign(s,name,"tube");
-  setDimensions(rmin,rmax,z,startPhi,deltaPhi);
+  _assign(new TGeoTubeSeg(rmin,rmax,z,RAD_2_DEGREE*startPhi,RAD_2_DEGREE*deltaPhi),name,"tube");
+  //MyConeSeg* s = new MyConeSeg();
+  //_assign(s,name,"tube");
+  //setDimensions(rmin,rmax,z,startPhi,deltaPhi);
 }
 
 /// Set the tube dimensions
 Tube& Tube::setDimensions(double rmin, double rmax, double z, double startPhi, double deltaPhi)
 {
-  //double params[] = {rmin,rmax,z,RAD_2_DEGREE*startPhi,RAD_2_DEGREE*deltaPhi};
-  double params[] = {z,rmin,rmax,rmin,rmax,RAD_2_DEGREE*startPhi,RAD_2_DEGREE*deltaPhi};
+  double params[] = {rmin,rmax,z,RAD_2_DEGREE*startPhi,RAD_2_DEGREE*deltaPhi};
+  //double params[] = {z,rmin,rmax,rmin,rmax,RAD_2_DEGREE*startPhi,RAD_2_DEGREE*deltaPhi};
   _setDimensions(params);
   return *this;
 }
@@ -375,8 +375,9 @@ Trap& Trap::setDimensions(double z,double theta,double phi,
   return *this;
 }
 
-/// Constructor to be used when creating a new object
-PolyhedraRegular::PolyhedraRegular(const string& name, int nsides, double rmin, double rmax, double zlen)  
+/// Helper function to create holy hedron
+void PolyhedraRegular::_create(const string& name, int nsides, double rmin, double rmax, 
+			       double zpos, double zneg, double start, double delta)
 {
   if ( rmin<0e0 || rmin>rmax )
     throw runtime_error("PolyhedraRegular: Illegal argument rmin:<"+_toString(rmin)+"> is invalid!");
@@ -384,71 +385,38 @@ PolyhedraRegular::PolyhedraRegular(const string& name, int nsides, double rmin,
     throw runtime_error("PolyhedraRegular: Illegal argument rmax:<"+_toString(rmax)+"> is invalid!");
   _assign(new TGeoPgon(),name,"polyhedra",false);
   double params[] = {
-    RAD_2_DEGREE * 2 * M_PI,
+    0,
     RAD_2_DEGREE * 2 * M_PI,
     double(nsides),
     2e0,
-    zlen/2e0,rmin,rmax,
-    -zlen/2e0,rmin,rmax
+    zpos,rmin,rmax,
+    zneg,rmin,rmax
   };
   _setDimensions(&params[0]);
 }
 
+/// Constructor to be used when creating a new object
+PolyhedraRegular::PolyhedraRegular(const string& name, int nsides, double rmin, double rmax, double zlen)  
+{
+  _create(name,nsides,rmin,rmax,zlen/2,-zlen/2,0,2*M_PI);
+}
+
 /// Constructor to be used when creating a new object
 PolyhedraRegular::PolyhedraRegular(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(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]);
+  _create("",nsides,rmin,rmax,zlen/2,-zlen/2,0,2*M_PI);
 }
 
 /// Constructor to be used when creating a new object
 PolyhedraRegular::PolyhedraRegular(int nsides, double phistart, 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(new TGeoPgon(),"polyhedra",false);
-  double params[] = {
-    RAD_2_DEGREE * phistart,
-    RAD_2_DEGREE * 2 * M_PI,
-    double(nsides),
-    2e0,
-    zlen/2e0,rmin,rmax,
-    -zlen/2e0,rmin,rmax
-  };
-  _setDimensions(&params[0]);
+  _create("",nsides,rmin,rmax,zlen/2,-zlen/2,phistart,2*M_PI);
 }
 
 /// Constructor to be used when creating a new object
 PolyhedraRegular::PolyhedraRegular(int nsides, double rmin, double rmax, double zplanes[2])  
 {
-  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,
-    zplanes[0],rmin,rmax,
-    zplanes[1],rmin,rmax
-  };
-  _setDimensions(&params[0]);
+  _create("",nsides,rmin,rmax,zplanes[0],zplanes[1],0,2*M_PI);
 }
 
 /// Constructor to be used when creating a new object. Position is identity, Rotation is the identity rotation
@@ -548,8 +516,8 @@ IntersectionSolid::IntersectionSolid(const Solid& shape1, const Solid& shape2)
 /// Constructor to be used when creating a new object. Placement by a generic transformation within the mother
 IntersectionSolid::IntersectionSolid(const Solid& shape1, const Solid& shape2, const Transform3D& trans)   {
   TGeoHMatrix* tr = new TGeoHMatrix();
-  Double_t* t = tr->GetTranslation();
-  Double_t* r = tr->GetRotationMatrix();
+  Double_t*    t  = tr->GetTranslation();
+  Double_t*    r  = tr->GetRotationMatrix();
   trans.GetComponents(r[0],r[1],r[2],t[0],r[3],r[4],r[5],t[1],r[6],r[7],r[8],t[2]);
   TGeoIntersection*  inter = new TGeoIntersection(shape1,shape2,identityTransform(),tr);
   _assign(new TGeoCompositeShape("",inter),"intersection");
@@ -557,8 +525,8 @@ IntersectionSolid::IntersectionSolid(const Solid& shape1, const Solid& shape2, c
 
 /// Constructor to be used when creating a new object. Position is identity.
 IntersectionSolid::IntersectionSolid(const Solid& shape1, const Solid& shape2, const Position& pos)    {
-  TGeoCombiTrans*    trans = new TGeoCombiTrans(pos.X(),pos.Y(),pos.Z(),0);
-  TGeoIntersection*  inter = new TGeoIntersection(shape1,shape2,identityTransform(),trans);
+  TGeoCombiTrans*   trans = new TGeoCombiTrans(pos.X(),pos.Y(),pos.Z(),0);
+  TGeoIntersection* inter = new TGeoIntersection(shape1,shape2,identityTransform(),trans);
   _assign(new TGeoCompositeShape("",inter),"intersection");
 }
 
@@ -566,9 +534,9 @@ IntersectionSolid::IntersectionSolid(const Solid& shape1, const Solid& shape2, c
 IntersectionSolid::IntersectionSolid(const Solid& shape1, const Solid& shape2, const Position& pos, const Rotation& rot)
 {
   TGeoRotation rotation("",rot.Phi()*RAD_2_DEGREE,rot.Theta()*RAD_2_DEGREE,rot.Psi()*RAD_2_DEGREE);
-  TGeoCombiTrans*    trans = new TGeoCombiTrans(pos.X(),pos.Y(),pos.Z(),0);
+  TGeoCombiTrans*   trans = new TGeoCombiTrans(pos.X(),pos.Y(),pos.Z(),0);
   trans->SetRotation(rotation.Inverse());
-  TGeoIntersection*  inter = new TGeoIntersection(shape1,shape2,identityTransform(),trans);
+  TGeoIntersection* inter = new TGeoIntersection(shape1,shape2,identityTransform(),trans);
   _assign(new TGeoCompositeShape("",inter),"intersection");
 }
 
diff --git a/DDCore/src/XML/DocumentHandler.cpp b/DDCore/src/XML/DocumentHandler.cpp
index c113328ad3ce0582339d59a9b2d2a2118c355d05..03e0ef4ed20b9c3473d7d840762713894dc2d0d9 100644
--- a/DDCore/src/XML/DocumentHandler.cpp
+++ b/DDCore/src/XML/DocumentHandler.cpp
@@ -326,3 +326,16 @@ int DocumentHandler::output(Document doc, const std::string& fname) const {
 }
 
 #endif
+ 
+/// Create new XML document by parsing empty xml buffer
+Document DocumentHandler::create(const char* tag, const char* comment)  const  {
+  string top(tag);
+  string empty = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n";
+  empty += "<"+top+"/>\0\0";
+  Document doc = parse(empty.c_str(),empty.length()+1);
+  if ( comment )  {
+    Element top_elt = doc.root();
+    top_elt.addComment(comment);
+  }
+  return doc;
+}
diff --git a/DDCore/src/XML/XMLDetector.cpp b/DDCore/src/XML/XMLDetector.cpp
index e865ede691c2f69342f0431adb4a3e1e71513682..d8a254dfa2c8bc3088ab88ab87506f2f0e3327ec 100644
--- a/DDCore/src/XML/XMLDetector.cpp
+++ b/DDCore/src/XML/XMLDetector.cpp
@@ -66,6 +66,10 @@ XML_ATTR_ACCESSOR(int,id)
   XML_ATTR_ACCESSOR(double,outer_z)
   XML_ATTR_ACCESSOR(double,inner_z)
 
+  XML_ATTR_ACCESSOR(double,b)
+  XML_ATTR_ACCESSOR(double,g)
+  XML_ATTR_ACCESSOR(double,B)
+  XML_ATTR_ACCESSOR(double,G)
   XML_ATTR_ACCESSOR(double,r)
   XML_ATTR_ACCESSOR_DOUBLE(r)
   XML_ATTR_ACCESSOR(double,R)
@@ -79,6 +83,11 @@ XML_ATTR_ACCESSOR(int,id)
   XML_ATTR_ACCESSOR(double,inner_radius)
 
   XML_ATTR_ACCESSOR(double,angle)
+  XML_ATTR_ACCESSOR(double,alpha)
+  XML_ATTR_ACCESSOR(double,beta)
+  XML_ATTR_ACCESSOR(double,gamma)
+  XML_ATTR_ACCESSOR(double,delta)
+  XML_ATTR_ACCESSOR(double,epsilon)
   XML_ATTR_ACCESSOR(double,theta)
   XML_ATTR_ACCESSOR(int,thetaBins)
   XML_ATTR_ACCESSOR(double,psi)
@@ -133,6 +142,9 @@ XML_ATTR_ACCESSOR(int,id)
   XML_ATTR_ACCESSOR(double,inner_field)
   XML_ATTR_ACCESSOR(double,outer_field)
   XML_ATTR_ACCESSOR(int,type)
+
+  XML_ATTR_ACCESSOR(bool,visible)
+  XML_ATTR_ACCESSOR(bool,show_daughters)
 #if 0
   XML_ATTR_ACCESSOR(double,)
   XML_ATTR_ACCESSOR(double,)
@@ -157,6 +169,10 @@ string Dimension::nameStr()  const  {
   return m_element.attr<string>(_U(name));
 }
 
+string Dimension::refStr()  const  {
+  return m_element.attr<string>(_U(ref));
+}
+
 string Dimension::typeStr()  const  {
   return m_element.attr<string>(_U(type));
 }
diff --git a/DDCore/src/XML/XMLElements.cpp b/DDCore/src/XML/XMLElements.cpp
index b42272692c2b92dd7ce5d4e5d51e0e71776af993..217d8c9e776c531538a0494952bc02b7dddd565d 100644
--- a/DDCore/src/XML/XMLElements.cpp
+++ b/DDCore/src/XML/XMLElements.cpp
@@ -454,8 +454,8 @@ vector<Attribute> Handle_t::attributes() const {
 #else
     xercesc::DOMNamedNodeMap* l = _E(m_node)->getAttributes();
     for(XmlSize_t i=0, n=l->getLength(); i<n; ++i)  {
-      xercesc::DOMNode* node = l->item(i);
-      attrs.push_back(Attribute(node));
+      xercesc::DOMNode* n = l->item(i);
+      attrs.push_back(Attribute(n));
     }
 #endif
   }
@@ -704,6 +704,11 @@ Handle_t Handle_t::setRef(const XmlChar* tag, const XmlChar* ref_name) {
   return ref;
 }
 
+/// Add reference child as a new child node. The obj must have the "name" attribute!
+Handle_t Handle_t::setRef(const XmlChar* tag, const string& ref_name) {
+  return setRef(tag,Strng_t(ref_name).ptr());
+}
+
 /// Checksum (sub-)tree of a xml document/tree
 static unsigned int adler32(unsigned int adler,const char* buf,size_t len)    {
 #define DO1(buf,i)  {s1 +=(unsigned char)buf[i]; s2 += s1;}
@@ -828,8 +833,13 @@ Attribute Element::getAttr(const XmlChar* name)   const  {
 }
 
 /// Set the reference attribute to the node (adds attribute ref="ref-name")
-Attribute Element::setRef(const XmlChar* tag, const XmlChar* refname)  const  {
-  return setChild(tag).setAttr(Unicode_ref,refname);
+Attribute Element::setRef(const XmlChar* tag, const XmlChar* ref_name)  const  {
+  return setChild(tag).setAttr(Unicode_ref,ref_name);
+}
+
+/// Set the reference attribute to the node (adds attribute ref="ref-name")
+Attribute Element::setRef(const XmlChar* tag, const string& ref_name)  const  {
+  return setRef(tag,Strng_t(ref_name).ptr());
 }
 
 /// Access the value of the reference attribute of the node (attribute ref="ref-name")
@@ -846,10 +856,19 @@ Handle_t Element::addChild(const XmlChar* tag)  const  {
 
 /// Check if a child with the required tag exists - if not create it and add it to the current node
 Handle_t Element::setChild(const XmlChar* t)  const  {
-  Elt_t e = m_element.child(t);
+  Elt_t e = m_element.child(t,false);
   return e ? Handle_t(e) : addChild(t);
 }
 
+/// Add comment node to the element
+void Element::addComment(const char* text) const {
+#ifdef DD4HEP_USE_TINYXML
+  _N(m_element)->appendChild(new TiXmlComment(text));
+#else
+  _N(m_element)->appendChild(_D(document().m_doc)->createComment(Strng_t(text)));
+#endif
+}
+
 RefElement::RefElement(const Document& document, const XmlChar* type, const XmlChar* name)  
 : Element(document, type) 
 {
diff --git a/DDCore/src/plugins/Compact2Objects.cpp b/DDCore/src/plugins/Compact2Objects.cpp
index 9d9681c776b95f209111054b00971e365df1c8fa..763ea5f37380666b0bb634bc7c6a6bc2b69e63a1 100644
--- a/DDCore/src/plugins/Compact2Objects.cpp
+++ b/DDCore/src/plugins/Compact2Objects.cpp
@@ -148,7 +148,7 @@ static Ref_t create_SolenoidField(lcdd_t& lcdd, xml_h e)  {
   obj.assign(ptr,c.nameStr(),c.typeStr());
   return obj;
 }
-DECLARE_XMLELEMENT(SolenoidMagnet,create_SolenoidField);
+DECLARE_XMLELEMENT(solenoid,create_SolenoidField);
 
 static Ref_t create_DipoleField(lcdd_t& /* lcdd */, xml_h e)  {
   xml_comp_t c(e);
@@ -374,24 +374,28 @@ template <> void Converter<VisAttr>::operator()(xml_h e)  const  {
   float g = e.hasAttr(_U(g)) ? e.attr<float>(_U(g)) : 1.0f;
   float b = e.hasAttr(_U(b)) ? e.attr<float>(_U(b)) : 1.0f;
   attr.setColor(r,g,b);
-  if ( e.hasAttr(_U(alpha))         ) attr.setAlpha(e.attr<float>(_U(alpha)));
-  if ( e.hasAttr(_U(visible))       ) attr.setVisible(e.attr<bool>(_U(visible)));
-  if ( e.hasAttr(_U(lineStyle))     )   {
+  if ( e.hasAttr(_U(alpha))      ) attr.setAlpha(e.attr<float>(_U(alpha)));
+  if ( e.hasAttr(_U(visible))    ) attr.setVisible(e.attr<bool>(_U(visible)));
+  if ( e.hasAttr(_U(lineStyle))  )   {
     string ls = e.attr<string>(_U(lineStyle));
-    if ( ls == "unbroken" ) attr.setLineStyle(VisAttr::SOLID);
-    if ( ls == "broken" ) attr.setLineStyle(VisAttr::DASHED);
+    if      ( ls == "unbroken"  ) attr.setLineStyle(VisAttr::SOLID);
+    else if ( ls == "broken"    ) attr.setLineStyle(VisAttr::DASHED);
   }
   else  {
     attr.setLineStyle(VisAttr::SOLID);
   }
-  if ( e.hasAttr(_U(drawingStyle))  )   {
+  if ( e.hasAttr(_U(drawingStyle)) )   {
     string ds = e.attr<string>(_U(drawingStyle));
-    if ( ds == "wireframe" ) attr.setDrawingStyle(VisAttr::WIREFRAME);
+    if      ( ds == "wireframe" ) attr.setDrawingStyle(VisAttr::WIREFRAME);
+    else if ( ds == "solid"     ) attr.setDrawingStyle(VisAttr::SOLID);
   }
   else  {
-    attr.setDrawingStyle(VisAttr::WIREFRAME);
+    attr.setDrawingStyle(VisAttr::SOLID);
   }
-  if ( e.hasAttr(_U(showDaughters)) ) attr.setShowDaughters(e.attr<bool>(_U(showDaughters)));
+  if ( e.hasAttr(_U(showDaughters)) ) 
+    attr.setShowDaughters(e.attr<bool>(_U(showDaughters)));
+  else
+    attr.setShowDaughters(true);
   lcdd.addVisAttribute(attr);
 }
 
diff --git a/DDCore/src/plugins/LCDDConverter.cpp b/DDCore/src/plugins/LCDDConverter.cpp
index a4f7a877bb15cb4607b54b764797f1727cb8d0c7..df4186f2bf93bb27e3308073974a110122a38a97 100644
--- a/DDCore/src/plugins/LCDDConverter.cpp
+++ b/DDCore/src/plugins/LCDDConverter.cpp
@@ -17,26 +17,30 @@
 #include "TROOT.h"
 #include "TColor.h"
 #include "TGeoShape.h"
-#include "TGeoEltu.h"
+
+#include "TGeoArb8.h"
+#include "TGeoBoolNode.h"
+#include "TGeoCompositeShape.h"
 #include "TGeoCone.h"
+#include "TGeoEltu.h"
+#include "TGeoHype.h"
+#include "TGeoMatrix.h"
 #include "TGeoParaboloid.h"
 #include "TGeoPara.h"
 #include "TGeoPcon.h"
 #include "TGeoPgon.h"
+#include "TGeoShapeAssembly.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 "TGeoShapeAssembly.h"
+#include "TGeoTube.h"
+
 #include "TGeoNode.h"
 #include "TClass.h"
 #include "TMath.h"
 #include "Reflex/PluginService.h"
+#include <fstream>
 #include <iostream>
 #include <iomanip>
 
@@ -47,16 +51,14 @@ using namespace std;
 namespace {
   typedef Position XYZRotation;
   XYZRotation getXYZangles(const Double_t* r)   {
-    static Double_t rad = DEGREE_2_RAD;
     Double_t cosb = sqrt(r[0]*r[0] + r[1]*r[1]);
     if (cosb > 0.00001) {
-      return XYZRotation(atan2(r[5], r[8])*rad, atan2(-r[2], cosb)*rad, atan2(r[1], r[0])*rad);
+      return XYZRotation(atan2(r[5], r[8]), atan2(-r[2], cosb), atan2(r[1], r[0]));
     }
-    return XYZRotation(atan2(-r[7], r[4])*rad,atan2(-r[2], cosb)*rad,0);
+    return XYZRotation(atan2(-r[7], r[4]),atan2(-r[2], cosb),0);
   }
 }
 
-
 void LCDDConverter::GeometryInfo::check(const string& name, const TNamed* n,map<string,const TNamed*>& m) const {
   map<string,const TNamed*>::const_iterator i=m.find(name);
   if ( i != m.end() ) {
@@ -112,7 +114,9 @@ xml_h LCDDConverter::handleMaterial(const string& name, const TGeoMedium* medium
     obj.setAttr(_U(type),"density");
 
     geo.checkMaterial(name,medium);
-
+    if ( name == "B" ) {
+      cout << "Converting material:" << name << endl;
+    }
     if ( m->IsMixture() ) {
       TGeoMixture* mix=(TGeoMixture*)m;
       const double *wmix = mix->GetWmixt();
@@ -132,6 +136,7 @@ xml_h LCDDConverter::handleMaterial(const string& name, const TGeoMedium* medium
     }
     else {
       TGeoElement *elt = m->GetElement(0);
+      cout << "Converting non mixing material:" << name << endl;
       xml_elt_t atom(geo.doc,_U(atom));
       handleElement(elt->GetName(),elt);
       mat.append(atom);
@@ -157,81 +162,93 @@ xml_h LCDDConverter::handleSolid(const string& name, const TGeoShape* shape)   c
       const TGeoBBox* s = (const TGeoBBox*)shape;
       geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(box)));
       solid.setAttr(_U(name),Unicode(name));
-      solid.setAttr(_U(x),s->GetDX()*CM_2_MM);
-      solid.setAttr(_U(y),s->GetDY()*CM_2_MM);
-      solid.setAttr(_U(z),s->GetDZ()*CM_2_MM);
+      solid.setAttr(_U(x), 2*s->GetDX()*CM_2_MM);
+      solid.setAttr(_U(y), 2*s->GetDY()*CM_2_MM);
+      solid.setAttr(_U(z), 2*s->GetDZ()*CM_2_MM);
       solid.setAttr(_U(lunit),"mm");
     }
     else if ( shape->IsA() == TGeoTube::Class() ) {
       const TGeoTube* s = (const TGeoTube*)shape;
       geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(tube)));
       solid.setAttr(_U(name),Unicode(name));
-      solid.setAttr(_U(rmin),s->GetRmin()*CM_2_MM);
-      solid.setAttr(_U(rmax),s->GetRmax()*CM_2_MM);
-      solid.setAttr(_U(z),s->GetDz()*CM_2_MM);
-      solid.setAttr(_U(startphi),0e0);
-      solid.setAttr(_U(deltaphi),2*M_PI);
+      solid.setAttr(_U(rmin),     s->GetRmin()*CM_2_MM);
+      solid.setAttr(_U(rmax),     s->GetRmax()*CM_2_MM);
+      solid.setAttr(_U(z),        2*s->GetDz()*CM_2_MM);
+      solid.setAttr(_U(startphi), 0e0);
+      solid.setAttr(_U(deltaphi), 2*M_PI);
       solid.setAttr(_U(aunit),"rad");
       solid.setAttr(_U(lunit),"mm");
     }
     else if ( shape->IsA() == TGeoEltu::Class() ) {
       const TGeoEltu* s = (const TGeoEltu*)shape;
       geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(eltube)));
+      solid.setAttr(_U(name), Unicode(name));
+      solid.setAttr(_U(dx),   s->GetA() *CM_2_MM);
+      solid.setAttr(_U(dy),   s->GetB() *CM_2_MM);
+      solid.setAttr(_U(dz),   s->GetDz()*CM_2_MM);
+      solid.setAttr(_U(lunit),"mm");
+    }
+    else if ( shape->IsA() == TGeoTubeSeg::Class() ) {
+      const TGeoTubeSeg* s = (const TGeoTubeSeg*)shape;
+      geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(tube)));
       solid.setAttr(_U(name),Unicode(name));
-      solid.setAttr(_U(dx),s->GetA()*CM_2_MM);
-      solid.setAttr(_U(dy),s->GetB()*CM_2_MM);
-      solid.setAttr(_U(dz),s->GetDz()*CM_2_MM);
+      solid.setAttr(_U(rmin),     s->GetRmin()*CM_2_MM);
+      solid.setAttr(_U(rmax),     s->GetRmax()*CM_2_MM);
+      solid.setAttr(_U(z),        2*s->GetDz()*CM_2_MM); // Full zlen in GDML, half zlen in TGeo
+      solid.setAttr(_U(startphi), s->GetPhi1()*DEGREE_2_RAD);
+      solid.setAttr(_U(deltaphi), s->GetPhi2()*DEGREE_2_RAD);
+      solid.setAttr(_U(aunit),"rad");
       solid.setAttr(_U(lunit),"mm");
     }
     else if ( shape->IsA() == TGeoTubeSeg::Class() ) {
       const TGeoTubeSeg* s = (const TGeoTubeSeg*)shape;
       geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(tube)));
       solid.setAttr(_U(name),Unicode(name));
-      solid.setAttr(_U(rmin),s->GetRmin()*CM_2_MM);
-      solid.setAttr(_U(rmax),s->GetRmax()*CM_2_MM);
-      solid.setAttr(_U(z),s->GetDz()*CM_2_MM);
-      solid.setAttr(_U(startphi),s->GetPhi1()*DEGREE_2_RAD);
-      solid.setAttr(_U(deltaphi),s->GetPhi2()*DEGREE_2_RAD);
+      solid.setAttr(_U(rmin),     s->GetRmin()*CM_2_MM);
+      solid.setAttr(_U(rmax),     s->GetRmax()*CM_2_MM);
+      solid.setAttr(_U(z),        2*s->GetDz()*CM_2_MM); // Full zlen in GDML, half zlen in TGeo
+      solid.setAttr(_U(startphi), s->GetPhi1()*DEGREE_2_RAD);
+      solid.setAttr(_U(deltaphi), s->GetPhi2()*DEGREE_2_RAD);
       solid.setAttr(_U(aunit),"rad");
       solid.setAttr(_U(lunit),"mm");
     }
-    else if ( shape->IsA() == TGeoTrd1::Class() ) {
-      const TGeoTrd1* s = (const TGeoTrd1*)shape;
-      geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(trd)));
+    else if ( shape->IsA() == TGeoHype::Class() ) {
+      const TGeoHype* s = (const TGeoHype*)shape;
+      geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(hype)));
       solid.setAttr(_U(name),Unicode(name));
-      solid.setAttr(_U(x1),s->GetDx1()*CM_2_MM);
-      solid.setAttr(_U(x2),s->GetDx2()*CM_2_MM);
-      solid.setAttr(_U(y1),s->GetDy()*CM_2_MM);
-      solid.setAttr(_U(y2),s->GetDy()*CM_2_MM);
-      solid.setAttr(_U(z), s->GetDz()*CM_2_MM);
+      solid.setAttr(_U(rmin), 2*s->GetRmin()*CM_2_MM);
+      solid.setAttr(_U(rmax), 2*s->GetRmax()*CM_2_MM);
+      solid.setAttr(_U(outst), 2*s->GetStOut()*CM_2_MM);
+      solid.setAttr(_U(z),     2*s->GetDz()*CM_2_MM); // Full zlen in GDML, half zlen in TGeo
+      solid.setAttr(_U(aunit),"rad");
       solid.setAttr(_U(lunit),"mm");
     }
     else if ( shape->IsA() == TGeoTrd2::Class() ) {
       const TGeoTrd2* s = (const TGeoTrd2*)shape;
       geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(trd)));
       solid.setAttr(_U(name),Unicode(name));
-      solid.setAttr(_U(x1),s->GetDx1()*CM_2_MM);
-      solid.setAttr(_U(x2),s->GetDx2()*CM_2_MM);
-      solid.setAttr(_U(y1),s->GetDy1()*CM_2_MM);
-      solid.setAttr(_U(y2),s->GetDy2()*CM_2_MM);
-      solid.setAttr(_U(z), s->GetDz()*CM_2_MM);
+      solid.setAttr(_U(x1), 2*s->GetDx1()*CM_2_MM);
+      solid.setAttr(_U(x2), 2*s->GetDx2()*CM_2_MM);
+      solid.setAttr(_U(y1), 2*s->GetDy1()*CM_2_MM);
+      solid.setAttr(_U(y2), 2*s->GetDy2()*CM_2_MM);
+      solid.setAttr(_U(z),  2*s->GetDz() *CM_2_MM); // Full zlen in GDML, half zlen in TGeo
       solid.setAttr(_U(lunit),"mm");
     }
     else if ( shape->IsA() == TGeoTrap::Class() ) {
       const TGeoTrap* s = (const TGeoTrap*)shape;
       geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(trap)));
       solid.setAttr(_U(name),Unicode(name));
-      solid.setAttr(_U(x1),s->GetBl1()*CM_2_MM);
-      solid.setAttr(_U(x2),s->GetTl1()*CM_2_MM);
-      solid.setAttr(_U(x3),s->GetBl2()*CM_2_MM);
-      solid.setAttr(_U(x4),s->GetTl2()*CM_2_MM);
-      solid.setAttr(_U(y1),s->GetH1()*CM_2_MM);
-      solid.setAttr(_U(y2),s->GetH2()*CM_2_MM);
-      solid.setAttr(_U(z),s->GetDz()*CM_2_MM);
+      solid.setAttr(_U(z),     2*s->GetDz()*CM_2_MM); // Full zlen in GDML, half zlen in TGeo
+      solid.setAttr(_U(x1),    2*s->GetBl1()*CM_2_MM);
+      solid.setAttr(_U(x2),    2*s->GetTl1()*CM_2_MM);
+      solid.setAttr(_U(x3),    2*s->GetBl2()*CM_2_MM);
+      solid.setAttr(_U(x4),    2*s->GetTl2()*CM_2_MM);
+      solid.setAttr(_U(y1),    2*s->GetH1()*CM_2_MM);
+      solid.setAttr(_U(y2),    2*s->GetH2()*CM_2_MM);
       solid.setAttr(_U(alpha1),s->GetAlpha1()*DEGREE_2_RAD);
       solid.setAttr(_U(alpha2),s->GetAlpha2()*DEGREE_2_RAD);
-      solid.setAttr(_U(theta),s->GetTheta()*DEGREE_2_RAD);
-      solid.setAttr(_U(phi),s->GetPhi()*DEGREE_2_RAD);
+      solid.setAttr(_U(theta), s->GetTheta()*DEGREE_2_RAD);
+      solid.setAttr(_U(phi),   s->GetPhi()*DEGREE_2_RAD);
       solid.setAttr(_U(aunit),"rad");
       solid.setAttr(_U(lunit),"mm");
     }
@@ -239,23 +256,24 @@ xml_h LCDDConverter::handleSolid(const string& name, const TGeoShape* shape)   c
       const TGeoPara* s = (const TGeoPara*)shape;
       geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(para)));
       solid.setAttr(_U(name),Unicode(name));
-      solid.setAttr(_U(x),s->GetX()*CM_2_MM);
-      solid.setAttr(_U(y),s->GetY()*CM_2_MM);
-      solid.setAttr(_U(z),s->GetZ()*CM_2_MM);
+      solid.setAttr(_U(x),    s->GetX()*CM_2_MM);
+      solid.setAttr(_U(y),    s->GetY()*CM_2_MM);
+      solid.setAttr(_U(z),    s->GetZ()*CM_2_MM);
       solid.setAttr(_U(alpha),s->GetAlpha()*DEGREE_2_RAD);
       solid.setAttr(_U(theta),s->GetTheta()*DEGREE_2_RAD);
-      solid.setAttr(_U(phi),s->GetPhi()*DEGREE_2_RAD);
+      solid.setAttr(_U(phi),  s->GetPhi()*DEGREE_2_RAD);
       solid.setAttr(_U(aunit),"rad");
       solid.setAttr(_U(lunit),"mm");
     }
     else if ( shape->IsA() == TGeoPgon::Class() ) {
       const TGeoPgon* s = (const TGeoPgon*)shape;
       geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(polyhedra)));
-      solid.setAttr(_U(name),Unicode(name));
+      solid.setAttr(_U(name),    Unicode(name));
       solid.setAttr(_U(startphi),s->GetPhi1()*DEGREE_2_RAD);
       solid.setAttr(_U(deltaphi),s->GetDphi()*DEGREE_2_RAD);
-      solid.setAttr(_U(aunit),"rad");
-      solid.setAttr(_U(lunit),"mm");
+      solid.setAttr(_U(numsides),s->GetNedges());
+      solid.setAttr(_U(aunit),  "rad");
+      solid.setAttr(_U(lunit),  "mm");
       for( size_t i=0; i<s->GetNz(); ++i )  {
 	zplane = xml_elt_t(geo.doc,_U(zplane));
 	zplane.setAttr(_U(rmin),s->GetRmin(i)*CM_2_MM);
@@ -280,39 +298,33 @@ xml_h LCDDConverter::handleSolid(const string& name, const TGeoShape* shape)   c
 	solid.append(zplane);
       }
     }
-    else if ( shape->IsA() == TGeoCone::Class() ) {
-      const TGeoCone* s = (const TGeoCone*)shape;
-      geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(cone)));
+    else if ( shape->IsA() == TGeoConeSeg::Class() ) {
+      const TGeoConeSeg* s = (const TGeoConeSeg*)shape;
+      geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(polycone)));
       solid.setAttr(_U(name),Unicode(name));
-      solid.setAttr(_U(z),s->GetDz()*CM_2_MM);
-      solid.setAttr(_U(rmin1),s->GetRmin1()*CM_2_MM);
-      solid.setAttr(_U(rmax1),s->GetRmax1()*CM_2_MM);
-      solid.setAttr(_U(rmin2),s->GetRmin2()*CM_2_MM);
-      solid.setAttr(_U(rmax2),s->GetRmax2()*CM_2_MM);
-      solid.setAttr(_U(z),s->GetDz()*CM_2_MM);
-      solid.setAttr(_U(startphi),0e0);
-      solid.setAttr(_U(deltaphi),2*M_PI);
+      solid.setAttr(_U(z),        2*s->GetDz()*CM_2_MM);
+      solid.setAttr(_U(rmin1),    s->GetRmin1()*CM_2_MM);
+      solid.setAttr(_U(rmin2),    s->GetRmin2()*CM_2_MM);
+      solid.setAttr(_U(rmax1),    s->GetRmax1()*CM_2_MM);
+      solid.setAttr(_U(rmax2),    s->GetRmax2()*CM_2_MM);
+      solid.setAttr(_U(startphi), s->GetPhi1()*DEGREE_2_RAD);
+      solid.setAttr(_U(deltaphi),(s->GetPhi2()-s->GetPhi1())*DEGREE_2_RAD);
       solid.setAttr(_U(aunit),"rad");
       solid.setAttr(_U(lunit),"mm");
     }
-    else if ( shape->IsA() == TGeoConeSeg::Class() ) {
-      const TGeoConeSeg* s = (const TGeoConeSeg*)shape;
+    else if ( shape->IsA() == TGeoCone::Class() ) {
+      const TGeoCone* s = (const TGeoCone*)shape;
       geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(cone)));
       solid.setAttr(_U(name),Unicode(name));
-      solid.setAttr(_U(startphi),s->GetPhi1()*DEGREE_2_RAD);
-      solid.setAttr(_U(deltaphi),(s->GetPhi2()-s->GetPhi1())*DEGREE_2_RAD);
+      solid.setAttr(_U(z),       2*s->GetDz()*CM_2_MM);
+      solid.setAttr(_U(rmin1),   s->GetRmin1()*CM_2_MM);
+      solid.setAttr(_U(rmax1),   s->GetRmax1()*CM_2_MM);
+      solid.setAttr(_U(rmin2),   s->GetRmin2()*CM_2_MM);
+      solid.setAttr(_U(rmax2),   s->GetRmax2()*CM_2_MM);
+      solid.setAttr(_U(startphi),0e0);
+      solid.setAttr(_U(deltaphi),2*M_PI);
       solid.setAttr(_U(aunit),"rad");
       solid.setAttr(_U(lunit),"mm");
-      zplane = xml_elt_t(geo.doc,_U(zplane));
-      zplane.setAttr(_U(rmin),s->GetRmin1()*CM_2_MM);
-      zplane.setAttr(_U(rmax),s->GetRmax1()*CM_2_MM);
-      zplane.setAttr(_U(z),s->GetDz()*CM_2_MM);
-      solid.append(zplane);
-      zplane = xml_elt_t(geo.doc,_U(zplane));
-      zplane.setAttr(_U(rmin),s->GetRmin2()*CM_2_MM);
-      zplane.setAttr(_U(rmax),s->GetRmax2()*CM_2_MM);
-      zplane.setAttr(_U(z),s->GetDz()*CM_2_MM);
-      solid.append(zplane);
     }
     else if ( shape->IsA() == TGeoParaboloid::Class() ) {
       const TGeoParaboloid* s = (const TGeoParaboloid*)shape;
@@ -326,13 +338,13 @@ xml_h LCDDConverter::handleSolid(const string& name, const TGeoShape* shape)   c
     else if ( shape->IsA() == TGeoSphere::Class() ) {
       const TGeoSphere* s = (const TGeoSphere*)shape;
       geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(sphere)));
-      solid.setAttr(_U(name),Unicode(name));
-      solid.setAttr(_U(rmin),s->GetRmin()*CM_2_MM);
-      solid.setAttr(_U(rmax),s->GetRmax()*CM_2_MM);
-      solid.setAttr(_U(startphi),s->GetPhi1()*DEGREE_2_RAD);
-      solid.setAttr(_U(deltaphi),(s->GetPhi2()-s->GetPhi1())*DEGREE_2_RAD);
-      solid.setAttr(_U(starttheta),s->GetTheta1()*DEGREE_2_RAD);
-      solid.setAttr(_U(deltatheta),(s->GetTheta2()-s->GetTheta1())*DEGREE_2_RAD);
+      solid.setAttr(_U(name),          Unicode(name));
+      solid.setAttr(_U(rmin),          s->GetRmin()*CM_2_MM);
+      solid.setAttr(_U(rmax),          s->GetRmax()*CM_2_MM);
+      solid.setAttr(_U(startphi),      s->GetPhi1()*DEGREE_2_RAD);
+      solid.setAttr(_U(deltaphi),     (s->GetPhi2()-s->GetPhi1())*DEGREE_2_RAD);
+      solid.setAttr(_U(starttheta),    s->GetTheta1()*DEGREE_2_RAD);
+      solid.setAttr(_U(deltatheta),   (s->GetTheta2()-s->GetTheta1())*DEGREE_2_RAD);
       solid.setAttr(_U(aunit),"rad");
       solid.setAttr(_U(lunit),"mm");
     }
@@ -340,26 +352,54 @@ xml_h LCDDConverter::handleSolid(const string& name, const TGeoShape* shape)   c
       const TGeoTorus* s = (const TGeoTorus*)shape;
       geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(torus)));
       solid.setAttr(_U(name),Unicode(name));
-      solid.setAttr(_U(rtor),s->GetR());
-      solid.setAttr(_U(rmin),s->GetRmin());
-      solid.setAttr(_U(rmax),s->GetRmax());
-      solid.setAttr(_U(startphi),s->GetPhi1()*DEGREE_2_RAD);
-      solid.setAttr(_U(deltaphi),s->GetDphi()*DEGREE_2_RAD);
+      solid.setAttr(_U(rtor),     s->GetR()*CM_2_MM);
+      solid.setAttr(_U(rmin),     s->GetRmin()*CM_2_MM);
+      solid.setAttr(_U(rmax),     s->GetRmax()*CM_2_MM);
+      solid.setAttr(_U(startphi), s->GetPhi1()*DEGREE_2_RAD);
+      solid.setAttr(_U(deltaphi), s->GetDphi()*DEGREE_2_RAD);
       solid.setAttr(_U(aunit),"rad");
       solid.setAttr(_U(lunit),"mm");
     }
+    else if ( shape->IsA() == TGeoArb8::Class() ) {
+      TGeoArb8* s = (TGeoArb8*)shape;
+      const double* vtx = s->GetVertices();
+      geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(arb8)));      
+      solid.setAttr(_U(name),Unicode(name));
+      solid.setAttr(_U(v1x),vtx[0]*CM_2_MM);
+      solid.setAttr(_U(v1y),vtx[1]*CM_2_MM);
+      solid.setAttr(_U(v2x),vtx[2]*CM_2_MM);
+      solid.setAttr(_U(v2y),vtx[3]*CM_2_MM);
+      solid.setAttr(_U(v3x),vtx[4]*CM_2_MM);
+      solid.setAttr(_U(v3y),vtx[5]*CM_2_MM);
+      solid.setAttr(_U(v4x),vtx[6]*CM_2_MM);
+      solid.setAttr(_U(v4y),vtx[7]*CM_2_MM);
+      solid.setAttr(_U(v5x),vtx[8]*CM_2_MM);
+      solid.setAttr(_U(v5y),vtx[9]*CM_2_MM);
+      solid.setAttr(_U(v6x),vtx[10]*CM_2_MM);
+      solid.setAttr(_U(v6y),vtx[11]*CM_2_MM);
+      solid.setAttr(_U(v7x),vtx[12]*CM_2_MM);
+      solid.setAttr(_U(v7y),vtx[13]*CM_2_MM);
+      solid.setAttr(_U(v8x),vtx[14]*CM_2_MM);
+      solid.setAttr(_U(v8y),vtx[15]*CM_2_MM);
+      solid.setAttr(_U(dz), s->GetDz()*CM_2_MM);
+      solid.setAttr(_U(lunit),"mm");
+    }
     else if ( shape->IsA() == TGeoShapeAssembly::Class() )  {
       TGeoShapeAssembly* s = (TGeoShapeAssembly*)shape;
       geo.doc_solids.append(solid = xml_elt_t(geo.doc,_U(assembly)));
       solid.setAttr(_U(name),Unicode(name));
     }
     else if ( shape->IsA() == TGeoCompositeShape::Class() ) {
+      char text[32];
       const TGeoCompositeShape* s = (const TGeoCompositeShape*)shape;
       const TGeoBoolNode* boolean = s->GetBoolNode();
       TGeoBoolNode::EGeoBoolType oper = boolean->GetBooleanOperator();
-      TGeoMatrix* m       = boolean->GetRightMatrix();
-      xml_h    left    = handleSolid(name+"_left", boolean->GetLeftShape());
-      xml_h    right   = handleSolid(name+"_right",boolean->GetRightShape());
+      TGeoMatrix* rm = boolean->GetRightMatrix();
+      TGeoMatrix* lm = boolean->GetLeftMatrix();
+      TGeoShape*  ls = boolean->GetLeftShape();
+      TGeoShape*  rs = boolean->GetRightShape();
+      xml_h    left  = handleSolid(ls->GetName(),ls);
+      xml_h    right = handleSolid(rs->GetName(),rs);
       xml_h first(0), second(0);
       if ( !left )   {
 	throw runtime_error("G4Converter: No left Geant4 Solid present for composite shape:"+name);
@@ -376,11 +416,12 @@ xml_h LCDDConverter::handleSolid(const string& name, const TGeoShape* shape)   c
 	solid = xml_elt_t(geo.doc,_U(intersection));
 
       xml_h obj;
+      geo.doc_solids.append(solid);
       solid.append(first=xml_elt_t(geo.doc,_U(first)));
       solid.setAttr(_U(name),Unicode(name));
-      first.setAttr(_U(ref),name+"_left");
-      XYZRotation    rot = getXYZangles(boolean->GetLeftMatrix()->Inverse().GetRotationMatrix());
-      const double  *tr  = boolean->GetLeftMatrix()->GetTranslation();
+      first.setAttr(_U(ref),ls->GetName());
+      XYZRotation    rot = getXYZangles(lm->Inverse().GetRotationMatrix());
+      const double  *tr  = lm->GetTranslation();
 
       if ((tr[0] != 0.0) || (tr[1] != 0.0) || (tr[2] != 0.0)) {
 	first.append(obj=xml_elt_t(geo.doc,_U(firstposition)));
@@ -390,26 +431,25 @@ xml_h LCDDConverter::handleSolid(const string& name, const TGeoShape* shape)   c
       }
       if ((rot.X() != 0.0) || (rot.Y() != 0.0) || (rot.Z() != 0.0)) {
 	first.append(obj=xml_elt_t(geo.doc,_U(firstrotation)));
-	obj.setAttr(_U(x),rot.X());
-	obj.setAttr(_U(y),rot.Y());
-	obj.setAttr(_U(z),rot.Z());
+	obj.setAttr(_U(x),rot.X()*DEGREE_2_RAD);
+	obj.setAttr(_U(y),rot.Y()*DEGREE_2_RAD);
+	obj.setAttr(_U(z),rot.Z()*DEGREE_2_RAD);
       }
-
-      rot = getXYZangles(boolean->GetRightMatrix()->Inverse().GetRotationMatrix());
-      tr  = boolean->GetRightMatrix()->GetTranslation();
+      TGeoMatrix& rinv = rm->Inverse();
+      rot = getXYZangles(rinv.GetRotationMatrix());
+      tr  = rm->GetTranslation();
       solid.append(second=xml_elt_t(geo.doc,_U(second)));
-      second.setAttr(_U(ref),name+"_right");
+      second.setAttr(_U(ref),rs->GetName());
+      ::sprintf(text,"_%p_",rm);
+      string rnam = rs->GetName();
+      rnam += text;
       if ((tr[0] != 0.0) || (tr[1] != 0.0) || (tr[2] != 0.0)) {
-	first.append(obj=xml_elt_t(geo.doc,_U(position)));
-	obj.setAttr(_U(x),tr[0]*CM_2_MM);
-	obj.setAttr(_U(y),tr[1]*CM_2_MM);
-	obj.setAttr(_U(z),tr[2]*CM_2_MM);
+	xml_ref_t pos = handlePosition(rnam+"pos",rm);
+	solid.setRef(_U(positionref),pos.name());
       }
       if ((rot.X() != 0.0) || (rot.Y() != 0.0) || (rot.Z() != 0.0)) {
-	first.append(obj=xml_elt_t(geo.doc,_U(rotation)));
-	obj.setAttr(_U(x),rot.X());
-	obj.setAttr(_U(y),rot.Y());
-	obj.setAttr(_U(z),rot.Z());
+	xml_ref_t rot = handleRotation(rnam+"rot",&rinv);
+	solid.setRef(_U(rotationref),rot.name());
       }
     }
     if ( !solid ) {
@@ -427,26 +467,25 @@ xml_h LCDDConverter::handlePosition(const std::string& name, const TGeoMatrix* t
   GeometryInfo& geo = data();
   xml_h pos = geo.xmlPositions[trafo];
   if ( !pos ) {
-    static xml_h identity;
     const double* tr = trafo->GetTranslation();
-    if ( tr[0] != 0 || tr[1] != 0 || tr[2] != 0 )   {
+    if ( tr[0] != 0.0 || tr[1] != 0.0 || tr[2] != 0.0 )   {
       geo.checkPosition(name,trafo);
       geo.doc_define.append(pos=xml_elt_t(geo.doc,_U(position)));
       pos.setAttr(_U(name),name);
-      pos.setAttr(_U(x),tr[0]);
-      pos.setAttr(_U(y),tr[1]);
-      pos.setAttr(_U(z),tr[2]);
+      pos.setAttr(_U(x),tr[0]*CM_2_MM);
+      pos.setAttr(_U(y),tr[1]*CM_2_MM);
+      pos.setAttr(_U(z),tr[2]*CM_2_MM);
     }
-    else if ( identity )  {
-      pos = identity;
+    else if ( geo.identity_pos )  {
+      pos = geo.identity_pos;
     }
     else {
-      geo.doc_define.append(identity=xml_elt_t(geo.doc,_U(position)));
-      identity.setAttr(_U(name),"identity_pos");
-      identity.setAttr(_U(x),0);
-      identity.setAttr(_U(y),0);
-      identity.setAttr(_U(z),0);
-      pos = identity;
+      geo.doc_define.append(geo.identity_pos=xml_elt_t(geo.doc,_U(position)));
+      geo.identity_pos.setAttr(_U(name),"identity_pos");
+      geo.identity_pos.setAttr(_U(x),0);
+      geo.identity_pos.setAttr(_U(y),0);
+      geo.identity_pos.setAttr(_U(z),0);
+      pos = geo.identity_pos;
       geo.checkPosition("identity_pos",0);
     }
     geo.xmlPositions[trafo] = pos;
@@ -459,26 +498,27 @@ xml_h LCDDConverter::handleRotation(const std::string& name, const TGeoMatrix* t
   GeometryInfo& geo = data();
   xml_h rot = geo.xmlRotations[trafo];
   if ( !rot ) {
-    static xml_h identity;
-    XYZRotation r = getXYZangles(trafo->Inverse().GetRotationMatrix());
-    if ( r.X() != 0 || r.Y() != 0 || r.Z() != 0 )   {
+    XYZRotation r = getXYZangles(trafo->GetRotationMatrix());
+    if ( r.X() != 0.0 || r.Y() != 0.0 || r.Z() != 0.0 )  {
       geo.checkRotation(name,trafo);
       geo.doc_define.append(rot=xml_elt_t(geo.doc,_U(rotation)));
       rot.setAttr(_U(name),name);
       rot.setAttr(_U(x),r.X());
       rot.setAttr(_U(y),r.Y());
       rot.setAttr(_U(z),r.Z());
+      rot.setAttr(_U(unit),"rad");
     }
-    else if ( identity )  {
-      rot = identity;
+    else if ( geo.identity_rot )  {
+      rot = geo.identity_rot;
     }
     else {
-      geo.doc_define.append(identity=xml_elt_t(geo.doc,_U(rotation)));
-      identity.setAttr(_U(name),"identity_rot");
-      identity.setAttr(_U(x),0);
-      identity.setAttr(_U(y),0);
-      identity.setAttr(_U(z),0);
-      rot = identity;
+      geo.doc_define.append(geo.identity_rot=xml_elt_t(geo.doc,_U(rotation)));
+      geo.identity_rot.setAttr(_U(name),"identity_rot");
+      geo.identity_rot.setAttr(_U(x),0);
+      geo.identity_rot.setAttr(_U(y),0);
+      geo.identity_rot.setAttr(_U(z),0);
+      geo.identity_rot.setAttr(_U(unit),"rad");
+      rot = geo.identity_rot;
       geo.checkRotation("identity_rot",0);
     }
     geo.xmlRotations[trafo] = rot;
@@ -506,34 +546,63 @@ xml_h LCDDConverter::handleVolume(const string& name, const TGeoVolume* volume)
     geo.checkVolume(name,volume);
     geo.doc_structure.append(vol=xml_elt_t(geo.doc,_U(volume)));
     vol.setAttr(_U(name),n);
-    vol.setRef(_U(solidref),sol.name());
     if ( m )   {
-      xml_ref_t med = handleMaterial(m->GetName(),m);
+      string mat_name = m->GetName();
+      xml_ref_t med = handleMaterial(mat_name,m);
       vol.setRef(_U(materialref),med.name());
     }
+    vol.setRef(_U(solidref),sol.name());
+    geo.xmlVolumes[v] = vol;
+    const TObjArray*  dau = ((TGeoVolume*)v)->GetNodes();
+    if ( dau && dau->GetEntries() > 0 ) {
+      for(Int_t i=0, n=dau->GetEntries(); i<n; ++i) {
+	TGeoNode* node = (TGeoNode*)dau->At(i);
+	handlePlacement(node->GetName(),node);
+      }
+    }
     if ( geo.doc_header && dynamic_cast<const Volume::Object*>(volume) ) {
       Region            reg = _v.region();
       LimitSet          lim = _v.limitSet();
       VisAttr           vis = _v.visAttributes();
       SensitiveDetector det = _v.sensitiveDetector();
-      if ( vis.isValid() )   {
-	xml_ref_t data = handleVis(vis.name(),vis.ptr());
-	vol.setRef(_U(visref),data.name());
+      if ( det.isValid() )   {
+	xml_ref_t data = handleSensitive(det.name(),det.ptr());
+	vol.setRef(_U(sdref),data.name());
+      }
+      if ( reg.isValid() )   {
+	xml_ref_t data = handleRegion(reg.name(),reg.ptr());
+	vol.setRef(_U(regionref),data.name());
       }
       if ( lim.isValid() )   {
 	xml_ref_t data = handleLimitSet(lim.name(),lim.ptr());
 	vol.setRef(_U(limitsetref),data.name());
       }
-      if ( reg.isValid() )   {
-	xml_ref_t data = handleRegion(reg.name(),reg.ptr());
-	vol.setRef(_U(regionref),data.name());
+      if ( vis.isValid() )   {
+	xml_ref_t data = handleVis(vis.name(),vis.ptr());
+	vol.setRef(_U(visref),data.name());
       }
-      if ( det.isValid() )   {
-	xml_ref_t data = handleSensitive(det.name(),det.ptr());
-	vol.setRef(_U(sdref),data.name());
+    }
+  }
+  return vol;
+}
+
+/// Dump logical volume in GDML format to output stream
+xml_h LCDDConverter::handleVolumeVis(const string& name, const TGeoVolume* volume)   const   {
+  GeometryInfo& geo = data();
+  xml_h vol = geo.xmlVolumes[volume];
+  if ( !vol ) {
+    const TGeoVolume*  v  = volume;
+    Volume            _v  = Ref_t(v);
+    if ( dynamic_cast<const Volume::Object*>(volume) ) {
+      VisAttr vis = _v.visAttributes();
+      if ( vis.isValid() )   {
+	geo.doc_structure.append(vol=xml_elt_t(geo.doc,_U(volume)));
+	vol.setAttr(_U(name),v->GetName());
+	xml_ref_t data = handleVis(vis.name(),vis.ptr());
+	vol.setRef(_U(visref),data.name());
+	geo.xmlVolumes[v] = vol;
       }
     }
-    geo.xmlVolumes[v] = vol;
   }
   return vol;
 }
@@ -581,22 +650,22 @@ xml_h LCDDConverter::handlePlacement(const string& name, const TGeoNode* node) c
   GeometryInfo& geo = data();
   xml_h place    = geo.xmlPlacements[node];
   if ( !place )   {
-    TGeoMatrix*  t = node->GetMatrix();
+    TGeoMatrix*  m = node->GetMatrix();
     TGeoVolume*  v = node->GetVolume();
-    xml_ref_t vol = xml_h(geo.xmlVolumes[v]);
-    xml_h   mot = geo.xmlVolumes[node->GetMotherVolume()];
+    xml_ref_t  vol = xml_h(geo.xmlVolumes[v]);
+    xml_h      mot = geo.xmlVolumes[node->GetMotherVolume()];
 
     place = xml_elt_t(geo.doc,_U(physvol));
     if ( mot ) { // Beware of top level volume!
       mot.append(place);
     }
     place.setRef(_U(volumeref),vol.name());
-    if ( t )  {
+    if ( m )  {
       char text[32];
       ::sprintf(text,"_%p_pos",node);
-      xml_ref_t pos = handlePosition(name+text,t);
+      xml_ref_t pos = handlePosition(name+text,m);
       ::sprintf(text,"_%p_rot",node);
-      xml_ref_t rot = handleRotation(name+text,t);
+      xml_ref_t rot = handleRotation(name+text,m);
       place.setRef(_U(positionref),pos.name());
       place.setRef(_U(rotationref),rot.name());
     }
@@ -669,7 +738,7 @@ xml_h LCDDConverter::handleSensitive(const string& name, const TNamed* sens_det)
     sensdet.setAttr(_U(name),sd.name());
     sensdet.setAttr(_U(ecut),sd.energyCutoff());
     sensdet.setAttr(_U(eunit),"MeV");
-    sensdet.setAttr(_U(verbose),sd.verbose());
+    sensdet.setAttr(_U(verbose),int(sd.verbose() ? 1 : 0));
     sensdet.setAttr(_U(hits_collection),sd.hitsCollection());
     if ( sd.combineHits() ) sensdet.setAttr(_U(combine_hits),sd.combineHits());
     Readout ro = sd.readout();
@@ -687,6 +756,7 @@ xml_h LCDDConverter::handleIdSpec(const std::string& name, const TNamed* id_spec
   GeometryInfo& geo = data();
   xml_h id = geo.xmlIdSpecs[id_spec];
   if ( !id )   {
+    int length=0, start=0;
     IDDescriptor desc = Ref_t(id_spec);
     geo.doc_idDict.append(id=xml_elt_t(geo.doc,_U(idspec)));
     id.setAttr(_U(name),name);
@@ -694,12 +764,15 @@ xml_h LCDDConverter::handleIdSpec(const std::string& name, const TNamed* id_spec
     for(IDDescriptor::FieldMap::const_iterator i=m.begin(); i!=m.end(); ++i) {
       xml_h idfield = xml_elt_t(geo.doc,_U(idfield));
       const IDDescriptor::Field& f = (*i).second;
+      start = f.first;
+      length = f.second<0 ? -f.second : f.second;
       idfield.setAttr(_U(signed),f.second<0 ? true : false);
       idfield.setAttr(_U(label),(*i).first);
-      idfield.setAttr(_U(length),f.second<0 ? -f.second : f.second);
-      idfield.setAttr(_U(start),f.first);
+      idfield.setAttr(_U(length),length);
+      idfield.setAttr(_U(start),start);
       id.append(idfield);
     }
+    id.setAttr(_U(length),length+start);
     geo.xmlIdSpecs[id_spec] = id;
   }
   return id;
@@ -724,11 +797,12 @@ xml_h LCDDConverter::handleVis(const string& name, const TNamed* v) const  {
     else if ( style == VisAttr::DASHED )
       vis.setAttr(_U(line_style),"broken");
     if ( draw == VisAttr::SOLID )
-      vis.setAttr(_U(line_style),"solid");
+      vis.setAttr(_U(drawing_style),"solid");
     else if ( draw == VisAttr::WIREFRAME )
-      vis.setAttr(_U(line_style),"wireframe");
+      vis.setAttr(_U(drawing_style),"wireframe");
 
     xml_h col = xml_elt_t(geo.doc,_U(color));
+    attr.rgb(r,g,b);
     col.setAttr(_U(alpha),attr.alpha());
     col.setAttr(_U(R),r);
     col.setAttr(_U(G),g);
@@ -746,15 +820,14 @@ xml_h LCDDConverter::handleField(const std::string& name, const TNamed* f)   con
   if ( !field ) {
     Ref_t  fld(f);
     string type = f->GetTitle();
-    field=xml_elt_t(geo.doc,_U(field));
+    field=xml_elt_t(geo.doc,Unicode(type));
     field.setAttr(_U(name),f->GetName());
-    field.setAttr(_U(type),type);
     fld = ROOT::Reflex::PluginService::Create<TNamed*>(type+"_Convert2LCDD",&m_lcdd,&field,&fld);
-    cout << (fld.isValid() ? "Converted" : "FAILED    to convert ")
-	 << " electromagnetic field:" << f->GetName() << " of type " << f->GetTitle() << endl;
+    cout << "++ " << (fld.isValid() ? "Converted" : "FAILED    to convert ")
+	 << " electromagnetic field:" << f->GetName() << " of type " << type << endl;
     if ( !fld.isValid() ) {
       throw runtime_error("Failed to locate plugin to convert electromagnetic field:"+
-			  string(f->GetName())+" of type "+string(f->GetTitle()));
+			  string(f->GetName())+" of type "+type);
     }
     geo.doc_fields.append(field);
   }
@@ -848,8 +921,7 @@ xml_doc_t LCDDConverter::createGDML(DetElement top) {
   collect(top,geo);
   m_checkOverlaps = false;
 
-  const char empty_gdml[] = XML_HEADER_DECLARATION
-    "<!--                                                               \n"
+  const char* comment = "\n"
     "      +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"
     "      ++++   Linear collider detector description GDML in C++  ++++\n"
     "      ++++   DD4hep Detector description generator.            ++++\n"
@@ -857,31 +929,32 @@ xml_doc_t LCDDConverter::createGDML(DetElement top) {
     "      ++++   Parser:" XML_IMPLEMENTATION_TYPE "                ++++\n"
     "      ++++                                                     ++++\n"
     "      ++++                              M.Frank CERN/LHCb      ++++\n"
-    "      +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"
-    "-->\n"
-    "<gdml "
-    "xmlns:xs=\"http://www/w3.org/2001/XMLSchema-instance\"\n"
-    "xsi:noNamespaceSchemaLocation=\"http://service-spi.web.cern.ch/service-spi/app/releases/GDML/schema/gdml.xsd\">\n"
-    "</gdml>\0\0";
-
+    "      +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n  ";
   XML::DocumentHandler docH;
-  xml_elt_t elt(0);
-  geo.doc = docH.parse(empty_gdml,sizeof(empty_gdml));
+  geo.doc = docH.create("gdml",comment);
   geo.doc_root = geo.doc.root();
+  geo.doc_root.setAttr(Unicode("xmlns:xs"),"http://www.w3.org/2001/XMLSchema-instance");
+  geo.doc_root.setAttr(Unicode("xs:noNamespaceSchemaLocation"),
+		       "http://service-spi.web.cern.ch/service-spi/app/releases/GDML/schema/gdml.xsd");
+  // geo.doc = docH.create("gdml_simple_extension",comment);
+  // geo.doc_root.setAttr(Unicode("xmlns:gdml_simple_extension"),"http://www.example.org");
+  // geo.doc_root.setAttr(Unicode("xs:noNamespaceSchemaLocation"),
+  //     "http://service-spi.web.cern.ch/service-spi/app/releases/GDML/schema/gdml.xsd");
   geo.doc_root.append(geo.doc_define    = xml_elt_t(geo.doc,_U(define)));
   geo.doc_root.append(geo.doc_materials = xml_elt_t(geo.doc,_U(materials)));
   geo.doc_root.append(geo.doc_solids    = xml_elt_t(geo.doc,_U(solids)));
   geo.doc_root.append(geo.doc_structure = xml_elt_t(geo.doc,_U(structure)));
   geo.doc_root.append(geo.doc_setup     = xml_elt_t(geo.doc,_U(setup)));
-  elt = xml_elt_t(geo.doc,_U(world));
-  elt.setAttr(_U(ref),lcdd.worldVolume().name());
-  geo.doc_setup.append(elt);
-
+  geo.doc_setup.setRef(_U(world),lcdd.worldVolume().name());
+  geo.doc_setup.setAttr(_U(name),Unicode("Default"));
+  geo.doc_setup.setAttr(_U(version),Unicode("1.0"));
 
   // Ensure that all required materials are present in the Geant4 material table
+#if 0
   const LCDD::HandleMap& mat = lcdd.materials();
   for(LCDD::HandleMap::const_iterator i=mat.begin(); i!=mat.end(); ++i)
     geo.materials.insert(dynamic_cast<TGeoMedium*>((*i).second.ptr()));
+#endif
 
   // Start creating the objects for materials, solids and log volumes.
   handle(this, geo.materials, &LCDDConverter::handleMaterial);
@@ -896,9 +969,6 @@ xml_doc_t LCDDConverter::createGDML(DetElement top) {
   handle(this, geo.volumes,   &LCDDConverter::handleVolume);
   cout << "++ Handled " << geo.volumes.size() << " volumes." << endl;
 
-  // Now place all this stuff appropriately
-  handleRMap(this, *m_data,   &LCDDConverter::handlePlacement);
-
   m_checkNames.clear();
   handle(this, geo.volumes,   &LCDDConverter::checkVolumes);
   return geo.doc;
@@ -906,7 +976,7 @@ xml_doc_t LCDDConverter::createGDML(DetElement top) {
 
 
 /// Create geometry conversion
-xml_doc_t LCDDConverter::createLCDD(DetElement top) {
+xml_doc_t LCDDConverter::createVis(DetElement top) {
   LCDD& lcdd = m_lcdd;
   if ( !top.isValid() ) {
     throw runtime_error("Attempt to call createLCDD with an invalid geometry!");
@@ -917,10 +987,7 @@ xml_doc_t LCDDConverter::createLCDD(DetElement top) {
   collect(top,geo);
   m_checkOverlaps = false;
 
-  #define ns_location "http://www.lcsim.org.schemas/lcdd/1.0"
-
-  const char empty_lcdd[] = XML_HEADER_DECLARATION
-    "<!--                                                               \n"
+  const char comment[] = "\n"
     "      +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"
     "      ++++   Linear collider detector description LCDD in C++  ++++\n"
     "      ++++   DD4hep Detector description generator.            ++++\n"
@@ -928,22 +995,51 @@ xml_doc_t LCDDConverter::createLCDD(DetElement top) {
     "      ++++   Parser:" XML_IMPLEMENTATION_TYPE "                ++++\n"
     "      ++++                                                     ++++\n"
     "      ++++                              M.Frank CERN/LHCb      ++++\n"
-    "      +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"
-    "-->\n"
-    "<lcdd "
-    "xmlns:lcdd=\"" ns_location "\"\n"
-    "xmlns:xs=\"http://www/w3.org/2001/XMLSchema-instance\"\n"
-    ">\n"
-    "</lcdd>\0\0";
+    "      +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n  ";
+  XML::DocumentHandler docH;
+  xml_elt_t elt(0);
+  geo.doc = docH.create("visualization",comment);
+  geo.doc_root = geo.doc.root();
+  geo.doc_root.append(geo.doc_display   = xml_elt_t(geo.doc,_U(display)));
+  geo.doc_root.append(geo.doc_structure = xml_elt_t(geo.doc,_U(structure)));
+
+  handle(this, geo.volumes,   &LCDDConverter::collectVolume);
+  handle(this, geo.volumes,   &LCDDConverter::handleVolumeVis);
+  cout << "++ Handled " << geo.volumes.size() << " volumes." << endl;
+  return geo.doc;
+}
+
+/// Create geometry conversion
+xml_doc_t LCDDConverter::createLCDD(DetElement top) {
+  LCDD& lcdd = m_lcdd;
+  if ( !top.isValid() ) {
+    throw runtime_error("Attempt to call createLCDD with an invalid geometry!");
+  }
+
+  GeometryInfo& geo = *(m_dataPtr=new GeometryInfo);
+  m_data->clear();
+  collect(top,geo);
+  m_checkOverlaps = false;
 
+  const char comment[] = "\n"
+    "      +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"
+    "      ++++   Linear collider detector description LCDD in C++  ++++\n"
+    "      ++++   DD4hep Detector description generator.            ++++\n"
+    "      ++++                                                     ++++\n"
+    "      ++++   Parser:" XML_IMPLEMENTATION_TYPE "                ++++\n"
+    "      ++++                                                     ++++\n"
+    "      ++++                              M.Frank CERN/LHCb      ++++\n"
+    "      +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n  ";
   XML::DocumentHandler docH;
   xml_elt_t elt(0);
-  geo.doc = docH.parse(empty_lcdd,sizeof(empty_lcdd));
-  //doc->setXmlStandalone(true);
-  //doc->setStrictErrorChecking(true);
+  geo.doc = docH.create("lcdd",comment);
   geo.doc_root = geo.doc.root();
+  geo.doc_root.setAttr(Unicode("xmlns:lcdd"),
+		       "http://www.lcsim.org/schemas/lcdd/1.0");
+  geo.doc_root.setAttr(Unicode("xmlns:xs"),"http://www.w3.org/2001/XMLSchema-instance");
+  geo.doc_root.setAttr(Unicode("xs:noNamespaceSchemaLocation"),
+		       "http://www.lcsim.org/schemas/lcdd/1.0/lcdd.xsd");
 
-  //Box worldSolid(doc,_U(world_box));
   geo.doc_root.append(geo.doc_header    = xml_elt_t(geo.doc,_U(header)));
   geo.doc_root.append(geo.doc_idDict    = xml_elt_t(geo.doc,_U(iddict)));
   geo.doc_root.append(geo.doc_detectors = xml_elt_t(geo.doc,_U(sensitive_detectors)));
@@ -952,23 +1048,22 @@ xml_doc_t LCDDConverter::createLCDD(DetElement top) {
   geo.doc_root.append(geo.doc_display   = xml_elt_t(geo.doc,_U(display)));
   geo.doc_root.append(geo.doc_gdml      = xml_elt_t(geo.doc,_U(gdml)));
   geo.doc_root.append(geo.doc_fields    = xml_elt_t(geo.doc,_U(fields)));
-  //elt = xml_elt_t();
 
   geo.doc_gdml.append(geo.doc_define    = xml_elt_t(geo.doc,_U(define)));
   geo.doc_gdml.append(geo.doc_materials = xml_elt_t(geo.doc,_U(materials)));
   geo.doc_gdml.append(geo.doc_solids    = xml_elt_t(geo.doc,_U(solids)));
   geo.doc_gdml.append(geo.doc_structure = xml_elt_t(geo.doc,_U(structure)));
   geo.doc_gdml.append(geo.doc_setup     = xml_elt_t(geo.doc,_U(setup)));
-  elt = xml_elt_t(geo.doc,_U(world));
-  elt.setAttr(_U(ref),lcdd.worldVolume().name());
-  geo.doc_setup.append(elt);
-
+  geo.doc_setup.setRef(_U(world),lcdd.worldVolume().name());
+  geo.doc_setup.setAttr(_U(name),Unicode("Default"));
+  geo.doc_setup.setAttr(_U(version),Unicode("1.0"));
 
   // Ensure that all required materials are present in the Geant4 material table
+#if 0
   const LCDD::HandleMap& mat = lcdd.materials();
   for(LCDD::HandleMap::const_iterator i=mat.begin(); i!=mat.end(); ++i)
     geo.materials.insert(dynamic_cast<TGeoMedium*>((*i).second.ptr()));
-
+#endif
   const LCDD::HandleMap& fld = lcdd.fields();
   for(LCDD::HandleMap::const_iterator i=fld.begin(); i!=fld.end(); ++i)
     geo.fields.insert((*i).second.ptr());
@@ -1002,12 +1097,8 @@ xml_doc_t LCDDConverter::createLCDD(DetElement top) {
   handle(this, geo.fields,     &LCDDConverter::handleField);
   cout << "++ Handled " << geo.fields.size() << " fields." << endl;
 
-  // Now place all this stuff appropriately
-  handleRMap(this, *m_data,    &LCDDConverter::handlePlacement);
-
   m_checkNames.clear();
   handle(this, geo.volumes,    &LCDDConverter::checkVolumes);
-
 #if 0
   //==================== Fields
   handleProperties(m_lcdd.properties());
@@ -1039,5 +1130,43 @@ static long create_lcdd(LCDD& lcdd, int argc, char** argv)   {
   return dump_output(wr.createLCDD(lcdd.world()),argc,argv);
 }
 
+static long create_vis(LCDD& lcdd, int argc, char** argv)   {
+  LCDDConverter wr(lcdd);
+  return dump_output(wr.createVis(lcdd.world()),argc,argv);
+}
+
+static long create_visASCII(LCDD& lcdd, int argc, char** argv)   {
+  LCDDConverter wr(lcdd);
+  xml_doc_t doc = wr.createVis(lcdd.world());
+  LCDDConverter::GeometryInfo& geo = wr.data();
+  map<string,xml_comp_t> vis;
+  for(xml_coll_t c(geo.doc_display,_U(vis)); c; ++c)
+    vis.insert(make_pair(xml_comp_t(c).nameStr(),xml_comp_t(c)));
+
+  const char* sep = ";";
+  ofstream os(argv[0]);
+  for(xml_coll_t c(geo.doc_structure,_U(volume)); c; ++c)  {
+    xml_comp_t vol = c;
+    xml_comp_t   r = c.child(_U(visref));
+    xml_comp_t   v = (*vis.find(r.refStr())).second;
+    xml_comp_t   c = v.child(_U(color));
+    os << "vol:" << vol.nameStr() << sep
+       << "vis:" << v.nameStr() << sep
+       << "visible:" << v.visible() << sep
+       << "r:"   << c.R() << sep
+       << "g:"   << c.G() << sep
+       << "b:"   << c.B() << sep
+       << "alpha:"   << c.alpha() << sep
+       << "line_style:" << v.attr<string>(_U(line_style)) << sep
+       << "drawing_style:" << v.attr<string>(_U(drawing_style)) << sep
+       << "show_daughters:" << v.show_daughters() << sep
+       << endl;
+  }
+  os.close();
+  return 1;
+}
+
+DECLARE_APPLY(DD4hepGeometry2VIS, create_vis);
+DECLARE_APPLY(DD4hepGeometry2VISASCII, create_visASCII);
 DECLARE_APPLY(DD4hepGeometry2GDML,create_gdml);
 DECLARE_APPLY(DD4hepGeometry2LCDD,create_lcdd);
diff --git a/DDCore/src/plugins/LCDDConverter.h b/DDCore/src/plugins/LCDDConverter.h
index ef72f9c1bd1cf00b5b304d40733ef49e8b6f4bb8..5d1511fe05fde7b2a0fb076c7d1cab5de574a4c6 100644
--- a/DDCore/src/plugins/LCDDConverter.h
+++ b/DDCore/src/plugins/LCDDConverter.h
@@ -89,6 +89,7 @@ namespace DD4hep {
 	void checkMaterial(const std::string& name,const TNamed* n) const { check(name,n,checks.materials); }
 
 	xml_doc_t           doc;
+	xml_h               identity_rot, identity_pos;
 	xml_elt_t           doc_root, doc_header, doc_idDict, doc_detectors, doc_limits, doc_regions,
 	  doc_display, doc_gdml, doc_fields, doc_define, doc_materials, doc_solids, doc_structure, doc_setup;
 	GeometryInfo();
@@ -120,6 +121,9 @@ namespace DD4hep {
       /// Create geometry conversion in LCDD format
       xml_doc_t createLCDD(DetElement top);
 
+      /// Create geometry conversion in Vis format
+      xml_doc_t createVis(DetElement top);
+
       /// Add header information in LCDD format
       virtual void handleHeader() const;
 
@@ -134,7 +138,8 @@ namespace DD4hep {
 
       /// Convert the geometry type logical volume into the corresponding Xml object(s).
       virtual xml_h handleVolume(const std::string& name, const TGeoVolume* volume) const;
-      virtual void     collectVolume(const std::string& name, const TGeoVolume* volume) const;
+      virtual xml_h handleVolumeVis(const std::string& name, const TGeoVolume* volume) const;
+      virtual void  collectVolume(const std::string& name, const TGeoVolume* volume) const;
 
       /// Convert the geometry type volume placement into the corresponding Xml object(s).
       virtual xml_h handlePlacement(const std::string& name, const TGeoNode* node) const;
diff --git a/DDCore/src/plugins/LCDDFields.cpp b/DDCore/src/plugins/LCDDFields.cpp
index 221f046af9a1d0b71ae52345bec222fcd7b36433..28f781f776b9ddfc3083e3eb0bd3f617da0dd8dc 100644
--- a/DDCore/src/plugins/LCDDFields.cpp
+++ b/DDCore/src/plugins/LCDDFields.cpp
@@ -49,7 +49,7 @@ static Ref_t convert_solenoid(LCDD& lcdd, xml_h field, Ref_t object) {
   field.setAttr(_U(zmax),s->maxZ);
   return object;
 }
-DECLARE_XML_PROCESSOR(SolenoidMagnet_Convert2LCDD,convert_solenoid);
+DECLARE_XML_PROCESSOR(solenoid_Convert2LCDD,convert_solenoid);
 
 static Ref_t convert_dipole(LCDD& lcdd, xml_h field, Ref_t object) {
   char text[128];