diff --git a/DDCore/include/DD4hep/Detector.h b/DDCore/include/DD4hep/Detector.h
index 3db7993c79a1a8aa770e8d0683f060077f65cf92..d6e60d6185bcb14b085ebfcc69fc2b73c88c601b 100644
--- a/DDCore/include/DD4hep/Detector.h
+++ b/DDCore/include/DD4hep/Detector.h
@@ -93,7 +93,14 @@ namespace DD4hep {
       typedef Ref_t                            Parent;
       typedef std::map<std::string,DetElement> Children;
       typedef std::vector<PlacedVolume>        Placements;
-
+      
+      enum {
+	COPY_NONE      = 0,
+	COPY_PLACEMENT = 1<<0,
+	COPY_PARENT    = 1<<1,
+	COPY_ALIGNMENT = 1<<2,
+	LAST            
+      } CopyParameters;
       struct Object  {
         unsigned int      magic;
         int               id;
@@ -103,15 +110,16 @@ namespace DD4hep {
         Readout           readout;
         Alignment         alignment;
         Conditions        conditions;
+	PlacedVolume      placement;
         Placements        placements;
 	Parent            parent;
         Children          children;
 	/// Default constructor
         Object();
 	/// Construct new empty object
-	virtual Value<TNamed,Object>* construct(int new_id) const;
+	virtual Value<TNamed,Object>* construct(int new_id, int flag) const;
 	/// Deep object copy to replicate DetElement trees e.g. for reflection
-	virtual void deepCopy(const Object& source, int new_id);
+	virtual void deepCopy(const Object& source, int new_id, int flag);
       };
 
       /// Additional data accessor
@@ -166,10 +174,16 @@ namespace DD4hep {
       /// Assign readout definition
       DetElement&     setReadout(const Readout& readout);
       
+      /// Access to the physical volume of this detector element
+      PlacedVolume    placement() const;
+      /// Set the physical volumes of the detector element
+      DetElement&     setPlacement(const PlacedVolume& volume);
+
       /// Access the physical volumes of the detector element
       Placements      placements() const;
       /// Set the physical volumes of the detector element
       DetElement&     addPlacement(const PlacedVolume& volume);
+
       /// Access to the logical volume of the placements (all daughters have the same!)
       Volume          volume() const;
       
diff --git a/DDCore/src/Detector.cpp b/DDCore/src/Detector.cpp
index c6bba7bcd726c1b5dd443e642d937b433392c8a2..bfe18cdb8862623ca5f9c170fae737991cd9fe47 100644
--- a/DDCore/src/Detector.cpp
+++ b/DDCore/src/Detector.cpp
@@ -17,29 +17,33 @@ using namespace DD4hep::Geometry;
 /// Default constructor
 DetElement::Object::Object()  
   : magic(magic_word()), id(0), combine_hits(0), readout(), 
-    alignment(), placements(), parent(), children()
+    alignment(), placement(), placements(), parent(), children()
 {
 }
 
 /// Construct new empty object
-Value<TNamed,DetElement::Object>* DetElement::Object::construct(int new_id) const {
+Value<TNamed,DetElement::Object>* DetElement::Object::construct(int new_id, int flag) const {
   Value<TNamed,Object>* obj = new Value<TNamed,Object>();
-  obj->deepCopy(*this,new_id);
+  obj->deepCopy(*this,new_id,flag);
   return obj;
 }
 
 /// Deep object copy to replicate DetElement trees e.g. for reflection
-void DetElement::Object::deepCopy(const Object& source, int new_id)  {
+void DetElement::Object::deepCopy(const Object& source, int new_id, int flag)  {
   id           = new_id;
   combine_hits = source.combine_hits;
   readout      = source.readout;
   volume       = source.volume;
   alignment    = Alignment();
   conditions   = Conditions();
-  placements   = Placements();
-  parent       = DetElement();
+  parent       = ((flag&COPY_PARENT)    == COPY_PARENT) ? source.parent : DetElement();
+  placement    = ((flag&COPY_PLACEMENT) == COPY_PLACEMENT) ? source.placement : PlacedVolume();
+
+  placements   = ((flag&COPY_PLACEMENT) == COPY_PLACEMENT) ? source.placements : Placements();
   for(DetElement::Children::const_iterator i=source.children.begin(); i != source.children.end(); ++i) {
-    DetElement child = (*i).second.clone((*i).second->GetName());
+    const DetElement::Object& d = (*i).second._data();
+    const TNamed* pc = (*i).second.ptr();
+    DetElement child(d.construct(d.id,COPY_PLACEMENT|COPY_PARENT),pc->GetName(),pc->GetTitle());
     children.insert(make_pair((*i).first,child));
   }
 }
@@ -129,18 +133,45 @@ DetElement::Placements DetElement::placements() const    {
 
 DetElement DetElement::clone(const string& new_name)  const  {
   if ( isValid() ) {
-    return DetElement(_data().construct(_data().id), new_name, ptr()->GetTitle());
+    return DetElement(_data().construct(_data().id,COPY_NONE), new_name, ptr()->GetTitle());
   }
   throw runtime_error("DetElement::clone: Self is not defined - clone failed! [Invalid Handle]");
 }
 
 DetElement DetElement::clone(const string& new_name, int new_id)  const  {
   if ( isValid() ) {
-    return DetElement(_data().construct(new_id), new_name, ptr()->GetTitle());
+    return DetElement(_data().construct(new_id, COPY_NONE), new_name, ptr()->GetTitle());
   }
   throw runtime_error("DetElement::clone: Self is not defined - clone failed! [Invalid Handle]");
 }
 
+/// Access to the physical volume of this detector element
+PlacedVolume DetElement::placement() const {
+  if ( isValid() ) {
+    Object& o = _data();
+    if ( o.placement.isValid() )  {
+      return o.placement;
+    }
+  }
+  return PlacedVolume();
+}
+
+/// Set the physical volumes of the detector element
+DetElement& DetElement::setPlacement(const PlacedVolume& placement) {
+  if ( isValid() ) {
+    if ( placement.isValid() )  {
+      Object& o = _data();
+      o.placement = placement;
+      o.volume = placement.volume();
+      placement.setDetElement(*this);
+      return *this;
+    }
+    throw runtime_error("DetElement::addPlacement: Placement is not defined [Invalid Handle]");
+  }
+  throw runtime_error("DetElement::addPlacement: Self is not defined [Invalid Handle]");
+}
+
+
 DetElement& DetElement::addPlacement(const PlacedVolume& placement)  {
   if ( isValid() ) {
     if ( placement.isValid() )  {
diff --git a/DDCore/src/Volumes.cpp b/DDCore/src/Volumes.cpp
index de6da0f03363a85086b1b69d9a2a699f7e570e11..76aed073971246e8b4f57c8987aca08c29e39fc3 100644
--- a/DDCore/src/Volumes.cpp
+++ b/DDCore/src/Volumes.cpp
@@ -17,6 +17,9 @@
 #include "TGeoMatrix.h"
 #include "TGeoMedium.h"
 
+#include "TGeoVoxelFinder.h"
+#include "TGeoShapeAssembly.h"
+
 // C/C++ include files
 #include <climits>
 #include <iostream>
@@ -81,12 +84,98 @@ namespace DD4hep  { namespace Geometry  {
     : public _VolWrap<TGeoVolume>, public Volume::Object  {
     Value(const char* name, TGeoShape* s=0, TGeoMedium* m=0) : _VolWrap<TGeoVolume>(name,s,m) {magic = magic_word();}
     virtual ~Value() {}
+    virtual TGeoVolume* MakeCopyVolume(TGeoShape *newshape) {
+      // make a copy of this volume. build a volume with same name, shape and medium
+      TGeoVolume *vol = new Value<TGeoVolume,Volume::Object>(GetName(), newshape, fMedium);
+      vol->SetVisibility(IsVisible());
+      vol->SetLineColor(GetLineColor());
+      vol->SetLineStyle(GetLineStyle());
+      vol->SetLineWidth(GetLineWidth());
+      vol->SetFillColor(GetFillColor());
+      vol->SetFillStyle(GetFillStyle());
+      vol->SetField(fField);
+      if (fFinder) vol->SetFinder(fFinder);
+      CloneNodesAndConnect(vol);
+      ((TObject*)vol)->SetBit(kVolumeClone);
+      return vol;       
+    }
+    TGeoVolume* CloneVolume() const    {
+      TGeoVolume *vol = new Value<TGeoVolume,Volume::Object>(GetName(), fShape, fMedium);
+      Int_t i;
+      // copy volume attributes
+      vol->SetLineColor(GetLineColor());
+      vol->SetLineStyle(GetLineStyle());
+      vol->SetLineWidth(GetLineWidth());
+      vol->SetFillColor(GetFillColor());
+      vol->SetFillStyle(GetFillStyle());
+      // copy other attributes
+      Int_t nbits = 8*sizeof(UInt_t);
+      for (i=0; i<nbits; i++) 
+	vol->SetAttBit(1<<i, TGeoAtt::TestAttBit(1<<i));
+      for (i=14; i<24; i++)
+	vol->SetBit(1<<i, TestBit(1<<i));   
+   
+      // copy field
+      vol->SetField(fField);
+      // Set bits
+      for (i=0; i<nbits; i++) 
+	vol->SetBit(1<<i, TObject::TestBit(1<<i));
+      vol->SetBit(kVolumeClone);   
+      // copy nodes
+      //   CloneNodesAndConnect(vol);
+      vol->MakeCopyNodes(this);   
+      // if volume is divided, copy finder
+      vol->SetFinder(fFinder);
+      // copy voxels
+      TGeoVoxelFinder *voxels = 0;
+      if (fVoxels) {
+	voxels = new TGeoVoxelFinder(vol);
+	vol->SetVoxelFinder(voxels);
+      }   
+      // copy option, uid
+      vol->SetOption(fOption);
+      vol->SetNumber(fNumber);
+      vol->SetNtotal(fNtotal);
+      return vol;
+    }
   };
   
   template <> struct Value<TGeoVolumeAssembly,Assembly::Object> 
     : public _VolWrap<TGeoVolumeAssembly>, public Assembly::Object  {
     Value(const char* name) : _VolWrap<TGeoVolumeAssembly>(name,0,0) {  magic = magic_word(); }
     virtual ~Value() {}
+
+    TGeoVolume *CloneVolume() const    {
+      TGeoVolume *vol = new Value<TGeoVolumeAssembly,Assembly::Object>(GetName());
+      Int_t i;
+      // copy other attributes
+      Int_t nbits = 8*sizeof(UInt_t);
+      for (i=0; i<nbits; i++) 
+	vol->SetAttBit(1<<i, TGeoAtt::TestAttBit(1<<i));
+      for (i=14; i<24; i++)
+	vol->SetBit(1<<i, TestBit(1<<i));   
+   
+      // copy field
+      vol->SetField(fField);
+      // Set bits
+      for (i=0; i<nbits; i++) 
+	vol->SetBit(1<<i, TObject::TestBit(1<<i));
+      vol->SetBit(kVolumeClone);   
+      // make copy nodes
+      vol->MakeCopyNodes(this);
+      ((TGeoShapeAssembly*)vol->GetShape())->NeedsBBoxRecompute();
+      // copy voxels
+      TGeoVoxelFinder *voxels = 0;
+      if (fVoxels) {
+	voxels = new TGeoVoxelFinder(vol);
+	vol->SetVoxelFinder(voxels);
+      }   
+      // copy option, uid
+      vol->SetOption(fOption);
+      vol->SetNumber(fNumber);
+      vol->SetNtotal(fNtotal);
+      return vol;
+    }
   };
 }}