diff --git a/geom/geom/inc/TGeoBoolNode.h b/geom/geom/inc/TGeoBoolNode.h
index 6328de163355429fdd07e40451b529480df12234..e32a6084f27f5ee903a0a2071cc810237bea368a 100644
--- a/geom/geom/inc/TGeoBoolNode.h
+++ b/geom/geom/inc/TGeoBoolNode.h
@@ -87,8 +87,10 @@ public:
    TGeoMatrix       *GetRightMatrix() const {return fRightMat;}
    TGeoShape        *GetLeftShape() const {return fLeft;}
    TGeoShape        *GetRightShape() const {return fRight;}
+   virtual TGeoBoolNode *MakeClone() const = 0;
    virtual void      Paint(Option_t *option);
    void              RegisterMatrices();
+   Bool_t            ReplaceMatrix(TGeoMatrix *mat, TGeoMatrix *newmat);
    virtual Double_t  Safety(Double_t *point, Bool_t in=kTRUE) const = 0;
    virtual void      SavePrimitive(std::ostream &out, Option_t *option = "");
    virtual void      SetPoints(Double_t *points) const;
@@ -131,6 +133,7 @@ public:
    virtual void      Sizeof3D() const;
 
    //CS specific
+   virtual TGeoBoolNode *MakeClone() const;
    virtual void      Paint(Option_t *option);
 
    ClassDef(TGeoUnion, 1)              // union node
@@ -169,6 +172,7 @@ public:
    virtual void      Sizeof3D() const;
 
    //CS specific
+   virtual TGeoBoolNode *MakeClone() const;
    virtual void      Paint(Option_t *option);
 
    ClassDef(TGeoIntersection, 1)              // intersection node
@@ -206,6 +210,7 @@ public:
    virtual void      Sizeof3D() const;
 
    //CS specific
+   virtual TGeoBoolNode *MakeClone() const;
    virtual void      Paint(Option_t *option);
 
    ClassDef(TGeoSubtraction, 1)              // subtraction node
diff --git a/geom/geom/inc/TGeoManager.h b/geom/geom/inc/TGeoManager.h
index 6aa0a2f363f0e9a9d33f0f33c1555a45c015449f..58b5080c07b8c6c0496c3a1633f17ec3282e2923 100644
--- a/geom/geom/inc/TGeoManager.h
+++ b/geom/geom/inc/TGeoManager.h
@@ -240,7 +240,7 @@ public:
    void                   DrawPath(const char *path);
    void                   PrintOverlaps() const; // *MENU*
    void                   RandomPoints(const TGeoVolume *vol, Int_t npoints=10000, Option_t *option="");
-   void                   RandomRays(Int_t nrays=1000, Double_t startx=0, Double_t starty=0, Double_t startz=0);
+   void                   RandomRays(Int_t nrays=1000, Double_t startx=0, Double_t starty=0, Double_t startz=0, const char *target_vol=0, Bool_t check_norm=kFALSE);
    TGeoNode              *SamplePoints(Int_t npoints, Double_t &dist, Double_t epsil=1E-5,
                                        const char *g3path="");
    void                   SetNmeshPoints(Int_t npoints=1000);
