diff --git a/DDCore/CMakeLists.txt b/DDCore/CMakeLists.txt
index 4078194af5f33be7f230de5afc97b16e5ee2be59..5d2f73cf5d38e7c794cbde00b896029ebdb3cbd5 100644
--- a/DDCore/CMakeLists.txt
+++ b/DDCore/CMakeLists.txt
@@ -89,7 +89,7 @@ endif()
 dd4hep_add_plugin(DDCorePlugins SOURCES src/plugins/*.cpp USES DDCore)
 
 # This plugins depends on the ROOT GDML readers. Hence, extra library
-IF(TARGET ROOT::Gdml)
+IF(TARGET ROOT::Gdml2)
   dd4hep_print("|++> Found Root::GDML: Creating DDGDMLPlugins")
   dd4hep_add_plugin(DDGDMLPlugins
     SOURCES src/gdml/*.cpp
diff --git a/DDCore/include/DD4hep/DetElement.h b/DDCore/include/DD4hep/DetElement.h
index 2ec476bb210941ecd505a9b5181007ea62647612..909d1ad4d268a7545043b8c4d94d3a0484f26e1d 100644
--- a/DDCore/include/DD4hep/DetElement.h
+++ b/DDCore/include/DD4hep/DetElement.h
@@ -166,7 +166,11 @@ namespace dd4hep {
    *       The access to conditions is exposed via the DetConditions interface.
    *       See dd4hep/DetConditions.h for further details.
    *    -  alignment information.
-   *    .
+   *
+   *  Reflection Note:
+   *    -  Reflecting a detector element is NOT the same as "clone".
+   *       The placed volumes of the reflected detector element and the
+   *       corresponding volumes/shapes have left-handed coordinates!
    *
    *  \author  M.Frank
    *  \version 1.0
@@ -323,6 +327,12 @@ namespace dd4hep {
     /// Clone (Deep copy) the DetElement structure with a new name and new identifier
     DetElement clone(const std::string& new_name, int new_id) const;
 
+    /// Reflect (Deep copy) the DetElement structure with a new name
+    std::pair<DetElement,Volume> reflect(const std::string& new_name) const;
+
+    /// Reflect (Deep copy) the DetElement structure with a new name and new identifier
+    std::pair<DetElement,Volume> reflect(const std::string& new_name, int new_id) const;
+
     /// Add an extension object to the detector element
     void* addExtension(ExtensionEntry* entry) const;
 
diff --git a/DDCore/include/DD4hep/Volumes.h b/DDCore/include/DD4hep/Volumes.h
index d8f2db09222f653abb350e6553dcd51d5db91ead..d227be84b786568140e2d160ccda072c5886326a 100644
--- a/DDCore/include/DD4hep/Volumes.h
+++ b/DDCore/include/DD4hep/Volumes.h
@@ -20,28 +20,15 @@
 
 // C/C++ include files
 #include <map>
+#include <memory>
 
 // ROOT include file (includes TGeoVolume + TGeoShape)
 #include "TGeoNode.h"
 #include "TGeoPatternFinder.h"
 
-#if ROOT_VERSION_CODE > ROOT_VERSION(5,34,9)
 // Recent ROOT versions
 #include "TGeoExtension.h"
 
-#else
-// Older ROOT version
-#define DD4HEP_EMULATE_TGEOEXTENSIONS
-class TGeoExtension : public TObject  {
-public:
-  virtual ~TGeoExtension() {}
-  /// TGeoExtension overload: Method called whenever requiring a pointer to the extension
-  virtual TGeoExtension *Grab() = 0;
-  /// TGeoExtension overload: Method called always when the pointer to the extension is not needed anymore
-  virtual void Release() const = 0;
-};
-#endif
-
 /// Namespace for the AIDA detector description toolkit
 namespace dd4hep {
 
@@ -78,14 +65,13 @@ namespace dd4hep {
     class VolIDs: public std::vector<VolID> {
     public:
       typedef std::vector<VolID> Base;
-      /// Default constructor
-      VolIDs() = default;
-      /// Copy constructor
-      VolIDs(const VolIDs& c) = default;
-      /// Destructor
-      ~VolIDs() {}
-      /// Assignment operator        
-      VolIDs& operator=(const VolIDs& c) = default;
+      using Base::Base;
+      /// Copy operator
+      VolIDs(const VolIDs& copy) = default;
+      /// Move assignment
+      VolIDs& operator=(VolIDs&& copy)  = default;
+      /// Assignment operator
+      VolIDs& operator=(const VolIDs& c)  = default;
       /// Find entry
       std::vector<VolID>::const_iterator find(const std::string& name) const;
       /// Insert new entry
@@ -117,7 +103,7 @@ namespace dd4hep {
     PlacedVolumeExtension(const PlacedVolumeExtension& c);
     /// Default destructor
     virtual ~PlacedVolumeExtension();
-    /// No move assignment
+    /// Move assignment
     PlacedVolumeExtension& operator=(PlacedVolumeExtension&& copy)  {
       magic  = std::move(copy.magic);
       volIDs = std::move(copy.volIDs);
@@ -235,6 +221,8 @@ namespace dd4hep {
     VisAttr             vis;
     /// Reference to the sensitive detector
     Handle<NamedObject> sens_det;
+    /// Reference to the reflected volume (or to the original volume for reflections)
+    Handle<TGeoVolume>  reflected;
     
     /// Default destructor
     virtual ~VolumeExtension();
@@ -243,11 +231,11 @@ namespace dd4hep {
     /// No move
     VolumeExtension(VolumeExtension&& copy) = delete;
     /// No copy
-    VolumeExtension(const VolumeExtension& copy) = delete;
+    VolumeExtension(const VolumeExtension& copy) = default;
     /// No move assignment
     VolumeExtension& operator=(VolumeExtension&& copy) = delete;
     /// No copy assignment
-    VolumeExtension& operator=(const VolumeExtension& copy) = delete;
+    VolumeExtension& operator=(const VolumeExtension& copy) = default;
     /// Copy the object
     void copy(const VolumeExtension& c) {
       magic      = c.magic;
@@ -295,7 +283,8 @@ namespace dd4hep {
     enum  {
       VETO_SIMU     = 1,
       VETO_RECO     = 2,
-      VETO_DISPLAY  = 3
+      VETO_DISPLAY  = 3,
+      REFLECTED     = 10
     };
   public:
     /// Default constructor
@@ -328,6 +317,9 @@ namespace dd4hep {
     /// Check if placement is properly instrumented
     Object* data() const;
 
+    /// Create a reflected volume. The reflected volume has left-handed coordinates
+    Volume reflect()  const;
+    
     /// If we import volumes from external sources, we have to attach the extensions to the tree
     Volume& import();
 
@@ -335,27 +327,27 @@ namespace dd4hep {
     Volume divide(const std::string& divname, int iaxis, int ndiv, double start, double step, int numed = 0, const char* option = "");
     /** Daughter placements with auto-generated copy number for the daughter volume  */
     /// Place daughter volume. The position and rotation are the identity
-    PlacedVolume placeVolume(const Volume& vol) const;
+    PlacedVolume placeVolume(const Volume& volume) const;
     /// Place daughter volume according to a 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;
+    PlacedVolume placeVolume(const Volume& volume, const Position& pos) const;
     /// Place rotated daughter volume. The position is automatically the identity position
-    PlacedVolume placeVolume(const Volume& vol, const RotationZYX& rot) const;
+    PlacedVolume placeVolume(const Volume& volume, const RotationZYX& rot) const;
     /// Place rotated daughter volume. The position is automatically the identity position
-    PlacedVolume placeVolume(const Volume& vol, const Rotation3D& rot) const;
+    PlacedVolume placeVolume(const Volume& volume, const Rotation3D& rot) const;
 
     /** Daughter placements with user supplied copy number for the daughter volume  */
     /// Place daughter volume. The position and rotation are the identity
-    PlacedVolume placeVolume(const Volume& vol, int copy_no) const;
+    PlacedVolume placeVolume(const Volume& volume, int copy_no) const;
     /// Place daughter volume according to a generic Transform3D
     PlacedVolume placeVolume(const Volume& volume, int copy_no, const Transform3D& tr) const;
     /// Place un-rotated daughter volume at the given position.
-    PlacedVolume placeVolume(const Volume& vol, int copy_no, const Position& pos) const;
+    PlacedVolume placeVolume(const Volume& volume, int copy_no, const Position& pos) const;
     /// Place rotated daughter volume. The position is automatically the identity position
-    PlacedVolume placeVolume(const Volume& vol, int copy_no, const RotationZYX& rot) const;
+    PlacedVolume placeVolume(const Volume& volume, int copy_no, const RotationZYX& rot) const;
     /// Place rotated daughter volume. The position is automatically the identity position
-    PlacedVolume placeVolume(const Volume& vol, int copy_no, const Rotation3D& rot) const;
+    PlacedVolume placeVolume(const Volume& volume, int copy_no, const Rotation3D& rot) const;
     /// Parametrized volume implementation
     /** Embedding parametrized daughter placements in a mother volume
      *  @param start  start transormation for the first placement
@@ -390,6 +382,9 @@ namespace dd4hep {
     void setFlagBit(unsigned int bit);
     /// Test the user flag bit
     bool testFlagBit(unsigned int bit)   const;
+
+    /// Test if this volume was reflected
+    bool isReflected()   const;
     
     /// Set the volume's option value
     void setOption(const std::string& opt) const;
diff --git a/DDCore/include/DD4hep/detail/DetectorInterna.h b/DDCore/include/DD4hep/detail/DetectorInterna.h
index 8cdf5509f8bb3f4349ae08006dcea7841a1b4cd5..c383fe225658db292619eda788d49096c7c21b05 100644
--- a/DDCore/include/DD4hep/detail/DetectorInterna.h
+++ b/DDCore/include/DD4hep/detail/DetectorInterna.h
@@ -178,6 +178,8 @@ namespace dd4hep {
     void update(unsigned int tags, void* param);
     /// Revalidate the caches
     void revalidate();
+    /// Reflect all volumes in a DetElement sub-tree and re-attach the placements
+    std::pair<DetElement,Volume> reflect(const std::string& new_name, int new_id);
   };
 
   /// Data class with properties of a detector element
diff --git a/DDCore/include/Parsers/Primitives.h b/DDCore/include/Parsers/Primitives.h
index 2cf0744ad85b61cb9032d4c33089146aff0267ec..7251a07c142ce8d6d89df5c6e6ea3fb919e317c5 100644
--- a/DDCore/include/Parsers/Primitives.h
+++ b/DDCore/include/Parsers/Primitives.h
@@ -21,6 +21,9 @@
 #include <list>
 #include <vector>
 #include <string>
+#if __cplusplus >= 201703 || (__clang__ && __APPLE__)
+#include <string_view>
+#endif
 #include <limits>
 
 #include <typeinfo>
diff --git a/DDCore/include/XML/UnicodeValues.h b/DDCore/include/XML/UnicodeValues.h
index dc35eaa2b18a75e73973ec59f4883b643a532855..a09cb70cdd03a3895dd85867e0acfbe49b0bcf05 100644
--- a/DDCore/include/XML/UnicodeValues.h
+++ b/DDCore/include/XML/UnicodeValues.h
@@ -430,6 +430,7 @@ UNICODE (shapes);
 UNICODE (shield);
 UNICODE (show_daughters);
 UNICODE (showDaughters);
+UNICODE (side);
 UNICODE (size);
 UNICODE (signed);
 UNICODE (skew);
diff --git a/DDCore/src/DetElement.cpp b/DDCore/src/DetElement.cpp
index d42e136f5de010ddf217413927505a8284dbbcd3..89b41922c39c582ee5f8b407a4cbad0dd2f00da7 100644
--- a/DDCore/src/DetElement.cpp
+++ b/DDCore/src/DetElement.cpp
@@ -258,15 +258,11 @@ DetElement DetElement::clone(int flg) const   {
   Object* n = o->clone(o->id, flg);
   n->SetName(o->GetName());
   n->SetTitle(o->GetTitle());
-  return DetElement(n);
+  return n;
 }
 
 DetElement DetElement::clone(const string& new_name) const {
-  Object* o = access();
-  Object* n = o->clone(o->id, COPY_NONE);
-  n->SetName(new_name.c_str());
-  n->SetTitle(o->GetTitle());
-  return DetElement(n);
+  return clone(new_name, access()->id);
 }
 
 DetElement DetElement::clone(const string& new_name, int new_id) const {
@@ -274,7 +270,20 @@ DetElement DetElement::clone(const string& new_name, int new_id) const {
   Object* n = o->clone(new_id, COPY_NONE);
   n->SetName(new_name.c_str());
   n->SetTitle(o->GetTitle());
-  return DetElement(n);
+  return n;
+}
+
+pair<DetElement,Volume> DetElement::reflect(const string& new_name) const {
+  return reflect(new_name, access()->id);
+}
+
+pair<DetElement,Volume> DetElement::reflect(const string& new_name, int new_id) const {
+  if ( placement().isValid() )   {
+    return m_element->reflect(new_name, new_id);
+  }
+  except("DetElement","reflect: Only placed DetElement objects can be reflected: %s",
+         path().c_str());
+  return make_pair(DetElement(),Volume());
 }
 
 /// Access to the ideal physical volume of this detector element
diff --git a/DDCore/src/DetectorImp.cpp b/DDCore/src/DetectorImp.cpp
index ccb1a5ac59a4dd0af1b8028cccf85bce2e9eee36..ece2ef65d4e3c3e4d34e76dc2f5067a171ad39a0 100644
--- a/DDCore/src/DetectorImp.cpp
+++ b/DDCore/src/DetectorImp.cpp
@@ -162,7 +162,7 @@ DetectorImp::DetectorImp(const string& name)
   : TNamed(), DetectorData(), DetectorLoad(this), m_buildType(BUILD_NONE)
 {
 #if ROOT_VERSION_CODE >= ROOT_VERSION(6,20,0)
-  TGeoUnit::setUnitType(TGeoUnit::kTGeant4Units);
+  //TGeoUnit::setUnitType(TGeoUnit::kTGeant4Units);
 #endif
   SetTitle("DD4hep detector description object");
   set_terminate( description_unexpected );
diff --git a/DDCore/src/DetectorInterna.cpp b/DDCore/src/DetectorInterna.cpp
index e7f89d39e133ed41c92fc34b78f00aa8158ee1c0..8b1fdc36cbbf23bc251f6364e0092e92b44917aa 100644
--- a/DDCore/src/DetectorInterna.cpp
+++ b/DDCore/src/DetectorInterna.cpp
@@ -133,6 +133,44 @@ DetElementObject* DetElementObject::clone(int new_id, int flg) const {
   return obj;
 }
 
+/// Reflect all volumes in a DetElement sub-tree and re-attach the placements
+pair<DetElement,Volume> DetElementObject::reflect(const std::string& new_name, int new_id)   {
+  struct ChildMapper  {
+    std::map<TGeoNode*,TGeoNode*> nodes;
+    void match(DetElement de)   {
+      auto i = nodes.find(de.placement().ptr());
+      if ( i == nodes.end() )  {
+        except("DetElement","reflect: Something went wrong when reflecting the source volume!");
+      }
+      de.setPlacement((*i).second);
+      const auto& children = de.children();
+      for(const auto& c : children)
+        match(c.second);
+    }
+    void map(TGeoNode* n1, TGeoNode* n2)   {
+      if ( nodes.find(n1) != nodes.end() )   {
+        TGeoVolume* v1 = n1->GetVolume();
+        TGeoVolume* v2 = n2->GetVolume();
+        nodes.insert(make_pair(n1,n2));
+        for(Int_t i=0; i<v1->GetNdaughters(); ++i)
+          map(v1->GetNode(i), v2->GetNode(i));
+      }
+    }
+  } mapper;
+  DetElement  det(this);
+  DetElement  det_ref   = det.clone(new_name, new_id);
+  Volume      vol       = det.volume();
+  TGeoVolume* vol_det   = vol.ptr();
+  TGeoVolume* vol_ref   = vol.reflect();
+  const auto& childrens = det.children();
+
+  for(Int_t i=0; i<vol_det->GetNdaughters(); ++i)
+    mapper.map(vol_det->GetNode(i), vol_ref->GetNode(i));
+  for(const auto& c : childrens)
+    mapper.match(c.second);
+  return make_pair(det_ref,vol_ref);
+}
+
 /// Access to the world object. Only possible once the geometry is closed.
 World DetElementObject::i_access_world()   {
   if ( !privateWorld.isValid() )  {
diff --git a/DDCore/src/Shapes.cpp b/DDCore/src/Shapes.cpp
index 455c7587dc19dcba9f857cfade8fa9b529e83bfe..c3ba87418abdf7dcb59c37906acf07ab1b803d2e 100644
--- a/DDCore/src/Shapes.cpp
+++ b/DDCore/src/Shapes.cpp
@@ -28,6 +28,7 @@
 #include "TClass.h"
 #include "TGeoMatrix.h"
 #include "TGeoBoolNode.h"
+#include "TGeoScaledShape.h"
 #include "TGeoCompositeShape.h"
 
 using namespace std;
@@ -250,6 +251,15 @@ namespace dd4hep {
         }
         return pars;
       }
+      else if (cl == TGeoScaledShape::Class()) {
+        TGeoScaledShape* sh = (TGeoScaledShape*) shape;
+        TGeoShape*       s_sh = sh->GetShape();
+        const Double_t*  scale = sh->GetScale()->GetScale();
+        vector<double>   pars {scale[0],scale[1],scale[2]};
+        vector<double>   s_pars = get_shape_dimensions(s_sh);
+        for(auto p : s_pars) pars.push_back(p);
+        return pars;
+      }
       else if (cl == TGeoCompositeShape::Class()) {
         Solid solid(shape);
         const TGeoCompositeShape* sh = (const TGeoCompositeShape*) shape;
@@ -584,6 +594,13 @@ namespace dd4hep {
         auto pars = params;
         solid._setDimensions(&pars[0]);
       }
+      else if (cl == TGeoScaledShape::Class()) {
+        TGeoScaledShape* sh = (TGeoScaledShape*) shape;
+        Solid            s_sh(sh->GetShape());
+        sh->GetScale()->SetScale(params[0], params[1], params[2]);
+        auto pars = params;
+        s_sh._setDimensions(&pars[3]);
+      }
       else if (cl == TGeoCompositeShape::Class()) {
         TGeoCompositeShape* sh = (TGeoCompositeShape*) shape;
         TGeoBoolNode* boolean = sh->GetBoolNode();
@@ -736,7 +753,7 @@ namespace dd4hep {
 #endif
       }
       else  {
-        printout(ERROR,"Solid","Failed to access dimensions for shape of type:%s.",
+        printout(ERROR,"Solid","Failed to set dimensions for shape of type:%s.",
                  cl->GetName());
       }
       return;
diff --git a/DDCore/src/VolumeManager.cpp b/DDCore/src/VolumeManager.cpp
index 4a7d7ee6440224a5e6966d8fbeabbbe57cfd10dd..c30cc39277806b6ad1597a7eb382ae312c93ca4c 100644
--- a/DDCore/src/VolumeManager.cpp
+++ b/DDCore/src/VolumeManager.cpp
@@ -132,7 +132,7 @@ namespace dd4hep {
                        parent.name(), pv.volume().name(), sd.ptr());
             }
           }
-          for (Int_t idau = 0, ndau = node->GetNdaughters(); idau < ndau; ++idau) {
+          for (int idau = 0, ndau = node->GetNdaughters(); idau < ndau; ++idau) {
             TGeoNode* daughter = node->GetDaughter(idau);
             PlacedVolume placement(daughter);
             if ( placement.data() ) {
diff --git a/DDCore/src/Volumes.cpp b/DDCore/src/Volumes.cpp
index 492bb47dc9ed0b293e3b2403c30d0bfda2ced186..61afc533f6cb4286fdbd766c61b42d4951e59353 100644
--- a/DDCore/src/Volumes.cpp
+++ b/DDCore/src/Volumes.cpp
@@ -29,6 +29,11 @@
 
 #include "TGeoVoxelFinder.h"
 #include "TGeoShapeAssembly.h"
+#if ROOT_VERSION_CODE >= ROOT_VERSION(6,20,0)
+#include "TGeoReflectionFactory.h"
+#endif
+#include "TGeoScaledShape.h"
+#include "TMap.h"
 
 // C/C++ include files
 #include <climits>
@@ -41,241 +46,6 @@ using namespace std;
 using namespace dd4hep;
 using namespace dd4hep::detail;
 
-#ifdef DD4HEP_EMULATE_TGEOEXTENSIONS
-namespace dd4hep {
-  namespace detail {
-
-    struct DDExtension  {
-      TGeoExtension* m_extension;
-      DDExtension() : m_extension(0) {}
-      DDExtension(const DDExtension& c) : m_extension(0) {
-        if ( c.m_extension ) m_extension = c.m_extension->Grab();
-      }
-      virtual ~DDExtension() {
-        if ( m_extension ) m_extension->Release();
-      }
-      DDExtension& operator=(const DDExtension& c) {
-        if ( this != &c ) SetUserExtension(c.GetUserExtension());
-        return *this;
-      }
-      void SetUserExtension(TGeoExtension *ext)  {
-        if (m_extension) m_extension->Release();
-        m_extension = 0;
-        if (ext) m_extension = ext->Grab();
-      }
-      TGeoExtension* GetUserExtension() const  {
-        return m_extension;
-      }
-    };
-    struct DD_TGeoNodeMatrix : public TGeoNodeMatrix, public DDExtension  {
-    private:
-      DD_TGeoNodeMatrix& operator=(const DD_TGeoNodeMatrix&) { return *this; }
-    public:
-      DD_TGeoNodeMatrix(const TGeoVolume* v, const TGeoMatrix* m)
-        : TGeoNodeMatrix(v, m), DDExtension() {
-        INCREMENT_COUNTER;
-      }
-      DD_TGeoNodeMatrix(const DD_TGeoNodeMatrix& c)
-        : TGeoNodeMatrix(c.GetVolume(), c.GetMatrix()), DDExtension(c) {
-        INCREMENT_COUNTER;
-      }
-      virtual ~DD_TGeoNodeMatrix() {
-        DECREMENT_COUNTER;
-      }
-      virtual TGeoNode *MakeCopyNode() const {
-        TGeoNodeMatrix *node = new DD_TGeoNodeMatrix(*this);
-        node->SetName(this->TGeoNodeMatrix::GetName());
-        // set the mother
-        node->SetMotherVolume(fMother);
-        // set the copy number
-        node->SetNumber(fNumber);
-        // copy overlaps
-        if (fNovlp > 0) {
-          if (fOverlaps) {
-            Int_t *ovlps = new Int_t[fNovlp];
-            memcpy(ovlps, fOverlaps, fNovlp * sizeof(Int_t));
-            node->SetOverlaps(ovlps, fNovlp);
-          }
-          else {
-            node->SetOverlaps(fOverlaps, fNovlp);
-          }
-        }
-        // copy VC
-        if (IsVirtual())
-          node->SetVirtual();
-        return node;
-      }
-    };
-
-    template <class T> struct _VolWrap: public T, public DDExtension {
-    public:
-      _VolWrap(const char* name) : T(name), DDExtension() {
-        INCREMENT_COUNTER;
-      }
-      virtual ~_VolWrap() {
-        DECREMENT_COUNTER;
-      }
-      virtual void AddNode(const TGeoVolume *vol, Int_t copy_no, TGeoMatrix *mat, Option_t* = "") {
-        TGeoMatrix *matrix = mat;
-        if (matrix == 0)
-          matrix = gGeoIdentity;
-        else
-          matrix->RegisterYourself();
-        if (!vol) {
-          this->T::Error("AddNode", "Volume is NULL");
-          return;
-        }
-        if (!vol->IsValid()) {
-          this->T::Error("AddNode", "Won't add node with invalid shape");
-          printf("### invalid volume was : %s\n", vol->GetName());
-          return;
-        }
-        if (!this->T::fNodes)
-          this->T::fNodes = new TObjArray();
-
-        if (this->T::fFinder) {
-          // volume already divided.
-          this->T::Error("AddNode", "Cannot add node %s_%i into divided volume %s", vol->GetName(), copy_no,
-                         this->T::GetName());
-          return;
-        }
-
-        TGeoNodeMatrix *node = new DD_TGeoNodeMatrix(vol, matrix);
-        //node = new TGeoNodeMatrix(vol, matrix);
-        node->SetMotherVolume(this);
-        this->T::fNodes->Add(node);
-        TString name = TString::Format("%s_%d", vol->GetName(), copy_no);
-        if (this->T::fNodes->FindObject(name))
-          this->T::Warning("AddNode", "Volume %s : added node %s with same name", this->T::GetName(), name.Data());
-        node->SetName(name);
-        node->SetNumber(copy_no);
-      }
-    };
-
-    template <> _VolWrap<TGeoVolume>::_VolWrap(const char* name) : TGeoVolume(name,0,0), DDExtension() {
-      INCREMENT_COUNTER;
-    }
-
-    struct TGeoVolumeValue : public _VolWrap<TGeoVolume> {
-      TGeoVolumeValue(const char* name, TGeoShape* s, TGeoMedium* m) : _VolWrap<TGeoVolume>(name) {
-        SetShape(s);
-        SetMedium(m);
-      }
-      virtual ~TGeoVolumeValue() {      }
-      TGeoVolume *_copyVol(TGeoShape *newshape) const {
-        TGeoVolumeValue *vol = new TGeoVolumeValue(this->TGeoVolume::GetName(),newshape,fMedium);
-        if ( m_extension ) vol->m_extension = m_extension->Grab();
-        //vol->copy(*this);
-        return vol;
-      }
-      virtual TGeoVolume* MakeCopyVolume(TGeoShape *newshape) {
-        // make a copy of this volume. build a volume with same name, shape and medium
-        TGeoVolume *vol = _copyVol(newshape);
-        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;
-      }
-      virtual TGeoVolume* CloneVolume() const {
-        TGeoVolume *vol = _copyVol(fShape);
-        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, this->TGeoVolume::TestBit(1 << i));
-
-        // copy field
-        vol->SetField(fField);
-        // Set bits
-        for (i = 0; i < nbits; i++)
-          vol->SetBit(1 << i, this->TGeoVolume::TestBit(1 << i));
-        vol->SetBit(kVolumeClone);
-        // copy nodes
-        //   CloneNodesAndConnect(vol);
-        vol->MakeCopyNodes(this);
-        // if volume is divided, copy finder
-        vol->SetFinder(fFinder);
-        // copy voxels
-        if (fVoxels) {
-          TGeoVoxelFinder *voxels = new TGeoVoxelFinder(vol);
-          vol->SetVoxelFinder(voxels);
-        }
-        // copy option, uid
-        vol->SetOption(fOption);
-        vol->SetNumber(fNumber);
-        vol->SetNtotal(fNtotal);
-        return vol;
-      }
-    };
-
-    struct TGeoVolumeAssemblyValue : public _VolWrap<TGeoVolumeAssembly>  {
-      TGeoVolumeAssemblyValue(const char* name) : _VolWrap<TGeoVolumeAssembly>(name) {
-      }
-      virtual ~TGeoVolumeAssemblyValue() {
-      }
-      TGeoVolume *CloneVolume() const {
-        TGeoVolumeAssemblyValue *vol = new TGeoVolumeAssemblyValue(this->TGeoVolume::GetName());
-        if ( m_extension ) vol->m_extension = m_extension->Grab();
-        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, this->TGeoVolumeAssembly::TestBit(1 << i));
-
-        // copy field
-        vol->SetField(fField);
-        // Set bits
-        for (i = 0; i < nbits; i++)
-          vol->SetBit(1 << i, this->TGeoVolumeAssembly::TestBit(1 << i));
-        vol->SetBit(kVolumeClone);
-        // make copy nodes
-        vol->MakeCopyNodes(this);
-        ((TGeoShapeAssembly*) vol->GetShape())->NeedsBBoxRecompute();
-        // copy voxels
-        if (fVoxels) {
-          TGeoVoxelFinder *voxels = new TGeoVoxelFinder(vol);
-          vol->SetVoxelFinder(voxels);
-        }
-        // copy option, uid
-        vol->SetOption(fOption);
-        vol->SetNumber(fNumber);
-        vol->SetNtotal(fNtotal);
-        return vol;
-      }
-    };
-
-  }
-}
-typedef DD_TGeoNodeMatrix       geo_node_t;
-typedef TGeoVolumeValue         geo_volume_t;
-typedef TGeoVolumeAssemblyValue geo_assembly_t;
-
-template <typename T> static typename T::Object* _userExtension(const T& v)  {
-  typedef typename T::Object O;
-  const DDExtension* p = dynamic_cast<const DDExtension*>(v.ptr());
-  O* o = (O*)(p ? p->GetUserExtension() : 0);
-  return o;
-}
-#else
-
 /*
  *  The section below uses the new ROOT features using user extensions to volumes
  *  and placements. Once this is common, the above mechanism should be thrown away....
@@ -291,7 +61,7 @@ template <typename T> static typename T::Object* _userExtension(const T& v)  {
   O* o = (O*)(v.ptr()->GetUserExtension());
   return o;
 }
-#endif
+
 ClassImp(PlacedVolumeExtension)
 namespace {
   TGeoVolume* _createTGeoVolume(const string& name, TGeoShape* s, TGeoMedium* m)  {
@@ -309,8 +79,25 @@ namespace {
     e->SetUserExtension(new VolumeMulti::Object());
     return e;
   }
+  PlacedVolume::Object* _data(const PlacedVolume& v) {
+    PlacedVolume::Object* o = _userExtension(v);
+    if (o) return o;
+    throw runtime_error("dd4hep: Attempt to access invalid handle of type: PlacedVolume");
+  }
+  /// Accessor to the data part of the Volume
+  Volume::Object* _data(const Volume& v, bool throw_exception = true) {
+    //if ( v.ptr() && v.ptr()->IsA() == TGeoVolume::Class() ) return v.data<Volume::Object>();
+    Volume::Object* o = _userExtension(v);
+    if (o)
+      return o;
+    else if (!throw_exception)
+      return nullptr;
+    throw runtime_error("dd4hep: Attempt to access invalid handle of type: PlacedVolume");
+  }
+
   class VolumeImport   {
   public:
+    /// Callback for simple imports. Simple add a user extension
     void operator()(TGeoVolume* v)   {
       TClass* c = v->IsA();
       if ( !v->GetUserExtension() )   {
@@ -335,7 +122,143 @@ namespace {
         (*this)(pv->GetVolume());
       }
     }
+    /// Callback for clone imports, where the user extension should be copied
+    void operator()(TGeoVolume* new_v, TGeoVolume* old_v, int set_bit)   {
+      if ( !new_v || !old_v )  {
+        except("dd4hep","VolumeImport: ERROR: The refected volume is INVALID!");        
+      }
+      else if ( !old_v->GetUserExtension() )   {
+        except("dd4hep","VolumeImport: ERROR: Reflection of non-dd4hep volume %s",new_v->IsA()->GetName());
+      }
+      else if ( !new_v->GetUserExtension() )   {
+        TClass* c = new_v->IsA();
+        Volume old_vol(old_v);
+        Volume new_vol(new_v);
+        if ( c == geo_volume_t::Class() )  {
+          Volume::Object *new_e, *old_e = (Volume::Object*)_data(old_vol);
+          old_e->reflected = new_v;
+          new_v->SetUserExtension(new_e = new Volume::Object(*old_e)); 
+          new_e->reflected = old_v;
+        }
+        else if  ( c == geo_assembly_t::Class() )  {
+          Assembly::Object *new_e, *old_e = (Assembly::Object*)_data(old_vol);
+          old_e->reflected = new_v;
+          new_v->SetUserExtension(new_e = new Assembly::Object(*old_e));
+          new_e->reflected = old_v;
+        }
+        else if  ( c == TGeoVolumeMulti::Class() )   {
+          VolumeMulti::Object *new_e, *old_e = (VolumeMulti::Object*)_data(old_vol);
+          TGeoVolumeMulti* new_mv = (TGeoVolumeMulti*)new_v;
+          TGeoVolumeMulti* old_mv = (TGeoVolumeMulti*)old_v;
+          new_v->SetUserExtension(new_e = new VolumeMulti::Object(*old_e));
+          old_e->reflected = new_v;
+          new_e->reflected = old_v;
+          for(int i=0, n=new_mv->GetNvolumes(); i<n; ++i)
+            (*this)(new_mv->GetVolume(i), old_mv->GetVolume(i), set_bit);
+        }
+        else
+          except("dd4hep","VolumeImport: Unknown TGeoVolume sub-class: %s",new_v->IsA()->GetName());
+
+        new_vol.setSensitiveDetector(old_vol.sensitiveDetector());
+        new_vol.setVisAttributes(old_vol.visAttributes());
+        new_vol.setLimitSet(old_vol.limitSet());
+        new_vol.setRegion(old_vol.region());
+
+        if ( set_bit >= 0 ) new_vol.setFlagBit(set_bit);
+        for(Int_t i=0; i<new_v->GetNdaughters(); ++i)  {
+          geo_node_t* pv = new_v->GetNode(i);
+          geo_node_t* ov = old_v->GetNode(i);
+          if ( !pv->GetUserExtension() )   {
+            auto* e = (PlacedVolume::Object*)ov->geo_node_t::GetUserExtension();
+            pv->geo_node_t::SetUserExtension(new PlacedVolume::Object(*e));
+          }
+          (*this)(pv->GetVolume(), ov->GetVolume(), set_bit);
+        }
+      }
+    }
   };
+
+  TGeoVolume *MakeReflection(TGeoVolume* v, const char *newname=0)  {
+    static TMap map(100);
+    TGeoVolume *vol = (TGeoVolume*)map.GetValue(v);
+    if (vol) {
+      if (newname && newname[0]) vol->SetName(newname);
+      return vol;
+    }
+    vol = v->CloneVolume();
+    if (!vol) {
+      printout(ERROR,"MakeReflection", "Cannot clone volume %s\n", v->GetName());
+      return nullptr;
+    }
+    map.Add((TObject*)v, vol);
+    if (newname && newname[0]) vol->SetName(newname);
+    delete vol->GetNodes();
+    vol->SetNodes(NULL);
+    vol->SetBit(TGeoVolume::kVolumeImportNodes, kFALSE);
+    v->CloneNodesAndConnect(vol);
+    // The volume is now properly cloned, but with the same shape.
+    // Reflect the shape (if any) and connect it.
+    if (v->GetShape())   {
+      TGeoScale* scale = new TGeoScale( 1., 1.,-1.);
+      TGeoShape *reflected_shape =
+        TGeoScaledShape::MakeScaledShape("", v->GetShape(), scale);
+      vol->SetShape(reflected_shape);
+    }
+    // Reflect the daughters.
+    Int_t nd = vol->GetNdaughters();
+    if (!nd) return vol;
+    TGeoNodeMatrix *node;
+    TGeoMatrix *local, *local_cloned;
+    TGeoVolume *new_vol;
+    if ( !vol->GetFinder() ) {
+      for (Int_t i=0; i<nd; i++) {
+        node = (TGeoNodeMatrix*)vol->GetNode(i);
+        local = node->GetMatrix();
+        //         printf("%s before\n", node->GetName());
+        //         local->Print();
+        Bool_t reflected = local->IsReflection();
+        local_cloned = new TGeoCombiTrans(*local);
+        local_cloned->RegisterYourself();
+        node->SetMatrix(local_cloned);
+        if (!reflected) {
+          // We need to reflect only the translation and propagate to daughters.
+          // H' = Sz * H * Sz
+          local_cloned->ReflectZ(kTRUE,kFALSE);
+          local_cloned->ReflectZ(kFALSE,kFALSE);
+          //            printf("%s after\n", node->GetName());
+          //            node->GetMatrix()->Print();
+          new_vol = MakeReflection(node->GetVolume());
+          node->SetVolume(new_vol);
+          continue;
+        }
+        // The next daughter is already reflected, so reflect on Z everything and stop
+        local_cloned->ReflectZ(kTRUE); // rot + tr
+        //         printf("%s already reflected... After:\n", node->GetName());
+        //         node->GetMatrix()->Print();
+      }
+      if ( vol->GetVoxels() ) vol->GetVoxels()->Voxelize();
+      return vol;
+    }
+    // Volume is divided, so we have to reflect the division.
+    //   printf("   ... divided %s\n", fFinder->ClassName());
+    TGeoPatternFinder *new_finder = v->GetFinder()->MakeCopy(kTRUE);
+    if (!new_finder) {
+      printout(ERROR,"MakeReflection", "Could not copy finder for volume %s", v->GetName());
+      return nullptr;
+    }
+    new_finder->SetVolume(vol);
+    vol->SetFinder(new_finder);
+    TGeoNodeOffset *nodeoff;
+    new_vol = 0;
+    for (Int_t i=0; i<nd; i++) {
+      nodeoff = (TGeoNodeOffset*)vol->GetNode(i);
+      nodeoff->SetFinder(new_finder);
+      new_vol = MakeReflection(nodeoff->GetVolume());
+      nodeoff->SetVolume(new_vol);
+    }
+    return vol;
+  }
+
 }
 
 /// Default constructor
@@ -356,14 +279,16 @@ PlacedVolumeExtension::PlacedVolumeExtension()
 
 /// Default move
 PlacedVolumeExtension::PlacedVolumeExtension(PlacedVolumeExtension&& c)
-  : TGeoExtension(c), magic(move(c.magic)), refCount(0), volIDs(move(c.volIDs)) {
+  : TGeoExtension(c), magic(move(c.magic)), refCount(0), volIDs() {
   INCREMENT_COUNTER;
+  volIDs = move(c.volIDs);
 }
 
 /// Copy constructor
 PlacedVolumeExtension::PlacedVolumeExtension(const PlacedVolumeExtension& c)
-  : TGeoExtension(), magic(c.magic), refCount(0), volIDs(c.volIDs) {
+  : TGeoExtension(), magic(c.magic), refCount(0), volIDs() {
   INCREMENT_COUNTER;
+  volIDs = c.volIDs;
 }
 
 /// Default destructor
@@ -422,12 +347,6 @@ string PlacedVolumeExtension::VolIDs::str()  const   {
   return str.str();
 }
 
-static PlacedVolume::Object* _data(const PlacedVolume& v) {
-  PlacedVolume::Object* o = _userExtension(v);
-  if (o) return o;
-  throw runtime_error("dd4hep: Attempt to access invalid handle of type: PlacedVolume");
-}
-
 /// Check if placement is properly instrumented
 PlacedVolume::Object* PlacedVolume::data() const   {
   PlacedVolume::Object* o = _userExtension(*this);
@@ -540,17 +459,6 @@ void VolumeExtension::Release() const  {
   }
 }
 
-/// Accessor to the data part of the Volume
-Volume::Object* _data(const Volume& v, bool throw_exception = true) {
-  //if ( v.ptr() && v.ptr()->IsA() == TGeoVolume::Class() ) return v.data<Volume::Object>();
-  Volume::Object* o = _userExtension(v);
-  if (o)
-    return o;
-  else if (!throw_exception)
-    return 0;
-  throw runtime_error("dd4hep: Attempt to access invalid handle of type: PlacedVolume");
-}
-
 /// Constructor to be used when creating a new geometry tree.
 Volume::Volume(const string& nam) {
   m_element = _createTGeoVolume(nam,0,0);
@@ -579,6 +487,24 @@ Volume::Object* Volume::data() const   {
   return o;
 }
 
+/// Create a reflected volume. The reflected volume has left-handed coordinates
+Volume Volume::reflect()  const   {
+  if ( m_element )   {
+    VolumeImport imp;
+    string nam = name();
+    nam       += "_refl";
+    Object* o = data();
+    if ( !o->reflected.isValid() )  {
+      TGeoVolume* vol = MakeReflection(m_element, nam.c_str());
+      imp(vol, m_element, Volume::REFLECTED);
+      o->reflected = vol;
+    }
+    return o->reflected;
+  }
+  except("dd4hep","Volume: Attempt to reflect an invalid Volume handle.");
+  return *this;
+}
+
 /// If we import volumes from external sources, we have to attach the extensions to the tree
 Volume& Volume::import()    {
   if ( m_element )   {
@@ -586,7 +512,7 @@ Volume& Volume::import()    {
     imp(m_element);
     return *this;
   }
-  except("dd4hep","Volume: Attempt to import invalid Volume handle.");
+  except("dd4hep","Volume: Attempt to import an invalid Volume handle.");
   return *this;
 }
 
@@ -608,6 +534,11 @@ bool Volume::testFlagBit(unsigned int bit)   const    {
   return false; // Anyhow never called. Only to satisfy the compiler.
 }    
 
+/// Test if this volume was reflected
+bool Volume::isReflected()   const    {
+  return testFlagBit(REFLECTED);
+}
+
 /// Divide volume into subsections (See the ROOT manuloa for details)
 Volume Volume::divide(const std::string& divname, int iaxis, int ndiv,
                       double start, double step, int numed, const char* option)   {
@@ -619,7 +550,13 @@ Volume Volume::divide(const std::string& divname, int iaxis, int ndiv,
     return mvp;
   }
   except("dd4hep","Volume: Attempt to divide an invalid logical volume.");
-  return 0;
+  return nullptr;
+}
+
+Int_t get_copy_number(TGeoVolume* par)    {
+  TObjArray* a = par ? par->GetNodes() : 0;
+  Int_t copy_nr = (a ? a->GetEntries() : 0);
+  return copy_nr;
 }
 
 PlacedVolume _addNode(TGeoVolume* par, TGeoVolume* daughter, int id, TGeoMatrix* transform) {
@@ -630,10 +567,18 @@ PlacedVolume _addNode(TGeoVolume* par, TGeoVolume* daughter, int id, TGeoMatrix*
   if ( !daughter )   {
     except("dd4hep","Volume: Attempt to assign an invalid physical daughter volume.");
   }
-  if (transform && transform != detail::matrix::_identity()) {
+  if ( !transform )   {
+    except("dd4hep","Volume: Attempt to place volume without placement matrix.");
+  }
+  if ( transform != detail::matrix::_identity() ) {
     string nam = string(daughter->GetName()) + "_placement";
     transform->SetName(nam.c_str());
   }
+#if 0
+  if ( transform->IsTranslation() ) {
+    cout << daughter->GetName() << ": Translation: " << transform->GetTranslation()[2] << endl;
+  }
+#endif
   TGeoShape* shape = daughter->GetShape();
   // Need to fix the daughter's BBox of assemblies, if the BBox was not calculated....
   if ( shape->IsA() == TGeoShapeAssembly::Class() )  {
@@ -658,40 +603,79 @@ PlacedVolume _addNode(TGeoVolume* par, TGeoVolume* daughter, int id, TGeoMatrix*
   return PlacedVolume(n);
 }
 
-PlacedVolume _addNode(TGeoVolume* par, TGeoVolume* daughter, TGeoMatrix* transform) {
-  TObjArray* a = par ? par->GetNodes() : 0;
-  Int_t id = (a ? a->GetEntries() : 0);
-  return _addNode(par, daughter, id, transform);
+PlacedVolume _addNode(TGeoVolume* par, Volume daughter, int copy_nr, const Rotation3D& rot3D)   {
+  Position   x,y,z;
+  Rotation3D rot = rot3D;
+  rot.GetComponents(x,y,z);
+  bool left_handed = (x.Cross(y)).Dot(z) < 0;
+  if ( left_handed )    {
+    // The reflected volume already scales Z with -1 to be left-handed
+    // We have to accomplish for and undo this when placing the volume
+    rot *= Rotation3D(1., 0., 0., 0., 1., 0., 0., 0., -1.);
+    daughter = daughter.reflect();
+    //cout << "REFLECTION: (x.Cross(y)).Dot(z) " << (x.Cross(y)).Dot(z) << endl;
+  }
+  double elements[9];
+  rot3D.GetComponents(elements);
+  auto r = new TGeoRotation();
+  r->SetMatrix(elements);
+  auto m = new TGeoCombiTrans(); 
+  m->SetRotation(r);
+  return _addNode(par, daughter, copy_nr, m);
+}
+
+PlacedVolume _addNode(TGeoVolume* par, Volume daughter, int copy_nr, const Transform3D& tr)   {
+  Position   x, y, z, pos3D;
+  Rotation3D rot3D;
+  tr.GetRotation(rot3D);
+  tr.GetTranslation(pos3D);
+  rot3D.GetComponents(x,y,z);
+  bool left_handed = (x.Cross(y)).Dot(z) < 0;
+  if ( left_handed )    {
+    // The reflected volume already scales Z with -1 to be left-handed
+    // We have to accomplish for and undo this when placing the volume
+    rot3D *= Rotation3D(1., 0., 0., 0., 1., 0., 0., 0., -1.);
+    daughter = daughter.reflect();
+    //cout << "REFLECTION: (x.Cross(y)).Dot(z) " << (x.Cross(y)).Dot(z) << endl;
+  }
+  double elements[9];
+  rot3D.GetComponents(elements);
+  auto m = new TGeoCombiTrans();
+  m->SetTranslation(pos3D.x(), pos3D.y(), pos3D.z()); 
+  auto r = new TGeoRotation();
+  r->SetMatrix(elements);
+  m->SetRotation(r);
+  return _addNode(par, daughter, copy_nr, m);
 }
 
 /// Place daughter volume according to generic Transform3D
 PlacedVolume Volume::placeVolume(const Volume& volume, const Transform3D& trans) const {
-  return _addNode(m_element, volume, detail::matrix::_transform(trans));
+  return _addNode(m_element, volume, get_copy_number(m_element), trans);
 }
 
 /// Place daughter volume. The position and rotation are the identity
 PlacedVolume Volume::placeVolume(const Volume& volume) const {
-  return _addNode(m_element, volume, detail::matrix::_identity());
+  return _addNode(m_element, volume, get_copy_number(m_element), detail::matrix::_identity());
 }
 
 /// Place un-rotated daughter volume at the given position.
 PlacedVolume Volume::placeVolume(const Volume& volume, const Position& pos) const {
-  return _addNode(m_element, volume, detail::matrix::_translation(pos));
+  return _addNode(m_element, volume, get_copy_number(m_element), detail::matrix::_translation(pos));
 }
 
 /// Place rotated daughter volume. The position is automatically the identity position
 PlacedVolume Volume::placeVolume(const Volume& volume, const RotationZYX& rot) const {
-  return _addNode(m_element, volume, detail::matrix::_rotationZYX(rot));
+  return _addNode(m_element, volume, get_copy_number(m_element), detail::matrix::_rotationZYX(rot));
 }
 
 /// Place rotated daughter volume. The position is automatically the identity position
 PlacedVolume Volume::placeVolume(const Volume& volume, const Rotation3D& rot) const {
-  return _addNode(m_element, volume, detail::matrix::_rotation3D(rot));
+  return _addNode(m_element, volume, get_copy_number(m_element), rot);
 }
 
 /// Place daughter volume according to generic Transform3D
 PlacedVolume Volume::placeVolume(const Volume& volume, int copy_no, const Transform3D& trans) const {
-  return _addNode(m_element, volume, copy_no, detail::matrix::_transform(trans));
+  return _addNode(m_element, volume, copy_no, trans);
 }
 
 /// Place daughter volume. The position and rotation are the identity
@@ -711,7 +695,7 @@ PlacedVolume Volume::placeVolume(const Volume& volume, int copy_no, const Rotati
 
 /// Place rotated daughter volume. The position is automatically the identity position
 PlacedVolume Volume::placeVolume(const Volume& volume, int copy_no, const Rotation3D& rot) const {
-  return _addNode(m_element, volume, copy_no, detail::matrix::_rotation3D(rot));
+  return _addNode(m_element, volume, copy_no, rot);
 }
 
 /// Constructor to be used when creating a new parametrized volume object
@@ -737,7 +721,7 @@ void Volume::paramVolume1D(const Transform3D& start,
 {
   Transform3D transformation(start);
   for(size_t i=0; i<count; ++i)    {
-    _addNode(m_element, entity, detail::matrix::_transform(transformation));
+    _addNode(m_element, entity, get_copy_number(m_element), detail::matrix::_transform(transformation));
     transformation *= trafo;
   }
 }
@@ -1007,6 +991,14 @@ std::string dd4hep::toStringMesh(PlacedVolume place, int prec)   {
   Solid        sol   = vol.solid();
   stringstream os;
 
+
+  if ( vol->IsA() == TGeoVolumeAssembly::Class() )    {
+    for(Int_t i=0; i<vol->GetNdaughters(); ++i)  {
+      os << toStringMesh(vol->GetNode(i), prec) << endl;
+    }
+    return os.str();
+  }
+
   // Prints shape parameters
   Int_t nvert = 0, nsegs = 0, npols = 0;
   sol->GetMeshNumbers(nvert, nsegs, npols);
@@ -1048,3 +1040,4 @@ std::string dd4hep::toStringMesh(PlacedVolume place, int prec)   {
   delete [] points;
   return os.str();
 }
+
diff --git a/DDCore/src/plugins/ShapePlugins.cpp b/DDCore/src/plugins/ShapePlugins.cpp
index d464456e36ee655f620b122997256c33cb7ce021..64aedbd0a46c543b619d89c8aade458b323eefeb 100644
--- a/DDCore/src/plugins/ShapePlugins.cpp
+++ b/DDCore/src/plugins/ShapePlugins.cpp
@@ -487,41 +487,64 @@ static Handle<TObject> create_BooleanMulti(Detector& description, xml_h element)
 }
 DECLARE_XML_SHAPE(BooleanShape__shape_constructor,create_BooleanMulti)
 
+#include "DD4hep/MatrixHelpers.h"
+#include <TGeoReflectionFactory.h>
+TGeoCombiTrans* createPlacement(const Rotation3D& iRot, const Position& iTrans) {
+  double elements[9];
+  iRot.GetComponents(elements);
+  TGeoRotation r;
+  r.SetMatrix(elements);
+  TGeoTranslation t(iTrans.x(), iTrans.y(), iTrans.z());
+  return new TGeoCombiTrans(t, r);
+}
+
 static Ref_t create_shape(Detector& description, xml_h e, Ref_t /* sens */)  {
-  xml_det_t    x_det  = e;
-  string       name   = x_det.nameStr();
-  xml_comp_t   x_test = x_det.child(xml_tag_t("test"), false);
-  DetElement   det     (name,x_det.id());
-  Assembly     assembly(name);
+  xml_det_t    x_det     = e;
+  string       name      = x_det.nameStr();
+  xml_dim_t    x_reflect = x_det.child(_U(reflect), false);
+  xml_comp_t   x_test    = x_det.child(xml_tag_t("test"), false);
+  DetElement   det         (name,x_det.id());
+  Assembly     assembly    (name);
   PlacedVolume pv;
   int count = 0;
   for ( xml_coll_t itm(e, _U(check)); itm; ++itm, ++count )   {
-    xml_dim_t   x_check = itm;
-    xml_comp_t  shape  (x_check.child(_U(shape)));
-    xml_dim_t   pos    (x_check.child(_U(position), false));
-    xml_dim_t   rot    (x_check.child(_U(rotation), false));
-    Solid       solid  (shape.createShape());
-    Volume      volume (name+_toString(count,"_vol_%d"),solid, description.air());
+    xml_dim_t  x_check = itm;
+    xml_comp_t shape    (x_check.child(_U(shape)));
+    xml_dim_t  pos      (x_check.child(_U(position), false));
+    xml_dim_t  rot      (x_check.child(_U(rotation), false));
+    bool       reflect = x_check.hasChild(_U(reflect));
+    Solid      solid    (shape.createShape());
+    Volume     volume   (name+_toString(count,"_vol_%d"),solid, description.air());
+
+    volume.setVisAttributes(description, x_check.visStr());
+    solid->SetName(shape.typeStr().c_str());
 
     if ( pos.ptr() && rot.ptr() )  {
-      Transform3D trafo(Rotation3D(RotationZYX(rot.z(0),rot.y(0),rot.x(0))),
-                        Position(pos.x(0),pos.y(0),pos.z(0)));
-      pv = assembly.placeVolume(volume,trafo);
+      Rotation3D  rot3D(RotationZYX(rot.z(0),rot.y(0),rot.x(0)));
+      Position    pos3D(pos.x(0),pos.y(0),pos.z(0));
+      Rotation3D  rrot3D(rot3D);
+      if ( reflect )
+        rrot3D = Rotation3D(1., 0., 0., 0., 1., 0., 0., 0., -1.) * rot3D;
+      Transform3D tr(rrot3D, pos3D);
+      pv = assembly.placeVolume(volume,tr);
     }
     else if ( pos.ptr() )  {
       pv = assembly.placeVolume(volume,Position(pos.x(0),pos.y(0),pos.z(0)));
     }
     else if ( rot.ptr() )  {
-      pv = assembly.placeVolume(volume,Rotation3D(RotationZYX(rot.z(0),rot.y(0),rot.x(0))));
+      Rotation3D rot3D(RotationZYX(rot.z(0),rot.y(0),rot.x(0)));
+      if ( reflect )
+        rot3D = Rotation3D(1., 0., 0., 0., 1., 0., 0., 0., -1.) * rot3D;
+      pv = assembly.placeVolume(volume,rot3D);
     }
     else {
       pv = assembly.placeVolume(volume);
     }
-    volume.setVisAttributes(description, x_check.visStr());
+
     if ( x_check.hasAttr(_U(id)) )  {
       pv.addPhysVolID("check",x_check.id());
     }
-    solid->SetName(shape.typeStr().c_str());
+
     printout(INFO,"TestShape","Created successfull shape of type: %s",
              shape.typeStr().c_str());
     bool instance_test = false;
@@ -584,8 +607,40 @@ static Ref_t create_shape(Detector& description, xml_h e, Ref_t /* sens */)  {
                shape.typeStr().c_str(), solid->GetTitle(), "OK");
     }
   }
