diff --git a/DDCore/include/DD4hep/ConditionDerived.h b/DDCore/include/DD4hep/ConditionDerived.h
index 34d639633a555ba852a8a33a83ba354c74c65d5a..921eec8209644d61d18334840f5d61bbe088f4d0 100644
--- a/DDCore/include/DD4hep/ConditionDerived.h
+++ b/DDCore/include/DD4hep/ConditionDerived.h
@@ -342,6 +342,8 @@ namespace dd4hep {
       ConditionDependency(DetElement de, const std::string& item, std::shared_ptr<ConditionUpdateCall> call);
       /// Initializing constructor used by builder
       ConditionDependency(DetElement de, Condition::itemkey_type item_key, std::shared_ptr<ConditionUpdateCall> call);
+      /// Initializing constructor used by builder
+      ConditionDependency(Condition::detkey_type det_key, Condition::itemkey_type item_key, std::shared_ptr<ConditionUpdateCall> call);
       /// Default constructor
       ConditionDependency();
       /// Access the dependency key
diff --git a/DDCore/include/DD4hep/Shapes.h b/DDCore/include/DD4hep/Shapes.h
index 0d3a9d2afb9b0784286c32244f0699e59b6de034..bb971c72ad4fe11145b558287a2cc817e73b1a4c 100644
--- a/DDCore/include/DD4hep/Shapes.h
+++ b/DDCore/include/DD4hep/Shapes.h
@@ -28,10 +28,8 @@
 #endif
 // ROOT include files
 #include "TGeoCone.h"
-#include "TGeoParaboloid.h"
 #include "TGeoPgon.h"
 #include "TGeoPcon.h"
-#include "TGeoSphere.h"
 #include "TGeoArb8.h"
 #include "TGeoTrd1.h"
 #include "TGeoTrd2.h"
@@ -40,7 +38,9 @@
 #include "TGeoXtru.h"
 #include "TGeoHype.h"
 #include "TGeoTorus.h"
+#include "TGeoSphere.h"
 #include "TGeoHalfSpace.h"
+#include "TGeoParaboloid.h"
 #include "TGeoCompositeShape.h"
 #include "TGeoShapeAssembly.h"
 #ifdef __GNUC__
@@ -65,6 +65,12 @@ namespace dd4hep {
   /// Set the shape dimensions (As for the TGeo shape, but angles in rad rather than degrees)
   void set_shape_dimensions(TGeoShape* shape, const std::vector<double>& params);
 
+  /// Type check of various shapes. Result like dynamic_cast. Compare with python's isinstance(obj,type)
+  template <typename SOLID> bool isInstance(const Handle<TGeoShape>& solid);
+  /// Type check of various shapes. Do not allow for polymorphism. Types must match exactly
+  template <typename SOLID> bool isA(const Handle<TGeoShape>& solid);
+  
+
   ///  Base class for Solid (shape) objects
   /**
    *   Generic handle holding an object of base TGeoShape.
@@ -148,9 +154,6 @@ namespace dd4hep {
   };
   typedef Solid_type<TGeoShape> Solid;
 
-  /// Type check of various shapes.
-  template <typename SOLID> bool instanceOf(const Handle<TGeoShape>& solid);
-  
   /// Class describing a shape-less solid shape
   /**
    *   For any further documentation please see the following ROOT documentation:
@@ -379,16 +382,7 @@ namespace dd4hep {
                                double rmin2, double rmax2,
                                double startPhi = 0.0, double endPhi = 2.0 * M_PI);
   };
-#if 0
-  /// Intermediate class to overcome drawing probles with the TGeoTubeSeg
-  class MyConeSeg: public TGeoConeSeg {
-  public:
-    MyConeSeg() : TGeoConeSeg(0.0,0.0,0.0,0.0,0.0,0.0,0.0) { }
-    virtual ~MyConeSeg() { }
-    double GetRmin() const {        return GetRmin1();      }
-    double GetRmax() const {        return GetRmax1();      }
-  };
-#endif
+
   /// Class describing a tube shape of a section of a tube
   /**
    *   TGeoTube - cylindrical tube class. It takes 3 parameters :
diff --git a/DDCore/src/ConditionDerived.cpp b/DDCore/src/ConditionDerived.cpp
index a96c4daba842fad326d24c2e08fb813297ccecb1..e5401f9d13518a2db178d63eb00b0f1fea83288c 100644
--- a/DDCore/src/ConditionDerived.cpp
+++ b/DDCore/src/ConditionDerived.cpp
@@ -139,6 +139,15 @@ ConditionDependency::ConditionDependency(Condition::key_type  key,
   InstanceCount::increment(this);
 }
 
+/// Initializing constructor
+ConditionDependency::ConditionDependency(Condition::detkey_type det_key,
+                                         Condition::itemkey_type item_key,
+                                         std::shared_ptr<ConditionUpdateCall> call)
+  : m_refCount(0), target(det_key, item_key), callback(std::move(call))
+{
+  InstanceCount::increment(this);
+}
+
 /// Initializing constructor
 ConditionDependency::ConditionDependency(DetElement              de,
                                          Condition::itemkey_type item_key,
@@ -172,7 +181,8 @@ ConditionDependency::ConditionDependency()
 }
 
 /// Default destructor
-ConditionDependency::~ConditionDependency()  {
+ConditionDependency::~ConditionDependency()
+{
   InstanceCount::decrement(this);
 }
 
diff --git a/DDCore/src/Shapes.cpp b/DDCore/src/Shapes.cpp
index c3ba87418abdf7dcb59c37906acf07ab1b803d2e..864c4d3d98cf47d75fb60c369535332d581fdbe5 100644
--- a/DDCore/src/Shapes.cpp
+++ b/DDCore/src/Shapes.cpp
@@ -43,78 +43,137 @@ namespace units = dd4hep;
 
 namespace dd4hep {
   static bool check_shape_type(const Handle<TGeoShape>& solid, const TClass* cl)   {
-    if ( solid.isValid() )   {
-      return solid->IsA() == cl;
-    }
-    return false;
+    return solid.isValid() && solid->IsA() == cl;
   }
 
-  /// Type check of various shapes.
-  template <typename SOLID> bool instanceOf(const Handle<TGeoShape>& solid)   {
-    if ( solid.isValid() )   {
-      return solid->IsA() == SOLID::Object::Class();
-    }
-    return false;
+  /// Type check of various shapes. Result like dynamic_cast. Compare with python's isinstance(obj,type)
+  template <typename SOLID> bool isInstance(const Handle<TGeoShape>& solid)   {
+    return check_shape_type(solid, SOLID::Object::Class());
+  }
+  template bool isInstance<Box>(const Handle<TGeoShape>& solid);
+  template bool isInstance<ShapelessSolid>(const Handle<TGeoShape>& solid);
+  template bool isInstance<HalfSpace>(const Handle<TGeoShape>& solid);
+  template bool isInstance<ConeSegment>(const Handle<TGeoShape>& solid);
+  template bool isInstance<CutTube>(const Handle<TGeoShape>& solid);
+  template bool isInstance<EllipticalTube>(const Handle<TGeoShape>& solid);
+  template bool isInstance<Trap>(const Handle<TGeoShape>& solid);
+  template bool isInstance<Trd1>(const Handle<TGeoShape>& solid);
+  template bool isInstance<Trd2>(const Handle<TGeoShape>& solid);
+  template bool isInstance<Torus>(const Handle<TGeoShape>& solid);
+  template bool isInstance<Sphere>(const Handle<TGeoShape>& solid);
+  template bool isInstance<Paraboloid>(const Handle<TGeoShape>& solid);
+  template bool isInstance<Hyperboloid>(const Handle<TGeoShape>& solid);
+  template bool isInstance<PolyhedraRegular>(const Handle<TGeoShape>& solid);
+  template bool isInstance<Polyhedra>(const Handle<TGeoShape>& solid);
+  template bool isInstance<ExtrudedPolygon>(const Handle<TGeoShape>& solid);
+  template bool isInstance<BooleanSolid>(const Handle<TGeoShape>& solid);
+
+  template <> bool isInstance<Cone>(const Handle<TGeoShape>& solid)  {
+    return check_shape_type(solid, TGeoConeSeg::Class())
+      ||   check_shape_type(solid, TGeoCone::Class());
+  }
+  template <> bool isInstance<Tube>(const Handle<TGeoShape>& solid)  {
+    return check_shape_type(solid, TGeoTubeSeg::Class())
+      ||   check_shape_type(solid, TGeoCtub::Class());
   }
-  template bool instanceOf<Box>(const Handle<TGeoShape>& solid);
-  template bool instanceOf<ShapelessSolid>(const Handle<TGeoShape>& solid);
-  template bool instanceOf<HalfSpace>(const Handle<TGeoShape>& solid);
-  template bool instanceOf<ConeSegment>(const Handle<TGeoShape>& solid);
-  template bool instanceOf<Tube>(const Handle<TGeoShape>& solid);
-  template bool instanceOf<CutTube>(const Handle<TGeoShape>& solid);
-  template bool instanceOf<EllipticalTube>(const Handle<TGeoShape>& solid);
-  template bool instanceOf<Cone>(const Handle<TGeoShape>& solid);
-  template bool instanceOf<Trap>(const Handle<TGeoShape>& solid);
-  template bool instanceOf<Trd1>(const Handle<TGeoShape>& solid);
-  template bool instanceOf<Trd2>(const Handle<TGeoShape>& solid);
-  template bool instanceOf<Torus>(const Handle<TGeoShape>& solid);
-  template bool instanceOf<Sphere>(const Handle<TGeoShape>& solid);
-  template bool instanceOf<Paraboloid>(const Handle<TGeoShape>& solid);
-  template bool instanceOf<Hyperboloid>(const Handle<TGeoShape>& solid);
-  template bool instanceOf<PolyhedraRegular>(const Handle<TGeoShape>& solid);
-  template bool instanceOf<Polyhedra>(const Handle<TGeoShape>& solid);
-  template bool instanceOf<ExtrudedPolygon>(const Handle<TGeoShape>& solid);
-  template bool instanceOf<BooleanSolid>(const Handle<TGeoShape>& solid);
-  template <> bool instanceOf<Polycone>(const Handle<TGeoShape>& solid)   {
+  template <> bool isInstance<Polycone>(const Handle<TGeoShape>& solid)   {
     return check_shape_type(solid, TGeoPcon::Class())
       ||   check_shape_type(solid, TGeoPgon::Class());
   }
-  template <> bool instanceOf<EightPointSolid>(const Handle<TGeoShape>& solid)   {
+  template <> bool isInstance<EightPointSolid>(const Handle<TGeoShape>& solid)   {
     if ( solid.isValid() )   {
       TClass* c = solid->IsA();
-      return c==TGeoTrap::Class() || c==TGeoArb8::Class() || c==TGeoGtra::Class();
+      return c==TGeoArb8::Class() || c==TGeoTrap::Class() || c==TGeoGtra::Class();
     }
     return false;
   }
-  template <> bool instanceOf<TruncatedTube>(const Handle<TGeoShape>& solid)   {
+  template <> bool isInstance<TruncatedTube>(const Handle<TGeoShape>& solid)   {
     if ( solid.isValid() )   {
       return solid->IsA() == TGeoCompositeShape::Class()
         &&   ::strcmp(solid->GetTitle(), TRUNCATEDTUBE_TAG) == 0;
     }
     return false;
   }
-  template <> bool instanceOf<PseudoTrap>(const Handle<TGeoShape>& solid)   {
+  template <> bool isInstance<PseudoTrap>(const Handle<TGeoShape>& solid)   {
     if ( solid.isValid() )   {
       return solid->IsA() == TGeoCompositeShape::Class()
         &&   ::strcmp(solid->GetTitle(), PSEUDOTRAP_TAG) == 0;
     }
     return false;
   }
-  template <> bool instanceOf<SubtractionSolid>(const Handle<TGeoShape>& solid)   {
+  template <> bool isInstance<SubtractionSolid>(const Handle<TGeoShape>& solid)   {
     TGeoCompositeShape* sh = (TGeoCompositeShape*)solid.ptr();
     return sh && sh->IsA() == TGeoCompositeShape::Class()
       &&   sh->GetBoolNode()->GetBooleanOperator() == TGeoBoolNode::kGeoSubtraction;
   }
-  template <> bool instanceOf<UnionSolid>(const Handle<TGeoShape>& solid)   {
+  template <> bool isInstance<UnionSolid>(const Handle<TGeoShape>& solid)   {
     TGeoCompositeShape* sh = (TGeoCompositeShape*)solid.ptr();
     return sh && sh->IsA() == TGeoCompositeShape::Class()
       &&   sh->GetBoolNode()->GetBooleanOperator() == TGeoBoolNode::kGeoUnion;
   }
-  template <> bool instanceOf<IntersectionSolid>(const Handle<TGeoShape>& solid)   {
+  template <> bool isInstance<IntersectionSolid>(const Handle<TGeoShape>& solid)   {
     TGeoCompositeShape* sh = (TGeoCompositeShape*)solid.ptr();
     return sh && sh->IsA() == TGeoCompositeShape::Class()
       &&   sh->GetBoolNode()->GetBooleanOperator() == TGeoBoolNode::kGeoIntersection;
   }
+
+  /// Type check of various shapes. Do not allow for polymorphism. Types must match exactly
+  template <typename SOLID> bool isA(const Handle<TGeoShape>& solid)   {
+    return check_shape_type(solid, SOLID::Object::Class());
+  }
+  template bool isA<Box>(const Handle<TGeoShape>& solid);
+  template bool isA<ShapelessSolid>(const Handle<TGeoShape>& solid);
+  template bool isA<HalfSpace>(const Handle<TGeoShape>& solid);
+  template bool isA<Cone>(const Handle<TGeoShape>& solid);
+  template bool isA<ConeSegment>(const Handle<TGeoShape>& solid);
+  template bool isA<Tube>(const Handle<TGeoShape>& solid);
+  template bool isA<CutTube>(const Handle<TGeoShape>& solid);
+  template bool isA<EllipticalTube>(const Handle<TGeoShape>& solid);
+  template bool isA<Trap>(const Handle<TGeoShape>& solid);
+  template bool isA<Trd1>(const Handle<TGeoShape>& solid);
+  template bool isA<Trd2>(const Handle<TGeoShape>& solid);
+  template bool isA<Torus>(const Handle<TGeoShape>& solid);
+  template bool isA<Sphere>(const Handle<TGeoShape>& solid);
+  template bool isA<Paraboloid>(const Handle<TGeoShape>& solid);
+  template bool isA<Hyperboloid>(const Handle<TGeoShape>& solid);
+  template bool isA<PolyhedraRegular>(const Handle<TGeoShape>& solid);
+  template bool isA<Polyhedra>(const Handle<TGeoShape>& solid);
+  template bool isA<ExtrudedPolygon>(const Handle<TGeoShape>& solid);
+  template bool isA<Polycone>(const Handle<TGeoShape>& solid);
+  template bool isA<EightPointSolid>(const Handle<TGeoShape>& solid);
+
+  template <> bool isA<TruncatedTube>(const Handle<TGeoShape>& solid)   {
+    if ( solid.isValid() )   {
+      return solid->IsA() == TGeoCompositeShape::Class()
+        &&   ::strcmp(solid->GetTitle(), TRUNCATEDTUBE_TAG) == 0;
+    }
+    return false;
+  }
+  template <> bool isA<PseudoTrap>(const Handle<TGeoShape>& solid)   {
+    if ( solid.isValid() )   {
+      return solid->IsA() == TGeoCompositeShape::Class()
+        &&   ::strcmp(solid->GetTitle(), PSEUDOTRAP_TAG) == 0;
+    }
+    return false;
+  }
+  template <> bool isA<SubtractionSolid>(const Handle<TGeoShape>& solid)   {
+    TGeoCompositeShape* sh = (TGeoCompositeShape*)solid.ptr();
+    return sh && sh->IsA() == TGeoCompositeShape::Class()
+      &&   sh->GetBoolNode()->GetBooleanOperator() == TGeoBoolNode::kGeoSubtraction
+      &&    ::strcmp(solid->GetTitle(), SUBTRACTION_TAG) == 0;
+  }
+  template <> bool isA<UnionSolid>(const Handle<TGeoShape>& solid)   {
+    TGeoCompositeShape* sh = (TGeoCompositeShape*)solid.ptr();
+    return sh && sh->IsA() == TGeoCompositeShape::Class()
+      &&   sh->GetBoolNode()->GetBooleanOperator() == TGeoBoolNode::kGeoUnion
+      &&    ::strcmp(solid->GetTitle(), UNION_TAG) == 0;
+  }
+  template <> bool isA<IntersectionSolid>(const Handle<TGeoShape>& solid)   {
+    TGeoCompositeShape* sh = (TGeoCompositeShape*)solid.ptr();
+    return sh && sh->IsA() == TGeoCompositeShape::Class()
+      &&   sh->GetBoolNode()->GetBooleanOperator() == TGeoBoolNode::kGeoIntersection
+      &&    ::strcmp(solid->GetTitle(), INTERSECTION_TAG) == 0;
+  }
 }
 
 namespace dd4hep {
@@ -267,7 +326,7 @@ namespace dd4hep {
         TGeoMatrix* right_matrix  = boolean->GetRightMatrix();
         TGeoShape*  left_solid    = boolean->GetLeftShape();
         TGeoShape*  right_solid   = boolean->GetRightShape();
-        if ( instanceOf<TruncatedTube>(solid) )   {
+        if ( isInstance<TruncatedTube>(solid) )   {
           stringstream params(right_matrix->GetTitle());
           vector<double> pars;
           pars.reserve(8);
@@ -350,7 +409,7 @@ namespace dd4hep {
               cutAtStart, cutAtDelta, cutInside ? 1.0 : 0.0 };
 #endif
         }
-        else if ( instanceOf<PseudoTrap>(solid) )   {
+        else if ( isInstance<PseudoTrap>(solid) )   {
           stringstream params(right_matrix->GetTitle());
           vector<double> pars;
           pars.reserve(7);
@@ -368,11 +427,11 @@ namespace dd4hep {
           }
           return pars;
         }
-        else if ( instanceOf<SubtractionSolid>(solid) )   {
+        else if ( isInstance<SubtractionSolid>(solid) )   {
         }
-        else if ( instanceOf<UnionSolid>(solid) )   {
+        else if ( isInstance<UnionSolid>(solid) )   {
         }
-        else if ( instanceOf<IntersectionSolid>(solid) )   {
+        else if ( isInstance<IntersectionSolid>(solid) )   {
         }
         
         TGeoBoolNode::EGeoBoolType oper = boolean->GetBooleanOperator();
@@ -607,7 +666,7 @@ namespace dd4hep {
         TGeoMatrix* right_matrix  = boolean->GetRightMatrix();
         TGeoShape*  left_solid    = boolean->GetLeftShape();
         TGeoShape*  right_solid   = boolean->GetRightShape();
-        if ( instanceOf<TruncatedTube>(solid) )   {
+        if ( isInstance<TruncatedTube>(solid) )   {
           TGeoTubeSeg* tubs = (TGeoTubeSeg*)left_solid;
           TGeoBBox*    box  = (TGeoBBox*)right_solid;
           double zhalf = params[0];
@@ -664,7 +723,7 @@ namespace dd4hep {
           combi->SetTranslation(xBox, 0, 0);
           return;
         }
-        else if ( instanceOf<PseudoTrap>(solid) )   {
+        else if ( isInstance<PseudoTrap>(solid) )   {
           double x1 = params[0];
           double x2 = params[1];
           double y1 = params[2];
@@ -742,11 +801,11 @@ namespace dd4hep {
           return;
         }
         // In general TGeoCompositeShape instances have an empty SetDimension call
-        else if ( instanceOf<SubtractionSolid>(solid) )   {
+        else if ( isInstance<SubtractionSolid>(solid) )   {
         }
-        else if ( instanceOf<UnionSolid>(solid) )   {
+        else if ( isInstance<UnionSolid>(solid) )   {
         }
-        else if ( instanceOf<IntersectionSolid>(solid) )   {
+        else if ( isInstance<IntersectionSolid>(solid) )   {
         }
 #ifdef DIMENSION_DEBUG
         throw runtime_error("Composite shape. setDimensions is not implemented!");
diff --git a/DDCore/src/plugins/ShapePlugins.cpp b/DDCore/src/plugins/ShapePlugins.cpp
index 4cfe5ff011728f4b8836bc5709a3f0fe77ce1464..c5fe7e68dfe054ea1e6f0f218d09908661f8f56b 100644
--- a/DDCore/src/plugins/ShapePlugins.cpp
+++ b/DDCore/src/plugins/ShapePlugins.cpp
@@ -546,55 +546,55 @@ static Ref_t create_shape(Detector& description, xml_h e, Ref_t /* sens */)  {
              shape.typeStr().c_str());
     bool instance_test = false;
     if ( 0 == strcasecmp(solid->GetTitle(),"box") )
-      instance_test = instanceOf<Box>(solid);
+      instance_test = isInstance<Box>(solid);
     else if ( 0 == strcasecmp(solid->GetTitle(),"Tube") )
-      instance_test = instanceOf<Tube>(solid);
+      instance_test = isInstance<Tube>(solid);
     else if ( 0 == strcasecmp(solid->GetTitle(),"CutTube") )
-      instance_test = instanceOf<CutTube>(solid);
+      instance_test = isInstance<CutTube>(solid);
     else if ( 0 == strcasecmp(solid->GetTitle(),"Cone") )
-      instance_test = instanceOf<Cone>(solid);
+      instance_test = isInstance<Cone>(solid);
     else if ( 0 == strcasecmp(solid->GetTitle(),"Trap") )
-      instance_test = instanceOf<Trap>(solid);
+      instance_test = isInstance<Trap>(solid);
     else if ( 0 == strcasecmp(solid->GetTitle(),"Trd1") )
-      instance_test = instanceOf<Trd1>(solid);
+      instance_test = isInstance<Trd1>(solid);
     else if ( 0 == strcasecmp(solid->GetTitle(),"Trd2") )
-      instance_test = instanceOf<Trd2>(solid);
+      instance_test = isInstance<Trd2>(solid);
     else if ( 0 == strcasecmp(solid->GetTitle(),"Torus") )
-      instance_test = instanceOf<Torus>(solid);
+      instance_test = isInstance<Torus>(solid);
     else if ( 0 == strcasecmp(solid->GetTitle(),"Sphere") )
-      instance_test = instanceOf<Sphere>(solid);
+      instance_test = isInstance<Sphere>(solid);
     else if ( 0 == strcasecmp(solid->GetTitle(),"HalfSpace") )
-      instance_test = instanceOf<HalfSpace>(solid);
+      instance_test = isInstance<HalfSpace>(solid);
     else if ( 0 == strcasecmp(solid->GetTitle(),"ConeSegment") )
-      instance_test = instanceOf<ConeSegment>(solid);
+      instance_test = isInstance<ConeSegment>(solid);
     else if ( 0 == strcasecmp(solid->GetTitle(),"Paraboloid") )
-      instance_test = instanceOf<Paraboloid>(solid);
+      instance_test = isInstance<Paraboloid>(solid);
     else if ( 0 == strcasecmp(solid->GetTitle(),"Hyperboloid") )
-      instance_test = instanceOf<Hyperboloid>(solid);
+      instance_test = isInstance<Hyperboloid>(solid);
     else if ( 0 == strcasecmp(solid->GetTitle(),"PolyhedraRegular") )
-      instance_test = instanceOf<PolyhedraRegular>(solid);
+      instance_test = isInstance<PolyhedraRegular>(solid);
     else if ( 0 == strcasecmp(solid->GetTitle(),"Polyhedra") )
-      instance_test = instanceOf<Polyhedra>(solid);
+      instance_test = isInstance<Polyhedra>(solid);
     else if ( 0 == strcasecmp(solid->GetTitle(),"EllipticalTube") )
-      instance_test = instanceOf<EllipticalTube>(solid);
+      instance_test = isInstance<EllipticalTube>(solid);
     else if ( 0 == strcasecmp(solid->GetTitle(),"ExtrudedPolygon") )
-      instance_test = instanceOf<ExtrudedPolygon>(solid);
+      instance_test = isInstance<ExtrudedPolygon>(solid);
     else if ( 0 == strcasecmp(solid->GetTitle(),"Polycone") )
-      instance_test = instanceOf<Polycone>(solid);
+      instance_test = isInstance<Polycone>(solid);
     else if ( 0 == strcasecmp(solid->GetTitle(),"EightPointSolid") )
-      instance_test = instanceOf<EightPointSolid>(solid);
+      instance_test = isInstance<EightPointSolid>(solid);
     else if ( 0 == strcasecmp(solid->GetTitle(),"SubtractionSolid") )
-      instance_test = instanceOf<SubtractionSolid>(solid);
+      instance_test = isInstance<SubtractionSolid>(solid);
     else if ( 0 == strcasecmp(solid->GetTitle(),"UnionSolid") )
-      instance_test = instanceOf<UnionSolid>(solid);
+      instance_test = isInstance<UnionSolid>(solid);
     else if ( 0 == strcasecmp(solid->GetTitle(),"IntersectionSolid") )
-      instance_test = instanceOf<IntersectionSolid>(solid);
+      instance_test = isInstance<IntersectionSolid>(solid);
     else if ( 0 == strcasecmp(solid->GetTitle(),"TruncatedTube") )
-      instance_test = instanceOf<TruncatedTube>(solid);
+      instance_test = isInstance<TruncatedTube>(solid);
     else if ( 0 == strcasecmp(solid->GetTitle(),"PseudoTrap") )
-      instance_test = instanceOf<PseudoTrap>(solid);
+      instance_test = isInstance<PseudoTrap>(solid);
 
-    if ( !instance_test || ::strcasecmp(shape.typeStr().c_str(),solid->GetTitle()) )   {
+    if ( !instance_test || ::strcasecmp(shape.typeStr().c_str(),solid->GetTitle()) != 0 )   {
       printout(ERROR,"TestShape","BAD shape type: %s <-> %s Instance test: %s",
                shape.typeStr().c_str(), solid->GetTitle(),
                instance_test ? "OK" : "FAILED");
@@ -712,11 +712,11 @@ void* shape_mesh_verifier(Detector& description, int argc, char** argv)    {
     for (Int_t ipv=0, npv=v->GetNdaughters(); ipv < npv; ipv++) {
       PlacedVolume place = v->GetNode(ipv);
       Solid solid = place.volume().solid();
-      if ( instanceOf<TruncatedTube>(solid) )   {
+      if ( isInstance<TruncatedTube>(solid) )   {
         auto params = solid.dimensions();
         solid.setDimensions(params);
       }
-      else if ( instanceOf<PseudoTrap>(solid) )   {
+      else if ( isInstance<PseudoTrap>(solid) )   {
         auto params = solid.dimensions();
         solid.setDimensions(params);
       }
diff --git a/DDG4/src/Geant4Converter.cpp b/DDG4/src/Geant4Converter.cpp
index aca24564310e06e3f7ae315740bc757db3d1bc4a..efc6f6b5d579ba41a01c4c92e080120398e91345 100644
--- a/DDG4/src/Geant4Converter.cpp
+++ b/DDG4/src/Geant4Converter.cpp
@@ -14,6 +14,7 @@
 // Framework include files
 #include "DD4hep/Detector.h"
 #include "DD4hep/Plugins.h"
+#include "DD4hep/Shapes.h"
 #include "DD4hep/Volumes.h"
 #include "DD4hep/Printout.h"
 #include "DD4hep/DD4hepUnits.h"
@@ -25,28 +26,16 @@
 #include "DDG4/Geant4Converter.h"
 #include "DDG4/Geant4UserLimits.h"
 #include "DDG4/Geant4SensitiveDetector.h"
+#include "Geant4ShapeConverter.h"
 
 // ROOT includes
 #include "TROOT.h"
 #include "TColor.h"
 #include "TGeoNode.h"
-#include "TGeoShape.h"
-#include "TGeoCone.h"
-#include "TGeoHype.h"
-#include "TGeoPcon.h"
-#include "TGeoEltu.h"
-#include "TGeoPgon.h"
-#include "TGeoSphere.h"
-#include "TGeoTorus.h"
-#include "TGeoTrd1.h"
-#include "TGeoTrd2.h"
-#include "TGeoTube.h"
-#include "TGeoArb8.h"
+
 #include "TGeoMatrix.h"
 #include "TGeoBoolNode.h"
 #include "TGeoParaboloid.h"
-#include "TGeoCompositeShape.h"
-#include "TGeoShapeAssembly.h"
 #include "TGeoScaledShape.h"
 #include "TGeoManager.h"
 #include "TClass.h"
@@ -57,26 +46,16 @@
 #include "G4ProductionCuts.hh"
 #include "G4VUserRegionInformation.hh"
 
-#include "G4Element.hh"
 #include "G4Box.hh"
-#include "G4Trd.hh"
 #include "G4Tubs.hh"
-#include "G4Trap.hh"
-#include "G4Cons.hh"
-#include "G4Hype.hh"
-#include "G4Torus.hh"
-#include "G4Sphere.hh"
-#include "G4Polycone.hh"
-#include "G4Polyhedra.hh"
-#include "G4UnionSolid.hh"
-#include "G4Paraboloid.hh"
 #include "G4Ellipsoid.hh"
-#include "G4GenericTrap.hh"
-#include "G4ExtrudedSolid.hh"
+#include "G4UnionSolid.hh"
 #include "G4ReflectedSolid.hh"
 #include "G4EllipticalTube.hh"
 #include "G4SubtractionSolid.hh"
 #include "G4IntersectionSolid.hh"
+
+#include "G4Element.hh"
 #include "G4Region.hh"
 #include "G4UserLimits.hh"
 #include "G4LogicalVolume.hh"
@@ -570,7 +549,7 @@ void* Geant4Converter::handleMaterial(const string& name, Material medium) const
 /// Dump solid in GDML format to output stream
 void* Geant4Converter::handleSolid(const string& name, const TGeoShape* shape) const {
   G4VSolid* solid = 0;
-  if (shape) {
+  if ( shape ) {
     if (0 != (solid = data().g4Solids[shape])) {
       return solid;
     }
@@ -579,149 +558,66 @@ void* Geant4Converter::handleSolid(const string& name, const TGeoShape* shape) c
     if (isa == TGeoShapeAssembly::Class()) {
       // Assemblies have no corresponding 'shape' in Geant4. Ignore the shape translation.
       // It does not harm, since this 'shape' is never accessed afterwards.
-      data().g4Solids[shape] = solid;
+      data().g4Solids[shape] = solid = convertShape<TGeoShapeAssembly>(shape);
       return solid;
     }
-    else if (isa == TGeoBBox::Class()) {
-      const TGeoBBox* sh = (const TGeoBBox*) shape;
-      solid = new G4Box(name, sh->GetDX() * CM_2_MM, sh->GetDY() * CM_2_MM, sh->GetDZ() * CM_2_MM);
-    }
-    else if (isa == TGeoTube::Class()) {
-      const TGeoTube* sh = (const TGeoTube*) shape;
-      solid = new G4Tubs(name, sh->GetRmin() * CM_2_MM, sh->GetRmax() * CM_2_MM, sh->GetDz() * CM_2_MM, 0, 2. * M_PI);
-    }
-    else if (isa == TGeoTubeSeg::Class()) {
-      const TGeoTubeSeg* sh = (const TGeoTubeSeg*) shape;
-      solid = new G4Tubs(name, sh->GetRmin() * CM_2_MM, sh->GetRmax() * CM_2_MM, sh->GetDz() * CM_2_MM,
-                         sh->GetPhi1() * DEGREE_2_RAD, (sh->GetPhi2()-sh->GetPhi1()) * DEGREE_2_RAD);
-    }
-    else if (isa == TGeoEltu::Class()) {
-      const TGeoEltu* sh = (const TGeoEltu*) shape;
-      solid = new G4EllipticalTube(name,sh->GetA() * CM_2_MM, sh->GetB() * CM_2_MM, sh->GetDz() * CM_2_MM);
-    }
-    else if (isa == TGeoTrd1::Class()) {
-      const TGeoTrd1* sh = (const TGeoTrd1*) shape;
-      solid = new G4Trd(name, sh->GetDx1() * CM_2_MM, sh->GetDx2() * CM_2_MM, sh->GetDy() * CM_2_MM, sh->GetDy() * CM_2_MM,
-                        sh->GetDz() * CM_2_MM);
-    }
-    else if (isa == TGeoTrd2::Class()) {
-      const TGeoTrd2* sh = (const TGeoTrd2*) shape;
-      solid = new G4Trd(name, sh->GetDx1() * CM_2_MM, sh->GetDx2() * CM_2_MM, sh->GetDy1() * CM_2_MM, sh->GetDy2() * CM_2_MM,
-                        sh->GetDz() * CM_2_MM);
-    }
-    else if (isa == TGeoHype::Class()) {
-      const TGeoHype* sh = (const TGeoHype*) shape;
-      solid = new G4Hype(name, sh->GetRmin() * CM_2_MM, sh->GetRmax() * CM_2_MM,
-                         sh->GetStIn() * DEGREE_2_RAD, sh->GetStOut() * DEGREE_2_RAD,
-                         sh->GetDz() * CM_2_MM);
-    }
-    else if (isa == TGeoXtru::Class()) {
-      const TGeoXtru* sh = (const TGeoXtru*) shape;
-      size_t nz = sh->GetNz();
-      vector<G4ExtrudedSolid::ZSection> z;
-      vector<G4TwoVector> polygon;
-      z.reserve(nz);
-      polygon.reserve(nz);
-      for(size_t i=0; i<nz; ++i)   {
-        z.emplace_back(G4ExtrudedSolid::ZSection(sh->GetZ(i) * CM_2_MM,
-                                              {sh->GetXOffset(i), sh->GetYOffset(i)},
-                                              sh->GetScale(i)));
-        polygon.emplace_back(G4TwoVector(sh->GetX(i) * CM_2_MM,sh->GetY(i) * CM_2_MM));
-      }
-      solid = new G4ExtrudedSolid(name, polygon, z);
-    }
-    else if (isa == TGeoPgon::Class()) {
-      const TGeoPgon* sh = (const TGeoPgon*) shape;
-      double phi_start = sh->GetPhi1() * DEGREE_2_RAD;
-      double phi_total = (sh->GetDphi() + sh->GetPhi1()) * DEGREE_2_RAD;
-      vector<double> rmin, rmax, z;
-      for (Int_t i = 0; i < sh->GetNz(); ++i) {
-        rmin.emplace_back(sh->GetRmin(i) * CM_2_MM);
-        rmax.emplace_back(sh->GetRmax(i) * CM_2_MM);
-        z.emplace_back(sh->GetZ(i) * CM_2_MM);
-      }
-      solid = new G4Polyhedra(name, phi_start, phi_total, sh->GetNedges(), sh->GetNz(), &z[0], &rmin[0], &rmax[0]);
-    }
-    else if (isa == TGeoPcon::Class()) {
-      const TGeoPcon* sh = (const TGeoPcon*) shape;
-      double phi_start = sh->GetPhi1() * DEGREE_2_RAD;
-      double phi_total = (sh->GetDphi() + sh->GetPhi1()) * DEGREE_2_RAD;
-      vector<double> rmin, rmax, z;
-      for (Int_t i = 0; i < sh->GetNz(); ++i) {
-        rmin.emplace_back(sh->GetRmin(i) * CM_2_MM);
-        rmax.emplace_back(sh->GetRmax(i) * CM_2_MM);
-        z.emplace_back(sh->GetZ(i) * CM_2_MM);
-      }
-      solid = new G4Polycone(name, phi_start, phi_total, sh->GetNz(), &z[0], &rmin[0], &rmax[0]);
-    }
-    else if (isa == TGeoCone::Class()) {
-      const TGeoCone* sh = (const TGeoCone*) shape;
-      solid = new G4Cons(name, sh->GetRmin1() * CM_2_MM, sh->GetRmax1() * CM_2_MM, sh->GetRmin2() * CM_2_MM,
-                         sh->GetRmax2() * CM_2_MM, sh->GetDz() * CM_2_MM, 0.0, 2.*M_PI);
-    }
-    else if (isa == TGeoConeSeg::Class()) {
-      const TGeoConeSeg* sh = (const TGeoConeSeg*) shape;
-      solid = new G4Cons(name, sh->GetRmin1() * CM_2_MM, sh->GetRmax1() * CM_2_MM,
-                         sh->GetRmin2() * CM_2_MM, sh->GetRmax2() * CM_2_MM,
-                         sh->GetDz() * CM_2_MM,
-                         sh->GetPhi1() * DEGREE_2_RAD, (sh->GetPhi2()-sh->GetPhi1()) * DEGREE_2_RAD);
-    }
-    else if (isa == TGeoParaboloid::Class()) {
-      const TGeoParaboloid* sh = (const TGeoParaboloid*) shape;
-      solid = new G4Paraboloid(name, sh->GetDz() * CM_2_MM, sh->GetRlo() * CM_2_MM, sh->GetRhi() * CM_2_MM);
-    }
-#if 0  /* Not existent */
-    else if (isa == TGeoEllisoid::Class()) {
-      const TGeoParaboloid* sh = (const TGeoParaboloid*) shape;
-      solid = new G4Paraboloid(name, sh->GetDz() * CM_2_MM, sh->GetRlo() * CM_2_MM, sh->GetRhi() * CM_2_MM);
-    }
-#endif
-    else if (isa == TGeoSphere::Class()) {
-      const TGeoSphere* sh = (const TGeoSphere*) shape;
-      solid = new G4Sphere(name, sh->GetRmin() * CM_2_MM, sh->GetRmax() * CM_2_MM, sh->GetPhi1() * DEGREE_2_RAD,
-                           sh->GetPhi2() * DEGREE_2_RAD, sh->GetTheta1() * DEGREE_2_RAD, sh->GetTheta2() * DEGREE_2_RAD);
-    }
-    else if (isa == TGeoTorus::Class()) {
-      const TGeoTorus* sh = (const TGeoTorus*) shape;
-      solid = new G4Torus(name, sh->GetRmin() * CM_2_MM, sh->GetRmax() * CM_2_MM, sh->GetR() * CM_2_MM,
-                          sh->GetPhi1() * DEGREE_2_RAD, sh->GetDphi() * DEGREE_2_RAD);
-    }
-    else if (isa == TGeoTrap::Class()) {
-      const TGeoTrap* sh = (const TGeoTrap*) shape;
-      solid = new G4Trap(name, sh->GetDz() * CM_2_MM, sh->GetTheta() * DEGREE_2_RAD, sh->GetPhi() * DEGREE_2_RAD,
-                         sh->GetH1() * CM_2_MM, sh->GetBl1() * CM_2_MM, sh->GetTl1() * CM_2_MM, sh->GetAlpha1() * DEGREE_2_RAD,
-                         sh->GetH2() * CM_2_MM, sh->GetBl2() * CM_2_MM, sh->GetTl2() * CM_2_MM, sh->GetAlpha2() * DEGREE_2_RAD);
-    }
-    else if (isa == TGeoArb8::Class())  {
-      vector<G4TwoVector> vertices;
-      TGeoTrap* sh = (TGeoTrap*) shape;
-      Double_t* vtx_xy = sh->GetVertices();
-      for ( size_t i=0; i<8; ++i, vtx_xy +=2 )
-        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 (isa == TGeoBBox::Class())
+      solid = convertShape<TGeoBBox>(shape);
+    else if (isa == TGeoTube::Class())
+      solid = convertShape<TGeoTube>(shape);
+    else if (isa == TGeoTubeSeg::Class())
+      solid = convertShape<TGeoTubeSeg>(shape);
+    else if (isa == TGeoCtub::Class())
+      solid = convertShape<TGeoCtub>(shape);
+    else if (isa == TGeoEltu::Class())
+      solid = convertShape<TGeoEltu>(shape);
+    else if (isa == TGeoTrd1::Class())
+      solid = convertShape<TGeoTrd1>(shape);
+    else if (isa == TGeoTrd2::Class())
+      solid = convertShape<TGeoTrd2>(shape);
+    else if (isa == TGeoHype::Class())
+      solid = convertShape<TGeoHype>(shape);
+    else if (isa == TGeoXtru::Class())
+      solid = convertShape<TGeoXtru>(shape);
+    else if (isa == TGeoPgon::Class())
+      solid = convertShape<TGeoPgon>(shape);
+    else if (isa == TGeoPcon::Class())
+      solid = convertShape<TGeoPcon>(shape);
+    else if (isa == TGeoCone::Class())
+      solid = convertShape<TGeoCone>(shape);
+    else if (isa == TGeoConeSeg::Class())
+      solid = convertShape<TGeoConeSeg>(shape);
+    else if (isa == TGeoParaboloid::Class())
+      solid = convertShape<TGeoParaboloid>(shape);
+    else if (isa == TGeoSphere::Class())
+      solid = convertShape<TGeoSphere>(shape);
+    else if (isa == TGeoTorus::Class())
+      solid = convertShape<TGeoTorus>(shape);
+    else if (isa == TGeoTrap::Class())
+      solid = convertShape<TGeoTrap>(shape);
+    else if (isa == TGeoArb8::Class()) 
+      solid = convertShape<TGeoArb8>(shape);
     else if (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());
+                               scaled, G4Scale3D(vals[0],vals[1],vals[2]));
     }
-    else if (isa == TGeoCompositeShape::Class())    {
+    else if (isa == TGeoCompositeShape::Class())   {
       const TGeoCompositeShape* sh = (const TGeoCompositeShape*) shape;
       const TGeoBoolNode* boolean = sh->GetBoolNode();
       TGeoBoolNode::EGeoBoolType oper = boolean->GetBooleanOperator();
       TGeoMatrix* matrix = boolean->GetRightMatrix();
       G4VSolid* left  = (G4VSolid*) handleSolid(name + "_left", boolean->GetLeftShape());
       G4VSolid* right = (G4VSolid*) handleSolid(name + "_right", boolean->GetRightShape());
-
+      
       if (!left) {
-        throw runtime_error("G4Converter: No left Geant4 Solid present for composite shape:" + name);
+        except("Geant4Converter","++ No left Geant4 Solid present for composite shape: %s",name.c_str());
       }
       if (!right) {
-        throw runtime_error("G4Converter: No right Geant4 Solid present for composite shape:" + name);
+        except("Geant4Converter","++ No right Geant4 Solid present for composite shape: %s",name.c_str());
       }
 
       //specific case!
@@ -776,14 +672,11 @@ void* Geant4Converter::handleSolid(const string& name, const TGeoShape* shape) c
       }
     }
 
-    if (!solid) {
-      string err = "Failed to handle unknown solid shape:" + name + " of type " + string(isa->GetName());
-      throw runtime_error(err);
-    }
-    else  {
-      printout(lvl,"Geant4Converter","++ Successessfully converted shape [%p] of type:%s to %s.",
-               solid,isa->GetName(),typeName(typeid(*solid)).c_str());
-    }
+    if (!solid)
+      except("Geant4Converter","++ Failed to handle unknown solid shape: %s of type %s",
+             name.c_str(), isa->GetName());
+    printout(lvl,"Geant4Converter","++ Successessfully converted shape [%p] of type:%s to %s.",
+             solid,isa->GetName(),typeName(typeid(*solid)).c_str());
     data().g4Solids[shape] = solid;
   }
   return solid;
diff --git a/DDG4/src/Geant4ShapeConverter.cpp b/DDG4/src/Geant4ShapeConverter.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e68d59b27bef9e08deb3cb9e7cb74649577dbb42
--- /dev/null
+++ b/DDG4/src/Geant4ShapeConverter.cpp
@@ -0,0 +1,220 @@
+//==========================================================================
+//  AIDA Detector description implementation 
+//--------------------------------------------------------------------------
+// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+// All rights reserved.
+//
+// For the licensing terms see $DD4hepINSTALL/LICENSE.
+// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
+//
+// Author     : M.Frank
+//
+//==========================================================================
+
+// Framework include files
+#include "DD4hep/Shapes.h"
+#include "DD4hep/Printout.h"
+#include "DD4hep/DD4hepUnits.h"
+
+#include "Geant4ShapeConverter.h"
+
+// ROOT includes
+#include "TClass.h"
+#include "TGeoMatrix.h"
+#include "TGeoBoolNode.h"
+#include "TGeoScaledShape.h"
+
+// Geant4 include files
+#include "G4Box.hh"
+#include "G4Trd.hh"
+#include "G4Tubs.hh"
+#include "G4Trap.hh"
+#include "G4Cons.hh"
+#include "G4Hype.hh"
+#include "G4Torus.hh"
+#include "G4Sphere.hh"
+#include "G4CutTubs.hh"
+#include "G4Polycone.hh"
+#include "G4Polyhedra.hh"
+#include "G4Paraboloid.hh"
+#include "G4Ellipsoid.hh"
+#include "G4GenericTrap.hh"
+#include "G4ExtrudedSolid.hh"
+#include "G4EllipticalTube.hh"
+
+// C/C++ include files
+
+using namespace std;
+using namespace dd4hep::detail;
+namespace units = dd4hep;
+
+/// Namespace for the AIDA detector description toolkit
+namespace dd4hep {
+
+  /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit
+  namespace sim {
+
+    static const double CM_2_MM = (CLHEP::centimeter/dd4hep::centimeter);
+
+    /// Convert a specific TGeo shape into the geant4 equivalent
+    template <typename T> G4VSolid* convertShape(const TGeoShape* shape)    {
+      if ( shape )   {
+        dd4hep::except("convertShape","Unsupported shape: %s",shape->IsA()->GetName());
+      }
+      dd4hep::except("convertShape","Invalid shape conversion requested.");
+      return 0;
+    }
+
+    template <> G4VSolid* convertShape<TGeoShapeAssembly>(const TGeoShape* /* shape */)  {
+      return 0;
+    }
+
+    template <> G4VSolid* convertShape<TGeoBBox>(const TGeoShape* shape)  {
+      const TGeoBBox* sh = (const TGeoBBox*) shape;
+      return new G4Box(sh->GetName(), sh->GetDX() * CM_2_MM, sh->GetDY() * CM_2_MM, sh->GetDZ() * CM_2_MM);
+    }
+
+    template <> G4VSolid* convertShape<TGeoTube>(const TGeoShape* shape)  {
+      const TGeoTube* sh = (const TGeoTube*) shape;
+      return new G4Tubs(sh->GetName(), sh->GetRmin() * CM_2_MM, sh->GetRmax() * CM_2_MM, sh->GetDz() * CM_2_MM, 0, 2. * M_PI);
+    }
+
+    template <> G4VSolid* convertShape<TGeoTubeSeg>(const TGeoShape* shape)  {
+      const TGeoTubeSeg* sh = (const TGeoTubeSeg*) shape;
+      return new G4Tubs(sh->GetName(), sh->GetRmin() * CM_2_MM, sh->GetRmax() * CM_2_MM, sh->GetDz() * CM_2_MM,
+                        sh->GetPhi1() * DEGREE_2_RAD, (sh->GetPhi2()-sh->GetPhi1()) * DEGREE_2_RAD);
+    }
+
+    template <> G4VSolid* convertShape<TGeoCtub>(const TGeoShape* shape)  {
+      const TGeoCtub* sh = (const TGeoCtub*) shape;
+      const Double_t* ln = sh->GetNlow();
+      const Double_t* hn = sh->GetNhigh();
+      G4ThreeVector   lowNorm (ln[0], ln[1], ln[2]);
+      G4ThreeVector   highNorm(hn[0], hn[1], hn[2]);
+      return new G4CutTubs(sh->GetName(), sh->GetRmin() * CM_2_MM, sh->GetRmax() * CM_2_MM, sh->GetDz() * CM_2_MM,
+                           sh->GetPhi1() * DEGREE_2_RAD, (sh->GetPhi2()-sh->GetPhi1()) * DEGREE_2_RAD, lowNorm, highNorm);
+    }
+
+    template <> G4VSolid* convertShape<TGeoEltu>(const TGeoShape* shape)  {
+      const TGeoEltu* sh = (const TGeoEltu*) shape;
+      return new G4EllipticalTube(sh->GetName(),sh->GetA() * CM_2_MM, sh->GetB() * CM_2_MM, sh->GetDz() * CM_2_MM);
+    }
+
+    template <> G4VSolid* convertShape<TGeoTrd1>(const TGeoShape* shape)  {
+      const TGeoTrd1* sh = (const TGeoTrd1*) shape;
+      return new G4Trd(sh->GetName(), sh->GetDx1() * CM_2_MM, sh->GetDx2() * CM_2_MM, sh->GetDy() * CM_2_MM, sh->GetDy() * CM_2_MM,
+                       sh->GetDz() * CM_2_MM);
+    }
+
+    template <> G4VSolid* convertShape<TGeoTrd2>(const TGeoShape* shape)  {
+      const TGeoTrd2* sh = (const TGeoTrd2*) shape;
+      return new G4Trd(sh->GetName(), sh->GetDx1() * CM_2_MM, sh->GetDx2() * CM_2_MM, sh->GetDy1() * CM_2_MM, sh->GetDy2() * CM_2_MM,
+                       sh->GetDz() * CM_2_MM);
+    }
+
+    template <> G4VSolid* convertShape<TGeoHype>(const TGeoShape* shape)  {
+      const TGeoHype* sh = (const TGeoHype*) shape;
+      return new G4Hype(sh->GetName(), sh->GetRmin() * CM_2_MM, sh->GetRmax() * CM_2_MM,
+                        sh->GetStIn() * DEGREE_2_RAD, sh->GetStOut() * DEGREE_2_RAD,
+                        sh->GetDz() * CM_2_MM);
+    }
+
+    template <> G4VSolid* convertShape<TGeoArb8>(const TGeoShape* shape)  {
+      vector<G4TwoVector> vertices;
+      TGeoArb8* sh = (TGeoArb8*) shape;
+      Double_t* vtx_xy = sh->GetVertices();
+      for ( size_t i=0; i<8; ++i, vtx_xy +=2 )
+        vertices.emplace_back(G4TwoVector(vtx_xy[0] * CM_2_MM,vtx_xy[1] * CM_2_MM));
+      return new G4GenericTrap(sh->GetName(), sh->GetDz() * CM_2_MM, vertices);
+    }
+
+    template <> G4VSolid* convertShape<TGeoXtru>(const TGeoShape* shape)  {
+      const TGeoXtru* sh = (const TGeoXtru*) shape;
+      size_t nz = sh->GetNz();
+      vector<G4ExtrudedSolid::ZSection> z;
+      vector<G4TwoVector> polygon;
+      z.reserve(nz);
+      polygon.reserve(nz);
+      for(size_t i=0; i<nz; ++i)   {
+        z.emplace_back(G4ExtrudedSolid::ZSection(sh->GetZ(i) * CM_2_MM,
+                                                 {sh->GetXOffset(i), sh->GetYOffset(i)},
+                                                 sh->GetScale(i)));
+        polygon.emplace_back(G4TwoVector(sh->GetX(i) * CM_2_MM,sh->GetY(i) * CM_2_MM));
+      }
+      return new G4ExtrudedSolid(sh->GetName(), polygon, z);
+    }
+
+    template <> G4VSolid* convertShape<TGeoPgon>(const TGeoShape* shape)  {
+      const TGeoPgon* sh = (const TGeoPgon*) shape;
+      double phi_start = sh->GetPhi1() * DEGREE_2_RAD;
+      double phi_total = (sh->GetDphi() + sh->GetPhi1()) * DEGREE_2_RAD;
+      vector<double> rmin, rmax, z;
+      for (Int_t i = 0; i < sh->GetNz(); ++i) {
+        rmin.emplace_back(sh->GetRmin(i) * CM_2_MM);
+        rmax.emplace_back(sh->GetRmax(i) * CM_2_MM);
+        z.emplace_back(sh->GetZ(i) * CM_2_MM);
+      }
+      return new G4Polyhedra(sh->GetName(), phi_start, phi_total, sh->GetNedges(), sh->GetNz(), &z[0], &rmin[0], &rmax[0]);
+    }
+
+    template <> G4VSolid* convertShape<TGeoPcon>(const TGeoShape* shape)  {
+      const TGeoPcon* sh = (const TGeoPcon*) shape;
+      double phi_start = sh->GetPhi1() * DEGREE_2_RAD;
+      double phi_total = (sh->GetDphi() + sh->GetPhi1()) * DEGREE_2_RAD;
+      vector<double> rmin, rmax, z;
+      for (Int_t i = 0; i < sh->GetNz(); ++i) {
+        rmin.emplace_back(sh->GetRmin(i) * CM_2_MM);
+        rmax.emplace_back(sh->GetRmax(i) * CM_2_MM);
+        z.emplace_back(sh->GetZ(i) * CM_2_MM);
+      }
+      return new G4Polycone(sh->GetName(), phi_start, phi_total, sh->GetNz(), &z[0], &rmin[0], &rmax[0]);
+    }
+
+    template <> G4VSolid* convertShape<TGeoCone>(const TGeoShape* shape)  {
+      const TGeoCone* sh = (const TGeoCone*) shape;
+      return new G4Cons(sh->GetName(), sh->GetRmin1() * CM_2_MM, sh->GetRmax1() * CM_2_MM, sh->GetRmin2() * CM_2_MM,
+                        sh->GetRmax2() * CM_2_MM, sh->GetDz() * CM_2_MM, 0.0, 2.*M_PI);
+    }
+
+    template <> G4VSolid* convertShape<TGeoConeSeg>(const TGeoShape* shape)  {
+      const TGeoConeSeg* sh = (const TGeoConeSeg*) shape;
+      return new G4Cons(sh->GetName(), sh->GetRmin1() * CM_2_MM, sh->GetRmax1() * CM_2_MM,
+                        sh->GetRmin2() * CM_2_MM, sh->GetRmax2() * CM_2_MM,
+                        sh->GetDz() * CM_2_MM,
+                        sh->GetPhi1() * DEGREE_2_RAD, (sh->GetPhi2()-sh->GetPhi1()) * DEGREE_2_RAD);
+    }
+
+    template <> G4VSolid* convertShape<TGeoParaboloid>(const TGeoShape* shape)  {
+      const TGeoParaboloid* sh = (const TGeoParaboloid*) shape;
+      return new G4Paraboloid(sh->GetName(), sh->GetDz() * CM_2_MM, sh->GetRlo() * CM_2_MM, sh->GetRhi() * CM_2_MM);
+    }
+
+    template <> G4VSolid* convertShape<TGeoSphere>(const TGeoShape* shape)  {
+      const TGeoSphere* sh = (const TGeoSphere*) shape;
+      return new G4Sphere(sh->GetName(), sh->GetRmin() * CM_2_MM, sh->GetRmax() * CM_2_MM, sh->GetPhi1() * DEGREE_2_RAD,
+                          sh->GetPhi2() * DEGREE_2_RAD, sh->GetTheta1() * DEGREE_2_RAD, sh->GetTheta2() * DEGREE_2_RAD);
+    }
+
+    template <> G4VSolid* convertShape<TGeoTorus>(const TGeoShape* shape)  {
+      const TGeoTorus* sh = (const TGeoTorus*) shape;
+      return new G4Torus(sh->GetName(), sh->GetRmin() * CM_2_MM, sh->GetRmax() * CM_2_MM, sh->GetR() * CM_2_MM,
+                         sh->GetPhi1() * DEGREE_2_RAD, sh->GetDphi() * DEGREE_2_RAD);
+    }
+
+    template <> G4VSolid* convertShape<TGeoTrap>(const TGeoShape* shape)  {
+      const TGeoTrap* sh = (const TGeoTrap*) shape;
+      return new G4Trap(sh->GetName(), sh->GetDz() * CM_2_MM, sh->GetTheta() * DEGREE_2_RAD, sh->GetPhi() * DEGREE_2_RAD,
+                        sh->GetH1() * CM_2_MM, sh->GetBl1() * CM_2_MM, sh->GetTl1() * CM_2_MM, sh->GetAlpha1() * DEGREE_2_RAD,
+                        sh->GetH2() * CM_2_MM, sh->GetBl2() * CM_2_MM, sh->GetTl2() * CM_2_MM, sh->GetAlpha2() * DEGREE_2_RAD);
+    }
+
+    template <> G4VSolid* convertShape<G4GenericTrap>(const TGeoShape* shape)  {
+      vector<G4TwoVector> vertices;
+      TGeoTrap* sh = (TGeoTrap*) shape;
+      Double_t* vtx_xy = sh->GetVertices();
+      for ( size_t i=0; i<8; ++i, vtx_xy +=2 )
+        vertices.emplace_back(G4TwoVector(vtx_xy[0] * CM_2_MM,vtx_xy[1] * CM_2_MM));
+      return new G4GenericTrap(sh->GetName(), sh->GetDz() * CM_2_MM, vertices);
+    }
+  }    // End namespace sim
+}      // End namespace dd4hep
diff --git a/DDG4/src/Geant4ShapeConverter.h b/DDG4/src/Geant4ShapeConverter.h
new file mode 100644
index 0000000000000000000000000000000000000000..38055c8b4494fd79b481ea81934efea1f58e6cd2
--- /dev/null
+++ b/DDG4/src/Geant4ShapeConverter.h
@@ -0,0 +1,35 @@
+//==========================================================================
+//  AIDA Detector description implementation 
+//--------------------------------------------------------------------------
+// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
+// All rights reserved.
+//
+// For the licensing terms see $DD4hepINSTALL/LICENSE.
+// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
+//
+// Author     : M.Frank
+//
+//==========================================================================
+#ifndef DD4HEP_DDG4_GEANT4SHAPECONVERTER_H
+#define DD4HEP_DDG4_GEANT4SHAPECONVERTER_H
+
+// Framework include files
+
+// C/C++ include files
+
+// Forward declarations
+class TGeoShape;
+class G4VSolid;
+
+/// Namespace for the AIDA detector description toolkit
+namespace dd4hep {
+
+  /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit
+  namespace sim {
+
+    /// Convert a specific TGeo shape into the geant4 equivalent
+    template <typename T> G4VSolid* convertShape(const TGeoShape* shape);
+
+  }    // End namespace sim
+}      // End namespace dd4hep
+#endif // DD4HEP_DDG4_GEANT4SHAPECONVERTER_H