diff --git a/dox/dev_guides/upgrade/upgrade.md b/dox/dev_guides/upgrade/upgrade.md
index 24dfcf10fb..1909ee2191 100644
--- a/dox/dev_guides/upgrade/upgrade.md
+++ b/dox/dev_guides/upgrade/upgrade.md
@@ -1501,3 +1501,4 @@ The following obsolete features have been removed:
   - *IntTools_IndexedDataMapOfTransientAddress* is removed as unused;
 * 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.
\ No newline at end of file
diff --git a/src/BOPAlgo/BOPAlgo_BOP.cxx b/src/BOPAlgo/BOPAlgo_BOP.cxx
index 0207408dc8..c1e8804295 100644
--- a/src/BOPAlgo/BOPAlgo_BOP.cxx
+++ b/src/BOPAlgo/BOPAlgo_BOP.cxx
@@ -995,38 +995,17 @@ void BOPAlgo_BOP::BuildSolid()
   }
   //
   TopTools_IndexedDataMapOfShapeListOfShape aMEF;
-  // Split faces will be added in the end
-  // to avoid errors in BuilderSolid algorithm
-  TopTools_ListOfShape aLF, aLFx;
+  // Fill the list of faces to build the result solids
+  TopTools_ListOfShape aSFS;
   aNb = aMFS.Extent();
   for (i = 1; i <= aNb; ++i) {
     const TopTools_ListOfShape& aLSx = aMFS(i);
     if (aLSx.Extent() == 1) {
       const TopoDS_Shape& aFx = aMFS.FindKey(i);
       TopExp::MapShapesAndAncestors(aFx, TopAbs_EDGE, TopAbs_FACE, aMEF);
-      if (IsBoundSplits(aFx, aMEF)){
-        aLFx.Append(aFx);
-        continue;
-      }
-      aLF.Append(aFx);
+      aSFS.Append(aFx);
     }
   }
-  //
-  // Faces to build result solids
-  TopTools_ListOfShape aSFS;
-  aItLS.Initialize(aLF);
-  for(; aItLS.More(); aItLS.Next()) {
-    const TopoDS_Shape& aFx = aItLS.Value();
-    aSFS.Append(aFx);
-  }
-  //
-  // Split faces
-  aItLS.Initialize(aLFx);
-  for (; aItLS.More(); aItLS.Next()) {
-    const TopoDS_Shape& aFx = aItLS.Value();
-    aSFS.Append(aFx);
-  }
-  //
   // Internal faces
   aNb = aMFI.Extent();
   for (i = 1; i <= aNb; ++i) {
@@ -1158,54 +1137,6 @@ void BOPAlgo_BOP::BuildSolid()
   myShape = aResult;
 }
 //=======================================================================
-//function : IsBoundSplits
-//purpose  : 
-//=======================================================================
-Standard_Boolean BOPAlgo_BOP::IsBoundSplits
-  (const TopoDS_Shape& aS,
-   TopTools_IndexedDataMapOfShapeListOfShape& aMEF)
-{
-  Standard_Boolean bRet = Standard_False;
-  if (mySplits.IsBound(aS) || myOrigins.IsBound(aS)) {
-    return !bRet;
-  }
-
-  TopTools_ListIteratorOfListOfShape aIt;
-  Standard_Integer aNbLS;
-  TopAbs_Orientation anOr;
-  //
-  //check face aF may be connected to face from mySplits
-  TopExp_Explorer aExp(aS, TopAbs_EDGE);
-  for (; aExp.More(); aExp.Next()) {
-    const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aExp.Current()));
-    //
-    anOr = aE.Orientation();
-    if (anOr==TopAbs_INTERNAL) {
-      continue;
-    }
-    //
-    if (BRep_Tool::Degenerated(aE)) {
-      continue;
-    }
-    //
-    const TopTools_ListOfShape& aLS=aMEF.FindFromKey(aE);
-    aNbLS = aLS.Extent();
-    if (!aNbLS) {
-      continue;
-    }
-    //
-    aIt.Initialize(aLS);
-    for (; aIt.More(); aIt.Next()) {
-      const TopoDS_Shape& aSx = aIt.Value();
-      if (mySplits.IsBound(aSx) || myOrigins.IsBound(aS)) {
-        return !bRet;
-      }
-    }
-  }
-  //
-  return bRet;
-}
-//=======================================================================
 //function : TypeToExplore
 //purpose  : 
 //=======================================================================
diff --git a/src/BOPAlgo/BOPAlgo_BOP.hxx b/src/BOPAlgo/BOPAlgo_BOP.hxx
index bab184bfec..8f18135c09 100644
--- a/src/BOPAlgo/BOPAlgo_BOP.hxx
+++ b/src/BOPAlgo/BOPAlgo_BOP.hxx
@@ -102,8 +102,6 @@ protected:
   
   Standard_EXPORT void BuildSolid();
   
-  Standard_EXPORT Standard_Boolean IsBoundSplits (const TopoDS_Shape& theS, TopTools_IndexedDataMapOfShapeListOfShape& theMEF);
-
   //! Treatment of the cases with empty shapes.<br>
   //! It returns TRUE if there is nothing to do, i.e.
   //! all shapes in one of the groups are empty shapes.
diff --git a/src/BOPAlgo/BOPAlgo_Builder.cxx b/src/BOPAlgo/BOPAlgo_Builder.cxx
index f0fa58cc79..da6483598d 100644
--- a/src/BOPAlgo/BOPAlgo_Builder.cxx
+++ b/src/BOPAlgo/BOPAlgo_Builder.cxx
@@ -49,10 +49,10 @@ BOPAlgo_Builder::BOPAlgo_Builder()
   myEntryPoint(0),
   myImages(100, myAllocator),
   myShapesSD(100, myAllocator),
-  mySplits(100, myAllocator),
   myOrigins(100, myAllocator),
   myNonDestructive(Standard_False),
-  myGlue(BOPAlgo_GlueOff)
+  myGlue(BOPAlgo_GlueOff),
+  myCheckInverted(Standard_True)
 {
 }
 //=======================================================================
@@ -70,10 +70,10 @@ BOPAlgo_Builder::BOPAlgo_Builder
   myEntryPoint(0),
   myImages(100, myAllocator), 
   myShapesSD(100, myAllocator),
-  mySplits(100, myAllocator),
   myOrigins(100, myAllocator),
   myNonDestructive(Standard_False),
-  myGlue(BOPAlgo_GlueOff)
+  myGlue(BOPAlgo_GlueOff),
+  myCheckInverted(Standard_True)
 {
 }
 //=======================================================================
@@ -100,7 +100,6 @@ void BOPAlgo_Builder::Clear()
   myMapFence.Clear();
   myImages.Clear();
   myShapesSD.Clear();
-  mySplits.Clear();
   myOrigins.Clear();
 }
 //=======================================================================
@@ -130,95 +129,6 @@ void BOPAlgo_Builder::SetArguments(const TopTools_ListOfShape& theShapes)
   }
 }
 //=======================================================================
-//function : Arguments
-//purpose  : 
-//=======================================================================
-const TopTools_ListOfShape& BOPAlgo_Builder::Arguments()const
-{
-  return myArguments;
-}
-//=======================================================================
-//function : Images
-//purpose  : 
-//=======================================================================
-const TopTools_DataMapOfShapeListOfShape& BOPAlgo_Builder::Images()const
-{
-  return myImages;
-}
-//=======================================================================
-//function : Origins
-//purpose  : 
-//=======================================================================
-const TopTools_DataMapOfShapeListOfShape& BOPAlgo_Builder::Origins()const
-{
-  return myOrigins;
-}
-
-//=======================================================================
-//function : ShapesSd
-//purpose  : 
-//=======================================================================
-const TopTools_DataMapOfShapeShape& BOPAlgo_Builder::ShapesSD()const
-{
-  return myShapesSD;
-}
-//=======================================================================
-//function : Splits
-//purpose  : 
-//=======================================================================
-const TopTools_DataMapOfShapeListOfShape& BOPAlgo_Builder::Splits()const
-{
-  return mySplits;
-}
-//=======================================================================
-//function : PPaveFiller
-//purpose  : 
-//=======================================================================
-BOPAlgo_PPaveFiller BOPAlgo_Builder::PPaveFiller()
-{
-  return myPaveFiller;
-}
-//=======================================================================
-//function : PDS
-//purpose  : 
-//=======================================================================
-BOPDS_PDS BOPAlgo_Builder::PDS()
-{
-  return myDS;
-}
-//=======================================================================
-//function : SetNonDestructive
-//purpose  : 
-//=======================================================================
-void BOPAlgo_Builder::SetNonDestructive(const Standard_Boolean theFlag)
-{
-  myNonDestructive = theFlag;
-}
-//=======================================================================
-//function : NonDestructive
-//purpose  : 
-//=======================================================================
-Standard_Boolean BOPAlgo_Builder::NonDestructive() const
-{
-  return myNonDestructive;
-}
-//=======================================================================
-//function : SetGlue
-//purpose  : 
-//=======================================================================
-void BOPAlgo_Builder::SetGlue(const BOPAlgo_GlueEnum theGlue)
-{
-  myGlue=theGlue;
-}
-//=======================================================================
-//function : Glue
-//purpose  : 
-//=======================================================================
-BOPAlgo_GlueEnum BOPAlgo_Builder::Glue() const 
-{
-  return myGlue;
-}
-//=======================================================================
 // function: CheckData
 // purpose: 
 //=======================================================================
diff --git a/src/BOPAlgo/BOPAlgo_Builder.hxx b/src/BOPAlgo/BOPAlgo_Builder.hxx
index 62e8f679a5..3ccbad05a7 100644
--- a/src/BOPAlgo/BOPAlgo_Builder.hxx
+++ b/src/BOPAlgo/BOPAlgo_Builder.hxx
@@ -53,6 +53,10 @@ class BOPAlgo_PaveFiller;
 //!                            shapes during the operation (by default it is off);<br>
 //! - *Gluing options* - allows to speed up the calculation of the intersections
 //!                      on the special cases, in which some sub-shapes are coinciding.<br>
+//! - *Disabling the check for inverted solids* - Disables/Enables the check of the input solids
+//!                          for inverted status (holes in the space). The default value is TRUE,
+//!                          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 Error statuses:
 //! - *BOPAlgo_AlertTooFewArguments* - in case there are no enough arguments to perform the operation;
@@ -66,139 +70,282 @@ public:
 
   DEFINE_STANDARD_ALLOC
 
-  
+  //! Empty constructor.
   Standard_EXPORT BOPAlgo_Builder();
