diff --git a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoNodeAction.h b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoNodeAction.h
index 9cb8656cbb02ce8d277c4af33e97380cf09a8784..bc08ace014ef6abd489aa45cd55f556c8fdf53d3 100644
--- a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoNodeAction.h
+++ b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoNodeAction.h
@@ -25,6 +25,8 @@
 #include "GeoModelKernel/GeoSerialDenominator.h"
 #include "GeoModelKernel/GeoSerialIdentifier.h"
 #include "GeoModelKernel/GeoSerialTransformer.h"
+#include "GeoModelKernel/GeoVSurface.h"
+#include "GeoModelKernel/GeoRectSurface.h"
 #include "GeoModelKernel/GeoNodePath.h"
 
 class GeoNodeAction 
@@ -65,6 +67,11 @@ class GeoNodeAction
   //	Handles a SerialIdentifier.
   virtual void handleSerialIdentifier(const GeoSerialIdentifier *);
 
+  //    Handle GeoVSurface
+  virtual void handleVSurface (const GeoVSurface *surface);
+
+  //    Handle GeoVSurface
+  virtual void handleRectSurface (const GeoRectSurface *surface);
 
   //	Returns a pointer to the path object.
   GeoNodePath* getPath ();
@@ -83,6 +90,8 @@ class GeoNodeAction
   
   //	Clears a depth limit, if any.
   void clearDepthLimit ();
+
+
   
  protected:
   //	Termination flag; causes an abortion of action execution.
diff --git a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoPrintGraphAction.h b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoPrintGraphAction.h
index bed2e982748e4513673ad6eae636e7cf7a4c759c..dd803947ca8951363608c8056984e12f68d61a8e 100644
--- a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoPrintGraphAction.h
+++ b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoPrintGraphAction.h
@@ -31,26 +31,32 @@ class GeoPrintGraphAction : public GeoNodeAction
   virtual ~GeoPrintGraphAction();
 
   //	Handles a Transform.
-  virtual void handleTransform (const GeoTransform *xform);
+  virtual void handleTransform (const GeoTransform *xform) override final;
   
   //	Handles a physical volume.
-  virtual void handlePhysVol (const GeoPhysVol *vol);
+  virtual void handlePhysVol (const GeoPhysVol *vol) override final;
   
   //	Handles a physical volume.
-  virtual void handleFullPhysVol (const GeoFullPhysVol *vol);
+  virtual void handleFullPhysVol (const GeoFullPhysVol *vol) override final;
   
   //	Handles a Name Tag.
-  virtual void handleNameTag (const GeoNameTag *nameTag);
+  virtual void handleNameTag (const GeoNameTag *nameTag) override final;
   
   //	Handles a Serial Denominator.
-  virtual void handleSerialDenominator (const GeoSerialDenominator *sD);
+  virtual void handleSerialDenominator (const GeoSerialDenominator *sD) override final;
   
   //	Handles a Serial Transformer
-  virtual void handleSerialTransformer (const GeoSerialTransformer  *sT);
+  virtual void handleSerialTransformer (const GeoSerialTransformer  *sT) override final;
   
   //	Handles an Identifier Tag.
-  virtual void handleIdentifierTag (const GeoIdentifierTag *idTag);
+  virtual void handleIdentifierTag (const GeoIdentifierTag *idTag) override final;
   
+  //    Handle a virtual surface.
+  virtual void handleVSurface(const GeoVSurface *surface) override final;
+
+  //    Handle a rectangular surface.
+  virtual void handleRectSurface( const GeoRectSurface *rect) override final; 
+
   //	Sets the notification state.  Default: everything on.
   void setNotification (Type type, bool state);
   