diff --git a/geom/geom/inc/TGeoMatrix.h b/geom/geom/inc/TGeoMatrix.h
index 8ac36b633e9062738d58b889a65c1af3a67b163a..db34dfa08c5c4b7fa9473e7ec7e4f241410115fa 100644
--- a/geom/geom/inc/TGeoMatrix.h
+++ b/geom/geom/inc/TGeoMatrix.h
@@ -42,6 +42,7 @@ class TGeoMatrix : public TNamed
 public:
 enum EGeoTransfTypes {
    kGeoIdentity  = 0,
+   kGeoShared       = BIT(14),
    kGeoTranslation  = BIT(17),
    kGeoRotation     = BIT(18),
    kGeoScale        = BIT(19),
@@ -78,6 +79,7 @@ public :
    Bool_t               IsRotation()    const {return TestBit(kGeoRotation);}
    Bool_t               IsReflection()  const {return TestBit(kGeoReflection);}
    Bool_t               IsScale()       const {return TestBit(kGeoScale);}
+   Bool_t               IsShared()      const {return TestBit(kGeoShared);}
    Bool_t               IsCombi()       const {return (TestBit(kGeoTranslation) 
                                                && TestBit(kGeoRotation));}
    Bool_t               IsGeneral()     const {return (TestBit(kGeoTranslation) 
@@ -112,6 +114,7 @@ public :
    virtual void         SetDx(Double_t) {}
    virtual void         SetDy(Double_t) {}
    virtual void         SetDz(Double_t) {}
+   void                 SetShared(Bool_t flag=kTRUE) {SetBit(kGeoShared, flag);}
    
    ClassDef(TGeoMatrix, 1)                 // base geometrical transformation class
 };
diff --git a/geom/geom/inc/TGeoPhysicalNode.h b/geom/geom/inc/TGeoPhysicalNode.h
index 5b5dcf6d0bd999af0cf014020a55cd8655cd198b..5a3bb2794e5826d8d7933f86655c00e77cb2f9a1 100644
--- a/geom/geom/inc/TGeoPhysicalNode.h
+++ b/geom/geom/inc/TGeoPhysicalNode.h
@@ -68,7 +68,7 @@ public:
    // destructor
    virtual ~TGeoPhysicalNode();
 
-   void              Align(TGeoMatrix *newmat=0, TGeoShape *newshape=0, Bool_t check=kFALSE, Double_t ovlp=0.001);
+   Bool_t            Align(TGeoMatrix *newmat=0, TGeoShape *newshape=0, Bool_t check=kFALSE, Double_t ovlp=0.001);
    void              cd() const;
    void              Draw(Option_t *option="");
    Int_t             GetLevel() const {return fLevel;}
diff --git a/geom/geom/inc/TGeoVolume.h b/geom/geom/inc/TGeoVolume.h
index 8d144679b87bab7a4d1220d6cf8afa9a570453c6..478b86f616e7e99c554db832430891d4223ec1e2 100644
--- a/geom/geom/inc/TGeoVolume.h
+++ b/geom/geom/inc/TGeoVolume.h
@@ -193,7 +193,7 @@ public:
    TGeoVolume     *MakeReflectedVolume(const char *newname="") const;
    Bool_t          OptimizeVoxels(); // *MENU*
    void            RandomPoints(Int_t npoints=1000000, Option_t *option=""); // *MENU*
-   void            RandomRays(Int_t nrays=10000, Double_t startx=0, Double_t starty=0, Double_t startz=0); // *MENU*
+   void            RandomRays(Int_t nrays=10000, Double_t startx=0, Double_t starty=0, Double_t startz=0, const char *target_vol=0, Bool_t check_norm=kFALSE); // *MENU*
    void            Raytrace(Bool_t flag=kTRUE); // *TOGGLE* *GETTER=IsRaytracing
    void            RegisterYourself(Option_t *option="");
    void            RemoveNode(TGeoNode *node);
diff --git a/geom/geom/inc/TVirtualGeoPainter.h b/geom/geom/inc/TVirtualGeoPainter.h
index 8ccbfb5f6e3de2d6f4a38612fd1922e670321f03..079aafacae308e95eea754b12088c14c0750616d 100644
--- a/geom/geom/inc/TVirtualGeoPainter.h
+++ b/geom/geom/inc/TVirtualGeoPainter.h
@@ -123,7 +123,7 @@ public:
    virtual void       PrintOverlaps() const = 0;
    virtual void       PaintVolume(TGeoVolume *vol, Option_t *option="", TGeoMatrix* global=0) = 0;
    virtual void       RandomPoints(const TGeoVolume *vol, Int_t npoints, Option_t *option="") = 0;
-   virtual void       RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz) = 0;
+   virtual void       RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz, const char *target_vol, Bool_t check_norm) = 0;
    virtual void       Raytrace(Option_t *option="") = 0;
    virtual TGeoNode  *SamplePoints(Int_t npoints, Double_t &dist, Double_t epsil, const char* g3path) = 0;
    virtual void       SetBombFactors(Double_t bombx=1.3, Double_t bomby=1.3, Double_t bombz=1.3,
diff --git a/geom/geom/src/TGeoBoolNode.cxx b/geom/geom/src/TGeoBoolNode.cxx
index 9f15ab5e81ab9e420df0b4b5088b3fad7d934d4c..3bdf235f40cd050b979700720c5ab10d1f8a1bc5 100644
--- a/geom/geom/src/TGeoBoolNode.cxx
+++ b/geom/geom/src/TGeoBoolNode.cxx
@@ -316,6 +316,31 @@ void TGeoBoolNode::RegisterMatrices()
    if (fRight->IsComposite()) ((TGeoCompositeShape*)fRight)->GetBoolNode()->RegisterMatrices();
 }
 