-Standard_EXPORT virtual ~BOPAlgo_Builder();
-  
-  Standard_EXPORT BOPAlgo_Builder(const Handle(NCollection_BaseAllocator)& theAllocator);
-  
-  Standard_EXPORT virtual void Clear() Standard_OVERRIDE;
-  
-  Standard_EXPORT BOPAlgo_PPaveFiller PPaveFiller();
-  
-  Standard_EXPORT BOPDS_PDS PDS();
-  
-  Standard_EXPORT virtual void AddArgument (const TopoDS_Shape& theShape);
-  
-  Standard_EXPORT virtual void SetArguments (const TopTools_ListOfShape& theLS);
-  
-  Standard_EXPORT const TopTools_ListOfShape& Arguments() const;
+  Standard_EXPORT virtual ~BOPAlgo_Builder();
+
+  Standard_EXPORT BOPAlgo_Builder(const Handle(NCollection_BaseAllocator)& theAllocator);
+
+  //! Clears the content of the algorithm.
+  Standard_EXPORT virtual void Clear() Standard_OVERRIDE;
+
+  //! Returns the PaveFiller, algorithm for sub-shapes intersection.
+  BOPAlgo_PPaveFiller PPaveFiller()
+  {
+    return myPaveFiller;
+  }
+
+  //! Returns the Data Structure, holder of intersection information.
+  BOPDS_PDS PDS()
+  {
+    return myDS;
+  }
+
+  //! Returns the Context, tool for cashing heavy algorithms.
+  Handle(IntTools_Context) Context() const
+  {
+    return myContext;
+  }
+
+
+public: //! @name Arguments
+
+  //! Adds the argument to the operation.
+  Standard_EXPORT virtual void AddArgument (const TopoDS_Shape& theShape);
+
+  //! Sets the list of arguments for the operation.
+  Standard_EXPORT virtual void SetArguments (const TopTools_ListOfShape& theLS);
+
+  //! Returns the list of arguments.
+  const TopTools_ListOfShape& Arguments() const
+  {
+    return myArguments;
+  }
+
+public: //! @name Options
 
-  Standard_EXPORT virtual void Perform() Standard_OVERRIDE;
-  
-  Standard_EXPORT virtual void PerformWithFiller (const BOPAlgo_PaveFiller& theFiller);
-  
-  //! Returns the  list of shapes generated from the
-  //! shape theS.
-  Standard_EXPORT virtual const TopTools_ListOfShape& Generated (const TopoDS_Shape& theS) Standard_OVERRIDE;
-  
-  //! Returns the list of shapes modified from the shape
-  //! theS.
-  Standard_EXPORT virtual const TopTools_ListOfShape& Modified (const TopoDS_Shape& theS) Standard_OVERRIDE;
-  
-  //! Returns true if the shape theS has been deleted.
-  Standard_EXPORT virtual Standard_Boolean IsDeleted (const TopoDS_Shape& theS) Standard_OVERRIDE;
-  
-  Standard_EXPORT const TopTools_DataMapOfShapeListOfShape& Images() const;
-  
-  Standard_EXPORT Standard_Boolean IsInterferred (const TopoDS_Shape& theS) const;
-  
-  //! Returns myOrigins.
-  Standard_EXPORT const TopTools_DataMapOfShapeListOfShape& Origins() const;
-  
-  //! Returns myShapesSD.
-  Standard_EXPORT const TopTools_DataMapOfShapeShape& ShapesSD() const;
-  
-  //! Returns mySplits.
-  Standard_EXPORT const TopTools_DataMapOfShapeListOfShape& Splits() const;
-  
-  
   //! Sets the flag that defines the mode of treatment.
   //! In non-destructive mode the argument shapes are not modified. Instead
   //! a copy of a sub-shape is created in the result if it is needed to be updated.
   //! This flag is taken into account if internal PaveFiller is used only.
   //! In the case of calling PerformWithFiller the corresponding flag of that PaveFiller
   //! is in force.
-  Standard_EXPORT void SetNonDestructive(const Standard_Boolean theFlag);
+  void SetNonDestructive(const Standard_Boolean theFlag)
+  {
+    myNonDestructive = theFlag;
+  }
 
   //! Returns the flag that defines the mode of treatment.
   //! In non-destructive mode the argument shapes are not modified. Instead
   //! a copy of a sub-shape is created in the result if it is needed to be updated.
-  Standard_EXPORT Standard_Boolean NonDestructive() const;
+  Standard_Boolean NonDestructive() const
+  {
+    return myNonDestructive;
+  }
 
   //! Sets the glue option for the algorithm
-  Standard_EXPORT void SetGlue(const BOPAlgo_GlueEnum theGlue);
-  
+  void SetGlue(const BOPAlgo_GlueEnum theGlue)
+  {
+    myGlue = theGlue;
+  }
+
   //! Returns the glue option of the algorithm
-  Standard_EXPORT BOPAlgo_GlueEnum Glue() const;
+  BOPAlgo_GlueEnum Glue() const
+  {
+    return myGlue;
+  }
 
-protected:
+  //! Enables/Disables the check of the input solids for inverted status
+  void SetCheckInverted(const Standard_Boolean theCheck)
+  {
+    myCheckInverted = theCheck;
+  }
 
-  //! Prepare information for history support
-  Standard_EXPORT virtual void PrepareHistory() Standard_OVERRIDE;
-  
+  //! Returns the flag defining whether the check for input solids on inverted status
+  //! should be performed or not.
+  Standard_Boolean CheckInverted() const
+  {
+    return myCheckInverted;
+  }
+
+
+public: //! @name Performing the operation
+
+  //! Performs the operation.
+  //! The intersection will be performed also.
+  Standard_EXPORT virtual void Perform() Standard_OVERRIDE;
+
+  //! Performs the operation with the prepared filler.
+  //! The intersection will not be performed in this case.
+  Standard_EXPORT virtual void PerformWithFiller (const BOPAlgo_PaveFiller& theFiller);
+
+
+public: //! @name History methods
+
+  //! Returns the  list of shapes generated from the
+  //! shape theS.
+  Standard_EXPORT virtual const TopTools_ListOfShape& Generated (const TopoDS_Shape& theS) Standard_OVERRIDE;
+
+  //! Returns the list of shapes modified from the shape
+  //! theS.
+  Standard_EXPORT virtual const TopTools_ListOfShape& Modified (const TopoDS_Shape& theS) Standard_OVERRIDE;
+
+  //! Returns true if the shape theS has been deleted.
+  Standard_EXPORT virtual Standard_Boolean IsDeleted (const TopoDS_Shape& theS) Standard_OVERRIDE;
+
+
+public: //! @name Images/Origins
+
+  //! Returns the map of images.
+  const TopTools_DataMapOfShapeListOfShape& Images() const
+  {
+    return myImages;
+  }
+
+  //! Returns the map of origins.
+  const TopTools_DataMapOfShapeListOfShape& Origins() const
+  {
+    return myOrigins;
+  }
+
+  //! Returns the map of Same Domain (SD) shapes - coinciding shapes
+  //! from different arguments.
+  const TopTools_DataMapOfShapeShape& ShapesSD() const
+  {
+    return myShapesSD;
+  }
+
+
+protected: //! @name Methods for building the result
+
+  //! Performs the building of the result.
+  //! The method calls the PerfromInternal1() method surrounded by a try-catch block.
   Standard_EXPORT virtual void PerformInternal (const BOPAlgo_PaveFiller& thePF);
-  
+
+  //! Performs the building of the result.
+  //! To build the result of any other operation
+  //! it will be necessary to override this method.
   Standard_EXPORT virtual void PerformInternal1 (const BOPAlgo_PaveFiller& thePF);
-  
+
+  //! Prepare information for history support.
+  Standard_EXPORT virtual void PrepareHistory() Standard_OVERRIDE;
+
+  //! Builds the result of operation.
+  //! The method is called for each of the arguments type and
+  //! adds into the result the splits of the arguments of that type.
+  Standard_EXPORT virtual void BuildResult (const TopAbs_ShapeEnum theType);
+
+
+protected: //! @name Checking input arguments
+
+  //! Checks the input data.
   Standard_EXPORT virtual void CheckData() Standard_OVERRIDE;
 
-  //! Checks if the intersection algorithm has Errors/Warnings
+  //! Checks if the intersection algorithm has Errors/Warnings.
   Standard_EXPORT void CheckFiller();
-  
+
+  //! Prepares the result shape by making it empty compound.
   Standard_EXPORT virtual void Prepare();
-  
+
+
+protected: //! @name Fill Images of VERTICES
+
+  //! Fills the images of vertices.
   Standard_EXPORT void FillImagesVertices();
-  
+
+
+protected: //! @name Fill Images of EDGES
+
+  //! Fills the images of edges.
   Standard_EXPORT void FillImagesEdges();
-  
-  Standard_EXPORT virtual void BuildResult (const TopAbs_ShapeEnum theType);
-  
+
+
+protected: //! @name Fill Images of CONTAINERS
+
+  //! Fills the images of containers (WIRES/SHELLS/COMPSOLID).
   Standard_EXPORT void FillImagesContainers (const TopAbs_ShapeEnum theType);
-  
-  Standard_EXPORT void FillImagesCompounds();
-  
+
+  //! Builds the image of the given container using the splits
+  //! of its sub-shapes.
   Standard_EXPORT void FillImagesContainer (const TopoDS_Shape& theS, const TopAbs_ShapeEnum theType);
-  
-  Standard_EXPORT void FillImagesCompound (const TopoDS_Shape& theS, TopTools_MapOfShape& theMF);
-  
+
+
+protected: //! @name Fill Images of FACES
+
+  //! Fills the images of faces.
+  //! The method consists of three steps:
+  //! 1. Build the splits of faces;
+  //! 2. Find SD faces;
+  //! 3. Add internal vertices (if any) to faces.
   Standard_EXPORT void FillImagesFaces();
-  
+
+  //! Builds the splits of faces using the information from the
+  //! intersection stage stored in Data Structure.
   Standard_EXPORT virtual void BuildSplitFaces();
-  
+
+  //! Looks for the same domain faces among the splits of the faces.
+  //! Updates the map of images with SD faces.
   Standard_EXPORT void FillSameDomainFaces();
-  
-  Standard_EXPORT void FillImagesFaces1();
-  
+
+  //! Classifies the alone vertices on faces relatively its splits
+  //! and adds them as INTERNAL into the splits.
+  Standard_EXPORT void FillInternalVertices();
+
+
+protected: //! @name Fill Images of SOLIDS
+
+  //! Fills the images of solids.
+  //! The method consists of four steps:
+  //! 1. Build the draft solid - just rebuild the solid using the splits of faces;
+  //! 2. Find faces from other arguments located inside the solids;
+  //! 3. Build splits of solid using the inside faces;
+  //! 4. Fill internal shapes for the splits (Wires and vertices).
   Standard_EXPORT void FillImagesSolids();
