diff --git a/dox/dev_guides/upgrade/upgrade.md b/dox/dev_guides/upgrade/upgrade.md
index 6742c1e57a..d1c5e44e0f 100644
--- a/dox/dev_guides/upgrade/upgrade.md
+++ b/dox/dev_guides/upgrade/upgrade.md
@@ -1503,6 +1503,7 @@ The following obsolete features have been removed:
 * The container *BiTgte_DataMapOfShapeBox* is replaced with *TopTools_DataMapOfShapeBox*;
 * The class *BOPTools* has been removed as duplicate of the class *TopExp*;
 * The method *BOPAlgo_Builder::Splits()* has been removed as excessive. The method *BOPAlgo_Builder::Images()* can be used instead.
+* The method *BOPTools_AlgoTools::CheckSameGeom()* has been removed as excessive. The method *BOPTools_AlgoTools::AreFacesSameDomain()* can be used instead.
 
 @section upgrade_occt730 Upgrade to OCCT 7.3.0
 
diff --git a/src/BOPAlgo/BOPAlgo.msg b/src/BOPAlgo/BOPAlgo.msg
index 72c842f7df..84cf724566 100644
--- a/src/BOPAlgo/BOPAlgo.msg
+++ b/src/BOPAlgo/BOPAlgo.msg
@@ -91,3 +91,6 @@ Error: The Feature Removal algorithm has failed
 
 .BOPAlgo_AlertSolidBuilderUnusedFaces
 Warning: Some of the faces passed to the Solid Builder algorithm have not been classified and not used for solids creation
+
+.BOPAlgo_AlertUnableToOrientTheShape
+Warning: Unable to orient the shape correctly
diff --git a/src/BOPAlgo/BOPAlgo_Alerts.hxx b/src/BOPAlgo/BOPAlgo_Alerts.hxx
index 7a4f927f76..8874825d11 100644
--- a/src/BOPAlgo/BOPAlgo_Alerts.hxx
+++ b/src/BOPAlgo/BOPAlgo_Alerts.hxx
@@ -104,4 +104,7 @@ DEFINE_SIMPLE_ALERT(BOPAlgo_AlertRemoveFeaturesFailed)
 //! and not used for solids creation
 DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertSolidBuilderUnusedFaces)
 
+//! Unable to orient the shape correctly
+DEFINE_ALERT_WITH_SHAPE(BOPAlgo_AlertUnableToOrientTheShape)
+
 #endif // _BOPAlgo_Alerts_HeaderFile
diff --git a/src/BOPAlgo/BOPAlgo_BOPAlgo_msg.pxx b/src/BOPAlgo/BOPAlgo_BOPAlgo_msg.pxx
index 6cd2187474..4eeb549ebb 100644
--- a/src/BOPAlgo/BOPAlgo_BOPAlgo_msg.pxx
+++ b/src/BOPAlgo/BOPAlgo_BOPAlgo_msg.pxx
@@ -93,4 +93,7 @@ static const char BOPAlgo_BOPAlgo_msg[] =
   "Error: The Feature Removal algorithm has failed\n"
   "\n"
   ".BOPAlgo_AlertSolidBuilderUnusedFaces\n"
-  "Warning: Some of the faces passed to the Solid Builder algorithm have not been classified and not used for solids creation\n";
+  "Warning: Some of the faces passed to the Solid Builder algorithm have not been classified and not used for solids creation\n"
+  "\n"
+  ".BOPAlgo_AlertUnableToOrientTheShape\n"
+  "Warning: Unable to orient the shape correctly\n";
diff --git a/src/BOPAlgo/BOPAlgo_Builder.hxx b/src/BOPAlgo/BOPAlgo_Builder.hxx
index 6f46abbcf6..6b8cadc6a3 100644
--- a/src/BOPAlgo/BOPAlgo_Builder.hxx
+++ b/src/BOPAlgo/BOPAlgo_Builder.hxx
@@ -58,6 +58,10 @@ class BOPAlgo_PaveFiller;
 //!                          i.e. the check is performed. Setting this flag to FALSE for inverted solids,
 //!                          most likely will lead to incorrect results.
 //!
+//! The algorithm returns the following warnings:
+//! - *BOPAlgo_AlertUnableToOrientTheShape* - in case the check on the orientation of the split shape
+//!                                           to match the orientation of the original shape has failed.
+//!
 //! The algorithm returns the following Error statuses:
 //! - *BOPAlgo_AlertTooFewArguments* - in case there are no enough arguments to perform the operation;
 //! - *BOPAlgo_AlertNoFiller* - in case the intersection tool has not been created;
diff --git a/src/BOPAlgo/BOPAlgo_Builder_1.cxx b/src/BOPAlgo/BOPAlgo_Builder_1.cxx
index 69fc0f84cb..97ec6c7846 100644
--- a/src/BOPAlgo/BOPAlgo_Builder_1.cxx
+++ b/src/BOPAlgo/BOPAlgo_Builder_1.cxx
@@ -226,7 +226,7 @@ void BOPAlgo_Builder::FillImagesVertices()
     {
       TopoDS_Shape aSSIm = aItIm.Value();
       if (!aSSIm.IsEqual(aSS) &&
-          BOPTools_AlgoTools::IsSplitToReverse(aSSIm, aSS, myContext))
+          BOPTools_AlgoTools::IsSplitToReverseWithWarn(aSSIm, aSS, myContext, myReport))
       {
         aSSIm.Reverse();
       }
diff --git a/src/BOPAlgo/BOPAlgo_Builder_2.cxx b/src/BOPAlgo/BOPAlgo_Builder_2.cxx
index 15b1b3cf38..fcc64ed2a7 100644
--- a/src/BOPAlgo/BOPAlgo_Builder_2.cxx
+++ b/src/BOPAlgo/BOPAlgo_Builder_2.cxx
@@ -61,7 +61,8 @@
 static
   TopoDS_Face BuildDraftFace(const TopoDS_Face& theFace,
                              const TopTools_DataMapOfShapeListOfShape& theImages,
-                             Handle(IntTools_Context)& theCtx);
+                             Handle(IntTools_Context)& theCtx,
+                             const Handle(Message_Report)& theReport);
 
 //=======================================================================
 //class    : BOPAlgo_PairOfShapeBoolean
@@ -311,7 +312,7 @@ void BOPAlgo_Builder::BuildSplitFaces()
       // the draft face will be null, as such sub-shapes may split the face on parts
       // (as in the case "bugs modalg_5 bug25245_1").
       // The BuilderFace algorithm will be called in this case.
-      TopoDS_Face aFD = BuildDraftFace(aF, myImages, myContext);
+      TopoDS_Face aFD = BuildDraftFace(aF, myImages, myContext, myReport);
       if (!aFD.IsNull())
       {
         aFacesIm(aFacesIm.Add(i, TopTools_ListOfShape())).Append(aFD);
@@ -404,7 +405,7 @@ void BOPAlgo_Builder::BuildSplitFaces()
         }// if (bIsClosed){
         //
         aSp.Orientation(anOriE);
-        bToReverse=BOPTools_AlgoTools::IsSplitToReverse(aSp, aE, myContext);
+        bToReverse=BOPTools_AlgoTools::IsSplitToReverseWithWarn(aSp, aE, myContext, myReport);
         if (bToReverse) {
           aSp.Reverse();
         }