+//_____________________________________________________________________________
+Bool_t TGeoBoolNode::ReplaceMatrix(TGeoMatrix *mat, TGeoMatrix *newmat)
+{
+// Replace one of the matrices. Does not work with TGeoIdentity. Returns true
+// if replacement was successful.
+   if (mat==gGeoIdentity || newmat==gGeoIdentity) {
+      Error("ReplaceMatrix", "Matrices should not be gGeoIdentity. Use default matrix constructor to repersent identities.");
+      return kFALSE;
+   }
+   if (!mat || !newmat) {
+      Error("ReplaceMatrix", "Matrices should not be null pointers.");
+      return kFALSE;
+   }
+   Bool_t replaced = kFALSE;
+   if (fLeftMat == mat) {
+      fLeftMat  = newmat;
+      replaced = kTRUE;
+   }
+   if (fRightMat == mat) {
+      fRightMat  = newmat;
+      replaced = kTRUE;
+   }
+   return replaced;
+}   
+       
 //_____________________________________________________________________________
 void TGeoBoolNode::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
 {
@@ -357,8 +382,16 @@ void TGeoBoolNode::Sizeof3D() const
    fLeft->Sizeof3D();
    fRight->Sizeof3D();
 }
+
 ClassImp(TGeoUnion)
 
+//______________________________________________________________________________
+TGeoBoolNode *TGeoUnion::MakeClone() const
+{
+// Make a clone of this. Pointers are preserved.
+   return new TGeoUnion(fLeft, fRight, fLeftMat, fRightMat);
+}   
+
 //______________________________________________________________________________
 void TGeoUnion::Paint(Option_t *option)
 {
@@ -739,6 +772,13 @@ void TGeoUnion::Sizeof3D() const
 
 ClassImp(TGeoSubtraction)
 
+//______________________________________________________________________________
+TGeoBoolNode *TGeoSubtraction::MakeClone() const
+{
+// Make a clone of this. Pointers are preserved.
+   return new TGeoSubtraction(fLeft, fRight, fLeftMat, fRightMat);
+}   
+
 //______________________________________________________________________________
 void TGeoSubtraction::Paint(Option_t *option)
 {
@@ -1048,6 +1088,13 @@ void TGeoSubtraction::Sizeof3D() const
 
 ClassImp(TGeoIntersection)
 
+//______________________________________________________________________________
+TGeoBoolNode *TGeoIntersection::MakeClone() const
+{
+// Make a clone of this. Pointers are preserved.
+   return new TGeoIntersection(fLeft, fRight, fLeftMat, fRightMat);
+}   
+
 //______________________________________________________________________________
 void TGeoIntersection::Paint(Option_t *option)
 {
diff --git a/geom/geom/src/TGeoManager.cxx b/geom/geom/src/TGeoManager.cxx
index c31aaa3251e12c09ecc29b7e8281a11c751afa66..4888cea42e7a099511f0dd3c90ef60cd59c0e961 100644
--- a/geom/geom/src/TGeoManager.cxx
+++ b/geom/geom/src/TGeoManager.cxx
@@ -2691,11 +2691,11 @@ Int_t TGeoManager::GetMaterialIndex(const char *matname) const
    return -1;  // fail
 }
 //_____________________________________________________________________________
-void TGeoManager::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz)
+void TGeoManager::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz, const char *target_vol, Bool_t check_norm)
 {
 // Randomly shoot nrays and plot intersections with surfaces for current
 // top node.
-   GetGeomPainter()->RandomRays(nrays, startx, starty, startz);
+   GetGeomPainter()->RandomRays(nrays, startx, starty, startz, target_vol, check_norm);
 }
 
 //_____________________________________________________________________________