-  
-  Standard_EXPORT void BuildDraftSolid (const TopoDS_Shape& theSolid, TopoDS_Shape& theDraftSolid, TopTools_ListOfShape& theLIF);
-  
-  Standard_EXPORT virtual void FillIn3DParts (TopTools_DataMapOfShapeListOfShape& theInParts, TopTools_DataMapOfShapeShape& theDraftSolids, const Handle(NCollection_BaseAllocator)& theAllocator);
-  
-  Standard_EXPORT void BuildSplitSolids (TopTools_DataMapOfShapeListOfShape& theInParts, TopTools_DataMapOfShapeShape& theDraftSolids, const Handle(NCollection_BaseAllocator)& theAllocator);
-  
+
+  //! Builds the draft solid by rebuilding the shells of the solid
+  //! with the splits of faces.
+  Standard_EXPORT void BuildDraftSolid (const TopoDS_Shape& theSolid,
+                                        TopoDS_Shape& theDraftSolid,
+                                        TopTools_ListOfShape& theLIF);
+
+  //! Finds faces located inside each solid.
+  Standard_EXPORT virtual void FillIn3DParts (TopTools_DataMapOfShapeListOfShape& theInParts,
+                                              TopTools_DataMapOfShapeShape& theDraftSolids,
+                                              const Handle(NCollection_BaseAllocator)& theAllocator);
+
+  //! Builds the splits of the solids using their draft versions
+  //! and faces located inside.
+  Standard_EXPORT void BuildSplitSolids (TopTools_DataMapOfShapeListOfShape& theInParts,
+                                         TopTools_DataMapOfShapeShape& theDraftSolids,
+                                         const Handle(NCollection_BaseAllocator)& theAllocator);
+
+  //! Classifies the vertices and edges from the arguments relatively
+  //! splits of solids and makes them INTERNAL for solids.
   Standard_EXPORT void FillInternalShapes();
-  
+
+
+protected: //! @name Fill Images of COMPOUNDS
+
+  //! Fills the images of compounds.
+  Standard_EXPORT void FillImagesCompounds();
+
+  //! Builds the image of the given compound.
+  Standard_EXPORT void FillImagesCompound (const TopoDS_Shape& theS,
+                                           TopTools_MapOfShape& theMF);
+
+protected: //! @name Post treatment
+
+  //! Post treatment of the result of the operation.
+  //! The method checks validity of the sub-shapes of the result
+  //! and updates the tolerances to make them valid.
   Standard_EXPORT virtual void PostTreat();
 
 
-  TopTools_ListOfShape myArguments;
-  TopTools_MapOfShape myMapFence;
-  BOPAlgo_PPaveFiller myPaveFiller;
-  BOPDS_PDS myDS;
-  Handle(IntTools_Context) myContext;
-  Standard_Integer myEntryPoint;
-  TopTools_DataMapOfShapeListOfShape myImages;
-  TopTools_DataMapOfShapeShape myShapesSD;
-  TopTools_DataMapOfShapeListOfShape mySplits;
-  TopTools_DataMapOfShapeListOfShape myOrigins;
-  Standard_Boolean myNonDestructive;
-  BOPAlgo_GlueEnum myGlue;
+protected: //! @name Fields
 
-private:
+  TopTools_ListOfShape myArguments;             //!< Arguments of the operation
+  TopTools_MapOfShape myMapFence;               //!< Fence map providing the uniqueness of the shapes in the list of arguments
+  BOPAlgo_PPaveFiller myPaveFiller;             //!< Pave Filler - algorithm for sub-shapes intersection
+  BOPDS_PDS myDS;                               //!< Data Structure - holder of intersection information
+  Handle(IntTools_Context) myContext;           //!< Context - tool for cashing heavy algorithms such as Projectors and Classifiers
+  Standard_Integer myEntryPoint;                //!< EntryPoint - controls the deletion of the PaveFiller, which could live longer than the Builder
+  TopTools_DataMapOfShapeListOfShape myImages;  //!< Images - map of Images of the sub-shapes of arguments
+  TopTools_DataMapOfShapeShape myShapesSD;      //!< ShapesSD - map of SD Shapes
+  TopTools_DataMapOfShapeListOfShape myOrigins; //!< Origins - map of Origins, back map of Images
+  Standard_Boolean myNonDestructive;            //!< Safe processing option allows avoiding modification of the input shapes
+  BOPAlgo_GlueEnum myGlue;                      //!< Gluing option allows speeding up the intersection of the input shapes
+  Standard_Boolean myCheckInverted;             //!< Check inverted option allows disabling the check of input solids on inverted status
 
 };
 
-
 #endif // _BOPAlgo_Builder_HeaderFile
diff --git a/src/BOPAlgo/BOPAlgo_Builder_1.cxx b/src/BOPAlgo/BOPAlgo_Builder_1.cxx
index 15eb1893dd..69fc0f84cb 100644
--- a/src/BOPAlgo/BOPAlgo_Builder_1.cxx
+++ b/src/BOPAlgo/BOPAlgo_Builder_1.cxx
@@ -40,28 +40,22 @@
 //=======================================================================
 void BOPAlgo_Builder::FillImagesVertices()
 {
-  Standard_Integer nV, nVSD;
-  TColStd_DataMapIteratorOfDataMapOfIntegerInteger aIt;
-  //
-  const TColStd_DataMapOfIntegerInteger& aMSDV=myDS->ShapesSD();
-  aIt.Initialize(aMSDV);
-  for (; aIt.More(); aIt.Next()) {
-    nV=aIt.Key();
-    nVSD=aIt.Value();
-    const TopoDS_Shape& aV=myDS->Shape(nV);
-    const TopoDS_Shape& aVSD=myDS->Shape(nVSD);
-    //
-    TopTools_ListOfShape aLVSD(myAllocator);
-    //
-    aLVSD.Append(aVSD);
-    myImages.Bind(aV, aLVSD);
-    //
+  TColStd_DataMapIteratorOfDataMapOfIntegerInteger aIt(myDS->ShapesSD());
+  for (; aIt.More(); aIt.Next())
+  {
+    Standard_Integer nV = aIt.Key();
+    Standard_Integer nVSD = aIt.Value();
+
+    const TopoDS_Shape& aV = myDS->Shape(nV);
+    const TopoDS_Shape& aVSD = myDS->Shape(nVSD);
+    // Add to Images map
+    myImages.Bound(aV, TopTools_ListOfShape(myAllocator))->Append(aVSD);
+    // Add to SD map
     myShapesSD.Bind(aV, aVSD);
-    //
+    // Add to Origins map
     TopTools_ListOfShape* pLOr = myOrigins.ChangeSeek(aVSD);
-    if (!pLOr) {
+    if (!pLOr)
       pLOr = myOrigins.Bound(aVSD, TopTools_ListOfShape());
-    }
     pLOr->Append(aV);
   }
 }
@@ -115,26 +109,6 @@ void BOPAlgo_Builder::FillImagesVertices()
   }
 }
 //=======================================================================
-// function: IsInterferred
-// purpose: 
-//=======================================================================
-  Standard_Boolean BOPAlgo_Builder::IsInterferred(const TopoDS_Shape& theS)const
-{
-  Standard_Boolean bInterferred;
-  TopoDS_Iterator aIt;
-  //
-  bInterferred=Standard_False;
-  aIt.Initialize(theS);
-  for (; aIt.More(); aIt.Next()) {
-    const TopoDS_Shape& aSx=aIt.Value();
-    if (myImages.IsBound(aSx)) {
-      bInterferred=!bInterferred;
-      break;
-    }
-  }
-  return bInterferred;
-}
-//=======================================================================
 //function : BuildResult
 //purpose  : 
 //=======================================================================