diff --git a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoSurfaceCursor.h b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoSurfaceCursor.h
new file mode 100644
index 0000000000000000000000000000000000000000..6f961144b664f731cc1236f16bff72542fc05f1e
--- /dev/null
+++ b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoSurfaceCursor.h
@@ -0,0 +1,65 @@
+#ifndef GEOMODELKERNEL_GEOSURFCURSOR_H
+#define GEOMODELKERNEL_GEOSURFCURSOR_H
+
+#include "GeoModelKernel/GeoNodeAction.h"
+#include "GeoModelKernel/GeoDefinitions.h"
+#include "GeoModelKernel/GeoVSurface.h"
+#include <vector>
+
+class GeoVAlignmentStore;
+
+class GeoSurfaceCursor final : public GeoNodeAction
+{
+ public:
+ 
+  using VSConstLink = GeoIntrusivePtr<const GeoVSurface>;
+  
+  GeoSurfaceCursor (PVConstLink parent, GeoVAlignmentStore* store=nullptr);
+  virtual ~GeoSurfaceCursor() override;
+  
+  GeoSurfaceCursor(const GeoSurfaceCursor &right) = delete;
+  GeoSurfaceCursor & operator=(const GeoSurfaceCursor &right) = delete;
+  
+  void next();
+  
+  bool atEnd() const;
+  
+  /// Returns the transformation to the surface or volume.
+  GeoTrf::Transform3D getTransform () const;
+  
+  /// Returns the default ransformation to the surface or volume.
+  GeoTrf::Transform3D getDefTransform () const;
+        
+ private:
+  /// Handles a Transform.
+  virtual void handleTransform (const GeoTransform *xform) override; 
+ 
+  /// Handles a physical volume.
+  virtual void handlePhysVol (const GeoPhysVol *vol) override;
+
+  /// Handles a physical volume.
+  virtual void handleFullPhysVol (const GeoFullPhysVol *vol) override;
+   
+  /// Handles a rectangular virtual surface.
+  virtual void handleVSurface (const GeoVSurface *surf) override;
+  
+  /// Ressucitate (undo terminate)
+  void resuscitate();
+  
+  PVConstLink                           m_parent;
+  PVConstLink                           m_volume;
+  VSConstLink                           m_surface;
+  GeoTrf::Transform3D                   m_transform;
+  GeoTrf::Transform3D                   m_defTransform;
+      
+  unsigned int                          m_majorIndex;
+  unsigned int                          m_volCount;
+  unsigned int                          m_surfCount;
+   
+  std::vector<const GeoTransform *>     m_pendingTransformList;
+  
+  bool                                  m_hasAlignTrans;  
+  GeoVAlignmentStore                   *m_alignStore;
+};
+
+#endif
diff --git a/GeoModelCore/GeoModelKernel/src/GeoNodeAction.cxx b/GeoModelCore/GeoModelKernel/src/GeoNodeAction.cxx
index e4164026dad22e33deee9fa3d5a12bdc3ae80285..04748c32a24d2daebfb0d9fa432345415ad98545 100755
--- a/GeoModelCore/GeoModelKernel/src/GeoNodeAction.cxx
+++ b/GeoModelCore/GeoModelKernel/src/GeoNodeAction.cxx
@@ -80,3 +80,12 @@ void GeoNodeAction::handleIdentifierTag (const GeoIdentifierTag *)
 void GeoNodeAction::handleSerialIdentifier(const GeoSerialIdentifier *)
 {
 }
+
+void GeoNodeAction::handleVSurface (const GeoVSurface *surface) {
+}
+
+void GeoNodeAction::handleRectSurface (const GeoRectSurface *rect) {
+}
+
+
+
diff --git a/GeoModelCore/GeoModelKernel/src/GeoPrintGraphAction.cxx b/GeoModelCore/GeoModelKernel/src/GeoPrintGraphAction.cxx
index 7ff1252d7cb02c341205e925ef52920108ee6759..9bf48b1d84a2f03c2329438f7ada1a42d6f1e539 100755
--- a/GeoModelCore/GeoModelKernel/src/GeoPrintGraphAction.cxx
+++ b/GeoModelCore/GeoModelKernel/src/GeoPrintGraphAction.cxx
@@ -86,6 +86,22 @@ void GeoPrintGraphAction::handleIdentifierTag (const GeoIdentifierTag *idTag)
   }
 }
 