diff --git a/geom/geom/src/TGeoNode.cxx b/geom/geom/src/TGeoNode.cxx
index 8cba09011adb89e585d0d6a027379c8de816317e..bf5b7b845f3bbcc6330f20f100776a41f5d3d6ed 100644
--- a/geom/geom/src/TGeoNode.cxx
+++ b/geom/geom/src/TGeoNode.cxx
@@ -704,6 +704,7 @@ TGeoNode *TGeoNodeMatrix::MakeCopyNode() const
    }
    // copy VC
    if (IsVirtual()) node->SetVirtual();
+   if (IsOverlapping()) node->SetOverlapping(); // <--- ADDED
    return node;
 }
 
diff --git a/geom/geom/src/TGeoPhysicalNode.cxx b/geom/geom/src/TGeoPhysicalNode.cxx
index 0e07ca0460beaf0a033ff3afd5145e9107998335..899aa33cbb003a4fb9e0ae770afe43a0623c14e1 100644
--- a/geom/geom/src/TGeoPhysicalNode.cxx
+++ b/geom/geom/src/TGeoPhysicalNode.cxx
@@ -51,6 +51,8 @@
 #include "TGeoCache.h"
 #include "TGeoMatrix.h"
 #include "TGeoShapeAssembly.h"
+#include "TGeoCompositeShape.h"
+#include "TGeoBoolNode.h"
 #include "TGeoVolume.h"
 #include "TVirtualGeoPainter.h"
 
@@ -133,7 +135,7 @@ TGeoPhysicalNode::~TGeoPhysicalNode()
 }
 
 //_____________________________________________________________________________