@@ -211,45 +185,57 @@ void BOPAlgo_Builder::FillImagesVertices()
   void BOPAlgo_Builder::FillImagesContainer(const TopoDS_Shape& theS,
                                             const TopAbs_ShapeEnum theType)
 {
-  Standard_Boolean bInterferred, bToReverse;
-  TopoDS_Iterator aIt;
-  BRep_Builder aBB;
-  TopTools_ListIteratorOfListOfShape aItIm; 
-  //
-  bInterferred=IsInterferred(theS);
-  if (!bInterferred){
+  // Check if any of the sub-shapes of the container have been modified
+  TopoDS_Iterator aIt(theS);
+  for (; aIt.More(); aIt.Next())
+  {
+    const TopoDS_Shape& aSS = aIt.Value();
+    const TopTools_ListOfShape* pLFIm = myImages.Seek(aSS);
+    if (pLFIm && ((pLFIm->Extent() != 1) || !pLFIm->First().IsSame(aSS)))
+      break;
+  }
+
+  if (!aIt.More())
+  {
+    // Non of the sub-shapes have been modified.
+    // No need to create the new container.
     return;
   }
-  //
+
+  BRep_Builder aBB;
+  // Make the new container of the splits of its sub-shapes
   TopoDS_Shape aCIm;
   BOPTools_AlgoTools::MakeContainer(theType, aCIm);
-  //
+
   aIt.Initialize(theS);
-  for (; aIt.More(); aIt.Next()) {
-    const TopoDS_Shape& aSx=aIt.Value();
-    if (myImages.IsBound(aSx)) {
-      const TopTools_ListOfShape& aLFIm=myImages.Find(aSx);
-      aItIm.Initialize(aLFIm);
-      for (; aItIm.More(); aItIm.Next()) {
-        TopoDS_Shape aSxIm=aItIm.Value();
-        //
-        bToReverse=BOPTools_AlgoTools::IsSplitToReverse(aSxIm, aSx, myContext);
-        if (bToReverse) {
-          aSxIm.Reverse();
-        }
-        aBB.Add(aCIm, aSxIm);
-      }
+  for (; aIt.More(); aIt.Next())
+  {
+    const TopoDS_Shape& aSS = aIt.Value();
+    const TopTools_ListOfShape* pLSSIm = myImages.Seek(aSS);
+
+    if (!pLSSIm)
+    {
+      // No splits, add the sub-shape itself
+      aBB.Add(aCIm, aSS);
+      continue;
     }
-    else {
-      aBB.Add(aCIm, aSx);
+
+    // Add the splits
+    TopTools_ListIteratorOfListOfShape aItIm(*pLSSIm);
+    for (; aItIm.More(); aItIm.Next())
+    {
+      TopoDS_Shape aSSIm = aItIm.Value();
+      if (!aSSIm.IsEqual(aSS) &&
+          BOPTools_AlgoTools::IsSplitToReverse(aSSIm, aSS, myContext))
+      {
+        aSSIm.Reverse();
+      }
+      aBB.Add(aCIm, aSSIm);
     }
   }
-  //
+
   aCIm.Closed(BRep_Tool::IsClosed(aCIm));
-  //
-  TopTools_ListOfShape aLSIm(myAllocator);
-  aLSIm.Append(aCIm);
-  myImages.Bind(theS, aLSIm); 
+  myImages.Bound(theS, TopTools_ListOfShape(myAllocator))->Append(aCIm);
 }
 //=======================================================================
 //function : FillImagesCompound
diff --git a/src/BOPAlgo/BOPAlgo_Builder_2.cxx b/src/BOPAlgo/BOPAlgo_Builder_2.cxx
index 37510efdec..b4bb60ed74 100644
--- a/src/BOPAlgo/BOPAlgo_Builder_2.cxx
+++ b/src/BOPAlgo/BOPAlgo_Builder_2.cxx
@@ -154,7 +154,7 @@ class BOPAlgo_VFI : public BOPAlgo_Algo {
   
   BOPAlgo_VFI() :
     BOPAlgo_Algo(),
-    myFlag(-1) {
+    myIsInternal(Standard_False) {
   }
   //
   virtual ~BOPAlgo_VFI(){
@@ -176,8 +176,8 @@ class BOPAlgo_VFI : public BOPAlgo_Algo {
     return myF;
   }
   //
-  Standard_Integer Flag()const {
-    return myFlag;
+  Standard_Boolean IsInternal()const {
+    return myIsInternal;
   }
   //
   void SetContext(const Handle(IntTools_Context)& aContext) {
@@ -192,11 +192,13 @@ class BOPAlgo_VFI : public BOPAlgo_Algo {
     Standard_Real aT1, aT2, dummy;
     //
     BOPAlgo_Algo::UserBreak();
-    myFlag = myContext->ComputeVF(myV, myF, aT1, aT2, dummy, myFuzzyValue);
+    Standard_Integer iFlag =
+      myContext->ComputeVF(myV, myF, aT1, aT2, dummy, myFuzzyValue);
+    myIsInternal = (iFlag == 0);
   }
   //
  protected:
-  Standard_Integer myFlag;
+  Standard_Boolean myIsInternal;
   TopoDS_Vertex myV;
   TopoDS_Face myF;
   Handle(IntTools_Context) myContext;
@@ -223,7 +225,7 @@ void BOPAlgo_Builder::FillImagesFaces()
 {
   BuildSplitFaces();
   FillSameDomainFaces();
-  FillImagesFaces1();
+  FillInternalVertices();
 }
 //=======================================================================
 //function : BuildSplitFaces
@@ -290,6 +292,20 @@ void BOPAlgo_Builder::BuildSplitFaces()
 
     if (!aNbPBIn && !aNbPBSc)
     {
+      if (!aNbAV)
+      {
+        // Check if any wires of the face have been modified.
+        // If not, there is no need to create the new face.
+        TopoDS_Iterator aItW(aF);
+        for (; aItW.More(); aItW.Next())
+        {
+          if (myImages.IsBound(aItW.Value()))
+            break;
+        }
+        if (!aItW.More())
+          continue;
+      }
+
       // No internal parts for the face, so just build the draft face
       // and keep it to pass directly into result.
       // If the original face has any internal edges, the draft face
@@ -454,7 +470,7 @@ void BOPAlgo_Builder::BuildSplitFaces()
     anOriF = aF.Orientation();
     const TopTools_ListOfShape& aLFR = aFacesIm(k);
     //
-    TopTools_ListOfShape* pLFIm = mySplits.Bound(aF, TopTools_ListOfShape());
+    TopTools_ListOfShape* pLFIm = myImages.Bound(aF, TopTools_ListOfShape());
     aIt.Initialize(aLFR);
     for (; aIt.More(); aIt.Next()) {
       TopoDS_Shape& aFR=aIt.ChangeValue();
@@ -564,7 +580,7 @@ void BOPAlgo_Builder::FillSameDomainFaces()
       }
     }
 
-    const TopTools_ListOfShape* pLFSp = mySplits.Seek(aF);
+    const TopTools_ListOfShape* pLFSp = myImages.Seek(aF);
     if (pLFSp)
     {
       TopTools_ListIteratorOfListOfShape aItLF(*pLFSp);
@@ -649,18 +665,83 @@ void BOPAlgo_Builder::FillSameDomainFaces()
   for (; aItB.More(); aItB.Next())
   {
     const TopTools_ListOfShape& aLSD = aItB.Value();
-    // First face will be SD face for all faces in the group
-    const TopoDS_Shape& aFSD1 = aLSD.First();
+    // If the group contains some original faces, the one with minimal
+    // index in the DS will be chosen as the SD for the whole group.
+    // If there are no original faces in the group, the first face from
+    // the group will be used as the SD face.
+    // Such SD face will be representative of the whole group in the result.
+    TopoDS_Face* pFSD = NULL;
+    Standard_Integer nFMin = ::IntegerLast();
     TopTools_ListIteratorOfListOfShape aItLF(aLSD);
     for (; aItLF.More(); aItLF.Next())
     {
-      const TopoDS_Shape& aFSD = aItLF.Value();
-      myShapesSD.Bind(aFSD, aFSD1);
-      // If the face has no splits but have an SD face, it is considered as being split
-      if (myDS->Index(aFSD) >= 0)
-        mySplits.Bound(aFSD, TopTools_ListOfShape())->Append(aFSD);
+      const TopoDS_Shape& aF = aItLF.Value();
+      // Check the index of the face in DS
+      const Standard_Integer nF = myDS->Index(aF);
+      if (nF >= 0)
+      {
+        // The fact that the face is found in the DS, means that
+        // the face has not been change, and thus it is original one.
+        //
+        // Such face does not have any splits, but have an SD face.
+        // Consider it being split.
+        myImages.Bound(aF, TopTools_ListOfShape())->Append(aF);
+
+        // For the SD face chose the one with minimal index
+        if (nF < nFMin)
+        {
+          nFMin = nF;
+          pFSD = (TopoDS_Face*)&aF;
+        }
+      }
+    }
+
+    if (!pFSD)
+    {
+      // No original faces in the group, take the first one
+      pFSD = (TopoDS_Face*)&aLSD.First();
+    }
+
+    // Save all SD connections
+    aItLF.Initialize(aLSD);
+    for (; aItLF.More(); aItLF.Next())
+    {
+      const TopoDS_Shape& aF = aItLF.Value();
+      myShapesSD.Bind(aF, *pFSD);
     }
   }
+
+  // Update the map of images with SD faces and
+  // fill the map of origins.
+  Standard_Integer aNbS = myDS->NbSourceShapes();
+  for (Standard_Integer i = 0; i < aNbS; ++i)
+  {
+    const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
+    if (aSI.ShapeType() != TopAbs_FACE)
+      continue;
+
+    const TopoDS_Shape& aF = aSI.Shape();
+    TopTools_ListOfShape* pLFIm = myImages.ChangeSeek(aF);
+    if (!pLFIm)
+      continue;
+
+    TopTools_ListIteratorOfListOfShape aItLFIm(*pLFIm);
+    for (; aItLFIm.More(); aItLFIm.Next())
+    {
+      TopoDS_Shape& aFIm = aItLFIm.ChangeValue();
+      const TopoDS_Shape* pFSD = myShapesSD.Seek(aFIm);
+      if (pFSD)
+        // Update image with SD face
+        aFIm = *pFSD;
+
+      // Fill the map of origins
+      TopTools_ListOfShape* pLFOr = myOrigins.ChangeSeek(aFIm);
+      if (!pLFOr)
+        pLFOr = myOrigins.Bound(aFIm, TopTools_ListOfShape());
+      pLFOr->Append(aF);
+    }
+  }
+
   aMBlocks.Clear();
   aDMSLS.Clear();
 }
@@ -668,103 +749,63 @@ void BOPAlgo_Builder::FillSameDomainFaces()
 // function: FillImagesFaces1
 // purpose: 
 //=======================================================================
-void BOPAlgo_Builder::FillImagesFaces1()
+void BOPAlgo_Builder::FillInternalVertices()
 {
-  Standard_Integer i, aNbS, iSense, nVx, aNbVFI, iFlag;
-  TopoDS_Face aFSD;
-  TopoDS_Vertex aVx;
-  BRep_Builder aBB;
-  TColStd_ListOfInteger aLIAV;
-  TopTools_ListOfShape aLFIm;
-  TColStd_ListIteratorOfListOfInteger aItV;
-  TopTools_ListIteratorOfListOfShape aItLS, aItF;
+  // Vector of pairs of Vertex/Face for classification of the vertices
+  // relatively faces, and adding them as internal into the faces
   BOPAlgo_VectorOfVFI aVVFI;
-  //
-  aNbS=myDS->NbSourceShapes();
-  for (i=0; i<aNbS; ++i) {
-    const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
-    if (aSI.ShapeType()!=TopAbs_FACE) {
+
+  Standard_Integer aNbS = myDS->NbSourceShapes();
+  for (Standard_Integer i = 0; i < aNbS; ++i)
+  {
+    const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
+    if (aSI.ShapeType() != TopAbs_FACE)
       continue;
-    }
-    //
-    const TopoDS_Face& aF=(*(TopoDS_Face*)(&aSI.Shape()));
-    //
-    if (!mySplits.IsBound(aF)) {
+
+    const TopoDS_Shape& aF = aSI.Shape();
+    const TopTools_ListOfShape* pLFIm = myImages.Seek(aF);
+    if (!pLFIm)
       continue;
-    }
-    // 
-    // 1.
-    aLIAV.Clear();
+
+    // Find vertices to add as internal into the splits
+    TColStd_ListOfInteger aLIAV;
     myDS->AloneVertices(i, aLIAV);
-    aLFIm.Clear();
-    //
-    const TopTools_ListOfShape& aLSp=mySplits.Find(aF);
-    aItLS.Initialize(aLSp);
-    for (; aItLS.More(); aItLS.Next()) {
-      const TopoDS_Face& aFSp=(*(TopoDS_Face*)(&aItLS.Value()));
-      if (!myShapesSD.IsBound(aFSp)) {
-        aLFIm.Append(aFSp);
-      }
-      else {
-        aFSD=(*(TopoDS_Face*)(&myShapesSD.Find(aFSp)));
-        iSense=BOPTools_AlgoTools::Sense(aFSp, aFSD, myContext);
-        if (iSense<0) {
-          aFSD.Reverse();
-        }
-        aLFIm.Append(aFSD);
-      }
-    }
-    //
-    //FillInternalVertices(aLFIm, aLIAV);
-    //
-    myImages.Bind(aF, aLFIm); 
-    //
-    // 2. fill myOrigins
-    aItLS.Initialize(aLFIm);
-    for (; aItLS.More(); aItLS.Next()) {
-      const TopoDS_Face& aFSp=(*(TopoDS_Face*)(&aItLS.Value()));
-      //
-      TopTools_ListOfShape* pLOr = myOrigins.ChangeSeek(aFSp);
-      if (!pLOr) {
-        pLOr = myOrigins.Bound(aFSp, TopTools_ListOfShape());
-      }
-      pLOr->Append(aF);
-    }
-    //
-    // 3.
-    aItV.Initialize(aLIAV);
-    for (; aItV.More(); aItV.Next()) {
-      nVx=aItV.Value();
-      aVx=(*(TopoDS_Vertex*)(&myDS->Shape(nVx)));
-      aVx.Orientation(TopAbs_INTERNAL);
-      //
-      aItF.Initialize(aLFIm);
-      for (; aItF.More(); aItF.Next()) {
-        TopoDS_Face& aFy=(*(TopoDS_Face*)(&aItF.Value()));
-        //
-        BOPAlgo_VFI& aVFI=aVVFI.Appended();
-        aVFI.SetVertex(aVx);
-        aVFI.SetFace(aFy);
+
+    // Add vertices and faces for classification
+    TColStd_ListIteratorOfListOfInteger aItLV(aLIAV);
+    for (; aItLV.More(); aItLV.Next())
+    {
+      TopoDS_Vertex aV = TopoDS::Vertex(myDS->Shape(aItLV.Value()));
+      aV.Orientation(TopAbs_INTERNAL);
+
+      TopTools_ListIteratorOfListOfShape aItLFIm(*pLFIm);
+      for (; aItLFIm.More(); aItLFIm.Next())
+      {
+        const TopoDS_Face& aFIm = TopoDS::Face(aItLFIm.Value());
+        // Make the pair
+        BOPAlgo_VFI& aVFI = aVVFI.Appended();
+        aVFI.SetVertex(aV);
+        aVFI.SetFace(aFIm);
         aVFI.SetFuzzyValue(myFuzzyValue);
         aVFI.SetProgressIndicator(myProgressIndicator);
       }
     }
-  }// for (i=0; i<aNbS; ++i) {
-  //
-  // 4. 
-  aNbVFI=aVVFI.Length();
+  }
+
+  // Perform classification
   //================================================================
   BOPAlgo_VFICnt::Perform(myRunParallel, aVVFI, myContext);
   //================================================================
-  //
-  for (i=0; i < aNbVFI; ++i) {
-    BOPAlgo_VFI& aVFI=aVVFI(i);
-    //
-    iFlag=aVFI.Flag();
-    if (!iFlag) {
-      TopoDS_Vertex& aVertex=aVFI.Vertex();
-      TopoDS_Face& aFy=aVFI.Face(); 
-      aBB.Add(aFy, aVertex);
+
+  Standard_Integer aNbVFI = aVVFI.Length();
+  for (Standard_Integer i = 0; i < aNbVFI; ++i)
+  {
+    BOPAlgo_VFI& aVFI = aVVFI(i);
+    if (aVFI.IsInternal())
+    {
+      TopoDS_Vertex& aV = aVFI.Vertex();
+      TopoDS_Face& aF = aVFI.Face();
+      BRep_Builder().Add(aF, aV);
     }
   }
 }
diff --git a/src/BOPAlgo/BOPAlgo_Builder_3.cxx b/src/BOPAlgo/BOPAlgo_Builder_3.cxx
index b741eb033a..f3f9c7d266 100644
--- a/src/BOPAlgo/BOPAlgo_Builder_3.cxx
+++ b/src/BOPAlgo/BOPAlgo_Builder_3.cxx
@@ -250,7 +250,7 @@ void BOPAlgo_Builder::BuildDraftSolid(const TopoDS_Shape& theSolid,
   TopAbs_Orientation aOrF, aOrSh, aOrSd;
   TopoDS_Iterator aIt1, aIt2;
   TopoDS_Shell aShD;
-  TopoDS_Shape aFSDx, aFx;
+  TopoDS_Shape aFx;
   BRep_Builder aBB;
   TopTools_ListIteratorOfListOfShape aItS; 
   //
@@ -281,21 +281,20 @@ void BOPAlgo_Builder::BuildDraftSolid(const TopoDS_Shape& theSolid,
           aFx=aItS.Value();
           //
           if (myShapesSD.IsBound(aFx)) {
-            aFSDx=myShapesSD.Find(aFx);
             //
             if (aOrF==TopAbs_INTERNAL) {
-              aFSDx.Orientation(aOrF);
-              theLIF.Append(aFSDx);
+              aFx.Orientation(aOrF);
+              theLIF.Append(aFx);
             }
             else {
               bToReverse=BOPTools_AlgoTools::IsSplitToReverse
-                (aFSDx, aF, myContext); 
+                (aFx, aF, myContext);
               if (bToReverse) {
-                aFSDx.Reverse();
+                aFx.Reverse();
               }
               //
               iFlag=1;
-              aBB.Add(aShD, aFSDx);
+              aBB.Add(aShD, aFx);
             }
           }//if (myShapesSD.IsBound(aFx)) {
           else {
diff --git a/src/BOPAlgo/BOPAlgo_Options.cxx b/src/BOPAlgo/BOPAlgo_Options.cxx
index ac5445b4d0..ddbade6f53 100644
--- a/src/BOPAlgo/BOPAlgo_Options.cxx
+++ b/src/BOPAlgo/BOPAlgo_Options.cxx
@@ -50,8 +50,7 @@ BOPAlgo_Options::BOPAlgo_Options()
   myAllocator(NCollection_BaseAllocator::CommonBaseAllocator()),
   myReport(new Message_Report),
   myRunParallel(myGlobalRunParallel),
-  myFuzzyValue(Precision::Confusion()),
-  myCheckInverted(Standard_True)
+  myFuzzyValue(Precision::Confusion())
 {
   BOPAlgo_LoadMessages();
 }
@@ -66,8 +65,7 @@ BOPAlgo_Options::BOPAlgo_Options
   myAllocator(theAllocator),
   myReport(new Message_Report),
   myRunParallel(myGlobalRunParallel),
-  myFuzzyValue(Precision::Confusion()),
-  myCheckInverted(Standard_True)
+  myFuzzyValue(Precision::Confusion())
 {
   BOPAlgo_LoadMessages();
 }
diff --git a/src/BOPAlgo/BOPAlgo_Options.hxx b/src/BOPAlgo/BOPAlgo_Options.hxx
index 0d51bac207..a6cda3ab15 100644
--- a/src/BOPAlgo/BOPAlgo_Options.hxx
+++ b/src/BOPAlgo/BOPAlgo_Options.hxx
@@ -32,10 +32,6 @@ class Message_ProgressIndicator;
 //!                       touching or coinciding cases;
 //! - *Progress indicator* - provides interface to track the progress of
 //!                          operation and stop the operation by user's break.
-//! - *Disabling the check for inverted solids* - Disables/Enables the check of the input solids
-//!                          for inverted status (holes in the space). The default value is TRUE,
-//!                          i.e. the check is performed. Setting this flag to FALSE for inverted solids,
-//!                          most likely will lead to incorrect results.
 //!
 class BOPAlgo_Options
 {
@@ -160,22 +156,6 @@ public:
   //! Set the Progress Indicator object.
   Standard_EXPORT void SetProgressIndicator(const Handle(Message_ProgressIndicator)& theObj);
 
-public:
-  //!@name Check input solids for inverted status
-
-  //! Enables/Disables the check of the input solids for inverted status
-  void SetCheckInverted(const Standard_Boolean theCheck)
-  {
-    myCheckInverted = theCheck;
-  }
-
-  //! Returns the flag defining whether the check for input solids on inverted status
-  //! should be performed or not.
-  Standard_Boolean CheckInverted() const
-  {
-    return myCheckInverted;
-  }
-
 protected:
 
   //! Breaks the execution if the break signal
@@ -189,7 +169,6 @@ protected:
   Standard_Boolean myRunParallel;
   Standard_Real myFuzzyValue;
   Handle(Message_ProgressIndicator) myProgressIndicator;
-  Standard_Boolean myCheckInverted;
 
 };
 
diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_7.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_7.cxx
index e614b7f315..dd115b219f 100644
--- a/src/BOPAlgo/BOPAlgo_PaveFiller_7.cxx
+++ b/src/BOPAlgo/BOPAlgo_PaveFiller_7.cxx
@@ -26,6 +26,7 @@
 #include <BOPDS_Interf.hxx>
 #include <BOPDS_Iterator.hxx>
 #include <BOPDS_ListOfPaveBlock.hxx>
+#include <BOPDS_MapOfCommonBlock.hxx>
 #include <BOPDS_MapOfPair.hxx>
 #include <BOPDS_MapOfPaveBlock.hxx>
 #include <BOPDS_Pave.hxx>
@@ -414,12 +415,11 @@ void BOPAlgo_PaveFiller::MakeSplitEdges()
     return;
   }
   //
-  Standard_Boolean bCB, bV1, bV2;
-  Standard_Integer i, nE, nV1, nV2, nSp, aNbPB, aNbVBSE, k;
+  Standard_Integer i, nE, nV1, nV2, nSp, aNbVBSE, k;
   Standard_Real aT1, aT2;
   BOPDS_ListIteratorOfListOfPaveBlock aItPB;
   Handle(BOPDS_PaveBlock) aPB;
-  BOPDS_MapOfPaveBlock aMPB(100);
+  BOPDS_MapOfCommonBlock aMCB(100);
   TopoDS_Vertex aV1, aV2;
   TopoDS_Edge aE;
   BOPAlgo_VectorOfSplitEdge aVBSE;
@@ -429,77 +429,96 @@ void BOPAlgo_PaveFiller::MakeSplitEdges()
   //
   aNbPBP=aPBP.Length();
   //
-  for (i=0; i<aNbPBP; ++i) {
-    BOPDS_ListOfPaveBlock& aLPB=aPBP(i);
-    //
-    aNbPB=aLPB.Extent();
-    if (aNbPB==1) {
-      aPB=aLPB.First();
-      aPB->Indices(nV1, nV2);
-      bV1=myDS->IsNewShape(nV1);
-      bV2=myDS->IsNewShape(nV2);
-      bCB=myDS->IsCommonBlock(aPB);
-      //
-      if (!(bV1 || bV2)) { // no new vertices here
-        if (!myNonDestructive || !bCB) {
-          if (bCB) {
-            if (!aPB->HasEdge()) {
-              const Handle(BOPDS_CommonBlock)& aCB = myDS->CommonBlock(aPB);
-              nE = aCB->PaveBlock1()->OriginalEdge();
-              aCB->SetEdge(nE);
-              // Compute tolerance of the common block and update the edge
-              Standard_Real aTol = BOPAlgo_Tools::ComputeToleranceOfCB(aCB, myDS, myContext);
-              myDS->UpdateEdgeTolerance(nE, aTol);
-            }
-          }
-          else {
-            nE = aPB->OriginalEdge();
-            aPB->SetEdge(nE);
-          }
-          continue;
-        }
-      }
-    }
+  for (i = 0; i < aNbPBP; ++i)
+  {
+    BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
     //
     aItPB.Initialize(aLPB);
     for (; aItPB.More(); aItPB.Next()) {
-      aPB=aItPB.Value();
-      nE=aPB->OriginalEdge();
-      const BOPDS_ShapeInfo& aSIE=myDS->ShapeInfo(nE);
-      if (aSIE.HasFlag()){
+      aPB = aItPB.Value();
+      nE = aPB->OriginalEdge();
+      const BOPDS_ShapeInfo& aSIE = myDS->ShapeInfo(nE);
+      if (aSIE.HasFlag())
+      {
+        // Skip degenerated edges
         continue;
       }
-      //
-      const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
-      bCB=!aCB.IsNull();
-      if (bCB) {
-        aPB=aCB->PaveBlock1();
-      }
-      //
-      if (aMPB.Add(aPB)) {
-        nE=aPB->OriginalEdge();
-        aPB->Indices(nV1, nV2);
-        aPB->Range(aT1, aT2);
-        //
-        aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); 
-        aE.Orientation(TopAbs_FORWARD);
-        //
-        aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
-        aV1.Orientation(TopAbs_FORWARD); 
-        //
-        aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
-        aV2.Orientation(TopAbs_REVERSED); 
-        //
-        BOPAlgo_SplitEdge& aBSE=aVBSE.Appended();
-        //
-        aBSE.SetData(aE, aV1, aT1, aV2, aT2);
-        aBSE.SetPaveBlock(aPB);
-        if (bCB) {
-          aBSE.SetCommonBlock(aCB);
+
+      const Handle(BOPDS_CommonBlock)& aCB = myDS->CommonBlock(aPB);
+      Standard_Boolean bCB = !aCB.IsNull();
+      if (bCB && !aMCB.Add(aCB))
+        continue;
+
+      aPB->Indices(nV1, nV2);
+      // Check if it is necessary to make the split of the edge
+      {
+        Standard_Boolean bV1 = myDS->IsNewShape(nV1);
+        Standard_Boolean bV2 = myDS->IsNewShape(nV2);
+
+        Standard_Boolean bToSplit = Standard_True;
+        if (!bV1 && !bV2) // no new vertices here
+        {
+          if (!myNonDestructive || !bCB)
+          {
+            if (bCB)
+            {
+              // Find the edge with these vertices
+              BOPDS_ListIteratorOfListOfPaveBlock it(aCB->PaveBlocks());
+              for (; it.More(); it.Next())
+              {
+                nE = it.Value()->OriginalEdge();
+                if (myDS->PaveBlocks(nE).Extent() == 1)
+                  break;
+              }
+              if (it.More())
+              {
+                // The pave block is found
+                bToSplit = Standard_False;
+                aCB->SetRealPaveBlock(it.Value());
+                aCB->SetEdge(nE);
+                // Compute tolerance of the common block and update the edge
+                Standard_Real aTol = BOPAlgo_Tools::ComputeToleranceOfCB(aCB, myDS, myContext);
+                myDS->UpdateEdgeTolerance(nE, aTol);
+              }
+            }
+            else if (aLPB.Extent() == 1)
+            {
+              bToSplit = Standard_False;
+              aPB->SetEdge(nE);
+            }
+            if (!bToSplit)
+              continue;
+          }
         }
-        aBSE.SetDS(myDS);
-        aBSE.SetProgressIndicator(myProgressIndicator);
       }
+
+      // Split the edge
+      if (bCB)
+      {
+        aPB = aCB->PaveBlock1();
+        nE = aPB->OriginalEdge();
+        aPB->Indices(nV1, nV2);
+      }
+      aPB->Range(aT1, aT2);
+      //
+      aE = (*(TopoDS_Edge *)(&myDS->Shape(nE)));
+      aE.Orientation(TopAbs_FORWARD);
+      //
+      aV1 = (*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
+      aV1.Orientation(TopAbs_FORWARD);
+      //
+      aV2 = (*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
+      aV2.Orientation(TopAbs_REVERSED);
+      //
+      BOPAlgo_SplitEdge& aBSE = aVBSE.Appended();
+      //
+      aBSE.SetData(aE, aV1, aT1, aV2, aT2);
+      aBSE.SetPaveBlock(aPB);
+      if (bCB) {
+        aBSE.SetCommonBlock(aCB);
+      }
+      aBSE.SetDS(myDS);
+      aBSE.SetProgressIndicator(myProgressIndicator);
     } // for (; aItPB.More(); aItPB.Next()) {
   }  // for (i=0; i<aNbPBP; ++i) {      
   //
diff --git a/src/BOPDS/BOPDS_CommonBlock.cxx b/src/BOPDS/BOPDS_CommonBlock.cxx
index 7bf768a582..06bf7a5e2a 100644
--- a/src/BOPDS/BOPDS_CommonBlock.cxx
+++ b/src/BOPDS/BOPDS_CommonBlock.cxx
@@ -116,6 +116,23 @@ void BOPDS_CommonBlock::AppendFaces(TColStd_ListOfInteger& aLF)
   return myPaveBlocks.First();
 }
 //=======================================================================
+// function:  SetRealPaveBlock
+// purpose: 
+//=======================================================================
+void BOPDS_CommonBlock::SetRealPaveBlock(const Handle(BOPDS_PaveBlock)& thePB)
+{
+  BOPDS_ListIteratorOfListOfPaveBlock it(myPaveBlocks);
+  for (; it.More(); it.Next())
+  {
+    if (it.Value() == thePB)
+    {
+      myPaveBlocks.Prepend(thePB);
+      myPaveBlocks.Remove(it);
+      break;
+    }
+  }
+}
+//=======================================================================
 // function:  PaveBlockOnEdge
 // purpose: 
 //=======================================================================
diff --git a/src/BOPDS/BOPDS_CommonBlock.hxx b/src/BOPDS/BOPDS_CommonBlock.hxx
index 71c9204340..e830e2aacf 100644
--- a/src/BOPDS/BOPDS_CommonBlock.hxx
+++ b/src/BOPDS/BOPDS_CommonBlock.hxx
@@ -149,29 +149,21 @@ public:
   
   Standard_EXPORT void Dump() const;
 
-
+  //! Moves the pave blocks in the list to make the given
+  //! pave block to be the first.
+  //! It will be representative for the whole group.
+  Standard_EXPORT void SetRealPaveBlock(const Handle(BOPDS_PaveBlock)& thePB);
 
 
   DEFINE_STANDARD_RTTIEXT(BOPDS_CommonBlock,Standard_Transient)
 
 protected:
 
-
   BOPDS_ListOfPaveBlock myPaveBlocks;
   TColStd_ListOfInteger myFaces;
 
-
 private:
 
-
-
-
 };
 
-
-
-
-
-
-
 #endif // _BOPDS_CommonBlock_HeaderFile
diff --git a/src/BRepAlgoAPI/BRepAlgoAPI_Algo.hxx b/src/BRepAlgoAPI/BRepAlgoAPI_Algo.hxx
index df2d5539f4..8f2262232a 100644
--- a/src/BRepAlgoAPI/BRepAlgoAPI_Algo.hxx
+++ b/src/BRepAlgoAPI/BRepAlgoAPI_Algo.hxx
@@ -55,7 +55,6 @@ public:
   using BOPAlgo_Options::ClearWarnings;
   using BOPAlgo_Options::GetReport;
   using BOPAlgo_Options::SetProgressIndicator;
-  using BOPAlgo_Options::SetCheckInverted;
 
 protected:
 
diff --git a/src/BRepAlgoAPI/BRepAlgoAPI_BuilderAlgo.cxx b/src/BRepAlgoAPI/BRepAlgoAPI_BuilderAlgo.cxx
index f0c565f770..d40583ec77 100644
--- a/src/BRepAlgoAPI/BRepAlgoAPI_BuilderAlgo.cxx
+++ b/src/BRepAlgoAPI/BRepAlgoAPI_BuilderAlgo.cxx
@@ -29,7 +29,8 @@ BRepAlgoAPI_BuilderAlgo::BRepAlgoAPI_BuilderAlgo()
   myDSFiller(NULL),
   myBuilder(NULL),
   myNonDestructive(Standard_False),
-  myGlue(BOPAlgo_GlueOff)
+  myGlue(BOPAlgo_GlueOff),
+  myCheckInverted(Standard_True)
 {}
 //=======================================================================
 // function: 
@@ -42,7 +43,8 @@ BRepAlgoAPI_BuilderAlgo::BRepAlgoAPI_BuilderAlgo
   myEntryType(0),
   myBuilder(NULL),
   myNonDestructive(Standard_False),
-  myGlue(BOPAlgo_GlueOff)
+  myGlue(BOPAlgo_GlueOff),
+  myCheckInverted(Standard_True)
 {
   BOPAlgo_PaveFiller* pPF=(BOPAlgo_PaveFiller*)&aPF;
   myDSFiller=pPF;
diff --git a/src/BRepAlgoAPI/BRepAlgoAPI_BuilderAlgo.hxx b/src/BRepAlgoAPI/BRepAlgoAPI_BuilderAlgo.hxx
index f13835111b..312dc134b8 100644
--- a/src/BRepAlgoAPI/BRepAlgoAPI_BuilderAlgo.hxx
+++ b/src/BRepAlgoAPI/BRepAlgoAPI_BuilderAlgo.hxx
@@ -31,9 +31,19 @@ class BOPAlgo_PaveFiller;
 class TopoDS_Shape;
 
 
-
 //! The class contains API level of the General Fuse algorithm.<br>
 //!
+//! Additionally to the options defined in the base class, the algorithm has
+//! the following options:<br>
+//! - *Safe processing mode* - allows to avoid modification of the input
+//!                            shapes during the operation (by default it is off);
+//! - *Gluing options* - allows to speed up the calculation of the intersections
+//!                      on the special cases, in which some sub-shapes are coinciding.
+//! - *Disabling the check for inverted solids* - Disables/Enables the check of the input solids
+//!                          for inverted status (holes in the space). The default value is TRUE,
+//!                          i.e. the check is performed. Setting this flag to FALSE for inverted solids,
+//!                          most likely will lead to incorrect results.
+//!
 //! It returns the following Error statuses:<br>
 //! - 0 - in case of success;<br>
 //! - *BOPAlgo_AlertTooFewArguments* - in case there are no enough arguments to perform the operation;<br>
@@ -72,6 +82,19 @@ Standard_EXPORT virtual ~BRepAlgoAPI_BuilderAlgo();
   //! Returns the glue option of the algorithm
   Standard_EXPORT BOPAlgo_GlueEnum Glue() const;
 
+  //! Enables/Disables the check of the input solids for inverted status
+  void SetCheckInverted(const Standard_Boolean theCheck)
+  {
+    myCheckInverted = theCheck;
+  }
+
+  //! Returns the flag defining whether the check for input solids on inverted status
+  //! should be performed or not.
+  Standard_Boolean CheckInverted() const
+  {
+    return myCheckInverted;
+  }
+
   //! Sets the arguments
   Standard_EXPORT void SetArguments (const TopTools_ListOfShape& theLS);
   
@@ -130,20 +153,10 @@ protected:
   Standard_Boolean myNonDestructive;
   TopTools_ListOfShape myArguments;
   BOPAlgo_GlueEnum myGlue;
-
+  Standard_Boolean myCheckInverted;
 
 private:
 
-
-
-
-
 };
 
-
-
-
-
-
-
 #endif // _BRepAlgoAPI_BuilderAlgo_HeaderFile
diff --git a/src/BRepFeat/BRepFeat_Builder.cxx b/src/BRepFeat/BRepFeat_Builder.cxx
index fae5e26533..480d2334bd 100644
--- a/src/BRepFeat/BRepFeat_Builder.cxx
+++ b/src/BRepFeat/BRepFeat_Builder.cxx
@@ -503,9 +503,7 @@
       }
     }
     //
-    mySplits.Bind(aF, aLFIm); 
     if (aLFIm.Extent() == 0) {
-      mySplits.UnBind(aF);
       myImages.UnBind(aF);
     }
   }
diff --git a/src/BRepOffset/BRepOffset_MakeOffset_1.cxx b/src/BRepOffset/BRepOffset_MakeOffset_1.cxx
index 6b3feb8bd7..47ff3c4e76 100644
--- a/src/BRepOffset/BRepOffset_MakeOffset_1.cxx
+++ b/src/BRepOffset/BRepOffset_MakeOffset_1.cxx
@@ -5632,14 +5632,8 @@ void UpdateValidEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theFImage
   GetBoundsToUpdate(aLF, theOEImages, theOEOrigins, aMEB,
                     aLABounds, aLAValid, aBounds, theAsDes);
   //
-  // intersect valid splits with bounds and update both
+  // Intersect valid splits with bounds and update both
   BOPAlgo_Builder aGF;
-  // The order is important here, because we need to keep the
-  // unmodified edges from the Bounds in the resulting maps.
-  // In case of total coincidence of the edges with the same vertices
-  // the edges in the common block will not be split and no new
-  // edges will be created and the first pave block
-  // will be used as a real pave block.
   aGF.AddArgument(aBounds);
   aGF.AddArgument(aSplits);
   aGF.Perform();
@@ -5667,18 +5661,56 @@ void UpdateValidEdges(const TopTools_IndexedDataMapOfShapeListOfShape& theFImage
     }
   }
   //
+  // Rebuild the map of edges to avoid, using the intersection results
+  TopTools_IndexedMapOfShape aMEAvoid;
+  // GF's data structure
+  const BOPDS_PDS& pDS = aGF.PDS();
+
   aNbE = theEdgesToAvoid.Extent();
-  for (i = 1; i <= aNbE; ++i) {
+  for (i = 1; i <= aNbE; ++i)
+  {
     const TopoDS_Shape& aE = theEdgesToAvoid(i);
     const TopTools_ListOfShape& aLEIm = aGF.Modified(aE);
-    TopTools_ListIteratorOfListOfShape aItLEIm(aLEIm);
-    for (; aItLEIm.More(); aItLEIm.Next()) {
-      const TopoDS_Shape& aEIm = aItLEIm.Value();
-      if (!aNewEdges.Contains(aEIm)) {
-        theEdgesToAvoid.Add(aEIm);
+
+    // Only untouched and fully coinciding edges should be kept in the avoid map
+    Standard_Boolean bKeep = aLEIm.IsEmpty();
+    if (aLEIm.Extent() == 1 && aE.IsSame(aLEIm.First()))
+    {
+      const BOPDS_ListOfPaveBlock& aLPB = pDS->PaveBlocks(pDS->Index(aE));
+      if (aLPB.Extent() == 1)
+      {
+        const Handle(BOPDS_PaveBlock)& aPB = aLPB.First();
+        const Handle(BOPDS_CommonBlock)& aCB = pDS->CommonBlock(aPB);
+        if (!aCB.IsNull())
+        {
+          const BOPDS_ListOfPaveBlock& aLPBCB = aCB->PaveBlocks();
+          BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPBCB);
+          for (; aItLPB.More(); aItLPB.Next())
+          {
+            if (pDS->PaveBlocks(aItLPB.Value()->OriginalEdge()).Extent() > 1)
+              break;
+          }
+          bKeep = !aItLPB.More();
+        }
       }
     }
+
+    if (bKeep)
+    {
+      // keep the original edge
+      aMEAvoid.Add(aE);
+      continue;
+    }
+
+    TopTools_ListIteratorOfListOfShape aItLEIm(aLEIm);
+    for (; aItLEIm.More(); aItLEIm.Next())
+    {
+      const TopoDS_Shape& aEIm = aItLEIm.Value();
+      if (!aNewEdges.Contains(aEIm))
+        aMEAvoid.Add(aEIm);
+    }
   }
+  theEdgesToAvoid = aMEAvoid;
 }
 
 //=======================================================================
diff --git a/tests/blend/complex/G9 b/tests/blend/complex/G9
index ff4881becc..340187c593 100644
--- a/tests/blend/complex/G9
+++ b/tests/blend/complex/G9
@@ -8,6 +8,6 @@ pcylinder c2 5 20
 ttranslate c2 4.9 0 10
 bfuse f c1b c2
 explode f E
-blend result f 4.9 f_5
+blend result f 4.9 f_4
 
 checkprops result -s 2104.35
diff --git a/tests/blend/complex/H2 b/tests/blend/complex/H2
deleted file mode 100644
index cc8343d537..0000000000
--- a/tests/blend/complex/H2
+++ /dev/null
@@ -1,16 +0,0 @@
-# ====================================
-## Grid	   : CFI900
-## Test    : N1
-## Comment : from USA60109
-## ====================================
-
-pcylinder c1 10 20
-pcylinder c2 5 20
-ttranslate c2 5 0 20
-bfuse f c1 c2
-explode f E
-blend result f 1 f_1
-explode result sh
-renamevar result_1 result
-
-checkprops result -s 2485.86
diff --git a/tests/blend/simple/Q4 b/tests/blend/simple/Q4
index e47e8603c6..cb6ec86dda 100644
--- a/tests/blend/simple/Q4
+++ b/tests/blend/simple/Q4
@@ -5,6 +5,6 @@ pcylinder c 1 10
 ttranslate c 2.5 2.5 2.5
 bfuse s c b
 explode s E
-blend result s 1 s_3
+blend result s 1 s_2
 
 checkprops result -s 192.343
diff --git a/tests/blend/simple/Z1 b/tests/blend/simple/Z1
index 1afc065575..ec3e6b9920 100644
--- a/tests/blend/simple/Z1
+++ b/tests/blend/simple/Z1
@@ -7,8 +7,8 @@ ttranslate c2 5 0 20
 
 bfuse f c1 c2
 
-explode f E
+explode c1 e
 
-blend result f 1 f_1
+blend result f 1 c1_3
 
 checkprops result -s 2485.86
diff --git a/tests/bugs/modalg_7/bug24632_1 b/tests/bugs/modalg_7/bug24632_1
index 759dd7f69e..312017ca39 100644
--- a/tests/bugs/modalg_7/bug24632_1
+++ b/tests/bugs/modalg_7/bug24632_1
@@ -26,7 +26,7 @@ bop beam_1 cut_2
 bopcut result
 checkshape result
 
-checknbshapes result -solid 2 -shell 2 -face 32 -wire 39
+checknbshapes result -solid 2 -shell 2 -face 33 -wire 40 -t
 checkprops result -v 5.40325e+7
 
 checkview -display result -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/bugs/modalg_7/bug24632_2 b/tests/bugs/modalg_7/bug24632_2
index 255d18acca..601a4e60dd 100644
--- a/tests/bugs/modalg_7/bug24632_2
+++ b/tests/bugs/modalg_7/bug24632_2
@@ -42,7 +42,7 @@ bop beam_2 cut_2
 bopcut result
 checkshape result
 
-checknbshapes result -solid 4 -shell 4 -face 64 -wire 73
+checknbshapes result -solid 4 -shell 4 -face 64 -wire 73 -t
 checkprops result -v 1.61677e+8
 
 checkview -display result -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/bugs/modalg_7/bug27711 b/tests/bugs/modalg_7/bug27711
index 8105c11ba3..6ec342352a 100644
--- a/tests/bugs/modalg_7/bug27711
+++ b/tests/bugs/modalg_7/bug27711
@@ -11,20 +11,15 @@ puts ""
 
 smallview
 
-box a -1.5 -1.5 0 3 3 3
-box b -3 -3 -3 6 6 3
-bfuse result a b
-set bug_info [string trim [checkshape result]]
-if {$bug_info != "This shape seems to be valid"} {
-  puts "ERROR: Problem of test case functionality. Should be additionally investigated."
-}
+restore [locate_data_file bug27711.brep] s
+
 clear
-display result
+display s
 fit
 xwd $imagedir/${casename}_step_0.png
 
-explode result e
-blend result result 0.5 result_12 0.5 result_11
+explode s e
+blend result s 0.5 s_12 0.5 s_11
 set bug_info [string trim [checkshape result]]
 if {$bug_info != "This shape seems to be valid"} {
   puts "ERROR: Problem of test case functionality. Should be additionally investigated."
diff --git a/tests/bugs/modalg_7/bug29333_1 b/tests/bugs/modalg_7/bug29333_1
new file mode 100644
index 0000000000..fa77f316f9
--- /dev/null
+++ b/tests/bugs/modalg_7/bug29333_1
@@ -0,0 +1,65 @@
+puts "========"
+puts "OCC29333"
+puts "========"
+puts ""
+#################################################
+# Boolean Operations - Prevent modification of the input shapes in case their sub-shapes have not been modified
+#################################################
+
+# create two touching faces
+plane p 0 0 0 0 0 1
+mkface f1 p -10 10 -10 10
+
+copy f1 f2
+ttranslate f2 20 0 0
+
+# fuse these faces
+bfuse s f1 f2
+
+# split one of these faces
+explode s f
+
+line l 0 0 0 1 0 0 
+mkedge e l
+bclearobjects
+bcleartools
+baddobjects s_1
+baddtools e
+bfillds
+bsplit s1_sp
+
+
+# fuse again
+bclearobjects
+bcleartools
+baddobjects s1_sp
+baddtools s_2
+bfillds
+bbuild result
+
+checkshape result
+checkprops result -s 800
+checknbshapes result -vertex 8 -edge 10 -wire 3 -face 3
+
+
+# check that non of the shapes from s1_sp is modified
+compound result s1_sp c
+checknbshapes c -vertex 8 -edge 10 -wire 3 -face 3
+
+
+# fuse with different order
+bclearobjects
+bcleartools
+baddobjects s_2
+baddtools s1_sp
+bfillds
+bbuild result
+
+checkshape result
+checkprops result -s 800
+checknbshapes result -vertex 8 -edge 10 -wire 3 -face 3
+
+
+# check that non of the shapes from s1_sp is modified
+compound result s1_sp c
+checknbshapes c -vertex 8 -edge 10 -wire 3 -face 3
diff --git a/tests/bugs/modalg_7/bug29333_2 b/tests/bugs/modalg_7/bug29333_2
new file mode 100644
index 0000000000..ccb0760745
--- /dev/null
+++ b/tests/bugs/modalg_7/bug29333_2
@@ -0,0 +1,62 @@
+puts "========"
+puts "OCC29333"
+puts "========"
+puts ""
+#################################################
+# Boolean Operations - Prevent modification of the input shapes in case their sub-shapes have not been modified
+#################################################
+
+# create two touching boxes
+box b1 10 10 10
+box b2 10 0 0 10 10 10
+
+# make them share the common face
+mkvolume s b1 b2
+
+# split one of these solids
+explode s so
+
+plane p 0 0 5 0 0 1
+mkface f p
+bclearobjects
+bcleartools
+baddobjects s_1
+baddtools f
+bfillds 
+bsplit s1_sp
+
+
+# fuse again
+bclearobjects
+bcleartools
+baddobjects s1_sp
+baddtools s_2
+bfillds
+bbuild result
+
+checkshape result
+checkprops result -s 1400 -v 2000
+checknbshapes result -vertex 16 -edge 28 -wire 16 -face 16 -shell 3 -solid 3
+
+
+# check that non of the shapes from s1_sp is modified
+compound result s1_sp c
+checknbshapes c -vertex 16 -edge 28 -wire 16 -face 16 -shell 3 -solid 3
+
+
+# fuse with different order
+bclearobjects
+bcleartools
+baddobjects s_2
+baddtools s1_sp
+bfillds
+bbuild result
+
+checkshape result
+checkprops result -s 1400 -v 2000
+checknbshapes result -vertex 16 -edge 28 -wire 16 -face 16 -shell 3 -solid 3
+
+
+# check that non of the shapes from s1_sp is modified
+compound result s1_sp c
+checknbshapes c -vertex 16 -edge 28 -wire 16 -face 16 -shell 3 -solid 3
diff --git a/tests/caf/named_shape/F8 b/tests/caf/named_shape/F8
index 36389003db..4147563580 100755
--- a/tests/caf/named_shape/F8
+++ b/tests/caf/named_shape/F8
@@ -9,7 +9,7 @@
 # 1. Create 3 boxes $B1, $B2, $B3
 # 2. $FS1 = Fuse ($B1, $B2)
 # 3. $FS2 = Fuse ($B1, $B3)
-# 4. Make  selections of the face 'fuse2_23'
+# 4. Make  selections of the face 'fuse2_19'
 # 5. Modify B2
 # 6. Recompute
 # ===============================================
@@ -37,12 +37,12 @@ GetShape $doc $FS2:2 fuse2
 explode fuse2 f
 
 
-#4. select fuse2_23 (using SelectShape)
-set Sel1 0:2:23
-SelectShape $doc $Sel1 fuse2_23 fuse2
-GetShape $doc $Sel1 f23before
-#f23before is face
-set info1 [whatis f23before]
+#4. select fuse2_19 (using SelectShape)
+set Sel1 0:2:19
+SelectShape $doc $Sel1 fuse2_19 fuse2
+GetShape $doc $Sel1 f19before
+#f19before is face
+set info1 [whatis f19before]
 
 
 #5. Modify
@@ -53,40 +53,40 @@ ComputeFun $doc $B2:1
 ComputeFun $doc $FS1
 ComputeFun $doc $FS2
 SolveSelection $doc $Sel1
-GetShape $doc $Sel1 f23after
-#f23after is face
-set info2 [whatis f23after]
+GetShape $doc $Sel1 f19after
+#f19after is face
+set info2 [whatis f19after]
 
 if { [regexp "shape" $info1] != 1 } {
-    puts "Error : There is not word shape in f23after"
+    puts "Error : There is not word shape in f19after"
 }
 if { [regexp "FACE" $info1] != 1 } {
-    puts "Error : There is not word FACE in f23after"
+    puts "Error : There is not word FACE in f19after"
 }
 if { [regexp "REVERSED" $info1] != 1 } {
-    puts "Error : There is not word REVERSED in f23after"
+    puts "Error : There is not word REVERSED in f19after"
 }
 if { [regexp "Modified" $info1] != 1 } {
-    puts "Error : There is not word Modified in f23after"
+    puts "Error : There is not word Modified in f19after"
 }
 if { [regexp "Orientable" $info1] != 1 } {
-    puts "Error : There is not word Orientable in f23after"
+    puts "Error : There is not word Orientable in f19after"
 }
 
 if { [regexp "shape" $info2] != 1 } {
-    puts "Error : There is not word shape in f23before"
+    puts "Error : There is not word shape in f19before"
 }
 if { [regexp "FACE" $info2] != 1 } {
-    puts "Error : There is not word FACE in f23before"
+    puts "Error : There is not word FACE in f19before"
 }
 if { [regexp "REVERSED" $info2] != 1 } {
-    puts "Error : There is not word REVERSED in f23before"
+    puts "Error : There is not word REVERSED in f19before"
 }
 if { [regexp "Modified" $info2] != 1 } {
-    puts "Error : There is not word Modified in f23before"
+    puts "Error : There is not word Modified in f19before"
 }
 if { [regexp "Orientable" $info2] != 1 } {
-    puts "Error : There is not word Orientable in f23before"
+    puts "Error : There is not word Orientable in f19before"
 }
 
 
diff --git a/tests/caf/named_shape/F9 b/tests/caf/named_shape/F9
index c3612a5515..4489ec0916 100755
--- a/tests/caf/named_shape/F9
+++ b/tests/caf/named_shape/F9
@@ -9,7 +9,7 @@
 # 1. Create 3 boxes $B1, $B2, $B3
 # 2. $FS1 = Fuse ($B1, $B2)
 # 3. $FS2 = Fuse ($B1, $B3)
-# 4. Make  selections of the face 'fuse2_23'
+# 4. Make  selections of the face 'fuse2_19'
 # 5. Modify B2
 # 6. Recompute
 # ===============================================
@@ -38,11 +38,11 @@ explode fuse2 f
 
 
 
-#4. Select fuse2_23 using Attach 
-set Sel2 [AttachShape $doc fuse2_23 $B1]
-GetShape $doc $Sel2:1:2 nf23before
-#nf23before is face
-set info1 [whatis nf23before]
+#4. Select fuse2_19 using Attach 
+set Sel2 [AttachShape $doc fuse2_19 $B1]
+GetShape $doc $Sel2:1:2 nf19before
+#nf19before is face
+set info1 [whatis nf19before]
 
 
 #5. Modify
@@ -56,38 +56,38 @@ ComputeFun $doc $B3:1
 ComputeFun $doc $FS1
 ComputeFun $doc $FS2
 ComputeFun $doc $Sel2:1
-GetShape $doc $Sel2:1:2 nf23after
-#nf23after is face
-set info2 [whatis nf23after]
+GetShape $doc $Sel2:1:2 nf19after
+#nf19after is face
+set info2 [whatis nf19after]
 
 if { [regexp "shape" $info1] != 1 } {
-    puts "Error : There is not word shape in nf23after"
+    puts "Error : There is not word shape in nf19after"
 }
 if { [regexp "FACE" $info1] != 1 } {
-    puts "Error : There is not word FACE in nf23after"
+    puts "Error : There is not word FACE in nf19after"
 }
 if { [regexp "REVERSED" $info1] != 1 } {
-    puts "Error : There is not word REVERSED in nf23after"
+    puts "Error : There is not word REVERSED in nf19after"
 }
 if { [regexp "Modified" $info1] != 1 } {
-    puts "Error : There is not word Modified in nf23after"
+    puts "Error : There is not word Modified in nf19after"
 }
 if { [regexp "Orientable" $info1] != 1 } {
-    puts "Error : There is not word Orientable in nf23after"
+    puts "Error : There is not word Orientable in nf19after"
 }
 
 if { [regexp "shape" $info2] != 1 } {
-    puts "Error : There is not word shape in nf23before"
+    puts "Error : There is not word shape in nf19before"
 }
 if { [regexp "FACE" $info2] != 1 } {
-    puts "Error : There is not word FACE in nf23before"
+    puts "Error : There is not word FACE in nf19before"
 }
 if { [regexp "REVERSED" $info2] != 1 } {
-    puts "Error : There is not word REVERSED in nf23before"
+    puts "Error : There is not word REVERSED in nf19before"
 }
 if { [regexp "Modified" $info2] != 1 } {
-    puts "Error : There is not word Modified in nf23before"
+    puts "Error : There is not word Modified in nf19before"
 }
 if { [regexp "Orientable" $info2] != 1 } {
-    puts "Error : There is not word Orientable in nf23before"
+    puts "Error : There is not word Orientable in nf19before"
 }
\ No newline at end of file
diff --git a/tests/perf/modalg/bug29237_1 b/tests/perf/modalg/bug29237_1
index 37ff7bfaf4..548e87b24c 100644
--- a/tests/perf/modalg/bug29237_1
+++ b/tests/perf/modalg/bug29237_1
@@ -37,10 +37,10 @@ dchrono cpu stop counter OCC29237
 
 # check the result of CUT
 checkshape rcut
-checknbshapes rcut -vertex 640 -edge 1760 -wire 842 -face 842 -shell 1 -solid 1
+checknbshapes rcut -vertex 1200 -edge 2040 -wire 842 -face 842 -shell 1 -solid 1 -t -m "CUT"
 checkprops rcut -s 3.4136e+006 -v 2.9712e+007
 
 # check the result of COMMON
 checkshape rcommon
-checknbshapes rcommon -vertex 616 -edge 1484 -wire 882 -face 882 -shell 147 -solid 147
+checknbshapes rcommon -vertex 1176 -edge 1764 -wire 882 -face 882 -shell 147 -solid 147 -t -m "COMMON"
 checkprops rcommon -s 2.13392e+006 -v 1.6448e+007
diff --git a/tests/perf/modalg/bug29237_3 b/tests/perf/modalg/bug29237_3
index 1f38f4fe2a..dc46481621 100644
--- a/tests/perf/modalg/bug29237_3
+++ b/tests/perf/modalg/bug29237_3
@@ -37,10 +37,10 @@ dchrono cpu stop counter OCC29237
 
 # check the result of CUT
 checkshape rcut
-checknbshapes rcut -vertex 1294 -edge 3074 -wire 1842 -face 1842 -shell 301 -solid 301
+checknbshapes rcut -vertex 2488 -edge 3732 -wire 1846 -face 1846 -shell 301 -solid 301 -t -m "CUT"
 checkprops rcut -s 2.59678e+006 -v 1.5346e+007
 
 # check the result of COMMON
 checkshape rcommon
-checknbshapes rcommon -vertex 0 -edge 0 -wire 0 -face 0 -shell 0 -solid 0
+checknbshapes rcommon -vertex 0 -edge 0 -wire 0 -face 0 -shell 0 -solid 0 -t -m "COMMON"
 checkprops rcommon -s empty -v empty