+
+//    Handle GeoVirSurface
+void GeoPrintGraphAction::handleVSurface (const GeoVSurface *surface) {
+  indent();
+  m_o << "HELLO from VirtualSurface" << std::endl;
+}
+
+  //    Handle GeoVSurface
+void GeoPrintGraphAction::handleRectSurface (const GeoRectSurface *surface) {
+  indent();
+  m_o << "HELLO from RectSurface" << std::endl;
+}
+
+
+
+
 void GeoPrintGraphAction::setNotification (Type type, bool state)
 {
   if (type==TRANSFORM) {
diff --git a/GeoModelCore/GeoModelKernel/src/GeoSurfaceCursor.cxx b/GeoModelCore/GeoModelKernel/src/GeoSurfaceCursor.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..ef5cac935d69a6736d150c073ea04b9a37902e52
--- /dev/null
+++ b/GeoModelCore/GeoModelKernel/src/GeoSurfaceCursor.cxx
@@ -0,0 +1,161 @@
+#include "GeoModelKernel/GeoSurfaceCursor.h"
+#include "GeoModelKernel/GeoAlignableTransform.h"
+
+GeoSurfaceCursor::GeoSurfaceCursor (PVConstLink parent, GeoVAlignmentStore* store)
+  : m_parent(parent)
+  , m_transform(GeoTrf::Transform3D::Identity())
+  , m_defTransform(GeoTrf::Transform3D::Identity())  
+  , m_majorIndex(0)
+  , m_volCount(0)
+  , m_surfCount(0)
+  , m_alignStore(store)  
+{
+  setDepthLimit(0);
+  next();
+}
+
+GeoSurfaceCursor::~GeoSurfaceCursor()
+{
+}
+
+void GeoSurfaceCursor::next() {
+  resuscitate();
+  
+  // not considering serial transformer
+  m_volume=nullptr;
+  m_surface=nullptr;
+
+  m_pendingTransformList.erase (m_pendingTransformList.begin (),
+ 	                        m_pendingTransformList.end ());  
+ 	                        
+  int N = m_parent->getNChildNodes();
+  std::cout << " ChildNodes = " << N << std::endl;////////////
+  std::cout << " m_majorIndex = " << m_majorIndex << std::endl;////////////
+  if (N==0) return;  
+  
+  const GeoGraphNode * const *node  = m_parent->getChildNode(m_majorIndex);
+  const GeoGraphNode * const *back  = m_parent->getChildNode(N-1);
+  const GeoGraphNode * const *end   = back+1;  
+  int i = 0;////////////
+  while (node!=end) {
+    (*node)->exec(this);
+    const GeoGraphNode * const * flag = node;
+    
+    node++;
+    m_majorIndex++;
+    
+    if (m_terminate) {
+      
+      if (dynamic_cast<const GeoVPhysVol*> (*flag)){
+        m_volCount++;
+        std::cout << " PHYSICS VOLUME " << std::endl;
+        std::cout << " volume count = " << m_volCount << std::endl;////////////
+      }
+      else if (dynamic_cast<const GeoVSurface*> (*flag)){
+        m_surfCount++;
+        std::cout << " VIRTUAL SURFACE " << std::endl;
+        std::cout << " surf count = " << m_surfCount << std::endl;////////////
+      }
+      
+      break;
+    }
+  }    
+}
+
+void GeoSurfaceCursor::resuscitate() {
+  m_terminate = false;
+}
+
+bool GeoSurfaceCursor::atEnd() const {
+  return (!m_volume and !m_surface);
+}
+
+void GeoSurfaceCursor::handleTransform (const GeoTransform *xform)
+{
+  m_pendingTransformList.push_back (xform);
+  if(dynamic_cast<const GeoAlignableTransform*>(xform))
+    m_hasAlignTrans = true;
+}
+
+void GeoSurfaceCursor::handlePhysVol (const GeoPhysVol *vol)
+{
+  m_volume = vol;
+  
+  unsigned int listSize = m_pendingTransformList.size ();
+  if (listSize == 0) {
+    m_transform    = GeoTrf::Transform3D::Identity();
+    m_defTransform = GeoTrf::Transform3D::Identity();
+  }
+  else {
+    m_transform = m_pendingTransformList[0]->getTransform(m_alignStore);
+    m_defTransform = m_pendingTransformList[0]->getDefTransform(m_alignStore);
+    for (unsigned int t = 1; t < m_pendingTransformList.size (); t++) {
+      m_transform    = m_transform    * m_pendingTransformList[t]->getTransform(m_alignStore);
+      m_defTransform = m_defTransform * m_pendingTransformList[t]->getDefTransform(m_alignStore);
+    }
+  }
+    
+  terminate ();
+}
+
+void GeoSurfaceCursor::handleFullPhysVol (const GeoFullPhysVol *vol)
+{
+  m_volume = vol;
+  
+  unsigned int listSize = m_pendingTransformList.size ();
+  if (listSize == 0) {
+    m_transform    = GeoTrf::Transform3D::Identity();
+    m_defTransform = GeoTrf::Transform3D::Identity();
+  }
+  else {
+    m_transform = m_pendingTransformList[0]->getTransform(m_alignStore);
+    m_defTransform = m_pendingTransformList[0]->getDefTransform(m_alignStore);
+    for (unsigned int t = 1; t < m_pendingTransformList.size (); t++) {
+      m_transform    = m_transform    * m_pendingTransformList[t]->getTransform(m_alignStore);
+      m_defTransform = m_defTransform * m_pendingTransformList[t]->getDefTransform(m_alignStore);
+    }
+  }  
+  
+  terminate ();
+}
+
+void GeoSurfaceCursor::handleVSurface (const GeoVSurface *surf)
+{
+  m_surface = surf;
+  
+  unsigned int listSize = m_pendingTransformList.size ();
+  if (listSize == 0) {
+    m_transform    = GeoTrf::Transform3D::Identity();
+    m_defTransform = GeoTrf::Transform3D::Identity();
+  }
+  else {
+    m_transform = m_pendingTransformList[0]->getTransform(m_alignStore);
+    m_defTransform = m_pendingTransformList[0]->getDefTransform(m_alignStore);
+    for (unsigned int t = 1; t < m_pendingTransformList.size (); t++) {
+      m_transform    = m_transform    * m_pendingTransformList[t]->getTransform(m_alignStore);
+      m_defTransform = m_defTransform * m_pendingTransformList[t]->getDefTransform(m_alignStore);
+    }
+  }  
+  
+  terminate ();
+}
+
+GeoTrf::Transform3D GeoSurfaceCursor::getTransform () const
+{
+  //if (m_minorLimit) {
+   // return m_transform*m_serialTransformer->getTransform(m_minorIndex);
+  //}
+  //else {
+    return m_transform;
+  //}
+}
+
+GeoTrf::Transform3D GeoSurfaceCursor::getDefTransform () const
+{
+  //if (m_minorLimit) {
+  //  return m_defTransform*m_serialTransformer->getTransform(m_minorIndex);
+  //}
+  //else {
+    return m_defTransform;
+  //}
+}
diff --git a/GeoModelExamples/SurfaceTestPlugin/src/SurfaceTestPlugin.cxx b/GeoModelExamples/SurfaceTestPlugin/src/SurfaceTestPlugin.cxx
index 5d4bac3a2e5df4db2a2502bc1161b037c2fe5e55..9dd5e22f9aaf9daefa6eabf0d16d8a04e8b04f44 100644
--- a/GeoModelExamples/SurfaceTestPlugin/src/SurfaceTestPlugin.cxx
+++ b/GeoModelExamples/SurfaceTestPlugin/src/SurfaceTestPlugin.cxx
@@ -21,15 +21,20 @@
 #include "GeoModelKernel/GeoMaterial.h"
 #include "GeoModelKernel/GeoBox.h"
 #include "GeoModelKernel/GeoTube.h"
+#include "GeoModelKernel/GeoPrintGraphAction.h"
+#include "GeoModelKernel/GeoVolumeCursor.h"
 
 #include "GeoModelKernel/GeoLogVol.h"
 #include "GeoModelKernel/GeoPhysVol.h"
 #include "GeoModelKernel/GeoTransform.h"
+#include "GeoModelKernel/GeoAlignableTransform.h"
 #include "GeoModelKernel/GeoShapeSubtraction.h"
 #include "GeoModelKernel/GeoShapeShift.h"
 #include "GeoModelKernel/GeoRectSurface.h"
 #include "GeoModelKernel/Units.h"
 #include "GeoModelHelpers/defineWorld.h"
+
+#include "GeoModelKernel/GeoSurfaceCursor.h"
 using namespace GeoModelKernelUnits;
 
 // Class Declaration
@@ -100,20 +105,57 @@ void SurfaceTestPlugin::create(GeoVPhysVol *world, bool /*publish*/) {
   GeoLogVol  *boxLog = new GeoLogVol("BoxLog",boxShape,Air);
   GeoPhysVol *boxPhys = new GeoPhysVol(boxLog);
 
-
+// define a virtual surface
   GeoRectSurface *rectSurface = new GeoRectSurface(5, 7.5);
+  GeoAlignableTransform *surf_rot=new GeoAlignableTransform(GeoTrf::TranslateZ3D(12));  
+  boxPhys->add(surf_rot);
   boxPhys->add(rectSurface);
-
+  surf_rot->setDelta(GeoTrf::RotateX3D(0.1)*GeoTrf::RotateY3D(0.15));
+//
   {
     GeoBox     *boxShape = new GeoBox(5,5,5);
     GeoLogVol  *boxLog = new GeoLogVol("BoxLog",boxShape,Air);
     GeoPhysVol *boxPhys2 = new GeoPhysVol(boxLog);
     boxPhys->add(boxPhys2);
+
+    GeoAlignableTransform *xf=new GeoAlignableTransform(GeoTrf::TranslateZ3D(12));
+    GeoPhysVol *boxPhys3 = new GeoPhysVol(boxLog);
+
+    boxPhys->add(xf);
+    boxPhys->add(boxPhys3);
+
+    xf->setDelta(GeoTrf::RotateX3D(0.1)*GeoTrf::RotateY3D(0.15));
   }
   
   world->add(boxPhys);
 
+  GeoPrintGraphAction printGraphAction(std::cout);
+  world->exec(&printGraphAction);;
 
+  {
+    int i = 0;
+    
+    std::cout << " " << std::endl;
+    std::cout << " " << std::endl;    
+    std::cout << " cursor at i= " << i << std::endl;
+    //GeoVolumeCursor cursor(boxPhys);
+    GeoSurfaceCursor cursor(boxPhys);
+    
+    while (!cursor.atEnd()) {
+      i += 1;
+      //std::cout << "!!! " << cursor.getVolume()->getLogVol() << std::endl;
+      std::cout << "!!! " << cursor.getTransform().rotation() << std::endl;
+      std::cout << "!!! " << cursor.getTransform().translation() << std::endl;
+      std::cout << " " << std::endl;
+      std::cout << " " << std::endl;
+      std::cout << " cursor at i= " << i << std::endl;
+      cursor.next();
+      //std::cout << " FINISHED NEXT " << std::endl;
+      std::cout << " " << std::endl;
+    }
+  }
+
+  
   
   //--------------------------------------//
 }