-  pv = description.worldVolume().placeVolume(assembly);
-  det.setPlacement(pv);
+  if ( x_reflect )   {
+    xml_dim_t   x_pos(x_reflect.child(_U(position), false));
+    xml_dim_t   x_rot(x_reflect.child(_U(rotation), false));
+    DetElement  full_detector(name+"_full",x_det.id());
+    Assembly    full_assembly(name+"_full");
+    RotationZYX refl_rot;
+    Position    refl_pos;
+
+    if ( x_rot ) refl_rot = RotationZYX(x_rot.z(0),x_rot.y(0),x_rot.x(0));
+    if ( x_pos ) refl_pos = Position(x_pos.x(0),x_pos.y(0),x_pos.z(0));
+    Transform3D refl_trafo(Rotation3D(refl_rot),refl_pos);
+
+    /// Place the regular detector
+    pv = full_assembly.placeVolume(assembly);
+    full_detector.add(det);
+    det.setPlacement(pv);
+
+    /// Place reflected object
+    auto reflected = det.reflect(name+"_reflected",x_det.id());
+    pv = full_assembly.placeVolume(reflected.second, refl_trafo);
+    full_detector.add(reflected.first);
+    reflected.first.setPlacement(pv);
+
+    /// Place mother
+    pv = description.worldVolume().placeVolume(full_assembly);
+    full_detector.setPlacement(pv);
+    
+    det = full_detector;
+  }
+  else  {
+    pv = description.worldVolume().placeVolume(assembly);
+    det.setPlacement(pv);
+  }
+
   if ( x_test.ptr() )  {
     string typ = x_test.typeStr();
     const void* argv[] = { &e, &pv, 0};
diff --git a/DDG4/src/Geant4Converter.cpp b/DDG4/src/Geant4Converter.cpp
index 460f9c0b3c181128d5d2b51cb6bd067acc40a4c6..19d2628b90fb8eb0cc4bfd1d18fefd4fac575bac 100644
--- a/DDG4/src/Geant4Converter.cpp
+++ b/DDG4/src/Geant4Converter.cpp
@@ -73,6 +73,7 @@
 #include "G4Ellipsoid.hh"
 #include "G4GenericTrap.hh"
 #include "G4ExtrudedSolid.hh"
+#include "G4ReflectedSolid.hh"
 #include "G4EllipticalTube.hh"
 #include "G4SubtractionSolid.hh"
 #include "G4IntersectionSolid.hh"
@@ -698,7 +699,16 @@ void* Geant4Converter::handleSolid(const string& name, const TGeoShape* shape) c
         vertices.emplace_back(G4TwoVector(vtx_xy[0] * CM_2_MM,vtx_xy[1] * CM_2_MM));
       solid = new G4GenericTrap(name, sh->GetDz() * CM_2_MM, vertices);
     }
