diff --git a/DDCore/include/DD4hep/Detector.h b/DDCore/include/DD4hep/Detector.h
index a0f841e5457364b42a8cb95120d24b001f49ac79..271c2bdee30e42b4cc66c3c46657a8cbf861e84f 100644
--- a/DDCore/include/DD4hep/Detector.h
+++ b/DDCore/include/DD4hep/Detector.h
@@ -59,7 +59,7 @@ namespace DD4hep {
         /// Default constructor
         Object();
         /// Internal object destructor: release extension object(s)
-        ~Object();
+        virtual ~Object();
       };
       protected:
 
diff --git a/DDCore/include/DD4hep/Fields.h b/DDCore/include/DD4hep/Fields.h
index b19014b21e6f6a9bcbb2a2d95eaea23b8de00860..7e2674d2e7b34481f12ce2f35c8453c1437147fe 100644
--- a/DDCore/include/DD4hep/Fields.h
+++ b/DDCore/include/DD4hep/Fields.h
@@ -55,7 +55,7 @@ namespace DD4hep {
 	/// Default constructor
 	Object();
 	/// Default destructor
-	~Object();
+	virtual ~Object();
 	/// Call to access the field components at a given location
 	virtual void fieldComponents(const double* pos, double* field) = 0;
       };
@@ -125,7 +125,7 @@ namespace DD4hep {
 	/// Default constructor
 	Object();
 	/// Default destructor
-	~Object();
+	virtual ~Object();
       };
 
       /// Default constructor
diff --git a/DDCore/include/DD4hep/IDDescriptor.h b/DDCore/include/DD4hep/IDDescriptor.h
index b2f9e81ce773dcc51cf7ada74cfe329436fb7149..906148cdbd92a1ba70aa0363783e23e48cb0de76 100644
--- a/DDCore/include/DD4hep/IDDescriptor.h
+++ b/DDCore/include/DD4hep/IDDescriptor.h
@@ -66,7 +66,7 @@ namespace DD4hep {
 	/// Standard constructor
 	Object();
 	/// Default destructor
-	~Object();
+	virtual ~Object();
       };
       public:
       /// Default constructor
diff --git a/DDCore/include/DD4hep/Objects.h b/DDCore/include/DD4hep/Objects.h
index 9e69323896ef18c3680d0e334cd6edf9cc4d2211..d75a40708052de361caffda9ab57baff1f02190c 100644
--- a/DDCore/include/DD4hep/Objects.h
+++ b/DDCore/include/DD4hep/Objects.h
@@ -105,7 +105,7 @@ namespace DD4hep {
 	/// Standard constructor
 	Object();
 	/// Default destructor
-	~Object();	
+	virtual ~Object();	
       };
       /// Default constructor
       Header() : Ref_t() {}
@@ -270,7 +270,7 @@ namespace DD4hep {
 	/// Standard constructor
 	Object();
 	/// Default destructor
-	~Object();
+	virtual ~Object();
       };
       /// Default constructor
       VisAttr() : Ref_t() {}
@@ -380,7 +380,7 @@ namespace DD4hep {
 	/// Standard constructor
 	Object();
 	/// Default destructor
-	~Object();
+	virtual ~Object();
       };
       /// Constructor to be used when reading the already parsed DOM tree
       LimitSet() : Ref_t() {}
@@ -411,7 +411,7 @@ namespace DD4hep {
 	/// Standard constructor
 	Object();
 	/// Default destructor
-	~Object();
+	virtual ~Object();
       };
       /// Default constructor
       Region() : Ref_t() {}
diff --git a/DDCore/include/DD4hep/Readout.h b/DDCore/include/DD4hep/Readout.h
index 690064105b75f6e0dee1eb741f3e9f8b7bb1d3ac..2321408ad5aed8e9df474337646402606bd6cf1f 100644
--- a/DDCore/include/DD4hep/Readout.h
+++ b/DDCore/include/DD4hep/Readout.h
@@ -49,7 +49,7 @@ namespace DD4hep {
 	/// Standard constructor
 	Object();
 	/// Default destructor
-	~Object();
+	virtual ~Object();
       };
     public:
       /// Default constructor