@@ -813,21 +814,27 @@ void BOPAlgo_Builder::FillInternalVertices()
 //purpose  : Checks if the edge has multi-connected vertices.
 //=======================================================================
 static Standard_Boolean HasMultiConnected(const TopoDS_Edge& theEdge,
-                                          TopTools_DataMapOfShapeInteger& theMap)
+                                          TopTools_DataMapOfShapeListOfShape& theMap)
 {
   TopoDS_Iterator itV(theEdge);
   for (; itV.More(); itV.Next())
   {
     const TopoDS_Shape& aV = itV.Value();
-    Standard_Integer *pCounter = theMap.ChangeSeek(aV);
-    if (!pCounter)
-      pCounter = theMap.Bound(aV, 1);
+    TopTools_ListOfShape *pList = theMap.ChangeSeek(aV);
+    if (!pList)
+    {
+      pList = theMap.Bound(aV, TopTools_ListOfShape());
+      pList->Append(theEdge);
+    }
     else
     {
-      if (*pCounter == 2)
-        return Standard_True;
+      // The list is expected to be 1-2 elements long,
+      // thus using "Contains" is safe.
+      if (!pList->Contains(theEdge))
+        pList->Append(theEdge);
 
-      ++(*pCounter);
+      if (pList->Extent() > 2)
+        return Standard_True;
     }
   }
   return Standard_False;
@@ -839,7 +846,8 @@ static Standard_Boolean HasMultiConnected(const TopoDS_Edge& theEdge,
 //=======================================================================
 TopoDS_Face BuildDraftFace(const TopoDS_Face& theFace,
                            const TopTools_DataMapOfShapeListOfShape& theImages,
-                           Handle(IntTools_Context)& theCtx)
+                           Handle(IntTools_Context)& theCtx,
+                           const Handle(Message_Report)& theReport)
 {
   BRep_Builder aBB;
   // Take the information from the original face
@@ -855,7 +863,7 @@ TopoDS_Face BuildDraftFace(const TopoDS_Face& theFace,
   // the vertices appearance, and if the multi-connexity is met return
   // the null face to use the BuilderFace algorithm for checking the
   // possibility of split.
-  TopTools_DataMapOfShapeInteger aVerticesCounter;
+  TopTools_DataMapOfShapeListOfShape aVerticesCounter;
 
   // Update wires of the original face and add them to draft face
   TopoDS_Iterator aItW(theFace.Oriented(TopAbs_FORWARD));
@@ -885,20 +893,21 @@ TopoDS_Face BuildDraftFace(const TopoDS_Face& theFace,
         return TopoDS_Face();
       }
 
+      // Check if the original edge is degenerated
+      Standard_Boolean bIsDegenerated = BRep_Tool::Degenerated(aE);
+
       // Check for the splits of the edge
       const TopTools_ListOfShape* pLEIm = theImages.Seek(aE);
       if (!pLEIm)
       {
         // Check if the edge has multi-connected vertices
-        if (HasMultiConnected(aE, aVerticesCounter))
+        if (!bIsDegenerated && HasMultiConnected(aE, aVerticesCounter))
           return TopoDS_Face();
 
         aBB.Add(aNewWire, aE);
         continue;
       }
 
-      // Check if the original edge is degenerated
-      Standard_Boolean bIsDegenerated = BRep_Tool::Degenerated(aE);
       // Check if the original edge is closed on the face
       Standard_Boolean bIsClosed = BRep_Tool::IsClosed(aE, theFace);
 
@@ -908,7 +917,7 @@ TopoDS_Face BuildDraftFace(const TopoDS_Face& theFace,
         TopoDS_Edge& aSp = TopoDS::Edge(aItLEIm.Value());
 
         // Check if the split has multi-connected vertices
-        if (HasMultiConnected(aSp, aVerticesCounter))
+        if (!bIsDegenerated && HasMultiConnected(aSp, aVerticesCounter))
           return TopoDS_Face();
 
         aSp.Orientation(anOriE);
@@ -918,13 +927,13 @@ TopoDS_Face BuildDraftFace(const TopoDS_Face& theFace,
           continue;
         }
 
-        // Check closeness of the split edge and if it is not
-        // make the second PCurve
+        // If the original edge is closed on the face check closeness
+        // of the split edge and if it is not closed make the second PCurve
         if (bIsClosed && !BRep_Tool::IsClosed(aSp, theFace))
           BOPTools_AlgoTools3D::DoSplitSEAMOnFace(aSp, theFace);
 
         // Check if the split should be reversed
-        if (BOPTools_AlgoTools::IsSplitToReverse(aSp, aE, theCtx))
+        if (BOPTools_AlgoTools::IsSplitToReverseWithWarn(aSp, aE, theCtx, theReport))
           aSp.Reverse();
 
         aBB.Add(aNewWire, aSp);
diff --git a/src/BOPAlgo/BOPAlgo_Builder_3.cxx b/src/BOPAlgo/BOPAlgo_Builder_3.cxx
index f7763d37cb..1f7d00024a 100644
--- a/src/BOPAlgo/BOPAlgo_Builder_3.cxx
+++ b/src/BOPAlgo/BOPAlgo_Builder_3.cxx
@@ -287,8 +287,8 @@ void BOPAlgo_Builder::BuildDraftSolid(const TopoDS_Shape& theSolid,
               theLIF.Append(aFx);
             }
             else {
-              bToReverse=BOPTools_AlgoTools::IsSplitToReverse
-                (aFx, aF, myContext);
+              bToReverse=BOPTools_AlgoTools::IsSplitToReverseWithWarn
+                (aFx, aF, myContext, myReport);
               if (bToReverse) {
                 aFx.Reverse();
               }
diff --git a/src/BOPTools/BOPTools_AlgoTools.cxx b/src/BOPTools/BOPTools_AlgoTools.cxx
index b4f474ba38..b5c07f02e3 100644
--- a/src/BOPTools/BOPTools_AlgoTools.cxx
+++ b/src/BOPTools/BOPTools_AlgoTools.cxx
@@ -17,6 +17,7 @@
 
 
 #include <BOPTools_AlgoTools.hxx>
+#include <BOPAlgo_Alerts.hxx>
 #include <BOPTools_AlgoTools2D.hxx>
 #include <BOPTools_AlgoTools3D.hxx>
 #include <BOPTools_CoupleOfShape.hxx>
@@ -64,6 +65,7 @@
 #include <TopTools_IndexedMapOfShape.hxx>
 #include <TopTools_MapOfShape.hxx>
 #include <TopTools_MapOfOrientedShape.hxx>
+#include <Message_Report.hxx>
 #include <NCollection_Array1.hxx>
 #include <algorithm>
 
@@ -77,7 +79,7 @@ static
   Standard_Boolean FindFacePairs (const TopoDS_Edge& theE,
                                   const TopTools_ListOfShape& thLF,
                                   BOPTools_ListOfCoupleOfShape& theLCFF,
-                                  Handle(IntTools_Context)& theContext);
+                                  const Handle(IntTools_Context)& theContext);
 static
   TopAbs_Orientation Orientation(const TopoDS_Edge& anE,
                                  const TopoDS_Face& aF);
@@ -91,7 +93,7 @@ static
                               const Standard_Boolean theSmallFaces,
                               gp_Dir& aDN,
                               gp_Dir& aDB,
-                              Handle(IntTools_Context)& theContext,
+                              const Handle(IntTools_Context)& theContext,
                               GeomAPI_ProjectPointOnSurf& aProjPL,
                               const Standard_Real aDt);
 static
@@ -99,7 +101,7 @@ static
                                    const gp_Pnt& aP,
                                    gp_Dir& aDB,
                                    gp_Pnt& aPOut,
-                                   Handle(IntTools_Context)& theContext,
+                                   const Handle(IntTools_Context)& theContext,
                                    GeomAPI_ProjectPointOnSurf& aProjPL,
                                    const Standard_Real aDt,
                                    const Standard_Real aTolE);
@@ -108,7 +110,7 @@ static
                           const TopoDS_Face& theF1,
                           const BOPTools_ListOfCoupleOfShape& theLCS,
                           const gp_Pnt& aP,
-                          Handle(IntTools_Context)& theContext,
+                          const Handle(IntTools_Context)& theContext,
                           Standard_Boolean& theSmallFaces);
 
 
@@ -589,7 +591,7 @@ TopAbs_State BOPTools_AlgoTools::ComputeStateByOnePoint
   (const TopoDS_Shape& theS,
    const TopoDS_Solid& theRef,
    const Standard_Real theTol,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   TopAbs_State aState;
   TopAbs_ShapeEnum aType;
@@ -616,7 +618,7 @@ TopAbs_State BOPTools_AlgoTools::ComputeState
    const TopoDS_Solid& theRef,
    const Standard_Real theTol,
    TopTools_IndexedMapOfShape& theBounds,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   TopAbs_State aState;
   TopExp_Explorer aExp; 
@@ -665,7 +667,7 @@ TopAbs_State BOPTools_AlgoTools::ComputeState
   (const TopoDS_Vertex& theV,
    const TopoDS_Solid& theRef,
    const Standard_Real theTol,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   TopAbs_State aState;
   gp_Pnt aP3D; 
@@ -683,7 +685,7 @@ TopAbs_State BOPTools_AlgoTools::ComputeState
   (const TopoDS_Edge& theE,
    const TopoDS_Solid& theRef,
    const Standard_Real theTol,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   Standard_Real aT1, aT2, aT = 0.;
   TopAbs_State aState;
@@ -735,7 +737,7 @@ TopAbs_State BOPTools_AlgoTools::ComputeState
   (const gp_Pnt& theP,
    const TopoDS_Solid& theRef,
    const Standard_Real theTol,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   TopAbs_State aState;
   //
@@ -755,7 +757,7 @@ Standard_Boolean BOPTools_AlgoTools::IsInternalFace
    const TopoDS_Solid& theSolid,
    TopTools_IndexedDataMapOfShapeListOfShape& theMEF,
    const Standard_Real theTol,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   Standard_Boolean bDegenerated;
   Standard_Integer aNbF, iRet, iFound;
@@ -866,7 +868,7 @@ Standard_Integer BOPTools_AlgoTools::IsInternalFace
   (const TopoDS_Face& theFace,
    const TopoDS_Edge& theEdge,
    TopTools_ListOfShape& theLF,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   Standard_Integer aNbF, iRet;
   //
@@ -911,7 +913,7 @@ Standard_Integer BOPTools_AlgoTools::IsInternalFace
    const TopoDS_Edge& theEdge,
    const TopoDS_Face& theFace1,
    const TopoDS_Face& theFace2,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   Standard_Boolean bRet;
   Standard_Integer iRet;
@@ -965,7 +967,7 @@ Standard_Boolean BOPTools_AlgoTools::GetFaceOff
    const TopoDS_Face& theF1,
    BOPTools_ListOfCoupleOfShape& theLCSOff,
    TopoDS_Face& theFOff,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   Standard_Boolean bRet, bIsComputed;
   Standard_Real aT, aT1, aT2, aAngle, aTwoPI, aAngleMin, aDt3D;
@@ -1091,7 +1093,7 @@ Standard_Boolean BOPTools_AlgoTools::GetEdgeOff(const TopoDS_Edge& theE1,
 Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain
   (const TopoDS_Face& theF1,
    const TopoDS_Face& theF2,
-   Handle(IntTools_Context)& theContext,
+   const Handle(IntTools_Context)& theContext,
    const Standard_Real theFuzz)
 {
   Standard_Boolean bFacesSD = Standard_False;
@@ -1151,43 +1153,13 @@ Standard_Boolean BOPTools_AlgoTools::AreFacesSameDomain
   return bFacesSD;
 }
 
-//=======================================================================
-//function : CheckSameGeom
-//purpose  : 
-//=======================================================================
-Standard_Boolean BOPTools_AlgoTools::CheckSameGeom
-  (const TopoDS_Face& theF1,
-   const TopoDS_Face& theF2,
-   Handle(IntTools_Context)& theContext)
-{
-  Standard_Boolean bRet;
-  Standard_Real aTolF1, aTolF2, aTol;
-  gp_Pnt2d aP2D;
-  gp_Pnt aP;
-  TopExp_Explorer aExp;
-  //
-  bRet=Standard_False;
-  aExp.Init(theF1, TopAbs_EDGE);
-  for (; aExp.More(); aExp.Next()) {
-    const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
-    if (!BRep_Tool::Degenerated(aE)) {
-      aTolF1=BRep_Tool::Tolerance(theF1);
-      aTolF2=BRep_Tool::Tolerance(theF2);
-      aTol=aTolF1+aTolF2;
-      BOPTools_AlgoTools3D::PointNearEdge(aE, theF1, aP2D, aP, theContext);
-      bRet=theContext->IsValidPointForFace(aP, theF2, aTol);
-      break;
-    }
-  }
-  return bRet;
-}
 //=======================================================================
 // function: Sense
 // purpose: 
 //=======================================================================
-Standard_Integer BOPTools_AlgoTools::Sense (const TopoDS_Face& theF1,
-                                            const TopoDS_Face& theF2,
-                                            const Handle(IntTools_Context)& theContext)
+Standard_Integer BOPTools_AlgoTools::Sense(const TopoDS_Face& theF1,
+                                           const TopoDS_Face& theF2,
+                                           const Handle(IntTools_Context)& theContext)
 {
   Standard_Integer iSense=0;
   gp_Dir aDNF1, aDNF2;
@@ -1235,7 +1207,8 @@ Standard_Integer BOPTools_AlgoTools::Sense (const TopoDS_Face& theF1,
 Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
   (const TopoDS_Shape& theSp,
    const TopoDS_Shape& theSr,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext,
+   Standard_Integer *theError)
 {
   Standard_Boolean bRet;
   TopAbs_ShapeEnum aType;
@@ -1247,22 +1220,49 @@ Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
     case TopAbs_EDGE: {
       const TopoDS_Edge& aESp=(*(TopoDS_Edge*)(&theSp));
       const TopoDS_Edge& aESr=(*(TopoDS_Edge*)(&theSr));
-      bRet=BOPTools_AlgoTools::IsSplitToReverse(aESp, aESr, theContext);
+      bRet=BOPTools_AlgoTools::IsSplitToReverse(aESp, aESr, theContext, theError);
     }
       break;
       //
     case TopAbs_FACE: {
       const TopoDS_Face& aFSp=(*(TopoDS_Face*)(&theSp));
       const TopoDS_Face& aFSr=(*(TopoDS_Face*)(&theSr));
-      bRet=BOPTools_AlgoTools::IsSplitToReverse(aFSp, aFSr, theContext);
+      bRet=BOPTools_AlgoTools::IsSplitToReverse(aFSp, aFSr, theContext, theError);
     }
       break;
       //
     default:
+      if (theError)
+        *theError = 100;
       break;
   }
   return bRet;
 }
+
+//=======================================================================
+//function : IsSplitToReverseWithWarn
+//purpose  :
+//=======================================================================
+Standard_Boolean BOPTools_AlgoTools::IsSplitToReverseWithWarn(const TopoDS_Shape& theSplit,
+                                                              const TopoDS_Shape& theShape,
+                                                              const Handle(IntTools_Context)& theContext,
+                                                              const Handle(Message_Report)& theReport)
+{
+  Standard_Integer anErr;
+  Standard_Boolean isToReverse = BOPTools_AlgoTools::IsSplitToReverse(theSplit, theShape, theContext, &anErr);
+  if (anErr != 0 && !theReport.IsNull())
+  {
+    // The error occurred during the check.
+    // Add warning to the report, storing the shapes into the warning.
+    TopoDS_Compound aWC;
+    BRep_Builder().MakeCompound(aWC);
+    BRep_Builder().Add(aWC, theSplit);
+    BRep_Builder().Add(aWC, theShape);
+    theReport->AddAlert(Message_Warning, new BOPAlgo_AlertUnableToOrientTheShape(aWC));
+  }
+  return isToReverse;
+}
+
 //=======================================================================
 //function :IsSplitToReverse
 //purpose  : 
@@ -1270,8 +1270,13 @@ Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
 Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
   (const TopoDS_Face& theFSp,
    const TopoDS_Face& theFSr,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext,
+   Standard_Integer *theError)
 {
+  // Set OK error status
+  if (theError)
+    *theError = 0;
+
   // Compare surfaces
   Handle(Geom_Surface) aSFSp = BRep_Tool::Surface(theFSp);
   Handle(Geom_Surface) aSFOr = BRep_Tool::Surface(theFSr);
@@ -1305,6 +1310,8 @@ Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
     }
     //
     if (!anExp.More()) {
+      if (theError)
+        *theError = 1;
       // The point has not been found.
       return bDone;
     }
@@ -1315,6 +1322,8 @@ Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
   bDone = BOPTools_AlgoTools3D::GetNormalToSurface
     (aSFSp, aP2DFSp.X(), aP2DFSp.Y(), aDNFSp);
   if (!bDone) {
+    if (theError)
+      *theError = 2;
     return bDone;
   }
   //
@@ -1328,6 +1337,8 @@ Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
   aProjector.Perform(aPFSp);
   bDone = (aProjector.NbPoints() > 0);
   if (!bDone) {
+    if (theError)
+      *theError = 3;
     return bDone;
   }
   // UV coordinates of the point on the original face
@@ -1338,6 +1349,8 @@ Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
   gp_Dir aDNFOr;
   bDone = BOPTools_AlgoTools3D::GetNormalToSurface(aSFOr, aU, aV, aDNFOr);
   if (!bDone) {
+    if (theError)
+      *theError = 4;
     return bDone;
   }
   //
@@ -1354,51 +1367,88 @@ Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
 //purpose  : 
 //=======================================================================
 Standard_Boolean BOPTools_AlgoTools::IsSplitToReverse
-  (const TopoDS_Edge& aEF1,
-   const TopoDS_Edge& aEF2,
-   Handle(IntTools_Context)& theContext)
+  (const TopoDS_Edge& theESp,
+   const TopoDS_Edge& theEOr,
+   const Handle(IntTools_Context)& theContext,
+   Standard_Integer *theError)
 {
-  Standard_Boolean bRet, bIsDegenerated;
-  //
-  bRet=Standard_False;
-  bIsDegenerated=(BRep_Tool::Degenerated(aEF1) || 
-                  BRep_Tool::Degenerated(aEF2));
-  if (bIsDegenerated) {
-    return bRet;
+  // The idea is to compare the tangent vectors of two edges computed in
+  // the same point. Thus, we need to take the point on split edge (since it is
+  // shorter) and project it onto original edge to find corresponding parameter.
+
+  if (BRep_Tool::Degenerated(theESp) ||
+      BRep_Tool::Degenerated(theEOr))
+  {
+    if (theError)
+      *theError = 1;
+    return Standard_False;
   }
-  //
-  Standard_Real a, b;
-  TopAbs_Orientation aOrE, aOrSp;
-  Handle(Geom_Curve)aC1, aC2;
-  //
-  aC2=BRep_Tool::Curve(aEF2, a, b);
-  aC1=BRep_Tool::Curve(aEF1, a, b);
-  //
-  if (aC1==aC2) {
-    aOrE=aEF2.Orientation();
-    aOrSp=aEF1.Orientation();
-    bRet=(aOrE!=aOrSp);
-    return bRet;
+
+  // Set OK error status
+  if (theError)
+    *theError = 0;
+
+  // Get the curves from the edges
+  Standard_Real f, l;
+  Handle(Geom_Curve) aCSp = BRep_Tool::Curve(theESp, f, l);
+  Handle(Geom_Curve) aCOr = BRep_Tool::Curve(theEOr, f, l);
+
+  // If the curves are the same, compare orientations only
+  if (aCSp == aCOr)
+    return theESp.Orientation() != theEOr.Orientation();
+
+  // Find valid range of the split edge, to ensure that the point for computing
+  // tangent vectors will be inside both edges.
+  if (!BRepLib::FindValidRange(theESp, f, l))
+    BRep_Tool::Range(theESp, f, l);
+
+  // Error code
+  Standard_Integer anErr = 0;
+  // Try a few sample points on the split edge until first valid found
+  const Standard_Integer aNbP = 11;
+  const Standard_Real aDT = (l - f) / aNbP;
+  for (Standard_Integer i = 1; i < aNbP; ++i)
+  {
+    const Standard_Real aTm = f + i*aDT;
+    // Compute tangent vector on split edge
+    gp_Vec aVSpTgt;
+    if (!BOPTools_AlgoTools2D::EdgeTangent(theESp, aTm, aVSpTgt))
+    {
+      // Unable to compute the tangent vector on the split edge
+      // in this point -> take the next point
+      anErr = 2;
+      continue;
+    }
+
+    // Find corresponding parameter on the original edge
+    Standard_Real aTmOr;
+    if (!theContext->ProjectPointOnEdge(aCSp->Value(aTm), theEOr, aTmOr))
+    {
+      // Unable to project the point inside the split edge
+      // onto the original edge -> take the next point
+      anErr = 3;
+      continue;
+    }
+
+    // Compute tangent vector on original edge
+    gp_Vec aVOrTgt;
+    if (!BOPTools_AlgoTools2D::EdgeTangent(theEOr, aTmOr, aVOrTgt))
+    {
+      // Unable to compute the tangent vector on the original edge
+      // in this point -> take the next point
+      anErr = 4;
+      continue;
+    }
+
+    // Compute the Dot product
+    Standard_Real aCos = aVSpTgt.Dot(aVOrTgt);
+    return (aCos < 0.);
   }
-  //
-  Standard_Real aT1, aT2, aScPr;
-  gp_Vec aV1, aV2;
-  gp_Pnt aP;
-  //
-  aT1=BOPTools_AlgoTools2D::IntermediatePoint(a, b);
-  aC1->D0(aT1, aP);
-  BOPTools_AlgoTools2D::EdgeTangent(aEF1, aT1, aV1);
-  gp_Dir aDT1(aV1);
-  //
-  theContext->ProjectPointOnEdge(aP, aEF2, aT2);
-  //
-  BOPTools_AlgoTools2D::EdgeTangent(aEF2, aT2, aV2);
-  gp_Dir aDT2(aV2);
-  //
-  aScPr=aDT1*aDT2;
-  bRet=(aScPr<0.);
-  //
-  return bRet;
+
+  if (theError)
+    *theError = anErr;
+
+  return Standard_False;
 }
 
 //=======================================================================
@@ -1715,7 +1765,7 @@ Standard_Boolean BOPTools_AlgoTools::GetEdgeOnFace
 Standard_Boolean FindFacePairs (const TopoDS_Edge& theE,
                                 const TopTools_ListOfShape& thLF,
                                 BOPTools_ListOfCoupleOfShape& theLCFF,
-                                Handle(IntTools_Context)& theContext)
+                                const Handle(IntTools_Context)& theContext)
 {
   Standard_Boolean bFound;
   Standard_Integer i, aNbCEF;
@@ -1841,7 +1891,7 @@ Standard_Boolean BOPTools_AlgoTools::IsBlockInOnFace
   (const IntTools_Range& aShrR,
    const TopoDS_Face& aF,
    const TopoDS_Edge& aE1,
-   Handle(IntTools_Context)& aContext)
+   const Handle(IntTools_Context)& aContext)
 {
   Standard_Boolean bFlag;
   Standard_Real f1, l1, ULD, VLD;
@@ -1978,7 +2028,7 @@ Standard_Boolean GetFaceDir(const TopoDS_Edge& aE,
                             const Standard_Boolean theSmallFaces,
                             gp_Dir& aDN,
                             gp_Dir& aDB,
-                            Handle(IntTools_Context)& theContext,
+                            const Handle(IntTools_Context)& theContext,
                             GeomAPI_ProjectPointOnSurf& aProjPL,
                             const Standard_Real aDt)
 {
@@ -2022,7 +2072,7 @@ Standard_Boolean FindPointInFace(const TopoDS_Face& aF,
                                  const gp_Pnt& aP,
                                  gp_Dir& aDB,
                                  gp_Pnt& aPOut,
-                                 Handle(IntTools_Context)& theContext,
+                                 const Handle(IntTools_Context)& theContext,
                                  GeomAPI_ProjectPointOnSurf& aProjPL,
                                  const Standard_Real aDt,
                                  const Standard_Real aTolE)
@@ -2092,7 +2142,7 @@ Standard_Real MinStep3D(const TopoDS_Edge& theE1,
                         const TopoDS_Face& theF1,
                         const BOPTools_ListOfCoupleOfShape& theLCS,
                         const gp_Pnt& aP,
-                        Handle(IntTools_Context)& theContext,
+                        const Handle(IntTools_Context)& theContext,
                         Standard_Boolean& theSmallFaces)
 {
   Standard_Real aDt, aTolE, aTolF, aDtMax, aDtMin;
diff --git a/src/BOPTools/BOPTools_AlgoTools.hxx b/src/BOPTools/BOPTools_AlgoTools.hxx
index 96102b3b5e..bb12821fe7 100644
--- a/src/BOPTools/BOPTools_AlgoTools.hxx
+++ b/src/BOPTools/BOPTools_AlgoTools.hxx
@@ -45,25 +45,235 @@ class IntTools_Context;
 class TopoDS_Solid;
 class IntTools_Range;
 class TopoDS_Shell;
+class Message_Report;
 
-
-class BOPTools_AlgoTools 
+//! Provides tools used in Boolean Operations algorithm:
+//! - Vertices intersection;
+//! - Vertex construction;
+//! - Edge construction;
+//! - Classification algorithms;
+//! - Making connexity blocks;
+//! - Shape validation.
+class BOPTools_AlgoTools
 {
 public:
 
   DEFINE_STANDARD_ALLOC
 
+public: //! @name Intersection of the vertices
+
+  //! Intersects the vertex <theV1> with the point <theP> with tolerance <theTolP>.
+  //! Returns the error status:
+  //! - 0 - no error, meaning that the vertex intersects the point;
+  //! - 1 - the distance between vertex and point is grater than the sum of tolerances.
+  Standard_EXPORT static Standard_Integer ComputeVV(const TopoDS_Vertex& theV,
+                                                    const gp_Pnt& theP,
+                                                    const Standard_Real theTolP);
+
+  //! Intersects the given vertices with given fuzzy value.
+  //! Returns the error status:
+  //! - 0 - no error, meaning that the vertices interferes with given tolerance;
+  //! - 1 - the distance between vertices is grater than the sum of their tolerances.
+  Standard_EXPORT static Standard_Integer ComputeVV(const TopoDS_Vertex& theV1,
+                                                    const TopoDS_Vertex& theV2,
+                                                    const Standard_Real theFuzz = Precision::Confusion());
+
+public: //! @name Vertices construction
+
+  //! Makes the vertex in the middle of given vertices with
+  //! the tolerance covering all tolerance spheres of vertices.
+  Standard_EXPORT static void MakeVertex(const TopTools_ListOfShape& theLV,
+                                         TopoDS_Vertex& theV);
+
+  //! Make a vertex using 3D-point <aP1> and 3D-tolerance value <aTol>
+  Standard_EXPORT static void MakeNewVertex(const gp_Pnt& aP1,
+                                            const Standard_Real aTol,
+                                            TopoDS_Vertex& aNewVertex);
+
+  //! Make a vertex using couple of vertices  <aV1, aV2>
+  Standard_EXPORT static void MakeNewVertex(const TopoDS_Vertex& aV1,
+                                            const TopoDS_Vertex& aV2,
+                                            TopoDS_Vertex& aNewVertex);
+
+  //! Make a vertex in place of intersection between two edges
+  //! <aE1, aE2> with parameters <aP1, aP2>
+  Standard_EXPORT static void MakeNewVertex(const TopoDS_Edge& aE1,
+                                            const Standard_Real aP1,
+                                            const TopoDS_Edge& aE2,
+                                            const Standard_Real aP2,
+                                            TopoDS_Vertex& aNewVertex);
+
+  //! Make a vertex in place of intersection between the edge <aE1>
+  //! with parameter <aP1> and the face <aF2>
+  Standard_EXPORT static void MakeNewVertex(const TopoDS_Edge& aE1,
+                                            const Standard_Real aP1,
+                                            const TopoDS_Face& aF2,
+                                            TopoDS_Vertex& aNewVertex);
+
+
+public: //! @name Updating the vertex
+
+  //! Update the tolerance value for vertex  <aV>
+  //! taking into account the fact that <aV> lays on
+  //! the curve <aIC>
+  Standard_EXPORT static void UpdateVertex(const IntTools_Curve& aIC,
+                                           const Standard_Real aT,
+                                           const TopoDS_Vertex& aV);
+
+  //! Update the tolerance value for vertex  <aV>
+  //! taking into account the fact that <aV> lays on
+  //! the edge <aE>
+  Standard_EXPORT static void UpdateVertex(const TopoDS_Edge& aE,
+                                           const Standard_Real aT,
+                                           const TopoDS_Vertex& aV);
+
+  //! Update the tolerance value for vertex  <aVN>
+  //! taking into account the fact that <aVN> should
+  //! cover tolerance zone of <aVF>
+  Standard_EXPORT static void UpdateVertex(const TopoDS_Vertex& aVF,
+                                           const TopoDS_Vertex& aVN);
+
+
+public: //! @name Edge construction
+
+  //! Makes the edge based on the given curve with given bounding vertices.
+  Standard_EXPORT static void MakeEdge(const IntTools_Curve& theCurve,
+                                       const TopoDS_Vertex& theV1,
+                                       const Standard_Real theT1,
+                                       const TopoDS_Vertex& theV2,
+                                       const Standard_Real theT2,
+                                       const Standard_Real theTolR3D,
+                                       TopoDS_Edge& theE);
+
+  //! Makes a copy of <theEdge> with vertices.
+  Standard_EXPORT static TopoDS_Edge CopyEdge(const TopoDS_Edge& theEdge);
+
+  //! Make the edge from base edge <aE1> and two vertices <aV1,aV2>
+  //! at parameters <aP1,aP2>
+  Standard_EXPORT static void MakeSplitEdge(const TopoDS_Edge& aE1,
+                                            const TopoDS_Vertex& aV1,
+                                            const Standard_Real aP1,
+                                            const TopoDS_Vertex& aV2,
+                                            const Standard_Real aP2,
+                                            TopoDS_Edge& aNewEdge);
+
+  //! Make the edge from 3D-Curve <aIC>  and two vertices <aV1,aV2>
+  //! at parameters <aP1,aP2>
+  Standard_EXPORT static void MakeSectEdge(const IntTools_Curve& aIC,
+                                           const TopoDS_Vertex& aV1,
+                                           const Standard_Real aP1,
+                                           const TopoDS_Vertex& aV2,
+                                           const Standard_Real aP2,
+                                           TopoDS_Edge& aNewEdge);
+
+
+public: //! @name Point/Edge/Face classification relatively solid
+
+  //! Computes the 3-D state of the point thePoint
+  //! toward solid theSolid.
+  //! theTol - value of precision of computation
+  //! theContext- cahed geometrical tools
+  //! Returns 3-D state.
+  Standard_EXPORT static TopAbs_State ComputeState(const gp_Pnt& thePoint,
+                                                   const TopoDS_Solid& theSolid,
+                                                   const Standard_Real theTol,
+                                                   const Handle(IntTools_Context)& theContext);
   
-  Standard_EXPORT static Standard_Integer ComputeVV (const TopoDS_Vertex& aV1, const gp_Pnt& aP2, const Standard_Real aTolP2);
+  //! Computes the 3-D state of the vertex theVertex
+  //! toward solid theSolid.
+  //! theTol - value of precision of computation
+  //! theContext- cahed geometrical tools
+  //! Returns 3-D state.
+  Standard_EXPORT static TopAbs_State ComputeState(const TopoDS_Vertex& theVertex,
+                                                   const TopoDS_Solid& theSolid,
+                                                   const Standard_Real theTol,
+                                                   const Handle(IntTools_Context)& theContext);
   
-  Standard_EXPORT static Standard_Integer ComputeVV (const TopoDS_Vertex& aV1, 
-                                                     const TopoDS_Vertex& aV2, 
-                                                     const Standard_Real theFuzz = Precision::Confusion());
+  //! Computes the 3-D state of the edge theEdge
+  //! toward solid theSolid.
+  //! theTol - value of precision of computation
+  //! theContext- cahed geometrical tools
+  //! Returns 3-D state.
+  Standard_EXPORT static TopAbs_State ComputeState(const TopoDS_Edge& theEdge,
+                                                  const TopoDS_Solid& theSolid,
+                                                  const Standard_Real theTol,
+                                                  const Handle(IntTools_Context)& theContext);
   
-  Standard_EXPORT static void MakeVertex (const TopTools_ListOfShape& aLV, TopoDS_Vertex& aV);
-  
-  Standard_EXPORT static void MakeEdge (const IntTools_Curve& theCurve, const TopoDS_Vertex& theV1, const Standard_Real theT1, const TopoDS_Vertex& theV2, const Standard_Real theT2, const Standard_Real theTolR3D, TopoDS_Edge& theE);
+  //! Computes the 3-D state of the face theFace
+  //! toward solid theSolid.
+  //! theTol - value of precision of computation
+  //! theBounds - set of edges of theFace to avoid
+  //! theContext- cahed geometrical tools
+  //! Returns 3-D state.
+  Standard_EXPORT static TopAbs_State ComputeState(const TopoDS_Face& theFace,
+                                                   const TopoDS_Solid& theSolid,
+                                                   const Standard_Real theTol,
+                                                   TopTools_IndexedMapOfShape& theBounds,
+                                                   const Handle(IntTools_Context)& theContext);
   
+  //! Computes the 3-D state of the shape theShape
+  //! toward solid theSolid.
+  //! theTol - value of precision of computation
+  //! theContext- cahed geometrical tools
+  //! Returns 3-D state.
+  Standard_EXPORT static TopAbs_State ComputeStateByOnePoint(const TopoDS_Shape& theShape,
+                                                             const TopoDS_Solid& theSolid,
+                                                             const Standard_Real theTol,
+                                                             const Handle(IntTools_Context)& theContext);
+
+
+public: //! @name Face classification relatively solid
+
+  //! For the face theFace and its edge theEdge
+  //! finds the face suitable to produce shell.
+  //! theLCEF - set of faces to search. All faces
+  //! from theLCEF must share edge theEdge
+  Standard_EXPORT static Standard_Boolean GetFaceOff(const TopoDS_Edge& theEdge,
+                                                     const TopoDS_Face& theFace,
+                                                     BOPTools_ListOfCoupleOfShape& theLCEF,
+                                                     TopoDS_Face& theFaceOff,
+                                                     const Handle(IntTools_Context)& theContext);
+
+  //! Returns True if the face theFace is inside of the
+  //! couple of faces theFace1, theFace2.
+  //! The faces theFace, theFace1, theFace2  must
+  //! share the edge theEdge
+  //! Return values:
+  //!  * 0 state is not IN
+  //!  * 1 state is IN
+  //!  * 2 state can not be found by the method of angles
+  Standard_EXPORT static Standard_Integer IsInternalFace(const TopoDS_Face& theFace,
+                                                         const TopoDS_Edge& theEdge,
+                                                         const TopoDS_Face& theFace1,
+                                                         const TopoDS_Face& theFace2,
+                                                         const Handle(IntTools_Context)& theContext);
+
+  //! Returns True if the face theFace is inside of the
+  //! appropriate couple of faces (from the set theLF)    .
+  //! The faces of the set theLF and theFace  must
+  //! share the edge theEdge
+  //!  * 0 state is not IN
+  //!  * 1 state is IN
+  //!  * 2 state can not be found by the method of angles
+  Standard_EXPORT static Standard_Integer IsInternalFace(const TopoDS_Face& theFace,
+                                                         const TopoDS_Edge& theEdge,
+                                                         TopTools_ListOfShape& theLF,
+                                                         const Handle(IntTools_Context)& theContext);
+
+  //! Returns True if the face theFace is inside the
+  //! solid theSolid.
+  //! theMEF - Map Edge/Faces for theSolid
+  //! theTol - value of precision of computation
+  //! theContext- cahed geometrical tools
+  Standard_EXPORT static Standard_Boolean IsInternalFace(const TopoDS_Face& theFace,
+                                                         const TopoDS_Solid& theSolid,
+                                                         TopTools_IndexedDataMapOfShapeListOfShape& theMEF,
+                                                         const Standard_Real theTol,
+                                                         const Handle(IntTools_Context)& theContext);
+
+
+public: //! @name PCurve construction
+
   //! Makes 2d curve of the edge <theE> on the faces <theF1> and <theF2>.<br>
   //! <theContext> - storage for caching the geometrical tools
   Standard_EXPORT static void MakePCurve (const TopoDS_Edge& theE,
@@ -73,123 +283,121 @@ public:
                                           const Standard_Boolean thePC1,
                                           const Standard_Boolean thePC2,
                                           const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
-  
-  Standard_EXPORT static void MakeContainer (const TopAbs_ShapeEnum theType, TopoDS_Shape& theShape);
-  
-  Standard_EXPORT static Standard_Boolean IsHole (const TopoDS_Shape& aW, const TopoDS_Shape& aF);
-  
-  //! Returns True if the shape theSplit has opposite
-  //! direction than theShape
-  //! theContext - cashed geometrical tools
-  Standard_EXPORT static Standard_Boolean IsSplitToReverse (const TopoDS_Shape& theSplit, const TopoDS_Shape& theShape, Handle(IntTools_Context)& theContext);
-  
-  //! Returns True if normal direction of the face
-  //! theShape is not the same as for the face
-  //! theSplit
-  //! theContext - cashed geometrical tools
-  Standard_EXPORT static Standard_Boolean IsSplitToReverse (const TopoDS_Face& theSplit, const TopoDS_Face& theShape, Handle(IntTools_Context)& theContext);
-  
-  Standard_EXPORT static Standard_Boolean IsSplitToReverse (const TopoDS_Edge& aE1, const TopoDS_Edge& aE2, Handle(IntTools_Context)& aContext);
-  
-  Standard_EXPORT static Standard_Boolean AreFacesSameDomain (const TopoDS_Face& theF1,
-                                         const TopoDS_Face& theF2, 
-                                         Handle(IntTools_Context)& theContext,
-                                         const Standard_Real theFuzz = Precision::Confusion());
-  
-  Standard_EXPORT static Standard_Boolean CheckSameGeom (const TopoDS_Face& theF1, const TopoDS_Face& theF2, Handle(IntTools_Context)& theContext);
-  
-  //! Basing on the normals directions of the faces the method
-  //! Defines whether to reverse the second face or not.<br>
-  //! <theContext> - storage for caching the geometrical tools
-  Standard_EXPORT static Standard_Integer Sense (const TopoDS_Face& theF1,
-                                                 const TopoDS_Face& theF2,
-                                                 const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
-  
-  //! Returns True if the face theFace contains
-  //! the edge theEdge but with opposite orientation.
-  //! If the method  returns True theEdgeOff is the
-  //! edge founded
-  Standard_EXPORT static Standard_Boolean GetEdgeOff (const TopoDS_Edge& theEdge, const TopoDS_Face& theFace, TopoDS_Edge& theEdgeOff);
-  
-  //! For the face theFace and its edge theEdge
-  //! finds the face suitable to produce shell.
-  //! theLCEF - set of faces to search. All faces
-  //! from theLCEF must share edge theEdge
-  Standard_EXPORT static Standard_Boolean GetFaceOff (const TopoDS_Edge& theEdge, const TopoDS_Face& theFace, BOPTools_ListOfCoupleOfShape& theLCEF, TopoDS_Face& theFaceOff, Handle(IntTools_Context)& theContext);
-  
-  //! Returns True if the face theFace is inside of the
-  //! couple of faces theFace1, theFace2.
-  //! The faces theFace, theFace1, theFace2  must
-  //! share the edge theEdge
-  //! Return values:
-  //!  * 0 state is not IN
-  //!  * 1 state is IN
-  //!  * 2 state can not be found by the method of angles
-  Standard_EXPORT static Standard_Integer IsInternalFace (const TopoDS_Face& theFace, const TopoDS_Edge& theEdge, const TopoDS_Face& theFace1, const TopoDS_Face& theFace2, Handle(IntTools_Context)& theContext);
-  
-  //! Returns True if the face theFace is inside of the
-  //! appropriate couple of faces (from the set theLF)    .
-  //! The faces of the set theLF and theFace  must
-  //! share the edge theEdge
-  //!  * 0 state is not IN
-  //!  * 1 state is IN
-  //!  * 2 state can not be found by the method of angles
-  Standard_EXPORT static Standard_Integer IsInternalFace (const TopoDS_Face& theFace, const TopoDS_Edge& theEdge, TopTools_ListOfShape& theLF, Handle(IntTools_Context)& theContext);
-  
-  //! Returns True if the face theFace is inside the
-  //! solid theSolid.
-  //! theMEF - Map Edge/Faces for theSolid
-  //! theTol - value of precision of computation
-  //! theContext- cahed geometrical tools
-  Standard_EXPORT static Standard_Boolean IsInternalFace (const TopoDS_Face& theFace, const TopoDS_Solid& theSolid, TopTools_IndexedDataMapOfShapeListOfShape& theMEF, const Standard_Real theTol, Handle(IntTools_Context)& theContext);
-  
-  //! For the face theFace gets the edge theEdgeOnF
-  //! that is the same as theEdge
-  //! Returns True if such edge exists
-  //! Returns False if there is no such edge
-  Standard_EXPORT static Standard_Boolean GetEdgeOnFace (const TopoDS_Edge& theEdge, const TopoDS_Face& theFace, TopoDS_Edge& theEdgeOnF);
-  
-  //! Computes the 3-D state of the point thePoint
-  //! toward solid theSolid.
-  //! theTol - value of precision of computation
-  //! theContext- cahed geometrical tools
-  //! Returns 3-D state.
-  Standard_EXPORT static TopAbs_State ComputeState (const gp_Pnt& thePoint, const TopoDS_Solid& theSolid, const Standard_Real theTol, Handle(IntTools_Context)& theContext);
-  
-  //! Computes the 3-D state of the vertex theVertex
-  //! toward solid theSolid.
-  //! theTol - value of precision of computation
-  //! theContext- cahed geometrical tools
-  //! Returns 3-D state.
-  Standard_EXPORT static TopAbs_State ComputeState (const TopoDS_Vertex& theVertex, const TopoDS_Solid& theSolid, const Standard_Real theTol, Handle(IntTools_Context)& theContext);
-  
-  //! Computes the 3-D state of the edge theEdge
-  //! toward solid theSolid.
-  //! theTol - value of precision of computation
-  //! theContext- cahed geometrical tools
-  //! Returns 3-D state.
-  Standard_EXPORT static TopAbs_State ComputeState (const TopoDS_Edge& theEdge, const TopoDS_Solid& theSolid, const Standard_Real theTol, Handle(IntTools_Context)& theContext);
-  
-  //! Computes the 3-D state of the face theFace
-  //! toward solid theSolid.
-  //! theTol - value of precision of computation
-  //! theBounds - set of edges of theFace to avoid
-  //! theContext- cahed geometrical tools
-  //! Returns 3-D state.
-  Standard_EXPORT static TopAbs_State ComputeState (const TopoDS_Face& theFace, const TopoDS_Solid& theSolid, const Standard_Real theTol, TopTools_IndexedMapOfShape& theBounds, Handle(IntTools_Context)& theContext);
-  
-  //! Computes the 3-D state of the shape theShape
-  //! toward solid theSolid.
-  //! theTol - value of precision of computation
-  //! theContext- cahed geometrical tools
-  //! Returns 3-D state.
-  Standard_EXPORT static TopAbs_State ComputeStateByOnePoint (const TopoDS_Shape& theShape, const TopoDS_Solid& theSolid, const Standard_Real theTol, Handle(IntTools_Context)& theContext);
-  
+
+
+public: //! @name Wire classification relatively face
+
+  //! Checks if the wire is a hole for the face.
+  Standard_EXPORT static Standard_Boolean IsHole(const TopoDS_Shape& theW,
+                                                 const TopoDS_Shape& theF);
+
+
+public: //! @name Choosing correct orientation for the split shape
+
+  //! Checks if the direction of the split shape is opposite to
+  //! the direction of the original shape.
+  //! The method is an overload for (Edge,Edge) and (Face,Face) corresponding
+  //! methods and checks only these types of shapes.
+  //! For faces the method checks if normal directions are opposite.
+  //! For edges the method checks if tangent vectors are opposite.
+  //!
+  //! In case the directions do not coincide, it returns TRUE, meaning
+  //! that split shape has to be reversed to match the direction of the
+  //! original shape.
+  //!
+  //! If requested (<theError> is not null), the method returns the status of the operation:
+  //! - 0 - no error;
+  //! - Error from (Edge,Edge) or (Face,Face) corresponding method
+  //! - 100 - bad types.
+  //! In case of any error the method always returns FALSE.
+  //!
+  //! @param theSplit [in] Split shape
+  //! @param theShape [in] Original shape
+  //! @param theContext [in] Cashed geometrical tools
+  //! @param theError [out] Error Status of the operation
+  Standard_EXPORT static Standard_Boolean IsSplitToReverse(const TopoDS_Shape& theSplit,
+                                                           const TopoDS_Shape& theShape,
+                                                           const Handle(IntTools_Context)& theContext,
+                                                           Standard_Integer *theError = NULL);
+
+  //! Add-on for the *IsSplitToReverse()* to check for its errors
+  //! and in case of any add the *BOPAlgo_AlertUnableToOrientTheShape*
+  //! warning to the report.
+  Standard_EXPORT static Standard_Boolean IsSplitToReverseWithWarn(const TopoDS_Shape& theSplit,
+                                                                   const TopoDS_Shape& theShape,
+                                                                   const Handle(IntTools_Context)& theContext,
+                                                                   const Handle(Message_Report)& theReport = NULL);
+
+  //! Checks if the normal direction of the split face is opposite to
+  //! the normal direction of the original face.
+  //! The normal directions for both faces are taken in the same point -
+  //! point inside the split face is projected onto the original face.
+  //! Returns TRUE if the normals do not coincide, meaning the necessity
+  //! to revert the orientation of the split face to match the direction
+  //! of the original face.
+  //!
+  //! If requested (<theError> is not null), the method returns the status of the operation:
+  //! - 0 - no error;
+  //! - 1 - unable to find the point inside split face;
+  //! - 2 - unable to compute the normal for the split face;
+  //! - 3 - unable to project the point inside the split face on the original face;
+  //! - 4 - unable to compute the normal for the original face.
+  //! In case of any error the method always returns FALSE.
+  //!
+  //! @param theSplit [in] Split face
+  //! @param theShape [in] Original face
+  //! @param theContext [in] Cashed geometrical tools
+  //! @param theError [out] Error Status of the operation
+  Standard_EXPORT static Standard_Boolean IsSplitToReverse(const TopoDS_Face& theSplit,
+                                                           const TopoDS_Face& theShape,
+                                                           const Handle(IntTools_Context)& theContext,
+                                                           Standard_Integer *theError = NULL);
+
+  //! Checks if the tangent vector of the split edge is opposite to
+  //! the tangent vector of the original edge.
+  //! The tangent vectors for both edges are computed in the same point -
+  //! point inside the split edge is projected onto the original edge.
+  //! Returns TRUE if the tangent vectors do not coincide, meaning the necessity
+  //! to revert the orientation of the split edge to match the direction
+  //! of the original edge.
+  //!
+  //! If requested (<theError> is not null), the method returns the status of the operation:
+  //! - 0 - no error;
+  //! - 1 - degenerated edges are given;
+  //! - 2 - unable to compute the tangent vector for the split edge;
+  //! - 3 - unable to project the point inside the split edge on the original edge;
+  //! - 4 - unable to compute the tangent vector for the original edge;
+  //! In case of any error the method always returns FALSE.
+  //!
+  //! @param theSplit [in] Split edge
+  //! @param theShape [in] Original edge
+  //! @param theContext [in] Cashed geometrical tools
+  //! @param theError [out] Error Status of the operation
+  Standard_EXPORT static Standard_Boolean IsSplitToReverse(const TopoDS_Edge& theSplit,
+                                                           const TopoDS_Edge& theShape,
+                                                           const Handle(IntTools_Context)& theContext,
+                                                           Standard_Integer *theError = NULL);
+
+  //! Checks if the normals direction of the given faces computed near
+  //! the shared edge coincide.
+  //! Returns the status of operation:
+  //! * 0 - in case of error (shared edge not found or directions are not collinear)
+  //! * 1 - normal directions coincide;
+  //! * -1 - normal directions are opposite.
+  Standard_EXPORT static Standard_Integer Sense(const TopoDS_Face& theF1,
+                                                const TopoDS_Face& theF2,
+                                                const Handle(IntTools_Context)& theContext);
+
+public: //! @name Making connexity blocks
+
   //! For the list of faces theLS build block
   //! theLSCB in terms of connexity by edges
   //! theMapAvoid - set of edges to avoid for
   //! the treatment
-  Standard_EXPORT static void MakeConnexityBlock (TopTools_ListOfShape& theLS, TopTools_IndexedMapOfShape& theMapAvoid, TopTools_ListOfShape& theLSCB, const Handle(NCollection_BaseAllocator)& theAllocator);
+  Standard_EXPORT static void MakeConnexityBlock(TopTools_ListOfShape& theLS,
+                                                 TopTools_IndexedMapOfShape& theMapAvoid,
+                                                 TopTools_ListOfShape& theLSCB,
+                                                 const Handle(NCollection_BaseAllocator)& theAllocator);
 
   //! For the compound <theS> builds the blocks (compounds) of
   //! elements of type <theElementType> connected through the shapes
@@ -219,139 +427,136 @@ public:
                                                   const TopAbs_ShapeEnum theElementType,
                                                   BOPTools_ListOfConnexityBlock& theLCB);
 
+public: //! @name Orienting elements in container
+
   //! Correctly orients edges on the wire
-  Standard_EXPORT static void OrientEdgesOnWire (TopoDS_Shape& theWire);
+  Standard_EXPORT static void OrientEdgesOnWire(TopoDS_Shape& theWire);
 
   //! Correctly orients faces on the shell
-  Standard_EXPORT static void OrientFacesOnShell (TopoDS_Shape& theShell);
-  
+  Standard_EXPORT static void OrientFacesOnShell(TopoDS_Shape& theShell);
+
+
+public: //! @name Methods for shape validation (correction)
 
   //! Provides valid values of tolerances for the shape <theS>
   //! <theTolMax> is max value of the tolerance that can be
   //! accepted for correction.  If real value of the tolerance
   //! will be greater than  <aTolMax>, the correction does not
   //! perform.
-  Standard_EXPORT static void CorrectTolerances
-              (const TopoDS_Shape& theS, 
-               const TopTools_IndexedMapOfShape& theMapToAvoid,
-               const Standard_Real theTolMax = 0.0001,
-               const Standard_Boolean theRunParallel = Standard_False);
+  Standard_EXPORT static void CorrectTolerances(const TopoDS_Shape& theS, 
+                                                const TopTools_IndexedMapOfShape& theMapToAvoid,
+                                                const Standard_Real theTolMax = 0.0001,
+                                                const Standard_Boolean theRunParallel = Standard_False);
 
   //! Provides valid values of tolerances for the shape <theS>
   //! in  terms of BRepCheck_InvalidCurveOnSurface.
-  Standard_EXPORT static void CorrectCurveOnSurface
-              (const TopoDS_Shape& theS,
-               const TopTools_IndexedMapOfShape& theMapToAvoid,
-               const Standard_Real theTolMax = 0.0001,
-               const Standard_Boolean theRunParallel = Standard_False);
+  Standard_EXPORT static void CorrectCurveOnSurface(const TopoDS_Shape& theS,
+                                                    const TopTools_IndexedMapOfShape& theMapToAvoid,
+                                                    const Standard_Real theTolMax = 0.0001,
+                                                    const Standard_Boolean theRunParallel = Standard_False);
 
   //! Provides valid values of tolerances for the shape <theS>
   //! in  terms of BRepCheck_InvalidPointOnCurve.
-  Standard_EXPORT static void CorrectPointOnCurve
-              (const TopoDS_Shape& theS,
-               const TopTools_IndexedMapOfShape& theMapToAvoid,
-               const Standard_Real theTolMax = 0.0001,
-               const Standard_Boolean theRunParallel = Standard_False);
+  Standard_EXPORT static void CorrectPointOnCurve(const TopoDS_Shape& theS,
+                                                  const TopTools_IndexedMapOfShape& theMapToAvoid,
+                                                  const Standard_Real theTolMax = 0.0001,
+                                                  const Standard_Boolean theRunParallel = Standard_False);
 
-  //! Make a vertex using 3D-point <aP1> and 3D-tolerance value <aTol>
-  Standard_EXPORT static void MakeNewVertex (const gp_Pnt& aP1, const Standard_Real aTol, TopoDS_Vertex& aNewVertex);
-  
+  //! Corrects tolerance values of the sub-shapes of the shape <theS> if needed.
+  Standard_EXPORT static void CorrectShapeTolerances(const TopoDS_Shape& theS,
+                                                     const TopTools_IndexedMapOfShape& theMapToAvoid,
+                                                     const Standard_Boolean theRunParallel = Standard_False);
 
-  //! Make a vertex using couple of vertices  <aV1, aV2>
-  Standard_EXPORT static void MakeNewVertex (const TopoDS_Vertex& aV1, const TopoDS_Vertex& aV2, TopoDS_Vertex& aNewVertex);
-  
 
-  //! Make a vertex in place of intersection between two edges
-  //! <aE1, aE2> with parameters <aP1, aP2>
-  Standard_EXPORT static void MakeNewVertex (const TopoDS_Edge& aE1, const Standard_Real aP1, const TopoDS_Edge& aE2, const Standard_Real aP2, TopoDS_Vertex& aNewVertex);
-  
+public: //! Checking if the faces are coinciding
 
-  //! Make a vertex in place of intersection between the edge <aE1>
-  //! with parameter <aP1> and the face <aF2>
-  Standard_EXPORT static void MakeNewVertex (const TopoDS_Edge& aE1, const Standard_Real aP1, const TopoDS_Face& aF2, TopoDS_Vertex& aNewVertex);
-  
+  //! Checks if the given faces are same-domain, i.e. coincide.
+  Standard_EXPORT static Standard_Boolean AreFacesSameDomain(const TopoDS_Face& theF1,
+                                                             const TopoDS_Face& theF2, 
+                                                             const Handle(IntTools_Context)& theContext,
+                                                             const Standard_Real theFuzz = Precision::Confusion());
 
-  //! Compute a 3D-point on the edge <aEdge> at parameter <aPrm>
-  Standard_EXPORT static void PointOnEdge (const TopoDS_Edge& aEdge, const Standard_Real aPrm, gp_Pnt& aP);
+public: //! @name Looking for the edge in the face
 
-  //! Makes a copy of <theEdge> with vertices.
-  Standard_EXPORT static TopoDS_Edge CopyEdge(const TopoDS_Edge& theEdge);
+  //! Returns True if the face theFace contains
+  //! the edge theEdge but with opposite orientation.
+  //! If the method  returns True theEdgeOff is the
+  //! edge founded
+  Standard_EXPORT static Standard_Boolean GetEdgeOff(const TopoDS_Edge& theEdge,
+                                                     const TopoDS_Face& theFace,
+                                                     TopoDS_Edge& theEdgeOff);
 
-  //! Make the edge from base edge <aE1> and two vertices <aV1,aV2>
-  //! at parameters <aP1,aP2>
-  Standard_EXPORT static void MakeSplitEdge (const TopoDS_Edge& aE1, const TopoDS_Vertex& aV1, const Standard_Real aP1, const TopoDS_Vertex& aV2, const Standard_Real aP2, TopoDS_Edge& aNewEdge);
-  
+  //! For the face theFace gets the edge theEdgeOnF
+  //! that is the same as theEdge
+  //! Returns True if such edge exists
+  //! Returns False if there is no such edge
+  Standard_EXPORT static Standard_Boolean GetEdgeOnFace(const TopoDS_Edge& theEdge,
+                                                        const TopoDS_Face& theFace,
+                                                        TopoDS_Edge& theEdgeOnF);
 
-  //! Make the edge from 3D-Curve <aIC>  and two vertices <aV1,aV2>
-  //! at parameters <aP1,aP2>
-  Standard_EXPORT static void MakeSectEdge (const IntTools_Curve& aIC, const TopoDS_Vertex& aV1, const Standard_Real aP1, const TopoDS_Vertex& aV2, const Standard_Real aP2, TopoDS_Edge& aNewEdge);
-  
 
-  //! Update the tolerance value for vertex  <aV>
-  //! taking into account the fact that <aV> lays on
-  //! the curve <aIC>
-  Standard_EXPORT static void UpdateVertex (const IntTools_Curve& aIC, const Standard_Real aT, const TopoDS_Vertex& aV);
-  
+public: //! @name Correction of the edges range
 
-  //! Update the tolerance value for vertex  <aV>
-  //! taking into account the fact that <aV> lays on
-  //! the edge <aE>
-  Standard_EXPORT static void UpdateVertex (const TopoDS_Edge& aE, const Standard_Real aT, const TopoDS_Vertex& aV);
-  
-
-  //! Update the tolerance value for vertex  <aVN>
-  //! taking into account the fact that <aVN> should
-  //! cover tolerance zone of <aVF>
-  Standard_EXPORT static void UpdateVertex (const TopoDS_Vertex& aVF, const TopoDS_Vertex& aVN);
+  //! Correct shrunk range <aSR> taking into account 3D-curve
+  //! resolution and corresponding tolerance values of <aE1>, <aE2>
+  Standard_EXPORT static void CorrectRange(const TopoDS_Edge& aE1,
+                                           const TopoDS_Edge& aE2,
+                                           const IntTools_Range& aSR,
+                                           IntTools_Range& aNewSR);
   
 
   //! Correct shrunk range <aSR> taking into account 3D-curve
-  //! resolution and corresp. tolerances' values of <aE1>, <aE2>
-  Standard_EXPORT static void CorrectRange (const TopoDS_Edge& aE1, const TopoDS_Edge& aE2, const IntTools_Range& aSR, IntTools_Range& aNewSR);
-  
+  //! resolution and corresponding tolerance values of <aE>, <aF>
+  Standard_EXPORT static void CorrectRange(const TopoDS_Edge& aE,
+                                           const TopoDS_Face& aF,
+                                           const IntTools_Range& aSR,
+                                           IntTools_Range& aNewSR);
 
-  //! Correct shrunk range <aSR> taking into account 3D-curve
-  //! resolution and corresp. tolerances' values of <aE>, <aF>
-  Standard_EXPORT static void CorrectRange (const TopoDS_Edge& aE, const TopoDS_Face& aF, const IntTools_Range& aSR, IntTools_Range& aNewSR);
-  
-
-  //! Returns TRUE if PaveBlock <aPB> lays on the face <aF>, i.e
-  //! the <PB> is IN or ON in 2D of <aF>
-  Standard_EXPORT static Standard_Boolean IsBlockInOnFace (const IntTools_Range& aShR, const TopoDS_Face& aF, const TopoDS_Edge& aE, Handle(IntTools_Context)& aContext);
-  
+public: //! @name Checking edge on micro status
 
   //! Checks if it is possible to compute shrunk range for the edge <aE>
   //! Flag <theCheckSplittable> defines whether to take into account 
-  //! the possiblity to split the edge or not.
-  Standard_EXPORT static Standard_Boolean IsMicroEdge (const TopoDS_Edge& theEdge,
-                                                       const Handle(IntTools_Context)& theContext,
-                                                       const Standard_Boolean theCheckSplittable = Standard_True);
-  
+  //! the possibility to split the edge or not.
+  Standard_EXPORT static Standard_Boolean IsMicroEdge(const TopoDS_Edge& theEdge,
+                                                      const Handle(IntTools_Context)& theContext,
+                                                      const Standard_Boolean theCheckSplittable = Standard_True);
 
-  //! Corrects tolerance values of the sub-shapes of the shape <theS> if needed.
-  Standard_EXPORT static void CorrectShapeTolerances
-              (const TopoDS_Shape& theS,
-               const TopTools_IndexedMapOfShape& theMapToAvoid,
-               const Standard_Boolean theRunParallel = Standard_False);
+public: //! @name Solid classification
 
-  //! Retutns dimension of the shape <theS>.
-  Standard_EXPORT static Standard_Integer Dimension (const TopoDS_Shape& theS);
-  
-  //! Returns true if the  shell <theShell> is open
-  Standard_EXPORT static Standard_Boolean IsOpenShell (const TopoDS_Shell& theShell);
-  
   //! Returns true if the solid <theSolid> is inverted
-  Standard_EXPORT static Standard_Boolean IsInvertedSolid (const TopoDS_Solid& theSolid);
-  
+  Standard_EXPORT static Standard_Boolean IsInvertedSolid(const TopoDS_Solid& theSolid);
+
+public: //! @name Edge/Face Deviation computation
 
   //! Computes the necessary value of the tolerance for the edge
-  Standard_EXPORT static Standard_Boolean ComputeTolerance (const TopoDS_Face& theFace, const TopoDS_Edge& theEdge, Standard_Real& theMaxDist, Standard_Real& theMaxPar);
+  Standard_EXPORT static Standard_Boolean ComputeTolerance(const TopoDS_Face& theFace,
+                                                           const TopoDS_Edge& theEdge,
+                                                           Standard_Real& theMaxDist,
+                                                           Standard_Real& theMaxPar);
 
+public: //! @name Other methods
 
-protected:
+  //! Makes empty container of requested type
+  Standard_EXPORT static void MakeContainer(const TopAbs_ShapeEnum theType,
+                                            TopoDS_Shape& theShape);
 
+  //! Compute a 3D-point on the edge <aEdge> at parameter <aPrm>
+  Standard_EXPORT static void PointOnEdge(const TopoDS_Edge& aEdge,
+                                          const Standard_Real aPrm,
+                                          gp_Pnt& aP);
 
-private:
+  //! Returns TRUE if PaveBlock <aPB> lays on the face <aF>, i.e
+  //! the <PB> is IN or ON in 2D of <aF>
+  Standard_EXPORT static Standard_Boolean IsBlockInOnFace(const IntTools_Range& aShR,
+                                                          const TopoDS_Face& aF,
+                                                          const TopoDS_Edge& aE,
+                                                          const Handle(IntTools_Context)& aContext);
+
+  //! Retutns dimension of the shape <theS>.
+  Standard_EXPORT static Standard_Integer Dimension(const TopoDS_Shape& theS);
+
+  //! Returns true if the  shell <theShell> is open
+  Standard_EXPORT static Standard_Boolean IsOpenShell(const TopoDS_Shell& theShell);
 
 };
 
diff --git a/src/BOPTools/BOPTools_AlgoTools2D.hxx b/src/BOPTools/BOPTools_AlgoTools2D.hxx
index a867d0d9aa..8db49a549d 100644
--- a/src/BOPTools/BOPTools_AlgoTools2D.hxx
+++ b/src/BOPTools/BOPTools_AlgoTools2D.hxx
@@ -42,19 +42,17 @@ public:
 
   DEFINE_STANDARD_ALLOC
 
-  
-
   //! Compute P-Curve for the edge <aE> on the face <aF>.<br>
   //! Raises exception Standard_ConstructionError if projection algorithm fails.<br>
   //! <theContext> - storage for caching the geometrical tools
-  Standard_EXPORT static void BuildPCurveForEdgeOnFace (const TopoDS_Edge& aE,
-                                                        const TopoDS_Face& aF,
-                                                        const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
-  
+  Standard_EXPORT static void BuildPCurveForEdgeOnFace(const TopoDS_Edge& aE,
+                                                       const TopoDS_Face& aF,
+                                                       const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
 
   //! Compute tangent for the edge  <aE> [in 3D]  at parameter <aT>
-  Standard_EXPORT static Standard_Boolean EdgeTangent (const TopoDS_Edge& anE, const Standard_Real aT, gp_Vec& Tau);
-  
+  Standard_EXPORT static Standard_Boolean EdgeTangent(const TopoDS_Edge& anE,
+                                                      const Standard_Real aT,
+                                                      gp_Vec& Tau);
 
   //! Compute surface parameters <U,V> of the face <aF>
   //! for  the point from the edge <aE> at parameter <aT>.<br>
@@ -62,24 +60,23 @@ public:
   //! projection and can
   //! raise exception Standard_ConstructionError if projection algorithm fails.<br>
   //! <theContext> - storage for caching the geometrical tools
-  Standard_EXPORT static void PointOnSurface (const TopoDS_Edge& aE,
-                                              const TopoDS_Face& aF,
-                                              const Standard_Real aT,
-                                              Standard_Real& U,
-                                              Standard_Real& V,
-                                              const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
-  
+  Standard_EXPORT static void PointOnSurface(const TopoDS_Edge& aE,
+                                             const TopoDS_Face& aF,
+                                             const Standard_Real aT,
+                                             Standard_Real& U,
+                                             Standard_Real& V,
+                                             const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
 
   //! Get P-Curve <aC>  for the edge <aE> on surface <aF> .<br>
   //! If the P-Curve does not exist, build  it using Make2D().<br>
   //! [aToler] - reached tolerance
   //! Raises exception Standard_ConstructionError if algorithm Make2D() fails.<br>
   //! <theContext> - storage for caching the geometrical tools
-  Standard_EXPORT static void CurveOnSurface (const TopoDS_Edge& aE,
-                                              const TopoDS_Face& aF,
-                                              Handle(Geom2d_Curve)& aC,
-                                              Standard_Real& aToler,
-                                              const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
+  Standard_EXPORT static void CurveOnSurface(const TopoDS_Edge& aE,
+                                             const TopoDS_Face& aF,
+                                             Handle(Geom2d_Curve)& aC,
+                                             Standard_Real& aToler,
+                                             const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
 
   //! Get P-Curve <aC>  for the edge <aE> on surface <aF> .<br>
   //! If the P-Curve does not exist, build  it using Make2D().<br>
@@ -87,102 +84,108 @@ public:
   //! [aToler] - reached tolerance<br>
   //! Raises exception Standard_ConstructionError if algorithm Make2D() fails.<br>
   //! <theContext> - storage for caching the geometrical tools
-  Standard_EXPORT static void CurveOnSurface (const TopoDS_Edge& aE,
-                                              const TopoDS_Face& aF,
-                                              Handle(Geom2d_Curve)& aC,
-                                              Standard_Real& aFirst,
-                                              Standard_Real& aLast,
-                                              Standard_Real& aToler,
-                                              const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
-  
+  Standard_EXPORT static void CurveOnSurface(const TopoDS_Edge& aE,
+                                             const TopoDS_Face& aF,
+                                             Handle(Geom2d_Curve)& aC,
+                                             Standard_Real& aFirst,
+                                             Standard_Real& aLast,
+                                             Standard_Real& aToler,
+                                             const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
 
   //! Returns TRUE if the edge <aE>  has  P-Curve <aC>
   //! on surface <aF> .
   //! [aFirst, aLast] - range of the P-Curve
   //! [aToler] - reached tolerance
   //! If the P-Curve does not exist, aC.IsNull()=TRUE.
-  Standard_EXPORT static Standard_Boolean HasCurveOnSurface (const TopoDS_Edge& aE, const TopoDS_Face& aF, Handle(Geom2d_Curve)& aC, Standard_Real& aFirst, Standard_Real& aLast, Standard_Real& aToler);
-  
+  Standard_EXPORT static Standard_Boolean HasCurveOnSurface(const TopoDS_Edge& aE,
+                                                            const TopoDS_Face& aF,
+                                                            Handle(Geom2d_Curve)& aC,
+                                                            Standard_Real& aFirst,
+                                                            Standard_Real& aLast,
+                                                            Standard_Real& aToler);
 
   //! Returns TRUE if the edge <aE>  has  P-Curve <aC>
   //! on surface <aF> .
   //! If the P-Curve does not exist, aC.IsNull()=TRUE.
-  Standard_EXPORT static Standard_Boolean HasCurveOnSurface (const TopoDS_Edge& aE, const TopoDS_Face& aF);
-  
+  Standard_EXPORT static Standard_Boolean HasCurveOnSurface(const TopoDS_Edge& aE,
+                                                            const TopoDS_Face& aF);
 
   //! Adjust P-Curve <theC2D> (3D-curve <theC3D>) on surface of the face <theF>.<br>
   //! <theContext> - storage for caching the geometrical tools
-  Standard_EXPORT static void AdjustPCurveOnFace (const TopoDS_Face& theF,
-                                                  const Handle(Geom_Curve)& theC3D,
-                                                  const Handle(Geom2d_Curve)& theC2D,
-                                                  Handle(Geom2d_Curve)& theC2DA,
-                                                  const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
-  
+  Standard_EXPORT static void AdjustPCurveOnFace(const TopoDS_Face& theF,
+                                                 const Handle(Geom_Curve)& theC3D,
+                                                 const Handle(Geom2d_Curve)& theC2D,
+                                                 Handle(Geom2d_Curve)& theC2DA,
+                                                 const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
 
   //! Adjust P-Curve <aC2D> (3D-curve <C3D>) on surface <aF> .<br>
   //! [aT1,  aT2] - range to adjust<br>
   //! <theContext> - storage for caching the geometrical tools
-  Standard_EXPORT static void AdjustPCurveOnFace (const TopoDS_Face& theF,
-                                                  const Standard_Real theFirst,
-                                                  const Standard_Real theLast,
-                                                  const Handle(Geom2d_Curve)& theC2D,
-                                                  Handle(Geom2d_Curve)& theC2DA,
-                                                  const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
+  Standard_EXPORT static void AdjustPCurveOnFace(const TopoDS_Face& theF,
+                                                 const Standard_Real theFirst,
+                                                 const Standard_Real theLast,
+                                                 const Handle(Geom2d_Curve)& theC2D,
+                                                 Handle(Geom2d_Curve)& theC2DA,
+                                                 const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
 
   //! Adjust P-Curve <aC2D> (3D-curve <C3D>) on surface <aF> .
   //! [aT1,  aT2] - range to adjust
-  Standard_EXPORT static void AdjustPCurveOnSurf (const BRepAdaptor_Surface& aF, const Standard_Real aT1, const Standard_Real aT2, const Handle(Geom2d_Curve)& aC2D, Handle(Geom2d_Curve)& aC2DA);
-  
+  Standard_EXPORT static void AdjustPCurveOnSurf(const BRepAdaptor_Surface& aF,
+                                                 const Standard_Real aT1,
+                                                 const Standard_Real aT2,
+                                                 const Handle(Geom2d_Curve)& aC2D,
+                                                 Handle(Geom2d_Curve)& aC2DA);
 
   //! Compute intermediate  value in  between [aFirst, aLast] .
-  Standard_EXPORT static Standard_Real IntermediatePoint (const Standard_Real aFirst, const Standard_Real aLast);
-  
+  Standard_EXPORT static Standard_Real IntermediatePoint(const Standard_Real aFirst,
+                                                         const Standard_Real aLast);
 
   //! Compute intermediate value of parameter for the edge <anE>.
-  Standard_EXPORT static Standard_Real IntermediatePoint (const TopoDS_Edge& anE);
+  Standard_EXPORT static Standard_Real IntermediatePoint(const TopoDS_Edge& anE);
 
   //! Make P-Curve <aC> for the edge <aE> on surface <aF> .<br>
   //! [aFirst, aLast] - range of the P-Curve<br>
   //! [aToler] - reached tolerance<br>
   //! Raises exception Standard_ConstructionError if algorithm fails.<br>
   //! <theContext> - storage for caching the geometrical tools
-  Standard_EXPORT static void Make2D (const TopoDS_Edge& aE,
-                                      const TopoDS_Face& aF,
-                                      Handle(Geom2d_Curve)& aC,
-                                      Standard_Real& aFirst,
-                                      Standard_Real& aLast,
-                                      Standard_Real& aToler,
-                                      const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
-  
+  Standard_EXPORT static void Make2D(const TopoDS_Edge& aE,
+                                     const TopoDS_Face& aF,
+                                     Handle(Geom2d_Curve)& aC,
+                                     Standard_Real& aFirst,
+                                     Standard_Real& aLast,
+                                     Standard_Real& aToler,
+                                     const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
 
   //! Make P-Curve <aC> for the 3D-curve <C3D> on surface <aF> .<br>
   //! [aToler] - reached tolerance<br>
   //! Raises exception Standard_ConstructionError if projection algorithm fails.<br>
   //! <theContext> - storage for caching the geometrical tools
-  Standard_EXPORT static void MakePCurveOnFace (const TopoDS_Face& aF,
-                                                const Handle(Geom_Curve)& C3D,
-                                                Handle(Geom2d_Curve)& aC,
-                                                Standard_Real& aToler,
-                                                const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
-  
+  Standard_EXPORT static void MakePCurveOnFace(const TopoDS_Face& aF,
+                                               const Handle(Geom_Curve)& C3D,
+                                               Handle(Geom2d_Curve)& aC,
+                                               Standard_Real& aToler,
+                                               const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
 
   //! Make P-Curve <aC> for the 3D-curve <C3D> on surface <aF> .<br>
   //! [aT1,  aT2] - range to build<br>
   //! [aToler] - reached tolerance<br>
   //! Raises exception Standard_ConstructionError if projection algorithm fails.<br>
   //! <theContext> - storage for caching the geometrical tools
-  Standard_EXPORT static void MakePCurveOnFace (const TopoDS_Face& aF,
-                                                const Handle(Geom_Curve)& C3D,
-                                                const Standard_Real aT1,
-                                                const Standard_Real aT2,
-                                                Handle(Geom2d_Curve)& aC,
-                                                Standard_Real& aToler,
-                                                const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
-  
+  Standard_EXPORT static void MakePCurveOnFace(const TopoDS_Face& aF,
+                                               const Handle(Geom_Curve)& C3D,
+                                               const Standard_Real aT1,
+                                               const Standard_Real aT2,
+                                               Handle(Geom2d_Curve)& aC,
+                                               Standard_Real& aToler,
+                                               const Handle(IntTools_Context)& theContext = Handle(IntTools_Context)());
+
   //! Attach P-Curve from the edge <aEold> on surface <aF>
   //! to the edge <aEnew>
   //! Returns 0 in case of success
-  Standard_EXPORT static Standard_Integer AttachExistingPCurve (const TopoDS_Edge& aEold, const TopoDS_Edge& aEnew, const TopoDS_Face& aF, const Handle(IntTools_Context)& aCtx);
+  Standard_EXPORT static Standard_Integer AttachExistingPCurve(const TopoDS_Edge& aEold,
+                                                               const TopoDS_Edge& aEnew,
+                                                               const TopoDS_Face& aF,
+                                                               const Handle(IntTools_Context)& aCtx);
 
   //! Checks if CurveOnSurface of theE on theF matches with isoline of theF surface.
   //! Sets corresponding values for isTheUIso and isTheVIso variables.
@@ -199,25 +202,6 @@ public:
                                             Standard_Boolean& isTheUIso,
                                             Standard_Boolean& isTheVIso);
 
-
-protected:
-
-
-
-
-
-private:
-
-
-
-
-
 };
 
-
-
-
-
-
-
 #endif // _BOPTools_AlgoTools2D_HeaderFile
diff --git a/src/BOPTools/BOPTools_AlgoTools2D_1.cxx b/src/BOPTools/BOPTools_AlgoTools2D_1.cxx
index 0434b142f0..e6591cf698 100644
--- a/src/BOPTools/BOPTools_AlgoTools2D_1.cxx
+++ b/src/BOPTools/BOPTools_AlgoTools2D_1.cxx
@@ -40,7 +40,7 @@
 #include <IntTools_Context.hxx>
 #include <IntTools_Tools.hxx>
 
-#include <BOPTools_AlgoTools2D.hxx>
+#include <BOPTools_AlgoTools.hxx>
 
 
 
@@ -49,10 +49,6 @@ static
                                       const TopoDS_Edge& ,
                                       const TopoDS_Face& , 
                                       const Handle(IntTools_Context)& );
-static
-  Standard_Boolean IsToReverse(const TopoDS_Edge& ,
-                               const TopoDS_Edge& ,
-                               const Handle(IntTools_Context)& );
 static
   Standard_Boolean IsClosed(const TopoDS_Edge& ,
                             const TopoDS_Face& );
@@ -85,7 +81,7 @@ Standard_Integer BOPTools_AlgoTools2D::AttachExistingPCurve
   //
   aC2DoldC=Handle(Geom2d_Curve)::DownCast(aC2Dold->Copy());
   //
-  bIsToReverse=IsToReverse(aE2, aE1, aCtx);
+  bIsToReverse = BOPTools_AlgoTools::IsSplitToReverse(aE1, aE2, aCtx);
   if (bIsToReverse) {
     Standard_Real aT21r, aT22r;
     //
@@ -281,49 +277,6 @@ Standard_Integer UpdateClosedPCurve(const TopoDS_Edge& aEold,
   return iRet;
 }
 //=======================================================================
-//function : IsToReverse
-//purpose  : 
-//=======================================================================
-Standard_Boolean IsToReverse(const TopoDS_Edge& aEold,
-                             const TopoDS_Edge& aEnew,
-                             const Handle(IntTools_Context)& aCtx)
-{
-  Standard_Boolean bRet, bIsDegenerated;
-  Standard_Real aTnew, aTold, aScPr, aTa, aTb, aT1, aT2;
-  gp_Vec aVold, aVnew, aVE, aVS;
-  gp_Pnt aP;
-  Handle(Geom_Curve) aCold, aCnew;
-  //
-  bRet=Standard_False;
-  //
-  bIsDegenerated=(BRep_Tool::Degenerated(aEold) ||
-                  BRep_Tool::Degenerated(aEnew));
-  if (bIsDegenerated) {
-    return bRet;
-  }
-  //
-  aCold=BRep_Tool::Curve(aEold, aT1, aT2);
-  aCnew=BRep_Tool::Curve(aEnew, aTa, aTb);
-  //
-  if (aCold==aCnew) {
-    return bRet;
-  }
-  //
-  aTnew=BOPTools_AlgoTools2D::IntermediatePoint(aTa, aTb);
-  aCnew->D1(aTnew, aP, aVnew);
-  aVnew.Normalize(); 
-  //
-  if (!aCtx->ProjectPointOnEdge(aP, aEold, aTold))
-    return Standard_False;
-  aCold->D1(aTold, aP, aVold);
-  aVold.Normalize(); 
-  //
-  aScPr=aVnew*aVold;
-  bRet=(aScPr<0.);
-  //
-  return bRet;
-}
-//=======================================================================
 //function : IsClosed
 //purpose  :
 //=======================================================================
diff --git a/src/BOPTools/BOPTools_AlgoTools3D.cxx b/src/BOPTools/BOPTools_AlgoTools3D.cxx
index d45c8a139f..06653d1605 100644
--- a/src/BOPTools/BOPTools_AlgoTools3D.cxx
+++ b/src/BOPTools/BOPTools_AlgoTools3D.cxx
@@ -369,7 +369,7 @@ Standard_Boolean BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge
    const Standard_Real aT,
    gp_Pnt& aPNear,
    gp_Dir& aDNF,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   gp_Pnt2d aPx2DNear;
   Standard_Integer iErr = BOPTools_AlgoTools3D::PointNearEdge 
@@ -398,7 +398,7 @@ Standard_Boolean BOPTools_AlgoTools3D::GetApproxNormalToFaceOnEdge
    const Standard_Real theStep,
    gp_Pnt& aPNear,
    gp_Dir& aDNF,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   gp_Pnt2d aPx2DNear;
   Standard_Integer iErr = BOPTools_AlgoTools3D::PointNearEdge 
@@ -510,7 +510,7 @@ Standard_Integer BOPTools_AlgoTools3D::PointNearEdge
    const Standard_Real aT, 
    gp_Pnt2d& aPx2DNear,
    gp_Pnt& aPxNear,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   Standard_Real aTolE, aTolF, dTx, dT2D;
   Handle(Geom_Surface) aS;
@@ -563,7 +563,7 @@ Standard_Integer BOPTools_AlgoTools3D::PointNearEdge
    const Standard_Real theStep,
    gp_Pnt2d& aPx2DNear,
    gp_Pnt& aPxNear,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   Standard_Integer iErr = BOPTools_AlgoTools3D::PointNearEdge 
     (aE, aF, aT, theStep, aPx2DNear, aPxNear);
@@ -593,7 +593,7 @@ Standard_Integer BOPTools_AlgoTools3D::PointNearEdge
    const TopoDS_Face& aF, 
    gp_Pnt2d& aPInFace2D, 
    gp_Pnt& aPInFace,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   Standard_Real aT, aT1, aT2;
   //
@@ -783,7 +783,7 @@ Standard_Integer BOPTools_AlgoTools3D::PointInFace
   (const TopoDS_Face& theF,
    gp_Pnt& theP,
    gp_Pnt2d& theP2D,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   Standard_Integer i, iErr = 1;
   Standard_Real aUMin, aUMax, aVMin, aVMax, aUx;
@@ -822,7 +822,7 @@ Standard_Integer BOPTools_AlgoTools3D::PointInFace
    const Standard_Real theDt2D,
    gp_Pnt& theP,
    gp_Pnt2d& theP2D,
-   Handle(IntTools_Context)& theContext)
+   const Handle(IntTools_Context)& theContext)
 {
   Standard_Integer iErr;
   Standard_Real f, l;
@@ -870,7 +870,7 @@ Standard_Integer BOPTools_AlgoTools3D::PointInFace
    const Handle(Geom2d_Curve)& theL2D,
    gp_Pnt& theP,
    gp_Pnt2d& theP2D,
-   Handle(IntTools_Context)& theContext,
+   const Handle(IntTools_Context)& theContext,
    const Standard_Real theDt2D)
 {
   Standard_Boolean bIsDone, bHasFirstPoint, bHasSecondPoint;
diff --git a/src/BOPTools/BOPTools_AlgoTools3D.hxx b/src/BOPTools/BOPTools_AlgoTools3D.hxx
index a9567b779a..9a3d5de623 100644
--- a/src/BOPTools/BOPTools_AlgoTools3D.hxx
+++ b/src/BOPTools/BOPTools_AlgoTools3D.hxx
@@ -100,7 +100,7 @@ public:
                                                                        const Standard_Real aT,
                                                                        gp_Pnt& aPx,
                                                                        gp_Dir& aD,
-                                                                       Handle(IntTools_Context)& theContext);
+                                                                       const Handle(IntTools_Context)& theContext);
   
   //! Computes normal to the face <aF> for the 3D-point that
   //! belongs to the edge <aE> at parameter <aT>.<br>
@@ -142,7 +142,7 @@ public:
                                                                        const Standard_Real aDt2D,
                                                                        gp_Pnt& aP,
                                                                        gp_Dir& aDNF,
-                                                                       Handle(IntTools_Context)& theContext);
+                                                                       const Handle(IntTools_Context)& theContext);
 
   //! Compute the point <aPx>,  (<aP2D>)  that is near to
   //! the edge <aE>   at parameter <aT>  towards to the
@@ -160,7 +160,7 @@ public:
                                                          const Standard_Real aDt2D,
                                                          gp_Pnt2d& aP2D,
                                                          gp_Pnt& aPx,
-                                                         Handle(IntTools_Context)& theContext);
+                                                         const Handle(IntTools_Context)& theContext);
 
   //! Compute the point <aPx>,  (<aP2D>)  that is near to
   //! the edge <aE>   at parameter <aT>  towards to the
@@ -191,7 +191,7 @@ public:
                                                          const Standard_Real aT,
                                                          gp_Pnt2d& aP2D,
                                                          gp_Pnt& aPx,
-                                                         Handle(IntTools_Context)& theContext);
+                                                         const Handle(IntTools_Context)& theContext);
   
 
   //! Compute the point <aPx>,  (<aP2D>)  that is near to
@@ -208,7 +208,7 @@ public:
                                                          const TopoDS_Face& aF,
                                                          gp_Pnt2d& aP2D,
                                                          gp_Pnt& aPx,
-                                                         Handle(IntTools_Context)& theContext);
+                                                         const Handle(IntTools_Context)& theContext);
   
 
   //! Returns simple step value that is used in 2D-computations
@@ -232,7 +232,7 @@ public:
   Standard_EXPORT static Standard_Integer PointInFace (const TopoDS_Face& theF, 
                                                        gp_Pnt& theP, 
                                                        gp_Pnt2d& theP2D, 
-                                                       Handle(IntTools_Context)& theContext);
+                                                       const Handle(IntTools_Context)& theContext);
 
   //! Computes a point <theP> inside the face <theF> 
   //! using starting point taken by the parameter <theT> 
@@ -249,7 +249,7 @@ public:
                                                        const Standard_Real theDt2D,
                                                        gp_Pnt& theP, 
                                                        gp_Pnt2d& theP2D, 
-                                                       Handle(IntTools_Context)& theContext);
+                                                       const Handle(IntTools_Context)& theContext);
 
   //! Computes a point <theP> inside the face <theF> 
   //! using the line <theL> so that 2D point
@@ -260,7 +260,7 @@ public:
                                                        const Handle(Geom2d_Curve)& theL,
                                                        gp_Pnt& theP, 
                                                        gp_Pnt2d& theP2D, 
-                                                       Handle(IntTools_Context)& theContext,
+                                                       const Handle(IntTools_Context)& theContext,
                                                        const Standard_Real theDt2D = 0.0);
 
 
diff --git a/tests/bugs/modalg_7/bug29698 b/tests/bugs/modalg_7/bug29698
new file mode 100644
index 0000000000..04deaadc2c
--- /dev/null
+++ b/tests/bugs/modalg_7/bug29698
@@ -0,0 +1,43 @@
+puts "============"
+puts "OCC29698"
+puts "============"
+puts ""
+###############################
+## Regression vs 7.2.0: Common operation raises FLT_INVALID_OPERATION exception
+###############################
+
+# the case is a copy of the test case
+# bugs/modalg_6/bug26952_1
+# to test the BOP operation on the same arguments
+# with FPE signals switched on
+
+restore [locate_data_file bug26952_B41.brep] b1
+restore [locate_data_file bug26952_Tank41_1.brep] b2
+
+# enable FPE signals
+dsetsignal 1
+
+bclearobjects
+bcleartools
+baddobjects b1
+baddtools b2
+bfillds
+bbop result 0
+
+# disable FPE signals
+dsetsignal 0
+
+checkprops result -s 424.666
+checknbshapes result -wire 2 -face 1
+
+# check modification of the front face of the solid
+savehistory h
+explode b2 f
+modified f_mod h b2_12
+
+explode result f
+checkprops f_mod -equal result_1
+
+checknbshapes f_mod -ref [nbshapes result_1]
+
+checkview -display result -2d -path ${imagedir}/${test_image}.png