-void TGeoPhysicalNode::Align(TGeoMatrix *newmat, TGeoShape *newshape, Bool_t check, Double_t ovlp)
+Bool_t TGeoPhysicalNode::Align(TGeoMatrix *newmat, TGeoShape *newshape, Bool_t check, Double_t ovlp)
 {
    // Align a physical node with a new relative matrix/shape.
    // Example: /TOP_1/A_1/B_1/C_1
@@ -144,15 +146,19 @@ void TGeoPhysicalNode::Align(TGeoMatrix *newmat, TGeoShape *newshape, Bool_t che
    // *NOTE* The operations will affect ONLY the LAST node in the branch. All
    //   volumes/nodes in the branch represented by this physical node are
    //   CLONED so the operation does not affect other possible replicas.
-   if (!newmat && !newshape) return;
+   if (!newmat && !newshape) return kFALSE;
    if (TGeoManager::IsLocked()) {
       Error("Align", "Not performed. Geometry in LOCKED mode !");
-      return;
+      return kFALSE;
    }
+   if (newmat == gGeoIdentity) {
+      Error("Align", "Cannot align using gGeoIdentity. Use some default matrix constructor to represent identities.");
+      return kFALSE;
+   }   
    TGeoNode *node = GetNode();
    if (node->IsOffset()) {
       Error("Align", "Cannot align division nodes: %s\n",node->GetName());
-      return;
+      return kFALSE;
    }
    TGeoNode *nnode = 0;
    TGeoVolume *vm = GetVolume(0);
@@ -168,7 +174,7 @@ void TGeoPhysicalNode::Align(TGeoMatrix *newmat, TGeoShape *newshape, Bool_t che
          if (id[i]<0) {
             Error("Align","%s cannot align node %s",GetName(), node->GetName());
             delete [] id;
-            return;
+            return kFALSE;
          }
       }
       for (i=0; i<fLevel; i++) {
@@ -179,13 +185,13 @@ void TGeoPhysicalNode::Align(TGeoMatrix *newmat, TGeoShape *newshape, Bool_t che
          if (!vd) {
             delete [] id;
             Fatal("Align", "Cannot clone volume %s", node->GetVolume()->GetName());
-            return;
+            return kFALSE;
          }   
          nnode = node->MakeCopyNode();
          if (!nnode) {
             delete [] id;
             Fatal("Align", "Cannot make copy node for %s", node->GetName());
-            return;
+            return kFALSE;
          }   
          // Correct pointers to mother and volume
          nnode->SetVolume(vd);
@@ -210,14 +216,77 @@ void TGeoPhysicalNode::Align(TGeoMatrix *newmat, TGeoShape *newshape, Bool_t che
    vm = nnode->GetMotherVolume();
    vd = nnode->GetVolume();
    if (newmat) {
+      // Check if the old matrix for this node was shared
+      Bool_t shared = kFALSE;
+      Int_t nd = vm->GetNdaughters();
+      TGeoCompositeShape *cs;
+      if (nnode->GetMatrix()->IsShared()) {
+         // Now find the node having a composite shape using this shared matrix
+         for (i=0; i<nd; i++) {
+            node = vm->GetNode(i);
+            if (node==nnode) continue;
+            if (node->IsOffset()) continue;
+            if (!node->GetVolume()->GetShape()->IsComposite()) continue;
+            // We found a node having a composite shape, scan for the shared matrix
+            cs = (TGeoCompositeShape*)node->GetVolume()->GetShape();
+            if (cs->GetBoolNode()->GetRightMatrix() != nnode->GetMatrix()) continue;
+            // The composite uses the matrix -> replace it
+            TGeoCompositeShape *ncs = new TGeoCompositeShape(cs->GetName(), cs->GetBoolNode()->MakeClone());
+            ncs->GetBoolNode()->ReplaceMatrix(nnode->GetMatrix(), newmat);
+            // We have to clone the node/volume having the composite shape
+            TGeoVolume *newvol = node->GetVolume()->CloneVolume();
+            if (!newvol) {
+               Error("Align", "Cannot clone volume %s", node->GetVolume()->GetName());
+               return kFALSE;
+            }
+            newvol->SetShape(ncs);
+            TGeoNode *newnode = node->MakeCopyNode();
+            if (!newnode) {
+               Error("Align", "Cannot clone node %s", node->GetName());
+               return kFALSE;
+            }
+            newnode->SetVolume(newvol);
+            newnode->SetMotherVolume(vm);   
+            if (vm->TestBit(TGeoVolume::kVolumeImportNodes)) {
+               gGeoManager->GetListOfGShapes()->Add(newnode);
+            }   
+            vm->GetNodes()->RemoveAt(i);
+            vm->GetNodes()->AddAt(newnode,i);
+            shared = kTRUE;
+         }
+         if (!shared) Error("Align", "The matrix replaced for %s is not actually shared", GetName());
+      } else {
+         // The aligned node may have a composite shape containing a shared matrix
+         if (vd->GetShape()->IsComposite()) {
+            cs = (TGeoCompositeShape*)vd->GetShape();
+            if (cs->GetBoolNode()->GetRightMatrix()->IsShared()) {
+               if (!nnode->GetMatrix()->IsIdentity()) {
+                  Error("Align", "The composite shape having a shared matrix on the subtracted branch must be positioned using identity matrix.");
+                  return kFALSE;
+               }
+               // We have to put the alignment matrix on top of the left branch
+               // of the composite shape. The node is already decoupled from logical tree.
+               TGeoCompositeShape *ncs = new TGeoCompositeShape(cs->GetName(), cs->GetBoolNode()->MakeClone());
+               TGeoMatrix *oldmat = ncs->GetBoolNode()->GetLeftMatrix();
+               TGeoHMatrix *newmat1 = new TGeoHMatrix(*newmat);
+               newmat1->Multiply(oldmat);
+               ncs->GetBoolNode()->ReplaceMatrix(oldmat, newmat1);
+               vd->SetShape(ncs);
+               // The right-side matrix pointer is preserved, so no need to update nodes.
+               aligned = 0; // to prevent updating its matrix
+            }
+         }
+      }
       // Register matrix and make it the active one
       if (!newmat->IsRegistered()) newmat->RegisterYourself();
-      aligned->SetMatrix(newmat);
-      // Update the global matrix for the aligned node
-      TGeoHMatrix *global = GetMatrix();
-      TGeoHMatrix *up = GetMatrix(fLevel-1);
-      *global = up;
-      global->Multiply(newmat);
+      if (aligned) {
+         aligned->SetMatrix(newmat);
+         // Update the global matrix for the aligned node
+         TGeoHMatrix *global = GetMatrix();
+         TGeoHMatrix *up = GetMatrix(fLevel-1);
+         *global = up;
+         global->Multiply(newmat);
+      }   
    }
    // Change the shape for the aligned node
    if (newshape) vd->SetShape(newshape);
@@ -245,7 +314,7 @@ void TGeoPhysicalNode::Align(TGeoMatrix *newmat, TGeoShape *newshape, Bool_t che
       // Set aligned node to be checked
       i = fLevel;
       node = GetNode(i);
-      if (!node) return;
+      if (!node) return kTRUE;
       if (node->IsOverlapping()) {
          Info("Align", "The check for overlaps for node: \n%s\n cannot be performed since the node is declared possibly overlapping",
               GetName());
@@ -267,6 +336,7 @@ void TGeoPhysicalNode::Align(TGeoMatrix *newmat, TGeoShape *newshape, Bool_t che
    // Clean current matrices from cache
    gGeoManager->CdTop();
    SetAligned(kTRUE);
+   return kTRUE;
 }
 
 //_____________________________________________________________________________
diff --git a/geom/geom/src/TGeoVolume.cxx b/geom/geom/src/TGeoVolume.cxx
index ae2c217741bdbdabdce1ebbb4d7fa15ccaea21c1..5fca75b1c2965d90b74ab0146cc4e4e9772710c9 100644
--- a/geom/geom/src/TGeoVolume.cxx
+++ b/geom/geom/src/TGeoVolume.cxx
@@ -1247,14 +1247,14 @@ void TGeoVolume::RandomPoints(Int_t npoints, Option_t *option)
 }
 
 //_____________________________________________________________________________
-void TGeoVolume::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz)
+void TGeoVolume::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz, const char *target_vol, Bool_t check_norm)
 {
 // Random raytracing method.
    if (gGeoManager != fGeoManager) gGeoManager = fGeoManager;
    TGeoVolume *old_vol = fGeoManager->GetTopVolume();
    if (old_vol!=this) fGeoManager->SetTopVolume(this);
    else old_vol=0;
-   fGeoManager->RandomRays(nrays, startx, starty, startz);
+   fGeoManager->RandomRays(nrays, startx, starty, startz, target_vol, check_norm);
    if (old_vol) fGeoManager->SetTopVolume(old_vol);
 }
 
diff --git a/geom/geompainter/inc/TGeoChecker.h b/geom/geompainter/inc/TGeoChecker.h
index 5a2e5acaf30f307d86c4e094d73eb1318fb84752..a293ac946560eb3c05c3f20cbb58fe7d94a88b0f 100644
--- a/geom/geompainter/inc/TGeoChecker.h
+++ b/geom/geompainter/inc/TGeoChecker.h
@@ -79,7 +79,7 @@ public:
                             Double_t rmin=0., Double_t rmax=9999999, Option_t *option="");
    void             PrintOverlaps() const;
    void             RandomPoints(TGeoVolume *vol, Int_t npoints, Option_t *option);
-   void             RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz);
+   void             RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz, const char *target_vol=0, Bool_t check_norm=kFALSE);
    TGeoOverlap     *MakeCheckOverlap(const char *name, TGeoVolume *vol1, TGeoVolume *vol2, TGeoMatrix *mat1, TGeoMatrix *mat2, Bool_t isovlp, Double_t ovlp);
    void             OpProgress(const char *opname, Long64_t current, Long64_t size, TStopwatch *watch=0, Bool_t last=kFALSE, Bool_t refresh=kFALSE);
    TGeoNode        *SamplePoints(Int_t npoints, Double_t &dist, Double_t epsil, const char* g3path);
diff --git a/geom/geompainter/inc/TGeoPainter.h b/geom/geompainter/inc/TGeoPainter.h
index fc14161d72f74ec20efd3a78162a7412f7e85ad2..3e1c3bd60c334cb970266075c749468e44b01c11 100644
--- a/geom/geompainter/inc/TGeoPainter.h
+++ b/geom/geompainter/inc/TGeoPainter.h
@@ -148,7 +148,7 @@ public:
    virtual void       PrintOverlaps() const;
    void               PaintPhysicalNode(TGeoPhysicalNode *node, Option_t *option="");
    virtual void       RandomPoints(const TGeoVolume *vol, Int_t npoints, Option_t *option="");
-   virtual void       RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz);
+   virtual void       RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz, const char *target_vol=0, Bool_t check_norm=kFALSE);
    virtual void       Raytrace(Option_t *option="");
    virtual TGeoNode  *SamplePoints(Int_t npoints, Double_t &dist, Double_t epsil, const char* g3path);
    virtual void       SetBombFactors(Double_t bombx=1.3, Double_t bomby=1.3, Double_t bombz=1.3, Double_t bombr=1.3);