@@ -76,6 +76,10 @@ namespace DD4hep {
     struct Alignment : public Ref_t {
       struct Object : public TNamed {
         Volume volume;
+	/// Standard constructor
+	Object();
+	/// Default destructor
+	virtual ~Object();
       };
       /// Default constructor
       Alignment() : Ref_t() {}
@@ -94,6 +98,10 @@ namespace DD4hep {
       */
     struct Conditions : public Ref_t {
       struct Object : public TNamed {
+	/// Standard constructor
+	Object();
+	/// Default destructor
+	virtual ~Object();	
       };
       /// Default constructor
       Conditions() : Ref_t() {}
diff --git a/DDCore/include/DD4hep/Segmentations.h b/DDCore/include/DD4hep/Segmentations.h
index e8e85295855866addbe355136a2882d457697ff8..6ad3dc724b4b6b40aac62c147ac0d3684775bf31 100644
--- a/DDCore/include/DD4hep/Segmentations.h
+++ b/DDCore/include/DD4hep/Segmentations.h
@@ -85,7 +85,7 @@ namespace DD4hep {
 	/// Standard constructor
         Object();
 	/// Default destructor
-        ~Object();
+        virtual ~Object();
       };
       
     protected:
diff --git a/DDCore/include/DD4hep/Shapes.h b/DDCore/include/DD4hep/Shapes.h
index 9bbf52314c66a354d27612fbfeecc9028119beaf..0450a1029aa9447dac8fe7256959377e242fcd8b 100644
--- a/DDCore/include/DD4hep/Shapes.h
+++ b/DDCore/include/DD4hep/Shapes.h
@@ -219,7 +219,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);
 
diff --git a/DDCore/include/DD4hep/VolumeManager.h b/DDCore/include/DD4hep/VolumeManager.h
index 6efe4fbea6d3731741cb2de403ede32b05ed26c4..50904a21f24b0f9a055574bd44bd8494015e878e 100644
--- a/DDCore/include/DD4hep/VolumeManager.h
+++ b/DDCore/include/DD4hep/VolumeManager.h
@@ -179,7 +179,7 @@ namespace DD4hep {
 	/// Default constructor
 	Object();
 	/// Default destructor
-	~Object();
+	virtual ~Object();
 	/// Search the locally cached volumes for a matching ID
 	Context* search(const VolIdentifier& id)  const;
       };
diff --git a/DDCore/include/DD4hep/Volumes.h b/DDCore/include/DD4hep/Volumes.h
index 2b0178bbf7936118ea7072b8b1d318f61dcc2f1c..3637e11dc5cc7a53fa6f04c523fdebb1127fa893 100644
--- a/DDCore/include/DD4hep/Volumes.h
+++ b/DDCore/include/DD4hep/Volumes.h
@@ -47,7 +47,7 @@ namespace DD4hep {
      *  @author  M.Frank
      *  @version 1.0
      */
-    struct PlacedVolume : Handle<TGeoNodeMatrix> {
+    struct PlacedVolume : Handle<TGeoNode> {
       typedef std::pair<std::string,int> VolID;
       struct VolIDs : public std::vector<VolID>   {
 	typedef std::vector<VolID> Base;
@@ -66,18 +66,18 @@ namespace DD4hep {
 	/// Copy constructor
 	Object(const Object& c);
 	/// Default destructor
-        ~Object();
+        virtual ~Object();
 	/// Assignment operator
 	Object& operator=(const Object& c) { magic=c.magic; volIDs=c.volIDs; return *this; }
       };
       /// Constructor to be used when reading the already parsed DOM tree
-      PlacedVolume(const TGeoNode* e) : Handle<TGeoNodeMatrix>(e) {}
+      PlacedVolume(const TGeoNode* e) : Handle<TGeoNode>(e) {}
       /// Default constructor
-      PlacedVolume() : Handle<TGeoNodeMatrix>() {}
+      PlacedVolume() : Handle<TGeoNode>() {}
       /// Copy assignment
-      PlacedVolume(const PlacedVolume& e) : Handle<TGeoNodeMatrix>(e) {}
+      PlacedVolume(const PlacedVolume& e) : Handle<TGeoNode>(e) {}
       /// Copy assignment from other handle type
-      template <typename T> PlacedVolume(const Handle<T>& e) : Handle<TGeoNodeMatrix>(e) {}
+      template <typename T> PlacedVolume(const Handle<T>& e) : Handle<TGeoNode>(e) {}
       /// Assignment operator (must match copy constructor)
       PlacedVolume& operator=(const PlacedVolume& v) {  m_element=v.m_element;  return *this; }
 
@@ -116,7 +116,7 @@ namespace DD4hep {
 	/// Default constructor
         Object();
 	/// Default destructor
-        ~Object();
+        virtual ~Object();
 	void copy(const Object& c) { 
 	  magic=c.magic; 
 	  region=c.region; 
diff --git a/DDCore/src/IDDescriptor.cpp b/DDCore/src/IDDescriptor.cpp
index 1fa4668dbc1e58f19714d84090e046800625e5e5..671b2549994aa6f05d037f39e9b4c39af56481a1 100644
--- a/DDCore/src/IDDescriptor.cpp
+++ b/DDCore/src/IDDescriptor.cpp
@@ -109,7 +109,7 @@ IDDescriptor::Field IDDescriptor::field(const string& field_name)  const  {
   const FieldMap& m = fields(); // This already checks the object validity
   for(FieldMap::const_iterator i=m.begin(); i!=m.end(); ++i)
     if ( (*i).first == field_name ) return (*i).second;
-  throw runtime_error(string(name())+": This ID descriptor has now field with the name:"+field_name);
+  throw runtime_error(string(name())+": This ID descriptor has no field with the name:"+field_name);
 }
 
 /// Get the field descriptor of one field by its identifier
@@ -123,5 +123,5 @@ size_t IDDescriptor::fieldID(const string& field_name)  const   {
   const FieldIDs& m = ids(); // This already checks the object validity
   for(FieldIDs::const_iterator i=m.begin(); i!=m.end(); ++i)
     if ( (*i).second == field_name ) return (*i).first;
-  throw runtime_error(string(name())+": This ID descriptor has now field with the name:"+field_name);
+  throw runtime_error(string(name())+": This ID descriptor has no field with the name:"+field_name);
 }
diff --git a/DDCore/src/LCDDImp.cpp b/DDCore/src/LCDDImp.cpp
index 22a68501d851a8a32f916cc82e9d34599421c783..5722b5586da341fc3a8fca5e2bf9c7d81bd0fb11 100644
--- a/DDCore/src/LCDDImp.cpp
+++ b/DDCore/src/LCDDImp.cpp
@@ -61,9 +61,12 @@ LCDDImp::LCDDImp()
 {
   InstanceCount::increment(this);
   m_properties = new Properties();
-  //if ( 0 == gGeoManager )
+  if ( 0 == gGeoManager )
   {
-    m_manager = gGeoManager = new TGeoManager();
+    gGeoManager = new TGeoManager();
+  }
+  {
+    m_manager = gGeoManager;
     m_manager->AddNavigator();
     m_manager->SetCurrentNavigator(0);
     //cout << "Navigator:" << (void*)m_manager->GetCurrentNavigator() << endl;
@@ -95,14 +98,11 @@ LCDDImp::~LCDDImp() {
   for_each(m_idDict.begin(),      m_idDict.end(),       del);
   for_each(m_limits.begin(),      m_limits.end(),       del);
   for_each(m_regions.begin(),     m_regions.end(),      del);
-  //for_each(m_detectors.begin(),   m_detectors.end(),    del);
   for_each(m_alignments.begin(),  m_alignments.end(),   del);
   for_each(m_sensitive.begin(),   m_sensitive.end(),    del);
   for_each(m_display.begin(),     m_display.end(),      del);
   for_each(m_fields.begin(),      m_fields.end(),       del);
   for_each(m_define.begin(),      m_define.end(),       del);
-  // for_each(m_materials.begin(), m_materials.end(),  del);
-  //for_each(.begin(), .end(),  del);
 
   m_trackers.clear();
   m_worldVol.clear();
@@ -223,145 +223,8 @@ namespace {
         }
       }
     }
-
-    typedef DetElement::Children _C;
-    DetElement findElt(DetElement e, PlacedVolume pv)  {
-      const _C& children = e.children();
-      if ( e.placement().ptr() == pv.ptr() ) return e;
-      for(_C::const_iterator i=children.begin(); i!=children.end(); ++i)   {
-	DetElement de = (*i).second;
-	if ( de.placement().ptr() == pv.ptr() ) return de;
-      }
-      for(_C::const_iterator i=children.begin(); i!=children.end(); ++i)   {
-	DetElement de = findElt((*i).second,pv);
-	if ( de.isValid() )  return de;
-      }
-      return DetElement();
-    }
-
-    unsigned long long int encode_cell(Readout ro, const PlacedVolume::VolIDs& ids)   {
-      unsigned long long value = ~0x0ull;
-      const IDDescriptor& en = ro.idSpec();
-      for(PlacedVolume::VolIDs::const_iterator i=ids.begin(); i!=ids.end(); ++i) {
-	const PlacedVolume::VolID& id = (*i);
-	value &= en.field(id.first).encode(id.second);
-      }
-      return value;
-    }
-
-    typedef void (::ShapePatcher::*Func_t)(DetElement parent, DetElement e,const TGeoNode* n, 
-					   const PlacedVolume::VolIDs& ids, 
-					   const vector<const TGeoNode*>& nodes,
-					   const vector<const TGeoNode*>& elt_nodes);
-
-    void scanNode(Func_t func,
-		  DetElement parent, DetElement e, PlacedVolume pv, 
-		  const PlacedVolume::VolIDs& vol_ids, 
-		  vector<const TGeoNode*>& nodes,
-		  vector<const TGeoNode*>& elt_nodes)
-    {
-      const TGeoNode* node = dynamic_cast<const TGeoNode*>(pv.ptr());
-      if ( node )  {
-	Int_t ndau = node->GetNdaughters();
-	PlacedVolume::VolIDs ids(vol_ids);
-	const PlacedVolume::VolIDs& ids_node = pv.volIDs();
-
-	nodes.push_back(node);
-	elt_nodes.push_back(node);
-	ids.PlacedVolume::VolIDs::Base::insert(ids.end(),ids_node.begin(),ids_node.end());
-	(this->*func)(parent, e, node, ids, nodes, elt_nodes);
-	for(Int_t idau=0; idau<ndau; ++idau)  {
-	  TGeoNode* daughter = node->GetDaughter(idau);
-	  if ( dynamic_cast<const PlacedVolume::Object*>(daughter) ) {
-	    PlacedVolume pv_dau = Ref_t(daughter);
-	    DetElement   de_dau = findElt(e,daughter);
-	    if ( de_dau.isValid() )  {
-	      vector<const TGeoNode*> dau_nodes;
-	      scanNode(func, parent, de_dau, pv_dau, ids, nodes, dau_nodes);
-	    }
-	    else {
-	      scanNode(func, parent, e, pv_dau, ids, nodes, elt_nodes);
-	    }
-	  }
-	}
-	elt_nodes.pop_back();
-	nodes.pop_back();
-      }
-    }
-    void scanVolumes(Func_t func)    {
-      const _C& children = m_world.children();
-      for(_C::const_iterator i=children.begin(); i!=children.end(); ++i)   {
-	DetElement   de = (*i).second;
-	PlacedVolume pv = de.placement();
-	if ( pv.isValid() )  {
-	  PlacedVolume::VolIDs ids;
-	  vector<const TGeoNode*> nodes, elt_nodes;
-	  scanNode(func, de, de, pv, ids, nodes, elt_nodes);
-	  continue;
-	}
-	cout << "++ Detector element " << de.name() << " has no placement." << endl;
-      }
-    }
-
-    void print_node(DetElement parent, DetElement e,const TGeoNode* n, 
-		    const PlacedVolume::VolIDs& ids, 
-		    const vector<const TGeoNode*>& nodes,
-		    const vector<const TGeoNode*>& elt_nodes);
-
-    GeoScan& printVolumes()  {
-      scanVolumes(&ShapePatcher::print_node);
-      return *this;
-    }
   };
 
-  void ShapePatcher::print_node(DetElement parent, 
-				DetElement e,
-				const TGeoNode* n, 
-				const PlacedVolume::VolIDs& ids, 
-				const vector<const TGeoNode*>& nodes,
-				const vector<const TGeoNode*>& elt_nodes)
-  {
-    static int s_count = 0;
-    Volume            vol = PlacedVolume(n).volume();
-    SensitiveDetector sd  = vol.sensitiveDetector();
-    Readout           ro  = sd.readout();
-    const IDDescriptor& en = ro.idSpec();
-    IDDescriptor::VolumeID volume_id = encode_cell(ro,ids);
-    PlacedVolume pv = Ref_t(n);
-    bool sensitive  = pv.volume().isSensitive();
-
-    if ( !sensitive ) return;
-    ++s_count;
-    cout << s_count << ": " << e.name() << " de:" << e.ptr() << " ro:" << ro.ptr() 
-	 << " pv:" << n->GetName() << " id:" << (void*)volume_id << " : ";
-    for(PlacedVolume::VolIDs::const_iterator i=ids.begin(); i!=ids.end(); ++i) {
-      const PlacedVolume::VolID& id = (*i);
-      IDDescriptor::Field f = ro.idSpec().field(id.first);
-      int value = en.field(id.first).decode(volume_id);
-      cout << id.first << "=" << id.second << "," << value 
-	   << " [" << f.first << "," << f.second << "] ";
-    }
-    cout << " Sensitive:" << (sensitive ? "YES" : "NO");
-    if ( sensitive )   {
-      VolumeManager section = m_volManager.subdetector(volume_id);
-      VolumeManager::Context* ctxt = section.lookupContext(volume_id|0xDEAD);
-      if ( ctxt->placement.ptr() != pv.ptr() )  {
-	cout << " !!!!! No Volume found!" << endl;
-      }
-      cout << " Pv:" << pv.ptr() << " <> " << ctxt->placement.ptr();
-    }
-    cout << endl;
-#if 0
-    cout << s_count << ": " << e.name() << " Detector GeoNodes:";
-    for(vector<const TGeoNode*>::const_iterator j=nodes.begin(); j!=nodes.end();++j)
-      cout << (void*)(*j) << " ";
-    cout << endl;
-    cout << s_count << ": " << e.name() << " Element  GeoNodes:";
-    for(vector<const TGeoNode*>::const_iterator j=elt_nodes.begin(); j!=elt_nodes.end();++j)
-      cout << (void*)(*j) << " ";
-    cout << endl;
-#endif
-  }
 }
 
 void LCDDImp::endDocument()  {
@@ -394,13 +257,9 @@ void LCDDImp::endDocument()  {
     /// Since we allow now for anonymous shapes,
     /// we will rename them to use the name of the volume they are assigned to
     mgr->CloseGeometry();
-    m_world.setPlacement(PlacedVolume(mgr->GetTopNode()));
-    m_volManager = VolumeManager("World", m_world, Readout(), VolumeManager::TREE);
+    m_world.setPlacement(PlacedVolume(mgr->GetTopNode()));    
     ShapePatcher patcher(m_volManager,m_world);
     patcher.patchShapes();
-    //patcher.printVolumes();
-    //cout << m_volManager << endl;
-    cout << "++ Volume manager populated and shaped names successfully updated." << endl;
   }
 }
 
@@ -452,15 +311,13 @@ void LCDDImp::fromXML(const string& xmlfile, LCDDBuildType build_type) {
     }
   }
   catch(const XML::XmlException& e)  {
-    cout << "XML-DOM Exception:" << XML::_toString(e.msg) << endl;
-    throw runtime_error("XML-DOM Exception:\""+XML::_toString(e.msg)+"\" while parsing "+xmlfile);
+    throw runtime_error("XML-DOM Exception:\n\""+XML::_toString(e.msg)+
+			"\"\n  while parsing "+xmlfile);
   } 
   catch(const exception& e)  {
-    cout << "Exception:" << e.what() << endl;
-    throw runtime_error("Exception:\""+string(e.what())+"\" while parsing "+xmlfile);
+    throw runtime_error(string(e.what())+"\n           while parsing "+xmlfile);
   }
   catch(...)  {
-    cout << "UNKNOWN Exception" << endl;
     throw runtime_error("UNKNOWN exception while parsing "+xmlfile);
   }
 #endif
diff --git a/DDCore/src/Readout.cpp b/DDCore/src/Readout.cpp
index 3b425a5d28abb1a40f189676bc5e7a9bee15c97c..29b0c5cf7de26e178c0acdd2c25b4f1abe80ea03 100644
--- a/DDCore/src/Readout.cpp
+++ b/DDCore/src/Readout.cpp
@@ -34,7 +34,7 @@ Readout::Readout(const string& nam)
 void Readout::setIDDescriptor(const Ref_t& new_descriptor)  const   {
   if ( isValid() )  {                    // Remember: segmentation is NOT owned by readout structure!
     if ( new_descriptor.isValid() )  {   // Do NOT delete!
-      object<Object>().id = new_descriptor;
+      data<Object>()->id = new_descriptor;
       return;
     }
   }
@@ -67,12 +67,32 @@ Segmentation Readout::segmentation() const  {
   return object<Object>().segmentation;
 }
 
+/// Standard constructor
+Alignment::Object::Object()  {
+  InstanceCount::increment(this);
+}
+
+/// Default destructor
+Alignment::Object::~Object()  {
+  InstanceCount::decrement(this);
+}
+
 /// Initializing constructor to create a new object
 Alignment::Alignment(const LCDD& /* lcdd */, const string& nam)
 {
   assign(new Object(),nam,"alignment");
 }
 
+/// Standard constructor
+Conditions::Object::Object()  {
+  InstanceCount::increment(this);
+}
+
+/// Default destructor
+Conditions::Object::~Object()  {
+  InstanceCount::decrement(this);
+}
+
 /// Initializing constructor to create a new object
 Conditions::Conditions(const LCDD& /* lcdd */, const string& nam)
 {
diff --git a/DDCore/src/Shapes.cpp b/DDCore/src/Shapes.cpp
index e447e0692d0507be288ae625568035114bd586c2..15bd7d971c823eca99e6a30af45ad3c15a588426 100644
--- a/DDCore/src/Shapes.cpp
+++ b/DDCore/src/Shapes.cpp
@@ -178,18 +178,16 @@ ConeSegment& ConeSegment::setDimensions(double dz, double rmin1, double rmax1, d
 /// 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 startPhi, double deltaPhi)
 {
-  //_assign((TGeoTubeSeg*)new TGeoTube(rmin*MM_2_CM,rmax*MM_2_CM,z*MM_2_CM),name,"tube",true);
-  _assign(new TGeoTubeSeg(rmin*MM_2_CM,rmax*MM_2_CM,z*MM_2_CM,RAD_2_DEGREE*startPhi,RAD_2_DEGREE*deltaPhi),name,"tube",true);
-  //MyConeSeg* s = new MyConeSeg();
-  //_assign(s,name,"tube",true);
-  //setDimensions(rmin,rmax,z,startPhi,deltaPhi);
+  //_assign(new TGeoTubeSeg(rmin*MM_2_CM,rmax*MM_2_CM,z*MM_2_CM,RAD_2_DEGREE*startPhi,RAD_2_DEGREE*deltaPhi),name,"tube",true);
+  _assign(new MyConeSeg(),name,"tube",true);
+  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*MM_2_CM,rmax*MM_2_CM,z*MM_2_CM,RAD_2_DEGREE*startPhi,RAD_2_DEGREE*deltaPhi};
-  //double params[] = {z*MM_2_CM,rmin*MM_2_CM,rmax*MM_2_CM,rmin*MM_2_CM,rmax*MM_2_CM,RAD_2_DEGREE*startPhi,RAD_2_DEGREE*deltaPhi};
+  //double params[] = {rmin*MM_2_CM,rmax*MM_2_CM,z*MM_2_CM,RAD_2_DEGREE*startPhi,RAD_2_DEGREE*deltaPhi};
+  double params[] = {z*MM_2_CM,rmin*MM_2_CM,rmax*MM_2_CM,rmin*MM_2_CM,rmax*MM_2_CM,RAD_2_DEGREE*startPhi,RAD_2_DEGREE*deltaPhi};
   _setDimensions(params);
   return *this;
 }
diff --git a/DDCore/src/VolumeManager.cpp b/DDCore/src/VolumeManager.cpp
index 5806159e01225f6294125515a3de965356463a48..a11ae0e1912e7358788e6e96b0c98232260dddee 100644
--- a/DDCore/src/VolumeManager.cpp
+++ b/DDCore/src/VolumeManager.cpp
@@ -66,6 +66,11 @@ namespace {
 	Volume vol = pv.volume();
 	node_chain.push_back(node);
 	elt_nodes.push_back(node);
+#if 0
+	const PlacedVolume::VolIDs::Base& vids = pv.volIDs();
+	for(PlacedVolume::VolIDs::Base::const_iterator i=vids.begin(); i!=vids.end(); ++i)
+	  ids.push_back(*i);
+#endif
 	ids.PlacedVolume::VolIDs::Base::insert(ids.end(),pv.volIDs().begin(),pv.volIDs().end());
 	if ( vol.isSensitive() )  {
 	  SensitiveDetector sd = vol.sensitiveDetector();
diff --git a/DDCore/src/Volumes.cpp b/DDCore/src/Volumes.cpp
index f296a4e7cb2a154531a09b6213e05af4375dea18..e588752ad34073d39d9c2fb9a664e8a0dbb2a1be 100644
--- a/DDCore/src/Volumes.cpp
+++ b/DDCore/src/Volumes.cpp
@@ -262,9 +262,13 @@ PlacedVolume::VolIDs::insert(const string& name, int value)   {
   return make_pair(i,true);
 }
 
+static PlacedVolume::Object* _data(const PlacedVolume& v)  {
+  return dynamic_cast<PlacedVolume::Object*>(v.ptr());
+}
+
 /// Add identifier
 PlacedVolume& PlacedVolume::addPhysVolID(const string& name, int value)   {
-  Object* obj = data<Object>();
+  Object* obj = _data(*this);
   obj->volIDs.push_back(VolID(name,value));
   return *this;
 }
@@ -283,12 +287,12 @@ Volume PlacedVolume::motherVol() const
 
 /// Access to the volume IDs
 const PlacedVolume::VolIDs& PlacedVolume::volIDs() const 
-{  return data<Object>()->volIDs;                                         }
+{  return _data(*this)->volIDs;                                           }
 
 /// String dump
 string PlacedVolume::toString() const {
   stringstream s;
-  Object* obj = data<Object>();
+  Object* obj = _data(*this);
   s << m_element->GetName() << ":  vol='" << m_element->GetVolume()->GetName()
     << "' mat:'" << m_element->GetMatrix()->GetName() << "' volID[" << obj->volIDs.size() << "] ";
   for(VolIDs::const_iterator i=obj->volIDs.begin(); i!=obj->volIDs.end();++i)
@@ -313,7 +317,7 @@ Volume::Object::~Object()  {
 
 /// Accessor to the data part of the Volume
 Volume::Object* _data(const Volume& v) {
-  if ( v.ptr() && v.ptr()->IsA() == TGeoVolume::Class() ) return v.data<Volume::Object>();
+  //if ( v.ptr() && v.ptr()->IsA() == TGeoVolume::Class() ) return v.data<Volume::Object>();
   return dynamic_cast<Volume::Object*>(v.ptr());
 }
 
@@ -350,7 +354,7 @@ static PlacedVolume _addNode(TGeoVolume* par, TGeoVolume* daughter, TGeoMatrix*
     transform->SetName(nam.c_str());
   }
   parent->AddNode(daughter,id,transform);
-  TGeoNodeMatrix* n = dynamic_cast<TGeoNodeMatrix*>(parent->GetNode(id));
+  TGeoNode* n = parent->GetNode(id);
   return PlacedVolume(n);
 }
 
@@ -513,7 +517,10 @@ void Volume::setSensitiveDetector(const SensitiveDetector& obj) const   {
 
 /// Access to the handle to the sensitive detector
 Ref_t Volume::sensitiveDetector() const
-{  return _data(*this)->sens_det;                         }
+{
+  const Object* o = _data(*this);
+  return o->sens_det;                         
+}
 
 /// Accessor if volume is sensitive (ie. is attached to a sensitive detector)
 bool Volume::isSensitive() const
diff --git a/DDCore/src/plugins/StandardPlugins.cpp b/DDCore/src/plugins/StandardPlugins.cpp
index 9c2fcf1c7629a441895365ac33907edde995fd86..d1f3f9c60e82fd236edc0ce966a1bbf704a9a3e9 100644
--- a/DDCore/src/plugins/StandardPlugins.cpp
+++ b/DDCore/src/plugins/StandardPlugins.cpp
@@ -12,6 +12,7 @@
 // Framework include files
 #include "DD4hep/Factories.h"
 #include "DD4hep/LCDD.h"
+#include "../LCDDImp.h"
 
 // ROOT includes
 #include "TGeoManager.h"
@@ -52,3 +53,19 @@ static long load_compact(LCDD& lcdd,int argc,char** argv)    {
 }
 DECLARE_APPLY(DD4hepCompactLoader,load_compact);
 
+static long load_volmgr(LCDD& lcdd,int,char**)    {
+  try {
+    LCDDImp* imp = dynamic_cast<LCDDImp*>(&lcdd);
+    imp->m_volManager = VolumeManager("World", imp->world(), Readout(), VolumeManager::TREE);
+    cout << "++ Volume manager populated and loaded." << endl;
+  }
+  catch(const exception& e)  {
+    throw runtime_error(string(e.what())+"\n"
+			"           while programming VolumeManager. Are your volIDs correct?");
+  }
+  catch(...)  {
+    throw runtime_error("UNKNOWN exception while programming VolumeManager. Are your volIDs correct?");
+  }
+  return 1;
+}
+DECLARE_APPLY(DD4hepVolumeManager,load_volmgr);
diff --git a/DDExamples/ILDExDet/src/compact/ILDExSIT_geo.cpp b/DDExamples/ILDExDet/src/compact/ILDExSIT_geo.cpp
index efb9ddf72b0c2cae40d2afd503740e8c358b32dc..3cae843fdb5e1bb5e59b6748c989f3afe3b341ce 100644
--- a/DDExamples/ILDExDet/src/compact/ILDExSIT_geo.cpp
+++ b/DDExamples/ILDExDet/src/compact/ILDExSIT_geo.cpp
@@ -79,6 +79,7 @@ static Ref_t create_element(LCDD& lcdd, xml_h e, SensitiveDetector sens)  {
    }
   }
   pv = lcdd.pickMotherVolume(sit).placeVolume(assembly);
+  pv.addPhysVolID("system",x_det.id());
   sit.setPlacement(pv);
   return sit;
 }
diff --git a/DDExamples/ILDExDet/src/compact/Tesla_VXD03_geo.cpp b/DDExamples/ILDExDet/src/compact/Tesla_VXD03_geo.cpp
index 583a0065206b37060d59beb38cba618a7ad3b2d7..3ac27c4d8e2e6aa1af13d8f56c631f5488ba245e 100644
--- a/DDExamples/ILDExDet/src/compact/Tesla_VXD03_geo.cpp
+++ b/DDExamples/ILDExDet/src/compact/Tesla_VXD03_geo.cpp
@@ -326,6 +326,7 @@ static Ref_t create_element(LCDD& lcdd, xml_h e, SensitiveDetector sens)  {
 
   assembly.setVisAttributes(lcdd.visAttributes(x_det.visStr()));
   PlacedVolume lpv = motherVol.placeVolume(assembly);
+  lpv.addPhysVolID("system",x_det.id());
   vxd.setPlacement(lpv);
   return vxd;
 }
diff --git a/DDExamples/UtilityApps/src/converter.cpp b/DDExamples/UtilityApps/src/converter.cpp
index c306fc1a36ec39bdd30e498b9e5e13b5ab2b6cb0..66ee4b9944b3d3e142af565ff81fc659fd6981b1 100644
--- a/DDExamples/UtilityApps/src/converter.cpp
+++ b/DDExamples/UtilityApps/src/converter.cpp
@@ -27,6 +27,8 @@ namespace {
       "                                    [Only valid for -compact2vis]             \n"
       "        -destroy        [OPTIONAL]  Force destruction of the LCDD instance    \n"
       "                                    before exiting the application            \n"
+      "        -volmgr         [OPTIONAL]  Load and populate phys.volume manager to  \n"
+      "                                    check the volume ids for duplicates etc.  \n"
 	 << endl;
     exit(EINVAL);
   }
@@ -36,6 +38,7 @@ namespace {
 //______________________________________________________________________________
 int main(int argc,char** argv)  {
   bool ascii = false;
+  bool volmgr = false;
   bool destroy      = false;
   bool compact2lcdd = false;
   bool compact2gdml = false;
@@ -61,6 +64,8 @@ int main(int argc,char** argv)  {
         ascii = true;
       else if ( strncmp(argv[i],"-destroy",2)==0 )
         destroy = true;
+      else if ( strncmp(argv[i],"-volmgr",2)==0 )
+        volmgr = true;
       else
 	usage();
     }
@@ -84,6 +89,7 @@ int main(int argc,char** argv)  {
     run_plugin(lcdd,"DD4hepGeometry2VISASCII",output,&argv[output]);
   else if ( compact2vis )
     run_plugin(lcdd,"DD4hepGeometry2VIS",output,&argv[output]);
+  if ( volmgr  ) run_plugin(lcdd,"DD4hepVolumeManager",0,0);
   if ( destroy ) delete &lcdd;
   return 0;
 }
diff --git a/DDExamples/UtilityApps/src/display.cpp b/DDExamples/UtilityApps/src/display.cpp
index 46eaf350bdd205280619f6fbb278fc2f215f54ee..abb2c9cf7dea41f8d3da0df25350fd9889815da9 100644
--- a/DDExamples/UtilityApps/src/display.cpp
+++ b/DDExamples/UtilityApps/src/display.cpp
@@ -21,6 +21,8 @@ namespace {
       "                                    starting the dispay.                      \n"
       "        -destroy     [OPTIONAL]     Force destruction of the LCDD instance    \n"
       "                                    before exiting the application            \n"
+      "        -volmgr      [OPTIONAL]     Load and populate phys.volume manager to  \n"
+      "                                    check the volume ids for duplicates etc.  \n"
 	 << endl;
     exit(EINVAL);
   }
@@ -28,6 +30,7 @@ namespace {
 
 //______________________________________________________________________________
 int main(int argc,char** argv)  {
+  bool volmgr = false;
   bool dry_run = false, destroy = false;
   vector<char*> geo_files;
   for(int i=1; i<argc;++i) {
@@ -38,6 +41,8 @@ int main(int argc,char** argv)  {
         dry_run = true;
       else if ( strncmp(argv[i],"-destroy",2)==0 )
         destroy = true;
+      else if ( strncmp(argv[i],"-volmgr",2)==0 )
+        volmgr = true;
       else
 	usage();
     }
@@ -51,6 +56,9 @@ int main(int argc,char** argv)  {
   LCDD& lcdd = dd4hep_instance();
   // Load all compact files
   run_plugin(lcdd,"DD4hepCompactLoader",int(geo_files.size()),&geo_files[0]);
+  // Create volume manager and populate it required
+  if ( volmgr  ) run_plugin(lcdd,"DD4hepVolumeManager",0,0);
+
   // Create an interactive ROOT application
   if ( !dry_run ) {
     pair<int, char**> args(0,0);
diff --git a/DDExamples/UtilityApps/src/plugin_runner.cpp b/DDExamples/UtilityApps/src/plugin_runner.cpp
index d5787d2584571ea19c87236ab018a75acb34f489..5c98e619c391334b3f65596132ff6f3886e9caf9 100644
--- a/DDExamples/UtilityApps/src/plugin_runner.cpp
+++ b/DDExamples/UtilityApps/src/plugin_runner.cpp
@@ -18,6 +18,8 @@ namespace {
       "        -input  <file>  [REQUIRED]  Specify input file.                       \n"
       "        -destroy        [OPTIONAL]  Force destruction of the LCDD instance    \n"
       "                                    before exiting the application            \n"
+      "        -volmgr         [OPTIONAL]  Load and populate phys.volume manager to  \n"
+      "                                    check the volume ids for duplicates etc.  \n"
 	 << endl;
     exit(EINVAL);
   }
@@ -26,6 +28,7 @@ namespace {
 //______________________________________________________________________________
 int main(int argc,char** argv)  {
   string plugin;
+  bool volmgr = false;
   bool destroy = false;
   vector<char*> geo_files;
   for(int i=1; i<argc;++i) {
@@ -36,6 +39,8 @@ int main(int argc,char** argv)  {
         plugin = argv[++i];
       else if ( strncmp(argv[i],"-destroy",2)==0 )
         destroy = true;
+      else if ( strncmp(argv[i],"-volmgr",2)==0 )
+        volmgr = true;
       else
 	usage();
     }
@@ -51,6 +56,7 @@ int main(int argc,char** argv)  {
   run_plugin(lcdd,"DD4hepCompactLoader",int(geo_files.size()),&geo_files[0]);
   // Execute plugin
   run_plugin(lcdd,plugin.c_str(),0,0);
+  if ( volmgr  ) run_plugin(lcdd,"DD4hepVolumeManager",0,0);
   if ( destroy ) delete &lcdd;
   return 0;
 }
diff --git a/doc/Volumes.cpp b/doc/Volumes.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b5d3d8116e4045a02d2ca08e91add9171b05f282
--- /dev/null
+++ b/doc/Volumes.cpp
@@ -0,0 +1,395 @@
+// $Id: Volumes.cpp 574 2013-05-17 20:38:31Z markus.frank $
+//====================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+
+// Framework include files
+#include "DD4hep/LCDD.h"
+#include "DD4hep/InstanceCount.h"
+
+// ROOT include files
+#include "TColor.h"
+#include "TGeoShape.h"
+#include "TGeoVolume.h"
+#include "TGeoNode.h"
+#include "TGeoMatrix.h"
+#include "TGeoMedium.h"
+#include "TGeoVoxelFinder.h"
+#include "TGeoShapeAssembly.h"
+
+// C/C++ include files
+#include <climits>
+#include <iostream>
+#include <stdexcept>
+#include <sstream>
+
+using namespace std;
+using namespace DD4hep::Geometry;
+
+/// Default constructor
+PlacedVolume::Object::Object() : refCount(0), magic(0), volIDs() {
+  InstanceCount::increment(this);
+}
+
+/// Copy constructor
+PlacedVolume::Object::Object(const Object& c) : refCount(0), magic(c.magic), volIDs(c.volIDs) {
+  InstanceCount::increment(this);
+}
+
+/// Default destructor
+PlacedVolume::Object::~Object()   {
+  InstanceCount::decrement(this);
+}
+
+/// TGeoExtension overload: Method called whenever requiring a pointer to the extension
+TGeoExtension* PlacedVolume::Object::Grab() const   {
+  Object* ext = const_cast<Object*>(this);
+  ++ext->refCount;
+  return ext;
+}
+
+/// TGeoExtension overload: Method called always when the pointer to the extension is not needed anymore
+void PlacedVolume::Object::Release() const  {
+  Object* ext = const_cast<Object*>(this);
+  --ext->refCount;
+  if ( 0 == ext->refCount ) delete ext;
+}
+
+/// Lookup volume ID
+vector<PlacedVolume::VolID>::const_iterator 
+PlacedVolume::VolIDs::find(const string& name)  const   {
+  for(Base::const_iterator i=this->Base::begin(); i!=this->Base::end(); ++i)  
+    if ( name == (*i).first ) return i;
+  return this->end();
+}
+
+/// Insert a new value into the volume ID container
+std::pair<vector<PlacedVolume::VolID>::iterator,bool> 
+PlacedVolume::VolIDs::insert(const string& name, int value)   {
+  Base::iterator i = this->Base::begin();
+  for(; i!=this->Base::end(); ++i)  
+    if ( name == (*i).first ) break;
+  //
+  if ( i != this->Base::end() ) {
+    return make_pair(i,false);
+  }
+  i = this->Base::insert(this->Base::end(),make_pair(name,value));
+  return make_pair(i,true);
+}
+
+/// Accessor to user structure
+PlacedVolume::Object& PlacedVolume::data() const   {
+  Object* o = (Object*)(ptr()->GetUserExtension());
+  return *o;
+}
+
+/// Add identifier
+PlacedVolume& PlacedVolume::addPhysVolID(const string& name, int value)   {
+  data().volIDs.push_back(VolID(name,value));
+  return *this;
+}
+
+/// Volume material
+Material PlacedVolume::material() const 
+{  return Material::handle_t(m_element ? m_element->GetMedium() : 0);     }
+
+/// Logical volume of this placement
+Volume   PlacedVolume::volume() const 
+{  return Volume::handle_t(m_element ? m_element->GetVolume() : 0);       }
+
+/// Parent volume (envelope)
+Volume PlacedVolume::motherVol() const 
+{  return Volume::handle_t(m_element ? m_element->GetMotherVolume() : 0); }
+
+/// Access to the volume IDs
+const PlacedVolume::VolIDs& PlacedVolume::volIDs() const 
+{  return data().volIDs;                                                  }
+
+/// String dump
+string PlacedVolume::toString() const {
+  stringstream s;
+  Object& obj = data();
+  s << m_element->GetName() << ":  vol='" << m_element->GetVolume()->GetName()
+    << "' mat:'" << m_element->GetMatrix()->GetName() << "' volID[" << obj.volIDs.size() << "] ";
+  for(VolIDs::const_iterator i=obj.volIDs.begin(); i!=obj.volIDs.end();++i)
+    s << (*i).first << "=" << (*i).second << "  ";
+  s << ends;
+  return s.str();
+}
+
+/// Default constructor
+Volume::Object::Object() : refCount(0), magic(0), region(), limits(), vis(), sens_det()  {
+  InstanceCount::increment(this);
+}
+
+/// Default destructor
+Volume::Object::~Object()  {
+  vis.clear();
+  region.clear();
+  limits.clear();
+  sens_det.clear();
+  InstanceCount::decrement(this);
+}
+
+/// TGeoExtension overload: Method called whenever requiring a pointer to the extension
+TGeoExtension* Volume::Object::Grab() const  {
+  Object* ext = const_cast<Object*>(this);
+  ++ext->refCount;
+  return ext;
+}
+
+/// TGeoExtension overload: Method called always when the pointer to the extension is not needed anymore
+void Volume::Object::Release() const  {
+  Object* ext = const_cast<Object*>(this);
+  --ext->refCount;
+  if ( 0 == ext->refCount )   {
+    delete ext;
+  }
+  else  {
+    cout << "Volume::Object::Release::refCount:" << ext->refCount << endl;
+  }
+}
+
+/// Constructor to be used when creating a new geometry tree.
+Volume::Volume(const string& name)    {
+  m_element = new TGeoVolume();
+  m_element->SetName(name.c_str());
+  m_element->SetUserExtension(new Object());
+}
+
+/// Constructor to be used when creating a new geometry tree. Also sets materuial and solid attributes
+Volume::Volume(const string& name, const Solid& s, const Material& m) {
+  m_element = new TGeoVolume(name.c_str(), s.ptr(), m.ptr());
+  m_element->SetUserExtension(new Object());
+}
+
+/// Accessor to user structure
+Volume::Object& Volume::data() const   {
+  Object* o = (Object*)(ptr()->GetUserExtension());
+  return *o;
+}
+
+/// Set the volume's material
+void Volume::setMaterial(const Material& m)  const  {
+  if ( m.isValid() )   {
+    TGeoMedium* medium = m._ptr<TGeoMedium>();
+    if ( medium )  {
+      m_element->SetMedium(medium);
+      return;
+    }
+    throw runtime_error("Volume: Medium "+string(m.name())+" is not registered with geometry manager.");
+  }
+  throw runtime_error("Volume: Attempt to assign invalid material.");
+}
+
+static PlacedVolume _addNode(TGeoVolume* par, TGeoVolume* daughter, TGeoMatrix* transform) {
+  TGeoVolume* parent = par;
+  TObjArray* a = parent->GetNodes();
+  Int_t id = a ? a->GetEntries() : 0;
+  if ( transform && transform != identityTransform() ) {
+    string nam = string(daughter->GetName())+"_placement";
+    transform->SetName(nam.c_str());
+  }
+  parent->AddNode(daughter,id,transform);
+  TGeoNodeMatrix* n = dynamic_cast<TGeoNodeMatrix*>(parent->GetNode(id));
+  PlacedVolume pv(n);
+  pv->SetUserExtension(new PlacedVolume::Object());
+  return pv;
+}
+
+static TGeoTranslation* _translation(const Position& pos) {
+  return new TGeoTranslation("",pos.X()*MM_2_CM,pos.Y()*MM_2_CM,pos.Z()*MM_2_CM);
+}
+
+static TGeoRotation* _rotation(const Rotation& rot) {
+  return new TGeoRotation("",rot.Phi()*RAD_2_DEGREE,rot.Theta()*RAD_2_DEGREE,rot.Psi()*RAD_2_DEGREE);
+}
+
+/// Place daughter volume according to generic Transform3D
+PlacedVolume Volume::placeVolume(const Volume& volume, const Transform3D& tr)  const  {
+  Rotation rot;
+  Position pos;
+  tr.GetDecomposition(rot,pos);
+  return placeVolume(volume,rot,pos);
+}
+
+/// Place translated and rotated daughter volume
+PlacedVolume Volume::placeVolume(const Volume& volume, const Position& pos, const Rotation& rot)  const  {
+  if ( volume.isValid() )   {
+    TGeoCombiTrans* transform = new TGeoCombiTrans("",pos.X()*MM_2_CM,pos.Y()*MM_2_CM,pos.Z()*MM_2_CM,_rotation(rot));
+    return _addNode(m_element,volume,transform);
+  }
+  throw runtime_error("Volume: Attempt to assign an invalid physical volume.");
+}
+
+/// Place daughter volume in rotated and then translated mother coordinate system
+PlacedVolume Volume::placeVolume(const Volume& volume, const Rotation& rot, const Position& pos)  const  {
+  if ( volume.isValid() )   {
+    TGeoHMatrix *trans = new TGeoHMatrix();
+    double t[3];
+    trans->RotateZ(rot.Phi()*RAD_2_DEGREE);
+    trans->RotateY(rot.Theta()*RAD_2_DEGREE);
+    trans->RotateX(rot.Psi()*RAD_2_DEGREE);
+    pos.GetCoordinates(t);
+    trans->SetDx(t[0]*MM_2_CM);
+    trans->SetDy(t[1]*MM_2_CM);
+    trans->SetDz(t[2]*MM_2_CM);
+    return _addNode(m_element,volume,trans);
+  }
+  throw runtime_error("Volume: Attempt to assign an invalid physical volume.");
+}
+
+/// Place un-rotated daughter volume at the given position.
+PlacedVolume Volume::placeVolume(const Volume& volume, const Position& pos)  const  {
+  if ( volume.isValid() )   {
+    return _addNode(m_element,volume,_translation(pos));
+  }
+  throw runtime_error("Volume: Attempt to assign an invalid physical volume.");
+}
+
+/// Place rotated daughter volume. The position is automatically the identity position
+PlacedVolume Volume::placeVolume(const Volume& volume, const Rotation& rot)  const  {
+  if ( volume.isValid() )   {
+    return _addNode(m_element,volume,_rotation(rot));
+  }
+  throw runtime_error("Volume: Attempt to assign an invalid physical volume.");
+}
+
+/// Place daughter volume. The position and rotation are the identity
+PlacedVolume Volume::placeVolume(const Volume& volume, const IdentityPos& /* pos */)  const  {
+  if ( volume.isValid() )   {
+    return _addNode(m_element,volume,identityTransform());
+  }
+  throw runtime_error("Volume: Attempt to assign an invalid physical volume.");
+}
+
+/// Place daughter volume. The position and rotation are the identity
+PlacedVolume Volume::placeVolume(const Volume& volume, const IdentityRot& /* rot */)  const  {
+  if ( volume.isValid() )   {
+    return _addNode(m_element,volume,identityTransform());
+  }
+  throw runtime_error("Volume: Attempt to assign an invalid physical volume.");
+}
+
+/// Set Visualization attributes to the volume
+void Volume::setVisAttributes(const VisAttr& attr) const   {
+  if ( attr.isValid() )  {
+    VisAttr::Object* vis = attr.data<VisAttr::Object>();
+    Color_t bright = TColor::GetColorBright(vis->color);
+    Color_t dark   = TColor::GetColorDark(vis->color);
+    int draw_style = vis->drawingStyle;
+    int line_style = vis->lineStyle;
+    m_element->SetLineColor(dark);
+    if ( draw_style == VisAttr::SOLID )  {
+      m_element->SetFillColor(bright);
+      m_element->SetFillStyle(1001); // Root: solid
+    }
+    else {
+      m_element->SetFillColor(0);
+      m_element->SetFillStyle(0);    // Root: hollow
+    }
+    if ( line_style == VisAttr::SOLID )
+      m_element->SetFillStyle(1);
+    else if ( line_style == VisAttr::DASHED )
+      m_element->SetFillStyle(2);
+    else
+      m_element->SetFillStyle(line_style);
+
+    m_element->SetLineWidth(10);
+    m_element->SetVisibility(vis->visible ? kTRUE : kFALSE);
+    m_element->SetAttBit(TGeoAtt::kVisContainers,kTRUE);
+    m_element->SetVisDaughters(vis->showDaughters ? kTRUE : kFALSE);
+  }
+  data().vis = attr;
+}
+
+/// Set Visualization attributes to the volume
+void Volume::setVisAttributes(const LCDD& lcdd, const string& name)  const {
+  if ( !name.empty() )   {
+    VisAttr attr = lcdd.visAttributes(name);
+    data().vis = attr;
+    setVisAttributes(attr);
+  }
+  else  {
+    /*
+     string tag = this->name();
+     if ( ::strstr(tag.c_str(),"_slice") )       // Slices turned off by default
+     setVisAttributes(lcdd.visAttributes("InvisibleNoDaughters"));
+     else if ( ::strstr(tag.c_str(),"_layer") )  // Layers turned off, but daughters possibly visible
+     setVisAttributes(lcdd.visAttributes("InvisibleWithDaughters"));
+     else if ( ::strstr(tag.c_str(),"_module") ) // Tracker modules similar to layers
+     setVisAttributes(lcdd.visAttributes("InvisibleWithDaughters"));
+     else if ( ::strstr(tag.c_str(),"_module_component") ) // Tracker modules similar to layers
+     setVisAttributes(lcdd.visAttributes("InvisibleNoDaughters"));
+     */
+  }
+}
+
+/// Attach attributes to the volume
+void Volume::setAttributes(const LCDD& lcdd,
+                           const string& region, 
+                           const string& limits, 
+                           const string& vis)   const
+{
+  if ( !region.empty() ) setRegion(lcdd.region(region));
+  if ( !limits.empty() ) setLimitSet(lcdd.limitSet(limits));
+  setVisAttributes(lcdd,vis);
+}
+
+/// Set the volume's solid shape
+void Volume::setSolid(const Solid& solid)  const  
+{  m_element->SetShape(solid);                     }
+
+/// Set the regional attributes to the volume
+void Volume::setRegion(const Region& obj)  const   
+{  data().region = obj;                            }
+
+/// Set the limits to the volume
+void Volume::setLimitSet(const LimitSet& obj)  const   
+{  data().limits = obj;                            }
+
+/// Assign the sensitive detector structure
+void Volume::setSensitiveDetector(const SensitiveDetector& obj) const   {
+  //cout << "Setting sensitive detector '" << obj.name() << "' to volume:" << ptr() << " " << name() << endl;
+  data().sens_det = obj;                          
+}
+
+/// Access to the handle to the sensitive detector
+Ref_t Volume::sensitiveDetector() const
+{  return data().sens_det;                         }
+
+/// Accessor if volume is sensitive (ie. is attached to a sensitive detector)
+bool Volume::isSensitive() const
+{  return data().sens_det.isValid();               }
+
+/// Access to Solid (Shape)
+Solid Volume::solid() const   
+{  return Solid((*this)->GetShape());              }
+
+/// Access to the Volume material
+Material Volume::material() const   
+{  return Ref_t(m_element->GetMedium());           }
+
+/// Access the visualisation attributes
+VisAttr Volume::visAttributes() const
+{  return data().vis;                              }
+
+/// Access to the handle to the region structure
+Region Volume::region() const   
+{  return data().region;                           }
+
+/// Access to the limit set
+LimitSet Volume::limitSet() const   
+{  return data().limits;                           }
+
+/// Constructor to be used when creating a new geometry tree.
+Assembly::Assembly(const string& name)   {
+  Object* ext = new Object();
+  m_element = new TGeoVolumeAssembly(name.c_str());
+  m_element->SetUserExtension(ext);
+}
+
diff --git a/doc/Volumes.h b/doc/Volumes.h
new file mode 100644
index 0000000000000000000000000000000000000000..c6b5ecaf802ce38e03aeaf9916673936d302b494
--- /dev/null
+++ b/doc/Volumes.h
@@ -0,0 +1,261 @@
+// $Id: Volumes.h 574 2013-05-17 20:38:31Z markus.frank $
+//====================================================================
+//  AIDA Detector description implementation for LCD
+//--------------------------------------------------------------------
+//
+//  Author     : M.Frank
+//
+//====================================================================
+
+#ifndef DD4hep_GEOMETRY_VOLUMES_H
+#define DD4hep_GEOMETRY_VOLUMES_H
+
+// Framework include files
+#include "DD4hep/Handle.h"
+#include "DD4hep/Shapes.h"
+#include "DD4hep/Objects.h"
+
+// C/C++ include files
+#include <map>
+
+// ROOT include file (includes TGeoVolume + TGeoShape)
+#include "TGeoNode.h"
+#include "TGeoExtension.h"
+#include "TGeoPatternFinder.h"
+
+/*
+ *   DD4hep namespace declaration
+ */
+namespace DD4hep {
+  
+  /*
+   *   Geometry namespace declaration
+   */
+  namespace Geometry  {
+    
+    // Forward declarations
+    struct LCDD;
+    struct Region;
+    struct LimitSet;
+    struct Material;
+    struct VisAttr;
+    struct Volume;
+    struct PlacedVolume;
+    struct SensitiveDetector;
+    
+    /** @class PlacedVolume Volume.h  DD4hep/lcdd/Volume.h
+     *  
+     *  @author  M.Frank
+     *  @version 1.0
+     */
+    struct PlacedVolume : Handle<TGeoNodeMatrix> {
+      typedef std::pair<std::string,int> VolID;
+      struct VolIDs : public std::vector<VolID>   {
+	typedef std::vector<VolID> Base;
+        VolIDs() : Base() {}
+	~VolIDs () {}
+	Base::const_iterator find(const std::string& name)  const;
+	std::pair<Base::iterator,bool> insert(const std::string& name, int value);
+      };
+      struct Object : public TGeoExtension  {
+	/// Reference count on object (used to implement Grab/Release)
+	long          refCount;
+	/// Magic word
+        unsigned long magic;
+	/// ID container
+        VolIDs        volIDs;
+	/// Default constructor
+        Object();
+	/// Copy constructor
+	Object(const Object& c);
+	/// Default destructor
+        virtual ~Object();
+	/// Assignment operator
+	Object& operator=(const Object& c) { 
+	  volIDs = c.volIDs;
+	  magic  = c.magic; 
+	  return *this; 
+	}
+	/// TGeoExtension overload: Method called whenever requiring a pointer to the extension
+	virtual TGeoExtension *Grab() const;
+	/// TGeoExtension overload: Method called always when the pointer to the extension is not needed anymore
+	virtual void Release() const;
+      };
+      /// Default constructor
+      PlacedVolume() : Handle<TGeoNodeMatrix>() {}
+      /// Constructor to be used when reading the already parsed DOM tree
+      PlacedVolume(const TGeoNode* e) : Handle<TGeoNodeMatrix>(e) {}
+      /// Copy assignment
+      PlacedVolume(const PlacedVolume& e) : Handle<TGeoNodeMatrix>(e) {}
+      /// Copy assignment from other handle type
+      template <typename T> PlacedVolume(const Handle<T>& e) : Handle<TGeoNodeMatrix>(e) {}
+      /// Assignment operator (must match copy constructor)
+      PlacedVolume& operator=(const PlacedVolume& v) {  m_element=v.m_element;  return *this; }
+
+      /// Accessor to user structure
+      Object& data() const;
+
+      /// Add identifier
+      PlacedVolume& addPhysVolID(const std::string& name, int value);
+      /// Volume material
+      Material material() const;
+      /// Logical volume of this placement
+      Volume   volume() const;
+      /// Parent volume (envelope)
+      Volume motherVol() const;
+      /// Access to the volume IDs
+      const VolIDs& volIDs() const;
+      /// String dump
+      std::string toString() const;
+    };
+    
+    /** @class Volume Volume.h  DD4hep/lcdd/Volume.h
+     *  
+     *  Handle describing a Volume
+     *
+     *  @author  M.Frank
+     *  @version 1.0
+     */
+    struct Volume : public Handle<TGeoVolume>  {
+
+      public:
+      typedef Handle<TGeoVolume> Base;
+      struct Object : public TGeoExtension  {
+	/// Reference count on object (used to implement Grab/Release)
+	long          refCount;
+	/// Magic word
+        unsigned long magic;
+        Region        region;
+        LimitSet      limits;
+        VisAttr       vis;
+        Ref_t         sens_det;
+	/// Default constructor
+        Object();
+	/// Default destructor
+        virtual ~Object();
+	/// Object copy
+	void copy(const Object& c) { 
+	  magic      = c.magic; 
+	  region     = c.region; 
+	  limits     = c.limits; 
+	  vis        = c.vis; 
+	  sens_det   = c.sens_det; 
+	}
+	/// TGeoExtension overload: Method called whenever requiring a pointer to the extension
+	virtual TGeoExtension *Grab() const;
+	/// TGeoExtension overload: Method called always when the pointer to the extension is not needed anymore
+	virtual void Release() const;
+      };
+
+      public:
+      /// Default constructor
+      Volume() : Base(0) {}
+      
+      /// Copy from handle
+      Volume(const Volume& v) : Base(v) {}
+      
+      /// Copy from arbitrary Element
+      template <typename T> Volume(const Handle<T>& v) : Base(v) {}
+      
+      /// Constructor to be used when creating a new geometry tree.
+      Volume(const std::string& name);
+      
+      /// Constructor to be used when creating a new geometry tree. Also sets materuial and solid attributes
+      Volume(const std::string& name, const Solid& s, const Material& m);
+      
+      /// Assignment operator (must match copy constructor)
+      Volume& operator=(const Volume& a) {  m_element=a.m_element;  return *this; }
+
+      /// Accessor to user structure
+      Object& data() const;
+
+      /// Place daughter volume. The position and rotation are the identity
+      PlacedVolume placeVolume(const Volume& vol)  const  
+      { return placeVolume(vol,IdentityPos());                        }
+      /// Place daughter volume according to generic Transform3D
+      PlacedVolume placeVolume(const Volume& volume, const Transform3D& tr)  const;
+      /// Place un-rotated daughter volume at the given position.
+      PlacedVolume placeVolume(const Volume& vol, const Position& pos)  const;
+      /// Place rotated daughter volume. The position is automatically the identity position
+      PlacedVolume placeVolume(const Volume& vol, const Rotation& rot)  const;
+      /// Place rotated and then translated daughter volume
+      PlacedVolume placeVolume(const Volume& vol, const Position& pos, const Rotation& rot)  const;
+      /// Place daughter volume in rotated and then translated mother coordinate system
+      PlacedVolume placeVolume(const Volume& vol, const Rotation& rot, const Position& pos)  const;
+      
+      /// Place daughter volume. The position and rotation are the identity
+      PlacedVolume placeVolume(const Volume& vol, const IdentityPos& pos)  const;
+      /// Place daughter volume. The position and rotation are the identity
+      PlacedVolume placeVolume(const Volume& vol, const IdentityRot& pos)  const;
+      
+      /// Attach attributes to the volume
+      void setAttributes(const LCDD& lcdd,
+                         const std::string& region, 
+                         const std::string& limits, 
+                         const std::string& vis) const;
+      
+      /// Set the regional attributes to the volume
+      void setRegion(const Region& obj)  const;
+      /// Access to the handle to the region structure
+      Region region() const;
+      
+      /// Set the limits to the volume
+      void setLimitSet(const LimitSet& obj)  const;
+      /// Access to the limit set
+      LimitSet limitSet() const;
+
+      /// Set Visualization attributes to the volume
+      void setVisAttributes(const VisAttr& obj) const;
+      /// Set Visualization attributes to the volume
+      void setVisAttributes(const LCDD& lcdd, const std::string& name) const;
+      /// Access the visualisation attributes
+      VisAttr  visAttributes() const;
+      
+      /// Assign the sensitive detector structure
+      void setSensitiveDetector(const SensitiveDetector& obj) const;
+      /// Access to the handle to the sensitive detector
+      Ref_t sensitiveDetector() const;
+      /// Accessor if volume is sensitive (ie. is attached to a sensitive detector)
+      bool isSensitive() const;
+
+      /// Set the volume's solid shape
+      void setSolid(const Solid& s)  const;
+      /// Access to Solid (Shape)
+      Solid solid() const;
+      
+      /// Set the volume's material
+      void setMaterial(const Material& m)  const;
+      /// Access to the Volume material
+      Material material() const;
+      
+      /// Auto conversion to underlying ROOT object
+      operator TGeoVolume*() const     { return m_element; }
+    };
+    
+    /** @class Assembly Volume.h  DD4hep/lcdd/Volume.h
+     *  
+     *  Handle describing a volume assembly
+     *
+     *  @author  M.Frank
+     *  @version 1.0
+     */
+    struct Assembly : public Volume   {
+      /// Default constructor
+      Assembly() : Volume() {}
+      
+      /// Copy from handle
+      Assembly(const Assembly& v) : Volume(v) {}
+      
+      /// Copy from arbitrary Element
+      template <typename T> Assembly(const Handle<T>& v) : Volume(v) {}
+      
+      /// Constructor to be used when creating a new geometry tree.
+      Assembly(const std::string& name);
+
+      /// Assignment operator (must match copy constructor)
+      Assembly& operator=(const Assembly& a) {  m_element=a.m_element;  return *this; }
+    };
+
+  }       /* End namespace Geometry          */
+}         /* End namespace DD4hep            */
+#endif    /* DD4hep_GEOMETRY_VOLUMES_H       */
diff --git a/doc/release.notes b/doc/release.notes
index 1aca76ff0a17b122a32ebe5eeaca484775d86b3b..f035cb5f29edaf8fa6e9149a8c15c1c66ba268c6 100644
--- a/doc/release.notes
+++ b/doc/release.notes
@@ -1,6 +1,47 @@
 DD4hep  ----  Release Notes
 =================================
 
+2013/02/06    Markus Frank
+--------------------------
+  1) Simplyfy inheritance for common objects from TNamed.
+     Use direct inheritance of Object from TNamed rather than hidden 
+     using the Value<a,b> construct.
+  2) Added physical volume manager to simplyfy the detector element 
+     and sensitive detector lookup from a given physical volume.
+     This implies: If the volume manager is instantiated, the readout specifiers
+     MUST be correct. This is in most xml files NOT the case.
+     The "system" field holding the sibdetector-id is MANDATORY!
+     Otherwise you will receive messages like this:
+
+     Exception:SITCollection: This ID descriptor has no field with the name:CellID0
+               while programming VolumeManager. Are your volIDs correct?
+
+  3) To check the volume identification, add argument -volmgr to geoConverter,
+     geoDisplay, etc.
+  4) To trace possible memory leaks:
+     export DD4HEP_TRACE=Yes
+     then run you converter etc. At the end a table is displayed with a "leakage"
+     column, showing how many objects were not deleted.
+     
+     +----------------------------------------------------------------+
+     |   I n s t a n c e   c o u n t e r s   b y    T Y P E I N F O   |
+     +----------+---------+-------------------------------------------+
+     |   Total  | Leaking |      Type identifier                      |
+     +----------+---------+-------------------------------------------+
+     |        13|        0|DD4hep::Geometry::DetElement::Object
+     |         3|        0|DD4hep::Geometry::SensitiveDetector::Object
+     |         3|        0|DD4hep::Geometry::Readout::Object
+     |         1|        0|DD4hep::Geometry::OverlayedField::Object
+     |         1|        0|DD4hep::Geometry::CartesianField::Object
+     ....
+     Ideally the second column only has "0"s. Instances of 1 may be OK (singletons).
+
+  Prenotice:
+     As soon as ROOT v 6.00 is out, we will have to use it!
+     Andrei kindly agreed to implement a few changes to TGeo, which will make 
+     life much easier and the implementation cleaner and less cumbersome.
+
+
  --------
 | v00-01 |
  --------
@@ -8,9 +49,6 @@ DD4hep  ----  Release Notes
     - first beta release...
 
 
-
-
-
 2013/20/03    Markus Frank
 --------------------------
   1) Finished the compact->lcdd converter