-    else if (shape->IsA() == TGeoCompositeShape::Class()) {
+    else if (shape->IsA() == TGeoScaledShape::Class())  {
+      TGeoScaledShape* sh = (TGeoScaledShape*) shape;
+      const double*    vals = sh->GetScale()->GetScale();
+      Solid            s_sh(sh->GetShape());
+      G4VSolid* scaled = (G4VSolid*)handleSolid(s_sh.name(), s_sh.ptr());
+      solid = new G4ReflectedSolid(scaled->GetName() + "_refl",
+                                   scaled, G4Scale3D(vals[0],vals[1],vals[2]));
+      printout(INFO,"G4Shapes","Converting scaled shape from reflection: %s",sh->GetName());
+    }
+    else if (shape->IsA() == TGeoCompositeShape::Class())    {
       const TGeoCompositeShape* sh = (const TGeoCompositeShape*) shape;
       const TGeoBoolNode* boolean = sh->GetBoolNode();
       TGeoBoolNode::EGeoBoolType oper = boolean->GetBooleanOperator();
@@ -851,7 +861,7 @@ void* Geant4Converter::handleVolume(const string& name, const TGeoVolume* volume
     info.g4Volumes[v] = vol;
     printout(lvl, "Geant4Converter", "++ Volume     + %s converted: %p ---> G4: %p", n.c_str(), v, vol);
   }
-  return 0;
+  return nullptr;
 }
 
 /// Dump logical volume in GDML format to output stream
diff --git a/GaudiPluginService/src/PluginServiceV2.cpp b/GaudiPluginService/src/PluginServiceV2.cpp
index 3bad3405316f204613caa8a67e7a2ce409e2128b..f6746d4015c3e86f14a28433147ee4ba6a7f5f11 100644
--- a/GaudiPluginService/src/PluginServiceV2.cpp
+++ b/GaudiPluginService/src/PluginServiceV2.cpp
@@ -153,16 +153,20 @@ namespace Gaudi {
           std::regex  line_format{"^(?:[[:space:]]*(?:(v[0-9]+)::)?([^:]+):(.*[^[:space:]]))?[[:space:]]*(?:#.*)?$"};
           std::smatch m;
 
-          std::string_view search_path = std::getenv( envVar );
+          std::string search_path = std::getenv( envVar );
           if ( !search_path.empty() ) {
             logger().debug( std::string( "searching factories in " ) + envVar );
 
-            std::string_view::size_type start_pos = 0, end_pos = 0;
-            while ( start_pos != std::string_view::npos ) {
+            std::string::size_type start_pos = 0, end_pos = 0;
+            while ( start_pos != std::string::npos ) {
               // correctly handle begin of string or path separator
               if ( start_pos ) ++start_pos;
 
               end_pos = search_path.find( sep, start_pos );
+              if ( end_pos == start_pos )   {
+                start_pos = std::string::npos;
+                continue;
+              }
               fs::path dirName =
 #ifdef USE_BOOST_FILESYSTEM
                   std::string{search_path.substr( start_pos, end_pos - start_pos )};
diff --git a/examples/ClientTests/compact/Check_Shape_Eightpoint_Reflect_Volume.xml b/examples/ClientTests/compact/Check_Shape_Eightpoint_Reflect_Volume.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9f02ddb5378a7e26af4041a6874b7b196f31fb73
--- /dev/null
+++ b/examples/ClientTests/compact/Check_Shape_Eightpoint_Reflect_Volume.xml
@@ -0,0 +1,54 @@
+<lccdd>
+  <includes>
+    <gdmlFile ref="CheckShape.xml"/>
+  </includes>
+
+  <detectors>
+    <detector id="1" name="Shape_Trapezoid" type="DD4hep_TestShape_Creator">
+<a>
+      <check vis="Shape1_vis">
+        <shape type="Trd2" z="30*cm" x1="30*cm" x2="50*cm" y1="15*cm" y2="30*cm"/>
+        <position x="30"  y="30" z="100*cm"/>
+        <rotation x="0."  y="0"  z="0"/>
+      </check>
+      <check vis="Shape2_vis">
+        <shape type="Trd2" z="30*cm" x1="30*cm" x2="50*cm" y1="15*cm" y2="30*cm"/>
+        <position x="30"   y="30" z="-100*cm"/>
+        <rotation x="0."   y="0"  z="0"/>
+        <reflect/>
+      </check>
+      <test  type="DD4hep_Mesh_Verifier" ref="${DD4hepExamplesINSTALL}/examples/ClientTests/ref/Ref_Trapezoid_Reflect_Volume.txt" create="1"/>
+</a>
+      <check vis="Shape1_vis">
+        <shape type="EightPointSolid" dz="30*cm">
+           <vertex x="-30*cm" y="-25*cm"/>
+           <vertex x="-25*cm" y=" 25*cm"/>
+           <vertex x="  5*cm" y=" 25*cm"/>
+           <vertex x=" 25*cm" y="-25*cm"/>
+           <vertex x="-28*cm" y="-23*cm"/>
+           <vertex x="-23*cm" y=" 27*cm"/>
+           <vertex x="-23*cm" y=" 27*cm"/>
+           <vertex x=" 13*cm" y="-27*cm"/>
+        </shape>
+        <position x="0"  y="0" z="100"/>
+        <rotation x="0"  y="0" z="0"/>
+      </check>
+      <check vis="Shape2_vis">
+        <shape type="EightPointSolid" dz="30*cm">
+           <vertex x="-30*cm" y="-25*cm"/>
+           <vertex x="-25*cm" y=" 25*cm"/>
+           <vertex x="  5*cm" y=" 25*cm"/>
+           <vertex x=" 25*cm" y="-25*cm"/>
+           <vertex x="-28*cm" y="-23*cm"/>
+           <vertex x="-23*cm" y=" 27*cm"/>
+           <vertex x="-23*cm" y=" 27*cm"/>
+           <vertex x=" 13*cm" y="-27*cm"/>
+        </shape>
+        <position x="0"  y="0" z="-100"/>
+        <rotation x="0"  y="0" z="0"/>
+        <reflect/>
+      </check>
+
+    </detector>
+  </detectors>
+</lccdd>
diff --git a/examples/ClientTests/compact/Check_Shape_Trapezoid.xml b/examples/ClientTests/compact/Check_Shape_Trapezoid.xml
index e1c1595ecd990e3ed9873f75418f46b42c7c117c..c2f6b751ea1b6fd818d9f213123fb88d1fb4f626 100644
--- a/examples/ClientTests/compact/Check_Shape_Trapezoid.xml
+++ b/examples/ClientTests/compact/Check_Shape_Trapezoid.xml
@@ -7,8 +7,8 @@
     <detector id="1" name="Shape_Trapezoid" type="DD4hep_TestShape_Creator">
       <check vis="Shape1_vis">
         <shape type="Trapezoid" z="30*cm" x1="30*cm" x2="50*cm" y1="15*cm" y2="30*cm"/>
-        <position x="30"  y="30" z="50"/>
-        <rotation x="0"   y="0"  z="0"/>
+        <position x="30*cm"  y="30*cm" z="50*cm"/>
+        <rotation x="0"      y="0"     z="0"/>
       </check>
       <test  type="DD4hep_Mesh_Verifier" ref="${DD4hepExamplesINSTALL}/examples/ClientTests/ref/Ref_Trapezoid.txt" create="CheckShape_create"/>
     </detector>
diff --git a/examples/ClientTests/compact/MiniTel.xml b/examples/ClientTests/compact/MiniTel.xml
index 8e0b0c1b4074dd1959ce8bca1c6e7f5fa989b1a3..388f1ab9eedf9a685bc9e259a0d2d1dc7db99f8c 100644
--- a/examples/ClientTests/compact/MiniTel.xml
+++ b/examples/ClientTests/compact/MiniTel.xml
@@ -42,6 +42,7 @@
       <dimensions z="1*mm" y="10*cm" x="10*cm" />
       <position z="0*mm" y="0*cm" x="0*cm" />
       <module name="pixel" type="MiniTelPixel" material="Silicon" x="6*mm" y="6*mm" z="1*mm" vis="ModVis" alpha="-2.*radian" beta="-2.*radian" gamma="-0.*radian" />
+      <reflect/>
     </detector>
 
     <detector name="MyLHCBdetector2" type="MiniTelPixel" material="Silicon" vis="DetVis" id ="2" sensitive="true" readout="MyLHCBdetector2Hits"  limits="minitel_limits" region="minitel_region">
@@ -49,6 +50,7 @@
       <dimensions z="1*mm" y="10*cm" x="10*cm" />
       <position z="10*mm" y="0*cm" x="0*cm" />
       <module name="pixel" type="MiniTelPixel" material="Silicon" x="6*mm" y="6*mm" z="1*mm" vis="ModVis" alpha="-2.*radian" beta="-2.*radian" gamma="-0.*radian" />
+      <reflect/>
     </detector>
 
     <detector name="MyLHCBdetector3" type="MiniTelPixel" material="Silicon" vis="DetVis" id ="3"  sensitive="true" readout="MyLHCBdetector3Hits" limits="minitel_limits" region="minitel_region">
@@ -56,6 +58,7 @@
       <dimensions z="1*mm" y="10*cm" x="10*cm" />
       <position z="20*mm" y="0*cm" x="0*cm" />
       <module name="pixel" type="MiniTelPixel" material="Silicon" x="6*mm" y="6*mm" z="5*mm" vis="ModVis" alpha="-2.*radian" beta="-2.*radian" gamma="-0.*radian" />
+      <reflect/>
     </detector>
 
 
@@ -64,6 +67,7 @@
       <dimensions z="1*mm" y="10*cm" x="10*cm"/>
       <position z="30*mm" y="0*cm" x="0*cm" />
       <module name="pixel" type="MiniTelPixel" material="Silicon" x="6*mm" y="6*mm" z="21*mm" vis="ModVis" alpha="-2.*radian" beta="-2.*radian" gamma="-0.*radian" />
+      <reflect/>
     </detector>
 
 
@@ -72,6 +76,7 @@
       <dimensions z="1*mm" y="10*cm" x="10*cm"/>
       <position z="40*mm" y="0*cm" x="0*cm" />
       <module name="pixel" type="MiniTelPixel" material="Silicon" x="6*mm" y="6*mm" z="10*mm" vis="ModVis" alpha="-2.*radian" beta="-2.*radian" gamma="-0.*radian" />
+      <reflect/>
     </detector>
 
 
@@ -80,6 +85,7 @@
       <dimensions z="1*mm" y="10*cm" x="10*cm" />
       <position z="50*mm" y="0*cm" x="0*cm" />
       <module name="pixel" type="MiniTelPixel" material="Silicon" x="6*mm" y="6*mm" z="1*mm" vis="ModVis" alpha="-2.*radian" beta="-2.*radian" gamma="-0.*radian" />
+      <reflect/>
     </detector>
 
 
@@ -88,6 +94,7 @@
       <dimensions  z="1*mm" y="10*cm" x="10*cm" />
       <position z="60*mm" y="0*cm" x="0*cm" />
       <module name="pixel" type="MiniTelPixel" material="Silicon" x="6*mm" y="6*mm" z="1*mm" vis="ModVis" alpha="-2.*radian" beta="-2.*radian" gamma="-0.*radian" />
+      <reflect/>
     </detector>
 
 
@@ -96,6 +103,7 @@
       <dimensions  z="1*mm" y="10*cm" x="10*cm" />
       <position z="70*mm" y="0*cm" x="0*cm" />
       <module name="pixel" type="MiniTelPixel" material="Silicon" x="6*mm" y="6*mm" z="1*mm" vis="ModVis" alpha="-2.*radian" beta="-2.*radian" gamma="-0.*radian" />
+      <reflect/>
     </detector>
 
     <detector name="MyLHCBdetector9" type="MiniTelPixel" material="Silicon" vis="DetVis" id ="9"  sensitive="true" readout="MyLHCBdetector9Hits" limits="minitel_limits" region="minitel_region">
@@ -103,6 +111,7 @@
       <dimensions  z="1*mm" y="10*cm" x="10*cm" />
       <position z="80*mm" y="0*cm" x="0*cm" />
       <module name="pixel" type="MiniTelPixel" material="Silicon" x="6*mm" y="6*mm" z="1*mm" vis="ModVis" alpha="-2.*radian" beta="-2.*radian" gamma="-0.*radian" />
+      <reflect/>
     </detector>
 
     <detector name="MyLHCBdetector10" type="MiniTelPixel" material="Silicon" vis="DetVis" id ="10" sensitive="true" readout="MyLHCBdetector10Hits" limits="minitel_limits" region="minitel_region">
@@ -110,6 +119,7 @@
       <dimensions  z="1*mm" y="10*cm" x="10*cm" />
       <position z="90*mm" y="0*cm" x="0*cm" />
       <module name="pixel" type="MiniTelPixel" material="Silicon" x="6*mm" y="6*mm" z="1*mm" vis="ModVis" alpha="-2.*radian" beta="-2.*radian" gamma="-0.*radian" />
+      <reflect/>
     </detector>
   </detectors>
 
@@ -145,43 +155,43 @@
   <readouts>
     <readout name="MyLHCBdetector1Hits">
       <segmentation type="CartesianGridXY" grid_size_x="6*mm" grid_size_y="6*mm" />
-      <id>system:6,x:12:-6,y:24:-6</id>
+      <id>system:6,side:1,x:12:-6,y:24:-6</id>
     </readout>
     <readout name="MyLHCBdetector2Hits">
       <segmentation type="CartesianGridXY" grid_size_x="6*mm" grid_size_y="6*mm" />
-      <id>system:6,x:12:-6,y:24:-6</id>
+      <id>system:6,side:1,x:12:-6,y:24:-6</id>
     </readout>
     <readout name="MyLHCBdetector3Hits">
       <segmentation type="CartesianGridXY" grid_size_x="6*mm" grid_size_y="6*mm" />
-      <id>system:6,x:12:-6,y:24:-6</id>
+      <id>system:6,side:1,x:12:-6,y:24:-6</id>
     </readout>
     <readout name="MyLHCBdetector4Hits">
       <segmentation type="CartesianGridXY" grid_size_x="6*mm" grid_size_y="6*mm" />
-      <id>system:6,x:12:-6,y:24:-6</id>
+      <id>system:6,side:1,x:12:-6,y:24:-6</id>
     </readout>
     <readout name="MyLHCBdetector5Hits">
       <segmentation type="CartesianGridXY" grid_size_x="6*mm" grid_size_y="6*mm" />
-      <id>system:6,x:12:-6,y:24:-6</id>
+      <id>system:6,side:1,x:12:-6,y:24:-6</id>
     </readout>
     <readout name="MyLHCBdetector6Hits">
       <segmentation type="CartesianGridXY" grid_size_x="6*mm" grid_size_y="6*mm" />
-      <id>system:6,x:12:-6,y:24:-6</id>
+      <id>system:6,side:1,x:12:-6,y:24:-6</id>
     </readout>
     <readout name="MyLHCBdetector7Hits">
       <segmentation type="CartesianGridXY" grid_size_x="6*mm" grid_size_y="6*mm" />
-      <id>system:6,x:12:-6,y:24:-6</id>
+      <id>system:6,side:1,x:12:-6,y:24:-6</id>
     </readout>
     <readout name="MyLHCBdetector8Hits">
       <segmentation type="CartesianGridXY" grid_size_x="6*mm" grid_size_y="6*mm" />
-      <id>system:6,x:12:-6,y:24:-6</id>
+      <id>system:6,side:1,x:12:-6,y:24:-6</id>
     </readout>
     <readout name="MyLHCBdetector9Hits">
       <segmentation type="CartesianGridXY" grid_size_x="6*mm" grid_size_y="6*mm" />
-      <id>system:6,x:12:-6,y:24:-6</id>
+      <id>system:6,side:1,x:12:-6,y:24:-6</id>
     </readout>
     <readout name="MyLHCBdetector10Hits">
       <segmentation type="CartesianGridXY" grid_size_x="6*mm" grid_size_y="6*mm" />
-      <id>system:6,x:12:-6,y:24:-6</id>
+      <id>system:6,side:1,x:12:-6,y:24:-6</id>
     </readout>
   </readouts>
 
diff --git a/examples/ClientTests/ref/Ref_Eightpoint_Reflect_Volume.txt b/examples/ClientTests/ref/Ref_Eightpoint_Reflect_Volume.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0df15d900185d3d7f71ee120c502511e177eb9cc
--- /dev/null
+++ b/examples/ClientTests/ref/Ref_Eightpoint_Reflect_Volume.txt
@@ -0,0 +1,22 @@
+ShapeCheck[0] TGeoTrd2         8 Mesh-points:
+TGeoTrd2         Trd2 N(mesh)=8  N(vert)=8  N(seg)=12  N(pols)=6
+TGeoTrd2         0   Local  ( -30.00,  -15.00,  -30.00) Global (   0.00,   15.00,   70.00)
+TGeoTrd2         1   Local  ( -30.00,   15.00,  -30.00) Global (   0.00,   45.00,   70.00)
+TGeoTrd2         2   Local  (  30.00,   15.00,  -30.00) Global (  60.00,   45.00,   70.00)
+TGeoTrd2         3   Local  (  30.00,  -15.00,  -30.00) Global (  60.00,   15.00,   70.00)
+TGeoTrd2         4   Local  ( -50.00,  -30.00,   30.00) Global ( -20.00,    0.00,  130.00)
+TGeoTrd2         5   Local  ( -50.00,   30.00,   30.00) Global ( -20.00,   60.00,  130.00)
+TGeoTrd2         6   Local  (  50.00,   30.00,   30.00) Global (  80.00,   60.00,  130.00)
+TGeoTrd2         7   Local  (  50.00,  -30.00,   30.00) Global (  80.00,    0.00,  130.00)
+TGeoTrd2         Bounding box:  dx=  50.00 dy=  30.00 dz=  30.00 Origin: x=   0.00 y=   0.00 z=   0.00
+ShapeCheck[1] TGeoTrd2         8 Mesh-points:
+TGeoTrd2         Trd2 N(mesh)=8  N(vert)=8  N(seg)=12  N(pols)=6
+TGeoTrd2         0   Local  ( -30.00,  -15.00,  -30.00) Global (   0.00,   45.00, -130.00)
+TGeoTrd2         1   Local  ( -30.00,   15.00,  -30.00) Global (   0.00,   15.00, -130.00)
+TGeoTrd2         2   Local  (  30.00,   15.00,  -30.00) Global (  60.00,   15.00, -130.00)
+TGeoTrd2         3   Local  (  30.00,  -15.00,  -30.00) Global (  60.00,   45.00, -130.00)
+TGeoTrd2         4   Local  ( -50.00,  -30.00,   30.00) Global ( -20.00,   60.00,  -70.00)
+TGeoTrd2         5   Local  ( -50.00,   30.00,   30.00) Global ( -20.00,    0.00,  -70.00)
+TGeoTrd2         6   Local  (  50.00,   30.00,   30.00) Global (  80.00,    0.00,  -70.00)
+TGeoTrd2         7   Local  (  50.00,  -30.00,   30.00) Global (  80.00,   60.00,  -70.00)
+TGeoTrd2         Bounding box:  dx=  50.00 dy=  30.00 dz=  30.00 Origin: x=   0.00 y=   0.00 z=   0.00
diff --git a/examples/ClientTests/src/MiniTel.cpp b/examples/ClientTests/src/MiniTel.cpp
index cc317c74f4c88522a638b47f51191b7938366e8a..3d76b40a9a6e01862413a1a5c1f65d5ce826691c 100644
--- a/examples/ClientTests/src/MiniTel.cpp
+++ b/examples/ClientTests/src/MiniTel.cpp
@@ -79,8 +79,6 @@ static Ref_t create_detector(Detector &description, xml_h e, SensitiveDetector s
 
   Volume motherVol = description.pickMotherVolume(sdet); //the mothers volume of our detector
 
-  PlacedVolume pv;	//struct of Handle giving the volume id(ayto pou 8a kanw volume kai 8a to steilw me setplacement),dld o detector mou
-
   xml_coll_t mi(x_det, _U(module));
   xml_comp_t dtc_mod = mi;	    // considering the module-pixel of the detector
   double pixelX = dtc_mod.x();  // The x dimension of the module
@@ -109,17 +107,29 @@ static Ref_t create_detector(Detector &description, xml_h e, SensitiveDetector s
   }
   Volume m_volume(det_name, Box(dim_x, dim_y, dim_z), mat);	//as parameters it needs name,solid,material
   m_volume.setVisAttributes(description.visAttributes(x_det.visStr()));	//I DONT MIND ABOUT THIS!
-  pv = motherVol.placeVolume(m_volume,Transform3D(Position(det_x,det_y,det_z)));  //det_x,det_y,det_z are the dimensions of the detector in space
-
-  xml_comp_t dtctr = x_det;
+  m_volume.setLimitSet(description,x_det.limitsStr());
   m_volume.setRegion(description,x_det.regionStr());
+  m_volume.setSensitiveDetector(sens);
+
+  PlacedVolume pv1, pv2;
+  pv1 = assembly.placeVolume(m_volume,Transform3D(Position(det_x,det_y,det_z)));  //det_x,det_y,det_z are the dimensions of the detector in space
+  if ( x_det.hasChild(_U(reflect)) )   {
+    /// Reflect in XY-plane
+    pv2 = assembly.placeVolume(m_volume,Transform3D(Rotation3D(1., 0., 0., 0., 1., 0., 0., 0., -1.),
+                                                    Position(det_x,det_y,-det_z)));
+  }
+  xml_comp_t dtctr = x_det;
   if ( dtctr.isSensitive() ) {
-    sens.setType("tracker");
-    pv.addPhysVolID("system",detectors_id);
-    m_volume.setSensitiveDetector(sens);
     // Set volume attributes
-    m_volume.setLimitSet(description,x_det.limitsStr());
+    sens.setType("tracker");
+    pv1.addPhysVolID("system",detectors_id);
+    pv1.addPhysVolID("side",0);
+    if ( pv2.isValid() )  {
+      pv2.addPhysVolID("system",detectors_id);
+      pv2.addPhysVolID("side",1);
+    }
   }
+  auto pv = motherVol.placeVolume(assembly);
   sdet.setPlacement(pv);
   // Support additional test if Detector_InhibitConstants is set to TRUE
   description.constant<double>("world_side");