diff --git a/geom/geompainter/src/TGeoChecker.cxx b/geom/geompainter/src/TGeoChecker.cxx
index b16914434db75cd4ce3485f137c622027602cdca..ed13c2cae4096329927fd7e3dbecf3f05d6fd26c 100644
--- a/geom/geompainter/src/TGeoChecker.cxx
+++ b/geom/geompainter/src/TGeoChecker.cxx
@@ -2104,16 +2104,22 @@ void TGeoChecker::RandomPoints(TGeoVolume *vol, Int_t npoints, Option_t *option)
 }   
 
 //______________________________________________________________________________
-void TGeoChecker::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz)
+void TGeoChecker::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz, const char *target_vol, Bool_t check_norm)
 {
 // Randomly shoot nrays from point (startx,starty,startz) and plot intersections 
 // with surfaces for current top node.
    TObjArray *pm = new TObjArray(128);
+   TString starget = target_vol;
    TPolyLine3D *line = 0;
    TPolyLine3D *normline = 0;
    TGeoVolume *vol=fGeoManager->GetTopVolume();
 //   vol->VisibleDaughters(kTRUE);
 
+   Bool_t random = kFALSE;
+   if (nrays<=0) {
+      nrays = 100000;
+      random = kTRUE;
+   }   
    Double_t start[3];
    Double_t dir[3];
    const Double_t *point = fGeoManager->GetCurrentPoint();
@@ -2127,6 +2133,9 @@ void TGeoChecker::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Doub
    Int_t n10=nrays/10;
    Double_t theta,phi, step, normlen;
    const Double_t *normal;
+   Double_t ox = ((TGeoBBox*)vol->GetShape())->GetOrigin()[0];
+   Double_t oy = ((TGeoBBox*)vol->GetShape())->GetOrigin()[1];
+   Double_t oz = ((TGeoBBox*)vol->GetShape())->GetOrigin()[2];
    Double_t dx = ((TGeoBBox*)vol->GetShape())->GetDX();
    Double_t dy = ((TGeoBBox*)vol->GetShape())->GetDY();
    Double_t dz = ((TGeoBBox*)vol->GetShape())->GetDZ();
@@ -2140,9 +2149,15 @@ void TGeoChecker::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Doub
       if (n10) {
          if ((itot%n10) == 0) printf("%i percent\n", Int_t(100*itot/nrays));
       }
-      start[0] = startx;
-      start[1] = starty;
-      start[2] = startz;
+      if (random) {
+         start[0] = ox-dx+2*dx*gRandom->Rndm();
+         start[1] = oy-dy+2*dy*gRandom->Rndm();
+         start[2] = oz-dz+2*dz*gRandom->Rndm();
+      } else {   
+         start[0] = startx;
+         start[1] = starty;
+         start[2] = startz;
+      }   
       phi = 2*TMath::Pi()*gRandom->Rndm();
       theta= TMath::ACos(1.-2.*gRandom->Rndm());
       dir[0]=TMath::Sin(theta)*TMath::Cos(phi);
@@ -2151,11 +2166,16 @@ void TGeoChecker::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Doub
       startnode = fGeoManager->InitTrack(start[0],start[1],start[2], dir[0],dir[1],dir[2]);
       line = 0;
       if (fGeoManager->IsOutside()) startnode=0;
-      vis1 = (startnode)?(startnode->IsOnScreen()):kFALSE;
+      vis1 = kFALSE;
+      if (target_vol) {
+         if (startnode && starget==startnode->GetVolume()->GetName()) vis1 = kTRUE;
+      } else {   
+         if (startnode && startnode->IsOnScreen()) vis1 = kTRUE;
+      }   
       if (vis1) {
          line = new TPolyLine3D(2);
          line->SetLineColor(startnode->GetVolume()->GetLineColor());
-         line->SetPoint(ipoint++, startx, starty, startz);
+         line->SetPoint(ipoint++, start[0], start[1], start[2]);
          i++;
          pm->Add(line);
       }
@@ -2164,13 +2184,18 @@ void TGeoChecker::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Doub
          if (step<TGeoShape::Tolerance()) inull++;
          else inull = 0;
          if (inull>5) break;
-         normal = fGeoManager->FindNormalFast();
-         if (!normal) break;
-         vis2 = endnode->IsOnScreen();
+         if (check_norm) {
+            normal = fGeoManager->FindNormalFast();
+            if (!normal) break;
+         }   
+         vis2 = kFALSE;
+         if (target_vol) {
+            if (starget==endnode->GetVolume()->GetName()) vis2 = kTRUE;
+         } else if (endnode->IsOnScreen()) vis2 = kTRUE;
          if (ipoint>0) {
          // old visible node had an entry point -> finish segment
             line->SetPoint(ipoint, point[0], point[1], point[2]);
-            if (!vis2) {
+            if (!vis2 && check_norm) {
                normline = new TPolyLine3D(2);
                normline->SetLineColor(kBlue);
                normline->SetLineWidth(1);
@@ -2189,15 +2214,17 @@ void TGeoChecker::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Doub
             line->SetLineColor(endnode->GetVolume()->GetLineColor());
             line->SetPoint(ipoint++, point[0], point[1], point[2]);
             i++;
-            normline = new TPolyLine3D(2);
-            normline->SetLineColor(kBlue);
-            normline->SetLineWidth(2);
-            normline->SetPoint(0, point[0], point[1], point[2]);
-            normline->SetPoint(1, point[0]+normal[0]*normlen, 
-                                  point[1]+normal[1]*normlen, 
-                                  point[2]+normal[2]*normlen);
+            if (check_norm) {
+               normline = new TPolyLine3D(2);
+               normline->SetLineColor(kBlue);
+               normline->SetLineWidth(2);
+               normline->SetPoint(0, point[0], point[1], point[2]);
+               normline->SetPoint(1, point[0]+normal[0]*normlen, 
+                                     point[1]+normal[1]*normlen, 
+                                     point[2]+normal[2]*normlen);
+            }                         
             pm->Add(line);
-            pm->Add(normline);
+            if (!random) pm->Add(normline);
          } 
       }      
    }   
diff --git a/geom/geompainter/src/TGeoPainter.cxx b/geom/geompainter/src/TGeoPainter.cxx
index 82075bb413991197357266035a91c971b810ec41..58726ead32989b65bb2cbff2af4235fe9c6b12ae 100644
--- a/geom/geompainter/src/TGeoPainter.cxx
+++ b/geom/geompainter/src/TGeoPainter.cxx
@@ -1485,10 +1485,10 @@ void TGeoPainter::RandomPoints(const TGeoVolume *vol, Int_t npoints, Option_t *o
 }   
 
 //______________________________________________________________________________
-void TGeoPainter::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz)
+void TGeoPainter::RandomRays(Int_t nrays, Double_t startx, Double_t starty, Double_t startz, const char *target_vol, Bool_t check_norm)
 {
 // Shoot nrays in the current drawn geometry
-   fChecker->RandomRays(nrays, startx, starty, startz);
+   fChecker->RandomRays(nrays, startx, starty, startz, target_vol, check_norm);
 }   
 
 //______________________________________________________________________________