diff --git a/DDCore/include/DD4hep/SurfaceInstaller.h b/DDCore/include/DD4hep/SurfaceInstaller.h
index 25fe31d266b5f49ecd2d1962f7e23a4381e38e89..7c967f304d081bdb67ed0a1be1da84e4f3dae766 100644
--- a/DDCore/include/DD4hep/SurfaceInstaller.h
+++ b/DDCore/include/DD4hep/SurfaceInstaller.h
@@ -31,13 +31,14 @@ namespace DDSurfaces  {
 
 /// Namespace for the AIDA detector description toolkit
 namespace DD4hep  {
-
+  
   /// Namespace for the reconstruction part of the AIDA detector description toolkit
   namespace DDRec  {
     /// Class describing surface data
-    class SurfaceData;
+    //    class SurfaceData;
+    class VolSurfaceBase;
   }
-
+  
   /** Base class to implement surface installers for known detector patterns
    *
    *  The class scans the geometry of a subdetector and gives callbacks
@@ -56,7 +57,7 @@ namespace DD4hep  {
     typedef Geometry::PlacedVolume PlacedVolume;
     typedef Geometry::DetectorTools::ElementPath   ElementPath;
     typedef Geometry::DetectorTools::PlacementPath PlacementPath;
-    typedef DDRec::SurfaceData      SurfaceData;
+    typedef DDRec::VolSurfaceBase      SurfaceData;
     typedef DDSurfaces::SurfaceType SurfaceType;
 
     typedef std::map<TGeoVolume*, SurfaceData* > Surfaces;
diff --git a/DDRec/include/DDRec/Material.h b/DDRec/include/DDRec/Material.h
index c97c6a40e909e63c3841b52bd765204f3ccbd70c..8c6bd7b1d890245249531c7141b9e6635db5c3f2 100644
--- a/DDRec/include/DDRec/Material.h
+++ b/DDRec/include/DDRec/Material.h
@@ -75,8 +75,29 @@ namespace DD4hep {
                                                _rho( m.density() ),
                                                _x0( m.radiationLength() ),
                                                _lambda( m.interactionLength() ) {}
+
+      /** Copy c'tor .*/
+      MaterialData( const IMaterial& m )  : _name( m.name() ),
+					    _Z( m.Z() ),
+					    _A( m.A() ),
+					    _rho( m.density() ),
+					    _x0( m.radiationLength() ),
+					    _lambda( m.interactionLength() ) {}
       
 
+      /// assignment from Geometry::Material
+      MaterialData& operator=(const IMaterial& m){
+      
+	_name = m.name() ;
+	_Z = m.Z() ;
+	_A = m.A() ;
+	_rho = m.density() ;
+	_x0 = m.radiationLength() ;
+	_lambda = m.interactionLength() ;
+	
+        return *this ;
+      }
+
       /// assignment from Geometry::Material
       MaterialData& operator=(const Geometry::Material& m){
       
diff --git a/DDRec/include/DDRec/Surface.h b/DDRec/include/DDRec/Surface.h
index 203208a91134afb97708044a33940a4666b5a9aa..f1c99e34dae78d1901dbf031a78547bd39c0e088 100644
--- a/DDRec/include/DDRec/Surface.h
+++ b/DDRec/include/DDRec/Surface.h
@@ -17,55 +17,23 @@ namespace DD4hep {
   
     using namespace DDSurfaces ;
     
-#define use_materialdata 1
-#if use_materialdata
-    typedef MaterialData SurfaceMaterial ;
+    //-------------------------------------------------------------------------------------------
 
-#else
-    /** Wrapper class to  Geometry::Material that implements the DDSurfaces::IMaterial interface.
-     *
-     * @author F.Gaede, DESY
-     * @date Apr, 6 2014
-     * @version $Id$
-     */
-    struct SurfaceMaterial : public virtual Geometry::Material ,  public IMaterial{
-    
-      /** Copy c'tor - copies handle */
-      SurfaceMaterial( Geometry::Material mat )  : Geometry::Material( mat ) {}  
-    
-      SurfaceMaterial( const SurfaceMaterial& smat ) : Geometry::Material( smat ) {}  
-    
-      virtual ~SurfaceMaterial() {}
-    
-      /// material name
-      virtual std::string name() const ;
-    
-      /// averaged proton number
-      virtual double Z() const ;
-    
-      /// averaged atomic number
-      virtual double A() const ;
-    
-      /// density - units ?
-      virtual double density() const ;
-    
-      /// radiation length - tgeo units 
-      virtual double radiationLength() const ;
-    
-      /// interaction length - tgeo units 
-      virtual double interactionLength() const  ;
-    
-    };
-#endif
+    class VolSurface  ;
 
-    
-    /** Helper class for holding surface data. 
-     * @author F.Gaede, DESY
-     * @date Apr, 6 2014
-     * @version $Id$
+    /** Implementation of ISurface for a local surface attached to a volume. 
+     *  Provides default implementations for all methods but distance().
+     *  Subclasses for specific surfaces overwrite methods as needed.
+     * 
+     *  @author F.Gaede, DESY
+     *  @date Sep 11, 2015
+     *  @version $Id$
      */
-    struct SurfaceData{
-    
+    class VolSurfaceBase : public ISurface {
+      
+      friend class VolSurface ;
+
+    protected:
       SurfaceType _type ;
       Vector3D _u ;
       Vector3D _v ;
@@ -73,23 +41,60 @@ namespace DD4hep {
       Vector3D _o ;
       double _th_i ;
       double _th_o ;
-      SurfaceMaterial _innerMat ;
-      SurfaceMaterial _outerMat ;    
+      MaterialData _innerMat ;
+      MaterialData _outerMat ;    
       Geometry::Volume _vol ;
+      int _id ;
+      unsigned _refCount ;
+
+      /// setter for daughter classes
+      virtual void setU(const Vector3D& u) ;
+      /// setter for daughter classes
+      virtual void setV(const Vector3D& v) ;
+      /// setter for daughter classes
+      virtual void setNormal(const Vector3D& n) ;
+
+    public:
     
-      /// default c'tor.
-      SurfaceData();
-    
-      /// Standard c'tor for initialization.
-      SurfaceData( SurfaceType type, double thickness_inner ,double thickness_outer, 
-                   Vector3D u ,Vector3D v ,Vector3D n ,Vector3D o, 
-                   Geometry::Volume vol /*= Geometry::Volume() */);
-    
-      /// Default destructor
-      virtual ~SurfaceData() {} 
-    
+      virtual ~VolSurfaceBase() {} 
+
+      ///default c'tor
+
+      VolSurfaceBase() : 
+	_type( SurfaceType() ) ,
+	_u( Vector3D() ) ,
+	_v( Vector3D()  ) ,
+	_n( Vector3D() ) ,
+	_o( Vector3D() ) ,
+	_th_i( 0. ),
+	_th_o( 0. ),
+	_innerMat( MaterialData() ),
+	_outerMat( MaterialData() ),
+	_vol(),
+	_id(0),_refCount(0)  { 
+      }
+      
+      
+      VolSurfaceBase( SurfaceType typ, 
+		      double thickness_inner ,double thickness_outer, 
+		      Vector3D u_val ,Vector3D v_val ,
+		      Vector3D n ,Vector3D o, Geometry::Volume vol,int id ) : 
+	_type(typ ) ,
+	_u( u_val ) ,
+	_v( v_val ) ,
+	_n( n ) ,
+	_o( o ),
+	_th_i( thickness_inner ),
+	_th_o( thickness_outer ),  
+	_innerMat( MaterialData() ),
+	_outerMat( MaterialData() ),
+	_vol(vol) ,
+	_id( id ), _refCount(0) {
+      }
+      
+      
       /// Copy the from object
-      void copy(const SurfaceData& c) {
+      VolSurfaceBase(const VolSurfaceBase& c) {
         _type = c._type ;
         _u = c._u ;
         _v = c._v ;
@@ -100,57 +105,128 @@ namespace DD4hep {
         _innerMat = c._innerMat ;
         _outerMat = c._innerMat ;
         _vol = c._vol;
+	_id = c._id ;
+	_refCount = 0 ; // new instance
       }
-    } ;
-  
 
-    /** Implementation of ISurface for a local surface attached to a volume. 
-     * 
+
+      /// the volume to which this surface is attached.
+      Geometry::Volume volume() const { return _vol ; }
+
+      /// The id of this surface 
+      virtual long64 id() const  ;
+
+      /** properties of the surface encoded in Type.
+       * @see SurfaceType
+       */
+      virtual const SurfaceType& type() const ;
+    
+      //==== geometry ====
+      
+      /** First direction of measurement U */
+      virtual Vector3D u( const Vector3D& point = Vector3D() ) const ;
+    
+      /** Second direction of measurement V */
+      virtual Vector3D v(const Vector3D& point = Vector3D() ) const ;
+    
+      /// Access to the normal direction at the given point
+      virtual Vector3D normal(const Vector3D& point = Vector3D() ) const ;
+    
+      /** Get Origin of local coordinate system on surface */
+      virtual const Vector3D& origin() const ;
+      
+      /** Convert the global position to the local position (u,v) on the surface */
+      virtual Vector2D globalToLocal( const Vector3D& point) const ;
+      
+      /** Convert the local position (u,v) on the surface to the global position */
+      virtual Vector3D localToGlobal( const Vector2D& point) const ;
+      
+      /// Access to the material in opposite direction of the normal
+      virtual const IMaterial& innerMaterial() const ;
+
+      /// Access to the material in direction of the normal
+      virtual const IMaterial& outerMaterial() const ;
+    
+      /** Thickness of inner material */
+      virtual double innerThickness() const ;
+
+      /** Thickness of outer material */
+      virtual double outerThickness() const ;
+
+
+      /** The length of the surface along direction u at the origin. For 'regular' boundaries, like rectangles, 
+       *  this can be used to speed up the computation of inSideBounds.
+       */
+      virtual double length_along_u() const ;
+
+      /** The length of the surface along direction v at the origin. For 'regular' boundaries, like rectangles, 
+       *  this can be used to speed up the computation of inSideBounds.
+       */
+      virtual double length_along_v() const ;
+
+
+      /** Distance to surface */
+      virtual double distance(const Vector3D& point ) const ;
+      
+      /// Checks if the given point lies within the surface
+      virtual bool insideBounds(const Vector3D& point, double epsilon=1e-4 ) const ;
+
+
+      virtual std::vector< std::pair<Vector3D, Vector3D> > getLines(unsigned nMax=100) ;
+ 
+      /// set the inner Material
+      void setInnerMaterial( const IMaterial& mat ){ _innerMat = mat ; }
+
+      /// set the outer Materal
+      void setOuterMaterial( const IMaterial& mat ){ _outerMat = mat ; }
+
+    };
+
+    //---------------------------------------------------------------------------------------------
+    /** Reference counted handle class for a local surface attached to a volume (VolSurfaceBase). 
+     *
      * @author F.Gaede, DESY
-     * @date Apr, 6 2014
+     * @date Sep, 14 2015
      * @version $Id$
      */
-    class VolSurface : public Geometry::Handle< SurfaceData > , public ISurface {
+    class VolSurface : public ISurface {
     
     protected:
 
-      /// setter for daughter classes
-      virtual void setU(const Vector3D& u) ;
-      
-      /// setter for daughter classes
-      virtual void setV(const Vector3D& v) ;
-
-      /// setter for daughter classes
-      virtual void setNormal(const Vector3D& n) ;
+      VolSurfaceBase* _surf ;
 
     public:
     
-      virtual ~VolSurface() {} 
-
+      virtual ~VolSurface(){
+	if( _surf ) {
+	  -- _surf->_refCount ;
+	  if(  _surf->_refCount == 0 ) delete _surf ;
+	}
+      } 
       ///default c'tor
-      VolSurface() { }
+      VolSurface() : _surf(0) { }
 
       /// Constructor to be used with an existing object
-      VolSurface(SurfaceData* p)
-        : Geometry::Handle< SurfaceData >(p) {
-      }
-      /// Constructor to be used with an existing object
-      VolSurface(const VolSurface& vsurf)
-        : Geometry::Handle< SurfaceData >(vsurf)  {
-      }
+      VolSurface(VolSurfaceBase* p) : _surf( p ) { ++ _surf->_refCount ; }
 
       /// Constructor to be used with an existing object
-      template <typename Q> VolSurface(const Geometry::Handle<Q>& e)
-        : Geometry::Handle< SurfaceData >(e) {
+      VolSurface(const VolSurface& vsurf) : _surf( vsurf._surf ) {
+	++ _surf->_refCount ;
       }
-
-      /// Standrad c'tor for initialization.
-      VolSurface( Geometry::Volume vol, SurfaceType type, double thickness_inner ,double thickness_outer, 
-                  Vector3D u ,Vector3D v ,Vector3D n , Vector3D o = Vector3D(0.,0.,0.) ) ;      
+      
+      VolSurface& operator=(const VolSurface& vsurf) {
+	_surf = vsurf._surf ;
+	++ _surf->_refCount ;
+	return *this ;
+      }
+      
 
       /// the volume to which this surface is attached.
-      Geometry::Volume volume() const { return ptr()->_vol; }
+      Geometry::Volume volume() const { return _surf->volume() ; }
 
+      /// pointer to underlying object 
+      VolSurfaceBase* ptr() const { return _surf ; }	
+      
       /// The id of this surface - always 0 for VolSurfaces
       virtual long64 id() const  ;
 
@@ -202,27 +278,22 @@ namespace DD4hep {
        */
       virtual double length_along_v() const ;
 
-
-
-      // need default implementations for putting it in list....
-      
       /** Distance to surface */
       virtual double distance(const Vector3D& point ) const ;
       
       /// Checks if the given point lies within the surface
       virtual bool insideBounds(const Vector3D& point, double epsilon=1e-4 ) const ;
 
+      virtual std::vector< std::pair<Vector3D, Vector3D> > getLines(unsigned nMax=100) ;
+ 
+      /// set the innerMaterial
+      void setInnerMaterial( const IMaterial& mat ){ _surf->setInnerMaterial( mat ) ; }
 
-      //fixme: protected: + friend declaration ?
-
-      /// set the inner Material
-      void setInnerMaterial( Geometry::Material mat ){  object<SurfaceData>()._innerMat = mat ; }
       /// set the outer Materal
-      void setOuterMaterial( Geometry::Material mat ){  object<SurfaceData>()._outerMat = mat ; }
+      void setOuterMaterial( const IMaterial& mat ){  _surf->setOuterMaterial( mat ) ; }
 
     };
 
-
     //======================================================================================================
 
 
@@ -263,87 +334,60 @@ namespace DD4hep {
 
     //======================================================================================================
 
-    /** Implementation of planar surface attached to a volume 
+    /** Implementation of a planar surface attached to a volume 
      * @author F.Gaede, DESY
-     * @date Apr, 6 2014
+     * @date Sep, 14 2014
      * @version $Id$
      */
-    class VolPlane : public VolSurface {
+    class VolPlaneImpl : public VolSurfaceBase {
       
     public:
       
       ///default c'tor
-      VolPlane() : VolSurface() { }
-
-      /// Constructor to be used with an existing object
-      VolPlane(SurfaceData* p)
-        : VolSurface(p) {
-      }
+      VolPlaneImpl() : VolSurfaceBase() { }
 
-      /// Constructor to be used with an existing object
-      template <typename Q> VolPlane(const Geometry::Handle<Q>& e)
-        : VolSurface(e) {
-      }
-
-      /// copy c'tor
-      VolPlane(const VolSurface& vs ) : VolSurface( vs ) { }
-      
       /// standard c'tor with all necessary arguments - origin is (0,0,0) if not given.
-      VolPlane( Geometry::Volume vol, SurfaceType typ, double thickness_inner ,double thickness_outer, 
-                Vector3D u_val ,Vector3D v_val ,Vector3D n_val , Vector3D o_val = Vector3D(0.,0.,0.) ) :
+      VolPlaneImpl( SurfaceType typ, double thickness_inner ,double thickness_outer, 
+		    Vector3D u_val ,Vector3D v_val ,Vector3D n_val , Vector3D o_val, Geometry::Volume vol, int id  ) :
 	
-        VolSurface( vol, typ, thickness_inner, thickness_outer, u_val,v_val,n_val,o_val ) {
-
-        object<SurfaceData>()._type.setProperty( SurfaceType::Plane    , true ) ;
-        object<SurfaceData>()._type.setProperty( SurfaceType::Cylinder , false ) ;
-        object<SurfaceData>()._type.checkParallelToZ( *this ) ;
-        object<SurfaceData>()._type.checkOrthogonalToZ( *this ) ;
-
+	VolSurfaceBase( typ, thickness_inner, thickness_outer, u_val,v_val, n_val, o_val, vol,id ) {
+	
+        _type.setProperty( SurfaceType::Plane    , true ) ;
+        _type.setProperty( SurfaceType::Cylinder , false ) ;
+        _type.checkParallelToZ( *this ) ;
+        _type.checkOrthogonalToZ( *this ) ;
       }      
       
       /** Distance to surface */
       virtual double distance(const Vector3D& point ) const  ;
-      
-      /// Checks if the given point lies within the surface
-      virtual bool insideBounds(const Vector3D& point, double epsilon=1.e-4) const  ;
-
-      
     } ;
 
     //======================================================================================================
-
     /** Implementation of cylindrical surface attached to a volume 
      * @author F.Gaede, DESY
      * @date Apr, 6 2014
      * @version $Id$
      */
-    class VolCylinder : public VolSurface {
+    class VolCylinderImpl : public VolSurfaceBase {
       
     public:
       
       /// default c'tor
-      VolCylinder() : VolSurface() { }
+      VolCylinderImpl() : VolSurfaceBase() { }
 
-      /// copy c'tor
-      VolCylinder(const VolSurface& vs ) : VolSurface( vs ) { }
       
       /** The standard constructor. The origin vector points to the origin of the coordinate system on the cylinder,
        *  its rho defining the radius of the cylinder. The measurement direction v is set to be (0,0,1), the normal is
        *  chosen to be parallel to the origin vector and u = n X v. 
        */
-      VolCylinder( Geometry::Volume vol, SurfaceType type, double thickness_inner ,double thickness_outer,  Vector3D origin ) ;
+      VolCylinderImpl( Geometry::Volume vol, SurfaceType type, double thickness_inner ,double thickness_outer,  Vector3D origin ) ;
 
 
       /** First direction of measurement U - rotated to point projected onto the cylinder.
        *  No check is done whether the point actually is on the cylinder surface
        */
       virtual Vector3D u( const Vector3D& point = Vector3D() ) const ;
-    
-      /** Second direction  of measurement V - rotated to point projected onto the cylinder.
-       *  No check is done whether the point actually is on the cylinder surface
-       */
-      virtual Vector3D v(const Vector3D& point = Vector3D() ) const ;
-    
+      
       /** The normal direction at the given point, projected  onto the cylinder.
        *  No check is done whether the point actually is on the cylinder surface
        */
@@ -352,9 +396,6 @@ namespace DD4hep {
       /** Distance to surface */
       virtual double distance(const Vector3D& point ) const  ;
       
-      /// Checks if the given point lies within the surface
-      virtual bool insideBounds(const Vector3D& point, double epsilon=1.e-4) const  ;
-
       /** Convert the global position to the local position (u,v) on the surface - u runs along the axis of the cylinder, v is r*phi */
       virtual Vector2D globalToLocal( const Vector3D& point) const ;
       
@@ -362,8 +403,39 @@ namespace DD4hep {
       virtual Vector3D localToGlobal( const Vector2D& point) const ;
     } ;
 
+
+
     //======================================================================================================
+    
+    /** Template for VolSurface specializations.
+     *  Works for surfaces that take all surface vectors (u,v,n,o) in the c'tor.
+     * @author F.Gaede, DESY
+     * @date Sep, 14 2015
+     * @version $Id$
+     */
+    template <class T>
+    class VolSurfaceHandle : public VolSurface {
+      
+    public:
+      VolSurfaceHandle( Geometry::Volume vol, SurfaceType typ, double thickness_inner ,double thickness_outer, 
+			Vector3D u_val ,Vector3D v_val ,Vector3D n_val , Vector3D o_val = Vector3D(0.,0.,0.) ) :
+	
+	VolSurface(  new T( typ, thickness_inner, thickness_outer, u_val, v_val, n_val, o_val, vol , 0 )  ){
+      }
+    } ;
+
+    //---------------------------------------------------------------------------------------------
+    typedef VolSurfaceHandle< VolPlaneImpl > VolPlane ;
+    //---------------------------------------------------------------------------------------------
+
+    class VolCylinder : public VolSurface{
+    public:
+      VolCylinder( Geometry::Volume vol, SurfaceType type, double thickness_inner ,double thickness_outer,  Vector3D origin ) :
+	VolSurface( new VolCylinderImpl( vol,  type,  thickness_inner , thickness_outer, origin ) ) {}
+    } ;
 
+    //======================================================================================================
+    
     /** Implementation of Surface class holding a local surface attached to a volume and the DetElement 
      *  holding this surface.
      * 
@@ -372,15 +444,15 @@ namespace DD4hep {
      * @version $Id$
      */
     class Surface:  public ISurface {
-    
+      
     protected:
       
       Geometry::DetElement _det ;
-      VolSurface _volSurf ;
+      mutable VolSurface _volSurf ;
       TGeoMatrix* _wtM ; // matrix for world transformation of surface
-
+      
       long64 _id ;
-
+      
       SurfaceType _type ;
       Vector3D _u ;
       Vector3D _v ;
@@ -474,7 +546,7 @@ namespace DD4hep {
       /** Get lines constraining the surface for drawing ( might not be exact boundaries) -
        *  at most nMax lines are returned.
        */
-      std::vector< std::pair< Vector3D, Vector3D> > getLines(unsigned nMax=100) ;
+      virtual std::vector< std::pair< Vector3D, Vector3D> > getLines(unsigned nMax=100) ;
 
     protected:
       void initialize() ;
@@ -495,27 +567,6 @@ namespace DD4hep {
       ///Standard c'tor.
       CylinderSurface( Geometry::DetElement det, VolSurface volSurf ) : Surface( det, volSurf ) { }      
       
-      /** First direction of measurement U - rotated to point projected onto the cylinder.
-       *  No check is done whether the point actually is on the cylinder surface
-       */
-      virtual Vector3D u( const Vector3D& point = Vector3D() ) const ;
-    
-      /** Second direction of measurement V - rotated to point projected onto the cylinder.
-       *  No check is done whether the point actually is on the cylinder surface
-       */
-      virtual Vector3D v(const Vector3D& point = Vector3D() ) const ;
-    
-      /** The normal direction at the given point - rotated to point projected onto the cylinder.
-       *  No check is done whether the point actually is on the cylinder surface
-       */
-      virtual Vector3D normal(const Vector3D& point = Vector3D() ) const ;
-
-      /** Convert the global position to the local position (u,v) on the surface - u runs along the axis of the cylinder, v is r*phi */
-      virtual Vector2D globalToLocal( const Vector3D& point) const ;
-      
-      /** Convert the local position (u,v) on the surface to the global position  - u runs along the axis of the cylinder, v is r*phi*/
-      virtual Vector3D localToGlobal( const Vector2D& point) const ;
-
       /// the radius of the cylinder (rho of the origin vector)
       virtual double radius() const ;
 
diff --git a/DDRec/src/Surface.cpp b/DDRec/src/Surface.cpp
index bc8cc64c3ffb972631476c061536ba21f22ce5d1..0b9ef27b46d4db93b98d68a11141bb539fbd2e72 100644
--- a/DDRec/src/Surface.cpp
+++ b/DDRec/src/Surface.cpp
@@ -20,74 +20,21 @@ namespace DD4hep {
     using namespace Geometry ;
 
 
-    //======================================================================================================
-    
-#if !use_materialdata
-   
-    std::string SurfaceMaterial::name() const { return Geometry::Material::name() ; }
-    double SurfaceMaterial::Z() const {  return Geometry::Material::Z() ; } 
-    double SurfaceMaterial::A() const { return Geometry::Material::A() ; } 
-    double SurfaceMaterial::density() const {  return Geometry::Material::density() ; }
-    double SurfaceMaterial::radiationLength() const { return Geometry::Material::radLength() ; } 
-    double SurfaceMaterial::interactionLength() const  { return Geometry::Material::intLength() ; }
-    
-#endif    
-    //======================================================================================================
-    
-    
-    
-    SurfaceData::SurfaceData() : _type( SurfaceType() ) ,
-                                 _u( Vector3D() ) ,
-                                 _v( Vector3D()  ) ,
-                                 _n( Vector3D() ) ,
-                                 _o( Vector3D() ) ,
-                                 _th_i( 0. ),
-                                 _th_o( 0. ),
-                                 _innerMat( MaterialData() ),
-                                 _outerMat( MaterialData() ),
-                                 _vol()
-    {
-    }
+      //======================================================================================================
   
-  
-    SurfaceData::SurfaceData( SurfaceType typ, double thickness_inner ,double thickness_outer, 
-                              Vector3D u_val ,Vector3D v_val ,Vector3D n ,Vector3D o, Volume vol ) :  _type(typ ) ,
-                                                                                                      _u( u_val ) ,
-                                                                                                      _v( v_val ) ,
-                                                                                                      _n( n ) ,
-      _o( o ),
-      _th_i( thickness_inner ),
-      _th_o( thickness_outer ),  
-      _innerMat( MaterialData() ),
-      _outerMat( MaterialData() ),
-      _vol(vol)
-    {
-    }
-  
-  
-    //======================================================================================================
-  
-
-    VolSurface::VolSurface( Volume vol, SurfaceType typ, double thickness_inner ,double thickness_outer, 
-                            Vector3D u_val ,Vector3D v_val ,Vector3D n ,Vector3D o ) :  
-      
-      Geometry::Handle< SurfaceData >( new SurfaceData(typ, thickness_inner ,thickness_outer, u_val,v_val,n,o, vol) )  {
-    }      
-    
-
-    void VolSurface::setU(const Vector3D& u_val) { object<SurfaceData>()._u = u_val  ; }
-    void VolSurface::setV(const Vector3D& v_val) { object<SurfaceData>()._v = v_val ; }
-    void VolSurface::setNormal(const Vector3D& n) { object<SurfaceData>()._n = n ; }
+    void VolSurfaceBase::setU(const Vector3D& u_val) {  _u = u_val  ; }
+    void VolSurfaceBase::setV(const Vector3D& v_val) {  _v = v_val ; }
+    void VolSurfaceBase::setNormal(const Vector3D& n) { _n = n ; }
     
-    long64 VolSurface::id() const  { return 0 ; } 
+    long64 VolSurfaceBase::id() const  { return 0 ; } 
 
-    const SurfaceType& VolSurface::type() const { return object<SurfaceData>()._type ; }
-    Vector3D VolSurface::u( const Vector3D& point ) const {  point.x() ; return object<SurfaceData>()._u ; }
-    Vector3D VolSurface::v(const Vector3D& point  ) const { point.x() ;  return object<SurfaceData>()._v ; }
-    Vector3D VolSurface::normal(const Vector3D& point ) const {  point.x() ; return object<SurfaceData>()._n ; }
-    const Vector3D& VolSurface::origin() const { return object<SurfaceData>()._o ;}
+    const SurfaceType& VolSurfaceBase::type() const { return _type ; }
+    Vector3D VolSurfaceBase::u( const Vector3D& point ) const {  point.x() ; return _u ; }
+    Vector3D VolSurfaceBase::v(const Vector3D& point  ) const { point.x() ;  return _v ; }
+    Vector3D VolSurfaceBase::normal(const Vector3D& point ) const {  point.x() ; return _n ; }
+    const Vector3D& VolSurfaceBase::origin() const { return _o ;}
 
-    Vector2D VolSurface::globalToLocal( const Vector3D& point) const {
+    Vector2D VolSurfaceBase::globalToLocal( const Vector3D& point) const {
 
       Vector3D p = point - origin() ;
 
@@ -103,20 +50,20 @@ namespace DD4hep {
       return  Vector2D(   p*uprime / uup ,  p*vprime / vvp ) ;
     }
     
-    Vector3D VolSurface::localToGlobal( const Vector2D& point) const {
+    Vector3D VolSurfaceBase::localToGlobal( const Vector2D& point) const {
 
       Vector3D g = origin() + point[0] * u() + point[1] * v() ;
 
       return g ;
     }
 
-    const IMaterial&  VolSurface::innerMaterial() const{  return  object<SurfaceData>()._innerMat ;  }
-    const IMaterial&  VolSurface::outerMaterial() const { return  object<SurfaceData>()._outerMat  ; }
-    double VolSurface::innerThickness() const { return object<SurfaceData>()._th_i ; }
-    double VolSurface::outerThickness() const { return object<SurfaceData>()._th_o ; }
+    const IMaterial&  VolSurfaceBase::innerMaterial() const{  return  _innerMat ;  }
+    const IMaterial&  VolSurfaceBase::outerMaterial() const { return  _outerMat  ; }
+    double VolSurfaceBase::innerThickness() const { return _th_i ; }
+    double VolSurfaceBase::outerThickness() const { return _th_o ; }
     
 
-    double VolSurface::length_along_u() const {
+    double VolSurfaceBase::length_along_u() const {
       
       const DDSurfaces::Vector3D& o = this->origin() ;
       const DDSurfaces::Vector3D& u_val = this->u( o ) ;      
@@ -126,7 +73,7 @@ namespace DD4hep {
       double dist_m = 0. ;
       
 
-      // std::cout << " VolSurface::length_along_u() : o =  " << o << " u = " <<    this->u( o ) 
+      // std::cout << " VolSurfaceBase::length_along_u() : o =  " << o << " u = " <<    this->u( o ) 
       // 		<< " -u = " << um << std::endl ;
 
 
@@ -138,7 +85,7 @@ namespace DD4hep {
 							      const_cast<double*> ( um.array()      ) ) ;
 	
 
-	// std::cout << " VolSurface::length_along_u() : shape contains(o)  =  " << volume()->GetShape()->Contains( o.const_array() )
+	// std::cout << " VolSurfaceBase::length_along_u() : shape contains(o)  =  " << volume()->GetShape()->Contains( o.const_array() )
 	// 	  << " dist_p " <<    dist_p
 	// 	  << " dist_m " <<    dist_m
 	// 	  << std::endl ;
@@ -154,7 +101,7 @@ namespace DD4hep {
 	dist_p *= 1.0001 ;
 	dist_m *= 1.0001 ;
 
-	// std::cout << " VolSurface::length_along_u() : shape contains(o)  =  " << volume()->GetShape()->Contains( o.const_array() )
+	// std::cout << " VolSurfaceBase::length_along_u() : shape contains(o)  =  " << volume()->GetShape()->Contains( o.const_array() )
 	// 	  << " dist_p " <<    dist_p
 	// 	  << " dist_m " <<    dist_m
 	// 	  << std::endl ;
@@ -168,7 +115,7 @@ namespace DD4hep {
 	dist_m += volume()->GetShape()->DistFromInside( const_cast<double*> ( o_2.const_array() ) , 
 							const_cast<double*> ( um.array()      ) ) ;
 
-	// std::cout << " VolSurface::length_along_u() : shape contains(o)  =  " << volume()->GetShape()->Contains( o.const_array() )
+	// std::cout << " VolSurfaceBase::length_along_u() : shape contains(o)  =  " << volume()->GetShape()->Contains( o.const_array() )
 	// 	  << " dist_p " <<    dist_p
 	// 	  << " dist_m " <<    dist_m
 	// 	  << std::endl ;
@@ -179,7 +126,7 @@ namespace DD4hep {
 
     }
     
-    double VolSurface::length_along_v() const {
+    double VolSurfaceBase::length_along_v() const {
 
       const DDSurfaces::Vector3D& o = this->origin() ;
       const DDSurfaces::Vector3D& v_val = this->v( o ) ;      
@@ -189,7 +136,7 @@ namespace DD4hep {
       double dist_m = 0. ;
       
 
-      // std::cout << " VolSurface::length_along_u() : o =  " << o << " u = " <<    this->u( o ) 
+      // std::cout << " VolSurfaceBase::length_along_u() : o =  " << o << " u = " <<    this->u( o ) 
       // 		<< " -u = " << vm << std::endl ;
 
 
@@ -201,7 +148,7 @@ namespace DD4hep {
 							      const_cast<double*> ( vm.array()      ) ) ;
 	
 
-	// std::cout << " VolSurface::length_along_u() : shape contains(o)  =  " << volume()->GetShape()->Contains( o.const_array() )
+	// std::cout << " VolSurfaceBase::length_along_u() : shape contains(o)  =  " << volume()->GetShape()->Contains( o.const_array() )
 	// 	  << " dist_p " <<    dist_p
 	// 	  << " dist_m " <<    dist_m
 	// 	  << std::endl ;
@@ -217,7 +164,7 @@ namespace DD4hep {
 	dist_p *= 1.0001 ;
 	dist_m *= 1.0001 ;
 
-	// std::cout << " VolSurface::length_along_u() : shape contains(o)  =  " << volume()->GetShape()->Contains( o.const_array() )
+	// std::cout << " VolSurfaceBase::length_along_u() : shape contains(o)  =  " << volume()->GetShape()->Contains( o.const_array() )
 	// 	  << " dist_p " <<    dist_p
 	// 	  << " dist_m " <<    dist_m
 	// 	  << std::endl ;
@@ -231,7 +178,7 @@ namespace DD4hep {
 	dist_m += volume()->GetShape()->DistFromInside( const_cast<double*> ( o_2.const_array() ) , 
 							const_cast<double*> ( vm.array()      ) ) ;
 
-	// std::cout << " VolSurface::length_along_u() : shape contains(o)  =  " << volume()->GetShape()->Contains( o.const_array() )
+	// std::cout << " VolSurfaceBase::length_along_u() : shape contains(o)  =  " << volume()->GetShape()->Contains( o.const_array() )
 	// 	  << " dist_p " <<    dist_p
 	// 	  << " dist_m " <<    dist_m
 	// 	  << std::endl ;
@@ -242,23 +189,10 @@ namespace DD4hep {
     }
     
 
-    double VolSurface::distance(const Vector3D& point ) const  {  point.x() ; return 1.e99 ; }
-    
-    bool VolSurface::insideBounds(const Vector3D& point, double epsilon) const {  
-      point.x() ; (void) epsilon ; return false ; 
-    }
-
-    //======================================================================================================
+    double VolSurfaceBase::distance(const Vector3D& point ) const  {  point.x() ; return 1.e99 ; }
 
-
-    /** Distance to surface */
-    double VolPlane::distance(const Vector3D& point ) const {
-
-      return ( point - origin() ) *  normal()  ;
-    }
-    
     /// Checks if the given point lies within the surface
-    bool VolPlane::insideBounds(const Vector3D& point, double epsilon) const {
+    bool VolSurfaceBase::insideBounds(const Vector3D& point, double epsilon) const {
       
 #if 0
       double dist = std::abs ( distance( point ) ) ;
@@ -280,121 +214,116 @@ namespace DD4hep {
     }
 
 
-    //=============================================================================================================
+    std::vector< std::pair<Vector3D, Vector3D> > VolSurfaceBase::getLines(unsigned nMax) {
+      // dummy implementation returning empty set
+      nMax ;
+      std::vector< std::pair<Vector3D, Vector3D> >  lines ;
+      return lines ;
+    }
 
-    VolCylinder::VolCylinder( Geometry::Volume vol, SurfaceType typ, double thickness_inner ,double thickness_outer,  Vector3D o ) :
+    //===================================================================
+    // simple wrapper methods forwarding the call to the implementation object
+
+    long64 VolSurface::id() const  { return _surf->id() ; } 
+    const SurfaceType& VolSurface::type() const { return _surf->type() ; }
+    Vector3D VolSurface::u( const Vector3D& point ) const {  return _surf->u(point) ; }
+    Vector3D VolSurface::v(const Vector3D& point  ) const {  return _surf->v(point) ; }
+    Vector3D VolSurface::normal(const Vector3D& point ) const {  return _surf->normal(point) ; }
+    const Vector3D& VolSurface::origin() const { return _surf->origin() ;}
+    Vector2D VolSurface::globalToLocal( const Vector3D& point) const { return _surf->globalToLocal( point ) ; }
+    Vector3D VolSurface::localToGlobal( const Vector2D& point) const { return _surf->localToGlobal( point) ; }
+    const IMaterial&  VolSurface::innerMaterial() const{ return _surf->innerMaterial() ; }
+    const IMaterial&  VolSurface::outerMaterial() const  { return _surf->outerMaterial()  ; }
+    double VolSurface::innerThickness() const { return _surf->innerThickness() ; }
+    double VolSurface::outerThickness() const { return _surf->outerThickness() ; }
+    double VolSurface::length_along_u() const { return _surf->length_along_u() ; }
+    double VolSurface::length_along_v() const { return _surf->length_along_v() ; }
+    double VolSurface::distance(const Vector3D& point ) const  {  return _surf->distance( point ) ; }
+    bool VolSurface::insideBounds(const Vector3D& point, double epsilon) const {
+      return _surf->insideBounds( point, epsilon ) ; 
+    }
+    std::vector< std::pair<Vector3D, Vector3D> > VolSurface::getLines(unsigned nMax) {
+      return _surf->getLines(nMax) ;
+    }
 
-      VolSurface( vol, typ, thickness_inner, thickness_outer, Vector3D() , Vector3D() , Vector3D() , o ) {
-    
-      Vector3D v_val( 0., 0., 1. ) ;
+    //===================================================================
 
-      Vector3D o_rphi( o.x() , o.y() , 0. ) ;
+    /** Distance to planar surface */
+    double VolPlaneImpl::distance(const Vector3D& point ) const {
+      return ( point - origin() ) *  normal()  ;
+    }
+   //======================================================================================================
 
+    VolCylinderImpl::VolCylinderImpl( Geometry::Volume vol, SurfaceType typ, 
+				      double thickness_inner ,double thickness_outer,  Vector3D o ) :
+
+      VolSurfaceBase(typ, thickness_inner, thickness_outer, Vector3D() , Vector3D() , Vector3D() , o , vol, 0) {
+      Vector3D v_val( 0., 0., 1. ) ;
+      Vector3D o_rphi( o.x() , o.y() , 0. ) ;
       Vector3D n =  o_rphi.unit() ; 
-    
       Vector3D u_val = v_val.cross( n ) ;
 
       setU( u_val ) ;
       setV( v_val ) ;
       setNormal( n ) ;
 
-      object<SurfaceData>()._type.setProperty( SurfaceType::Plane    , false ) ;
-
-      object<SurfaceData>()._type.setProperty( SurfaceType::Cylinder , true ) ;
- 
-      object<SurfaceData>()._type.checkParallelToZ( *this ) ;
-
-      object<SurfaceData>()._type.checkOrthogonalToZ( *this ) ;
+      _type.setProperty( SurfaceType::Plane    , false ) ;
+      _type.setProperty( SurfaceType::Cylinder , true ) ;
+      _type.checkParallelToZ( *this ) ;
+      _type.checkOrthogonalToZ( *this ) ;
     }      
 
-
-    Vector3D VolCylinder::v( const Vector3D& point  ) const { 
-      // for now we just have v const as (0,0,1)
-      point.x() ; return VolSurface::v() ; 
-    }
-    
-    Vector3D VolCylinder::u(const Vector3D& point ) const {  
+    Vector3D VolCylinderImpl::u(const Vector3D& point ) const {  
 
       Vector3D n( 1. , point.phi() , 0. , Vector3D::cylindrical ) ;
 
-      // std::cout << " u : " << u()
-      // 		<< " n : " << n 
-      // 		<< " u X n :" << u().cross( n ) ;  
       return v().cross( n ) ; 
     }
     
-    Vector3D VolCylinder::normal(const Vector3D& point ) const {  
+    Vector3D VolCylinderImpl::normal(const Vector3D& point ) const {  
 
       // normal is just given by phi of the point 
       return Vector3D( 1. , point.phi() , 0. , Vector3D::cylindrical ) ;
     }
 
-
-
-
-    Vector2D VolCylinder::globalToLocal( const Vector3D& point) const {
+    Vector2D VolCylinderImpl::globalToLocal( const Vector3D& point) const {
       
       // cylinder is parallel to v here so u is Z and v is r *Phi
       double phi = point.phi() - origin().phi() ;
       
       while( phi < -M_PI ) phi += 2.*M_PI ;
       while( phi >  M_PI ) phi -= 2.*M_PI ;
- 
+      
       return  Vector2D( origin().rho() * phi, point.z() - origin().z() ) ;
     }
     
     
-    Vector3D VolCylinder::localToGlobal( const Vector2D& point) const {
-
+    Vector3D VolCylinderImpl::localToGlobal( const Vector2D& point) const {
+      
       double z = point.v() + origin().z() ;
       double phi = point.u() / origin().rho() + origin().phi() ;
-
+      
       while( phi < -M_PI ) phi += 2.*M_PI ;
       while( phi >  M_PI ) phi -= 2.*M_PI ;
-
+      
       return Vector3D( origin().rho() , phi, z  , Vector3D::cylindrical )    ;
     }
 
 
     /** Distance to surface */
-    double VolCylinder::distance(const Vector3D& point ) const {
-
+    double VolCylinderImpl::distance(const Vector3D& point ) const {
+      
       return point.rho() - origin().rho()  ;
     }
     
-    /// Checks if the given point lies within the surface
-    bool VolCylinder::insideBounds(const Vector3D& point, double epsilon) const {
-      
-#if 0
-      double distR = std::abs( distance( point ) ) ;
-      
-      bool inShapeT = volume()->GetShape()->Contains( const_cast<double*> ( point.const_array() ) ) ;
-      
-      std::cout << " ** Surface::insideBound( " << point << " ) - distance = " << distR 
-                << " origin = " << origin() 
-                << " isInShape : " << inShapeT << std::endl ;
-      
-      return distR < epsilon && inShapeT ;
-#else
-      
-      return ( std::abs ( distance( point ) ) < epsilon )  &&  volume()->GetShape()->Contains( const_cast<double*> (point.const_array())  ) ; 
-
-#endif
-    }
-
-
-
-
     //================================================================================================================
 
 
     VolSurfaceList::~VolSurfaceList(){
-      
-      // delete all surfaces attached to this volume
-      for( VolSurfaceList::iterator i=begin(), n=end() ; i !=n ; ++i ) {
-        i->clear() ;
-      }
-      
+      // // delete all surfaces attached to this volume
+      // for( VolSurfaceList::iterator i=begin(), n=end() ; i !=n ; ++i ) {
+      //   i->clear() ;
+      // }
     }
     //=======================================================
 
@@ -519,52 +448,42 @@ namespace DD4hep {
     
     const IMaterial& Surface::innerMaterial() const {
       
-      SurfaceMaterial& mat = _volSurf->_innerMat ;
+      const IMaterial& mat = _volSurf.innerMaterial() ;
       
-      //      std::cout << "  **** Surface::innerMaterial() " << mat << std::endl ;
-
-      if( ! mat.isValid() ) {
+      if( ! ( mat.Z() > 0 ) ) {
 	
         MaterialManager matMgr ;
-
-        Vector3D p = _o - innerThickness() * _n  ;
+        
+	Vector3D p = _o - innerThickness() * _n  ;
 
         const MaterialVec& materials = matMgr.materialsBetween( _o , p  ) ;
-	
-        // std::cout << " ####### found materials between points : " << _o << " and " << p << " : " ;
-        // for( unsigned i=0,n=materials.size();i<n;++i){
-        //   std::cout <<  materials[i].first.name() << "[" <<   materials[i].second << "], " ;
-        // }
-        // std::cout << std::endl ;
-        // const MaterialData& matAvg = matMgr.createAveragedMaterial( materials ) ; 
-        // mat = matAvg ;
-        // std::cout << "  **** Surface::innerMaterial() - assigning averaged material to surface : " << mat << std::endl ;
-
-        mat = ( materials.size() > 1  ? matMgr.createAveragedMaterial( materials ) : materials[0].first  ) ;
 
+	_volSurf.setInnerMaterial(  materials.size() > 1  ? 
+				    matMgr.createAveragedMaterial( materials ) :
+				    materials[0].first  )  ;
       }
       return  mat ;
     }
-      
 
     const IMaterial& Surface::outerMaterial() const {
-
-      SurfaceMaterial& mat = _volSurf->_outerMat ;
       
-      if( ! mat.isValid() ) {
+      const IMaterial& mat = _volSurf.outerMaterial() ;
+      
+      if( ! ( mat.Z() > 0 ) ) {
 	
         MaterialManager matMgr ;
-
-        Vector3D p = _o + outerThickness() * _n  ;
+        
+	Vector3D p = _o - outerThickness() * _n  ;
 
         const MaterialVec& materials = matMgr.materialsBetween( _o , p  ) ;
-	
-        mat = ( materials.size() > 1  ? matMgr.createAveragedMaterial( materials ) : materials[0].first  ) ;
 
+	_volSurf.setOuterMaterial(  materials.size() > 1  ? 
+				    matMgr.createAveragedMaterial( materials ) :
+				    materials[0].first  )  ;
       }
       return  mat ;
-    }          
-
+    }
+      
 
     Vector2D Surface::globalToLocal( const Vector3D& point) const {
 
@@ -608,7 +527,8 @@ namespace DD4hep {
       _wtM->MasterToLocal( point , pa ) ;
       Vector3D localPoint( pa ) ;
       
-      return ( _volSurf.type().isPlane() ?   VolPlane(_volSurf).distance( localPoint )  : VolCylinder(_volSurf).distance( localPoint ) ) ;
+      return _volSurf.distance( point ) ;
+      //FG      return ( _volSurf.type().isPlane() ?   VolPlane(_volSurf).distance( localPoint )  : VolCylinder(_volSurf).distance( localPoint ) ) ;
     }
       
     bool Surface::insideBounds(const Vector3D& point, double epsilon) const {
@@ -617,7 +537,9 @@ namespace DD4hep {
       _wtM->MasterToLocal( point , pa ) ;
       Vector3D localPoint( pa ) ;
       
-      return ( _volSurf.type().isPlane() ?   VolPlane(_volSurf).insideBounds( localPoint, epsilon )  : VolCylinder(_volSurf).insideBounds( localPoint , epsilon) ) ;
+      return _volSurf.insideBounds( localPoint , epsilon) ;
+
+      //FG      return ( _volSurf.type().isPlane() ?   VolPlane(_volSurf).insideBounds( localPoint, epsilon )  : VolCylinder(_volSurf).insideBounds( localPoint , epsilon) ) ;
     }
 
     void Surface::initialize() {
@@ -741,7 +663,28 @@ namespace DD4hep {
 
       std::vector< std::pair<Vector3D, Vector3D> > lines ;
 
+      //--------------------------------------------
+      // check if there are lines defined in the VolSurface :
+      const std::vector< std::pair<Vector3D, Vector3D> >& local_lines = _volSurf.getLines() ;
+      
+      if( local_lines.size() > 0 ) {
+	unsigned n=local_lines.size() ;
+	lines.reserve( n ) ;
 	
+	for( unsigned i=0;i<n;++i){
+	  
+	  DDSurfaces::Vector3D av,bv;
+	  _wtM->LocalToMasterVect( local_lines[i].first ,  av.array() ) ;
+	  _wtM->LocalToMasterVect( local_lines[i].second , bv.array() ) ;
+	  
+	  lines.push_back( std::make_pair( av, bv ) );
+	}
+	
+	return lines ;
+      }
+      //--------------------------------------------
+
+
       // get local and global surface vectors
       const DDSurfaces::Vector3D& lu = _volSurf.u() ;
       //      const DDSurfaces::Vector3D& lv = _volSurf.v() ;
@@ -1081,62 +1024,13 @@ namespace DD4hep {
 
     //================================================================================================================
 
-    Vector3D CylinderSurface::u( const Vector3D& point  ) const { 
-
-      Vector3D lp , u_val ;
-      _wtM->MasterToLocal( point , lp.array() ) ;
-      const DDSurfaces::Vector3D& lu = VolCylinder(_volSurf).u( lp  ) ;
-      _wtM->LocalToMasterVect( lu , u_val.array() ) ;
-      return u_val ; 
-    }
-    
-    Vector3D CylinderSurface::v(const Vector3D& point ) const {  
-      Vector3D lp , v_val ;
-      _wtM->MasterToLocal( point , lp.array() ) ;
-      const DDSurfaces::Vector3D& lv =  VolCylinder(_volSurf).v( lp  ) ;
-      _wtM->LocalToMasterVect( lv , v_val.array() ) ;
-      return v_val ; 
-    }
-    
-    Vector3D CylinderSurface::normal(const Vector3D& point ) const {  
-      Vector3D lp , n ;
-      _wtM->MasterToLocal( point , lp.array() ) ;
-      const DDSurfaces::Vector3D& ln =  VolCylinder(_volSurf).normal( lp  ) ;
-      _wtM->LocalToMasterVect( ln , n.array() ) ;
-      return n ; 
-    }
-
-    Vector2D CylinderSurface::globalToLocal( const Vector3D& point) const {
-      
-      Vector3D lp;
-      _wtM->MasterToLocal( point , lp.array() ) ;
-
-      return   VolCylinder(_volSurf).globalToLocal( lp )  ;
-    }
-    
-    
-    Vector3D CylinderSurface::localToGlobal( const Vector2D& point) const {
-
-      Vector3D lp =  VolCylinder(_volSurf).localToGlobal( point ) ;
-      Vector3D p ;
-      _wtM->LocalToMaster( lp , p.array() ) ;
-
-      return p ;
-    }
-
     double CylinderSurface::radius() const {	return _volSurf.origin().rho() ;  }
 
     Vector3D CylinderSurface::center() const {	return volumeOrigin() ;  }
 
     //================================================================================================================
 
-
-
-
   } // namespace
 } // namespace
 
 
-#include "DD4hep/Handle.inl"
-typedef DD4hep::DDRec::SurfaceData SurfaceData;
-DD4HEP_INSTANTIATE_HANDLE_UNNAMED(SurfaceData);
diff --git a/DDTest/src/test_surface.cc b/DDTest/src/test_surface.cc
index f8468b75b379636f4a5df8f307be362dea5c61ac..78595a71884d13b106b1e9cbfd402de08453f125 100644
--- a/DDTest/src/test_surface.cc
+++ b/DDTest/src/test_surface.cc
@@ -140,19 +140,19 @@ int main(int argc, char** argv ){
 
 
 
-    // --- test SurfaceMaterial
-    SurfaceMaterial sm( mat ) ;
+    // --- test MaterialData
+    MaterialData sm( mat ) ;
 
     // material properies of Si :
-    test( STR( sm.A() )  , STR( 28.0855 ) , "   SurfaceMaterial.A() == 28.0855 " ) ; 
+    test( STR( sm.A() )  , STR( 28.0855 ) , "   MaterialData.A() == 28.0855 " ) ; 
 
-    test( STR( sm.Z() )  , STR( 14 ) , "   SurfaceMaterial.Z() == 14 " ) ; 
+    test( STR( sm.Z() )  , STR( 14 ) , "   MaterialData.Z() == 14 " ) ; 
 
-    test( STR( sm.density() )  , STR( 2.33 ) , "   SurfaceMaterial.density() == 2.33 " ) ; 
+    test( STR( sm.density() )  , STR( 2.33 ) , "   MaterialData.density() == 2.33 " ) ; 
 
-    test( STR( sm.radiationLength() / dd4hep::mm )  , STR( 93.4961 ) , "   SurfaceMaterial.radiationLength() == 93.4961 * mm " ) ; 
+    test( STR( sm.radiationLength() / dd4hep::mm )  , STR( 93.4961 ) , "   MaterialData.radiationLength() == 93.4961 * mm " ) ; 
 
-    test( STR( sm.interactionLength() / dd4hep::mm )  , STR( 457.532 ) , "   SurfaceMaterial.interactionLength() == 457.532 * mm " ) ; 
+    test( STR( sm.interactionLength() / dd4hep::mm )  , STR( 457.532 ) , "   MaterialData.interactionLength() == 457.532 * mm " ) ; 
     
 
 
diff --git a/doc/release.notes b/doc/release.notes
index fb36c28c65cb4c89bb3716308b58f8a0308c6df2..3f6168c1b9dfed585657b33b6e5489630c9dd352 100644
--- a/doc/release.notes
+++ b/doc/release.notes
@@ -3,6 +3,13 @@
 DD4hep  ----  Release Notes
 =================================
 
+2015-09-15 F.Gaede
+  - refactoring of Surface classes:
+    - made VolSurface a reference counting handle to 
+      a polymorphic pointer of type VolSurfaceBase
+      - this should facilitate the creation
+        of dedicated surface classes for special cases
+        such as inside the beampipe or the face of the calorimeter
 
 2015-08-27 F.Gaede
   - added macros DD4HEP_VERSION_GE(MAJV,MINV) and DD4HEP_VERSION_GT(MAJV,MINV)