diff --git a/src/BOPAlgo/BOPAlgo_Builder_2.cxx b/src/BOPAlgo/BOPAlgo_Builder_2.cxx
index 210dab9d06..157b1fd30c 100644
--- a/src/BOPAlgo/BOPAlgo_Builder_2.cxx
+++ b/src/BOPAlgo/BOPAlgo_Builder_2.cxx
@@ -116,33 +116,13 @@ class BOPAlgo_PairOfShapeBoolean : public BOPAlgo_Algo {
   Handle(IntTools_Context) myContext;
 };
 //
-typedef NCollection_Vector<BOPAlgo_PairOfShapeBoolean> \
-  BOPAlgo_VectorOfPairOfShapeBoolean;
-//
-typedef BOPTools_ContextFunctor 
-  <BOPAlgo_PairOfShapeBoolean,
-  BOPAlgo_VectorOfPairOfShapeBoolean,
-  Handle(IntTools_Context), 
-  IntTools_Context> BOPAlgo_BuilderSDFaceFunctor;
-//
-typedef BOPTools_ContextCnt 
-  <BOPAlgo_BuilderSDFaceFunctor,
-  BOPAlgo_VectorOfPairOfShapeBoolean,
-  Handle(IntTools_Context)> BOPAlgo_BuilderSDFaceCnt;
-//
+typedef NCollection_Vector<BOPAlgo_PairOfShapeBoolean> BOPAlgo_VectorOfPairOfShapeBoolean;
+
 //=======================================================================
 // BuilderFace
 //
 typedef NCollection_Vector<BOPAlgo_BuilderFace> BOPAlgo_VectorOfBuilderFace;
-//
-typedef BOPTools_Functor 
-  <BOPAlgo_BuilderFace,
-  BOPAlgo_VectorOfBuilderFace> BOPAlgo_BuilderFaceFunctor;
-//
-typedef BOPTools_Cnt 
-  <BOPAlgo_BuilderFaceFunctor,
-  BOPAlgo_VectorOfBuilderFace> BOPAlgo_BuilderFaceCnt;
-//
+
 //=======================================================================
 //class    : BOPAlgo_VFI
 //purpose  : 
@@ -205,18 +185,7 @@ class BOPAlgo_VFI : public BOPAlgo_Algo {
 };
 //
 typedef NCollection_Vector<BOPAlgo_VFI> BOPAlgo_VectorOfVFI; 
-//
-typedef BOPTools_ContextFunctor 
-  <BOPAlgo_VFI,
-  BOPAlgo_VectorOfVFI,
-  Handle(IntTools_Context), 
-  IntTools_Context> BOPAlgo_VFIFunctor;
-//
-typedef BOPTools_ContextCnt 
-  <BOPAlgo_VFIFunctor,
-  BOPAlgo_VectorOfVFI,
-  Handle(IntTools_Context)> BOPAlgo_VFICnt;
-//
+
 //=======================================================================
 //function : FillImagesFaces
 //purpose  : 
@@ -474,7 +443,7 @@ void BOPAlgo_Builder::BuildSplitFaces()
   }// for (i=0; i<aNbS; ++i) {
   //
   //===================================================
-  BOPAlgo_BuilderFaceCnt::Perform(myRunParallel, aVBF);
+  BOPTools_Parallel::Perform (myRunParallel, aVBF);
   //===================================================
   //
   Standard_Integer aNbBF = aVBF.Length();
@@ -663,7 +632,7 @@ void BOPAlgo_Builder::FillSameDomainFaces()
 
   //================================================================
   // Perform analysis
-  BOPAlgo_BuilderSDFaceCnt::Perform(myRunParallel, aVPSB, myContext);
+  BOPTools_Parallel::Perform (myRunParallel, aVPSB, myContext);
   //================================================================
 
   NCollection_List<TopTools_ListOfShape> aMBlocks(aAllocator);
@@ -816,7 +785,7 @@ void BOPAlgo_Builder::FillInternalVertices()
 
   // Perform classification
   //================================================================
-  BOPAlgo_VFICnt::Perform(myRunParallel, aVVFI, myContext);
+  BOPTools_Parallel::Perform (myRunParallel, aVVFI, myContext);
   //================================================================
 
   Standard_Integer aNbVFI = aVVFI.Length();
diff --git a/src/BOPAlgo/BOPAlgo_Builder_3.cxx b/src/BOPAlgo/BOPAlgo_Builder_3.cxx
index 2896c4cf9a..52aac55d00 100644
--- a/src/BOPAlgo/BOPAlgo_Builder_3.cxx
+++ b/src/BOPAlgo/BOPAlgo_Builder_3.cxx
@@ -341,13 +341,6 @@ private:
 
 // Vector of Solid Builders
 typedef NCollection_Vector<BOPAlgo_SplitSolid> BOPAlgo_VectorOfBuilderSolid;
-// Functors to split solids
-typedef BOPTools_Functor<BOPAlgo_SplitSolid,
-                       BOPAlgo_VectorOfBuilderSolid> BOPAlgo_BuilderSolidFunctor;
-//
-typedef BOPTools_Cnt<BOPAlgo_BuilderSolidFunctor,
-                   BOPAlgo_VectorOfBuilderSolid> BOPAlgo_BuilderSolidCnt;
-//=======================================================================
 
 //=======================================================================
 //function : BuildSplitSolids
@@ -447,7 +440,7 @@ void BOPAlgo_Builder::BuildSplitSolids(TopTools_DataMapOfShapeShape& theDraftSol
   aNbBS=aVBS.Length();
   //
   //===================================================
-  BOPAlgo_BuilderSolidCnt::Perform(myRunParallel, aVBS);
+  BOPTools_Parallel::Perform (myRunParallel, aVBS);
   //===================================================
   //
   for (k = 0; k < aNbBS; ++k)
diff --git a/src/BOPAlgo/BOPAlgo_CheckerSI.cxx b/src/BOPAlgo/BOPAlgo_CheckerSI.cxx
index 1f6dad63fd..3a34b9b2dd 100644
--- a/src/BOPAlgo/BOPAlgo_CheckerSI.cxx
+++ b/src/BOPAlgo/BOPAlgo_CheckerSI.cxx
@@ -102,17 +102,7 @@ class BOPAlgo_FaceSelfIntersect :
 
 //=======================================================================
 
-typedef NCollection_Vector
-  <BOPAlgo_FaceSelfIntersect> BOPAlgo_VectorOfFaceSelfIntersect; 
-//
-typedef BOPTools_Functor 
-  <BOPAlgo_FaceSelfIntersect,
-  BOPAlgo_VectorOfFaceSelfIntersect> BOPAlgo_FaceSelfIntersectFunctor;
-//
-typedef BOPTools_Cnt 
-  <BOPAlgo_FaceSelfIntersectFunctor,
-  BOPAlgo_VectorOfFaceSelfIntersect> BOPAlgo_FaceSelfIntersectCnt;
-
+typedef NCollection_Vector<BOPAlgo_FaceSelfIntersect> BOPAlgo_VectorOfFaceSelfIntersect;
 
 //=======================================================================
 //function : 
@@ -447,7 +437,7 @@ void BOPAlgo_CheckerSI::CheckFaceSelfIntersection()
   
   Standard_Integer aNbFace = aVFace.Length();
   //======================================================
-  BOPAlgo_FaceSelfIntersectCnt::Perform(myRunParallel, aVFace);
+  BOPTools_Parallel::Perform (myRunParallel, aVFace);
   //======================================================
   //
   for (Standard_Integer k = 0; k < aNbFace; k++)
diff --git a/src/BOPAlgo/BOPAlgo_CheckerSI_1.cxx b/src/BOPAlgo/BOPAlgo_CheckerSI_1.cxx
index edac5d9cf8..dc9b8c6f90 100644
--- a/src/BOPAlgo/BOPAlgo_CheckerSI_1.cxx
+++ b/src/BOPAlgo/BOPAlgo_CheckerSI_1.cxx
@@ -115,19 +115,8 @@ class BOPAlgo_VertexSolid  {
   Handle(IntTools_Context) myContext;
 };
 //=======================================================================
-typedef NCollection_Vector
-  <BOPAlgo_VertexSolid> BOPAlgo_VectorOfVertexSolid; 
-//
-typedef BOPTools_ContextFunctor 
-  <BOPAlgo_VertexSolid,
-  BOPAlgo_VectorOfVertexSolid,
-  Handle(IntTools_Context), 
-  IntTools_Context> BOPAlgo_VertexSolidFunctor;
-//
-typedef BOPTools_ContextCnt 
-  <BOPAlgo_VertexSolidFunctor,
-  BOPAlgo_VectorOfVertexSolid,
-  Handle(IntTools_Context)> BOPAlgo_VertexSolidCnt;
+typedef NCollection_Vector<BOPAlgo_VertexSolid> BOPAlgo_VectorOfVertexSolid;
+
 /////////////////////////////////////////////////////////////////////////
 //=======================================================================
 //class    : BOPAlgo_ShapeSolid
@@ -185,17 +174,8 @@ class BOPAlgo_ShapeSolid  {
   BOPDS_DS* myDS;
 };
 //=======================================================================
-typedef NCollection_Vector
-  <BOPAlgo_ShapeSolid> BOPAlgo_VectorOfShapeSolid; 
-//
-typedef BOPTools_Functor 
-  <BOPAlgo_ShapeSolid,
-  BOPAlgo_VectorOfShapeSolid> BOPAlgo_ShapeSolidFunctor;
-//
-typedef BOPTools_Cnt 
-  <BOPAlgo_ShapeSolidFunctor,
-  BOPAlgo_VectorOfShapeSolid> BOPAlgo_ShapeSolidCnt;
-//
+typedef NCollection_Vector<BOPAlgo_ShapeSolid> BOPAlgo_VectorOfShapeSolid;
+
 /////////////////////////////////////////////////////////////////////////
 //=======================================================================
 //class    : BOPAlgo_SolidSolid
@@ -225,18 +205,7 @@ class BOPAlgo_SolidSolid : public  BOPAlgo_ShapeSolid {
   };
 };
 //=======================================================================
-typedef NCollection_Vector
-  <BOPAlgo_SolidSolid> BOPAlgo_VectorOfSolidSolid; 
-//
-typedef BOPTools_Functor 
-  <BOPAlgo_SolidSolid,
-  BOPAlgo_VectorOfSolidSolid> BOPAlgo_SolidSolidFunctor;
-//
-typedef BOPTools_Cnt 
-  <BOPAlgo_SolidSolidFunctor,
-  BOPAlgo_VectorOfSolidSolid> BOPAlgo_SolidSolidCnt;
-//
-/////////////////////////////////////////////////////////////////////////
+typedef NCollection_Vector<BOPAlgo_SolidSolid> BOPAlgo_VectorOfSolidSolid;
 
 //=======================================================================
 //function : PerformVZ
@@ -286,7 +255,7 @@ void BOPAlgo_CheckerSI::PerformVZ()
   //
   aNbVVS=aVVS.Length();
   //=============================================================
-  BOPAlgo_VertexSolidCnt::Perform(myRunParallel, aVVS, myContext);
+  BOPTools_Parallel::Perform (myRunParallel, aVVS, myContext);
   //=============================================================
   for (k=0; k < aNbVVS; ++k) {
     const BOPAlgo_VertexSolid& aVertexSolid=aVVS(k);
@@ -344,7 +313,7 @@ void BOPAlgo_CheckerSI::PerformZZ()
   //
   aNbSolidSolid=aVSolidSolid.Length();
   //======================================================
-  BOPAlgo_SolidSolidCnt::Perform(myRunParallel, aVSolidSolid);
+  BOPTools_Parallel::Perform (myRunParallel, aVSolidSolid);
   //======================================================
   //
   BOPDS_VectorOfInterfZZ& aZZs=myDS->InterfZZ();
@@ -391,7 +360,7 @@ void BOPAlgo_CheckerSI::PerformSZ(const TopAbs_ShapeEnum aTS)
   //
   aNbShapeSolid=aVShapeSolid.Length();
   //======================================================
-  BOPAlgo_ShapeSolidCnt::Perform(myRunParallel, aVShapeSolid);
+  BOPTools_Parallel::Perform (myRunParallel, aVShapeSolid);
   //======================================================
   //
   BOPDS_VectorOfInterfEZ& aEZs=myDS->InterfEZ();
diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_2.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_2.cxx
index c9d101c3ee..13ec495cf2 100644
--- a/src/BOPAlgo/BOPAlgo_PaveFiller_2.cxx
+++ b/src/BOPAlgo/BOPAlgo_PaveFiller_2.cxx
@@ -136,20 +136,8 @@ class BOPAlgo_VertexEdge : public BOPAlgo_Algo {
   Handle(BOPDS_PaveBlock) myPB;
 };
 //=======================================================================
-typedef NCollection_Vector
-  <BOPAlgo_VertexEdge> BOPAlgo_VectorOfVertexEdge; 
-//
-typedef BOPTools_ContextFunctor 
-  <BOPAlgo_VertexEdge,
-  BOPAlgo_VectorOfVertexEdge,
-  Handle(IntTools_Context), 
-  IntTools_Context> BOPAlgo_VertexEdgeFunctor;
-//
-typedef BOPTools_ContextCnt 
-  <BOPAlgo_VertexEdgeFunctor,
-  BOPAlgo_VectorOfVertexEdge,
-  Handle(IntTools_Context)> BOPAlgo_VertexEdgeCnt;
-//
+typedef NCollection_Vector<BOPAlgo_VertexEdge> BOPAlgo_VectorOfVertexEdge;
+
 //=======================================================================
 // function: PerformVE
 // purpose: 
@@ -271,7 +259,7 @@ void BOPAlgo_PaveFiller::IntersectVE
   //
   // Perform intersection
   //=============================================================
-  BOPAlgo_VertexEdgeCnt::Perform(myRunParallel, aVVE, myContext);
+  BOPTools_Parallel::Perform (myRunParallel, aVVE, myContext);
   //=============================================================
   //
   // Keep the modified edges for further update
diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx
index f653b783bc..4171cc90d7 100644
--- a/src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx
+++ b/src/BOPAlgo/BOPAlgo_PaveFiller_3.cxx
@@ -114,18 +114,8 @@ class BOPAlgo_EdgeEdge :
 };
 //
 //=======================================================================
-typedef NCollection_Vector
-  <BOPAlgo_EdgeEdge> BOPAlgo_VectorOfEdgeEdge; 
-//
-typedef BOPTools_Functor 
-  <BOPAlgo_EdgeEdge,
-  BOPAlgo_VectorOfEdgeEdge> BOPAlgo_EdgeEdgeFunctor;
-//
-typedef BOPTools_Cnt 
-  <BOPAlgo_EdgeEdgeFunctor,
-  BOPAlgo_VectorOfEdgeEdge> BOPAlgo_EdgeEdgeCnt;
-//
-/////////////////////////////////////////////////////////////////////////
+typedef NCollection_Vector<BOPAlgo_EdgeEdge> BOPAlgo_VectorOfEdgeEdge;
+
 //=======================================================================
 // function: PerformEE
 // purpose: 
@@ -234,7 +224,7 @@ void BOPAlgo_PaveFiller::PerformEE()
   //
   aNbEdgeEdge=aVEdgeEdge.Length();
   //======================================================
-  BOPAlgo_EdgeEdgeCnt::Perform(myRunParallel, aVEdgeEdge);
+  BOPTools_Parallel::Perform (myRunParallel, aVEdgeEdge);
   //======================================================
   //
   for (k = 0; k < aNbEdgeEdge; ++k) {
@@ -1050,7 +1040,7 @@ void BOPAlgo_PaveFiller::ForceInterfEE()
   anAlloc->Reset();
 
   // Perform intersection of the found pairs
-  BOPAlgo_EdgeEdgeCnt::Perform(myRunParallel, aVEdgeEdge);
+  BOPTools_Parallel::Perform (myRunParallel, aVEdgeEdge);
 
   BOPDS_VectorOfInterfEE& aEEs = myDS->InterfEE();
   if (aEEs.IsEmpty())
diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_4.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_4.cxx
index 34f1e51553..2e8fd76989 100644
--- a/src/BOPAlgo/BOPAlgo_PaveFiller_4.cxx
+++ b/src/BOPAlgo/BOPAlgo_PaveFiller_4.cxx
@@ -132,20 +132,8 @@ class BOPAlgo_VertexFace : public BOPAlgo_Algo {
   Handle(IntTools_Context) myContext;
 };
 //=======================================================================
-typedef NCollection_Vector<BOPAlgo_VertexFace>
-  BOPAlgo_VectorOfVertexFace; 
-//
-typedef BOPTools_ContextFunctor 
-  <BOPAlgo_VertexFace,
-  BOPAlgo_VectorOfVertexFace,
-  Handle(IntTools_Context), 
-  IntTools_Context> BOPAlgo_VertexFaceFunctor;
-//
-typedef BOPTools_ContextCnt 
-  <BOPAlgo_VertexFaceFunctor,
-  BOPAlgo_VectorOfVertexFace,
-  Handle(IntTools_Context)> BOPAlgo_VertexFaceCnt;
-//
+typedef NCollection_Vector<BOPAlgo_VertexFace> BOPAlgo_VectorOfVertexFace;
+
 //=======================================================================
 // function: PerformVF
 // purpose: 
@@ -234,7 +222,7 @@ void BOPAlgo_PaveFiller::PerformVF()
   //
   aNbVF=aVVF.Length();
   //================================================================
-  BOPAlgo_VertexFaceCnt::Perform(myRunParallel, aVVF, myContext);
+  BOPTools_Parallel::Perform (myRunParallel, aVVF, myContext);
   //================================================================
   //
   for (k=0; k < aNbVF; ++k) {
diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx
index bdbc8f6303..5a8aa81184 100644
--- a/src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx
+++ b/src/BOPAlgo/BOPAlgo_PaveFiller_5.cxx
@@ -128,18 +128,7 @@ class BOPAlgo_EdgeFace :
 //
 //=======================================================================
 typedef NCollection_Vector<BOPAlgo_EdgeFace> BOPAlgo_VectorOfEdgeFace; 
-//
-typedef BOPTools_ContextFunctor 
-  <BOPAlgo_EdgeFace,
-  BOPAlgo_VectorOfEdgeFace,
-  Handle(IntTools_Context), 
-  IntTools_Context> BOPAlgo_EdgeFaceFunctor;
-//
-typedef BOPTools_ContextCnt 
-  <BOPAlgo_EdgeFaceFunctor,
-  BOPAlgo_VectorOfEdgeFace,
-  Handle(IntTools_Context)> BOPAlgo_EdgeFaceCnt;
-//
+
 //=======================================================================
 //function : PerformEF
 //purpose  : 
@@ -265,7 +254,7 @@ void BOPAlgo_PaveFiller::PerformEF()
   //
   aNbEdgeFace=aVEdgeFace.Length();
   //=================================================================
-  BOPAlgo_EdgeFaceCnt::Perform(myRunParallel, aVEdgeFace, myContext);
+  BOPTools_Parallel::Perform (myRunParallel, aVEdgeFace, myContext);
   //=================================================================
   //
   for (k=0; k < aNbEdgeFace; ++k) {
@@ -972,7 +961,7 @@ void BOPAlgo_PaveFiller::ForceInterfEF(const BOPDS_IndexedMapOfPaveBlock& theMPB
   anAlloc->Reset();
 
   // Perform intersection of the found pairs
-  BOPAlgo_EdgeFaceCnt::Perform(myRunParallel, aVEdgeFace, myContext);
+  BOPTools_Parallel::Perform (myRunParallel, aVEdgeFace, myContext);
 
   BOPDS_VectorOfInterfEF& aEFs = myDS->InterfEF();
   if (theAddInterf && aEFs.IsEmpty())
diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx
index 116a24dad3..7cfdeeab36 100644
--- a/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx
+++ b/src/BOPAlgo/BOPAlgo_PaveFiller_6.cxx
@@ -165,16 +165,8 @@ class BOPAlgo_FaceFace :
 };
 //
 //=======================================================================
-typedef NCollection_Vector
-  <BOPAlgo_FaceFace> BOPAlgo_VectorOfFaceFace; 
-//
-typedef BOPTools_Functor 
-  <BOPAlgo_FaceFace,
-  BOPAlgo_VectorOfFaceFace> BOPAlgo_FaceFaceFunctor;
-//
-typedef BOPTools_Cnt 
-  <BOPAlgo_FaceFaceFunctor,
-  BOPAlgo_VectorOfFaceFace> BOPAlgo_FaceFaceCnt;
+typedef NCollection_Vector<BOPAlgo_FaceFace> BOPAlgo_VectorOfFaceFace;
+
 /////////////////////////////////////////////////////////////////////////
 //=======================================================================
 //function : PerformFF
@@ -287,7 +279,7 @@ void BOPAlgo_PaveFiller::PerformFF()
   //
   //======================================================
   // Perform intersection
-  BOPAlgo_FaceFaceCnt::Perform(myRunParallel, aVFaceFace);
+  BOPTools_Parallel::Perform (myRunParallel, aVFaceFace);
   //======================================================
   // Treatment of the results
   Standard_Integer k, aNbFaceFace = aVFaceFace.Length();
diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_7.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_7.cxx
index 727fc8be40..dbbb975233 100644
--- a/src/BOPAlgo/BOPAlgo_PaveFiller_7.cxx
+++ b/src/BOPAlgo/BOPAlgo_PaveFiller_7.cxx
@@ -169,20 +169,8 @@ class BOPAlgo_SplitEdge : public BOPAlgo_Algo  {
 };
 //
 //=======================================================================
-typedef NCollection_Vector
-  <BOPAlgo_SplitEdge> BOPAlgo_VectorOfSplitEdge; 
-//
-typedef BOPTools_ContextFunctor
-  <BOPAlgo_SplitEdge,
-  BOPAlgo_VectorOfSplitEdge,
-  Handle(IntTools_Context),
-  IntTools_Context> BOPAlgo_SplitEdgeFunctor;
-//
-typedef BOPTools_ContextCnt
-  <BOPAlgo_SplitEdgeFunctor,
-  BOPAlgo_VectorOfSplitEdge,
-  Handle(IntTools_Context)> BOPAlgo_SplitEdgeCnt;
-//
+typedef NCollection_Vector<BOPAlgo_SplitEdge> BOPAlgo_VectorOfSplitEdge;
+
 //=======================================================================
 //class    : BOPAlgo_MPC
 //purpose  : 
@@ -333,20 +321,8 @@ class BOPAlgo_MPC : public BOPAlgo_Algo  {
 };
 //
 //=======================================================================
-typedef NCollection_Vector
-  <BOPAlgo_MPC> BOPAlgo_VectorOfMPC; 
-//
-typedef BOPTools_ContextFunctor 
-  <BOPAlgo_MPC,
-  BOPAlgo_VectorOfMPC,
-  Handle(IntTools_Context), 
-  IntTools_Context> BOPAlgo_MPCFunctor;
-//
-typedef BOPTools_ContextCnt 
-  <BOPAlgo_MPCFunctor,
-  BOPAlgo_VectorOfMPC,
-  Handle(IntTools_Context)> BOPAlgo_MPCCnt;
-//
+typedef NCollection_Vector<BOPAlgo_MPC> BOPAlgo_VectorOfMPC;
+
 //=======================================================================
 //class    : BOPAlgo_BPC
 //purpose  : 
@@ -391,18 +367,8 @@ class BOPAlgo_BPC {
   Standard_Boolean myToUpdate;
 };
 //=======================================================================
-typedef NCollection_Vector
-  <BOPAlgo_BPC> BOPAlgo_VectorOfBPC; 
-//
-typedef BOPTools_Functor 
-  <BOPAlgo_BPC,
-  BOPAlgo_VectorOfBPC> BOPAlgo_BPCFunctor;
-//
-typedef BOPTools_Cnt 
-  <BOPAlgo_BPCFunctor,
-  BOPAlgo_VectorOfBPC> BOPAlgo_BPCCnt;
-//
-//
+typedef NCollection_Vector<BOPAlgo_BPC> BOPAlgo_VectorOfBPC;
+
 //=======================================================================
 // function: MakeSplitEdges
 // purpose: 
@@ -524,7 +490,7 @@ void BOPAlgo_PaveFiller::MakeSplitEdges()
   //
   aNbVBSE=aVBSE.Length();
   //======================================================
-  BOPAlgo_SplitEdgeCnt::Perform(myRunParallel, aVBSE, myContext);
+  BOPTools_Parallel::Perform (myRunParallel, aVBSE, myContext);
   //======================================================
   //
   for (k=0; k < aNbVBSE; ++k) {
@@ -753,7 +719,7 @@ void BOPAlgo_PaveFiller::MakePCurves()
   }//if (bPCurveOnS1 || bPCurveOnS2 ) {
   //
   //======================================================
-  BOPAlgo_MPCCnt::Perform(myRunParallel, aVMPC, myContext);
+  BOPTools_Parallel::Perform (myRunParallel, aVMPC, myContext);
   //======================================================
 
   // Add warnings of the failed projections and update edges with new pcurves
@@ -876,7 +842,7 @@ void BOPAlgo_PaveFiller::Prepare()
   }
   //
   //======================================================
-  BOPAlgo_BPCCnt::Perform(myRunParallel, aVBPC);
+  BOPTools_Parallel::Perform (myRunParallel, aVBPC);
   //======================================================
 
   // pcurves are built, and now update edges
diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_9.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_9.cxx
index f55902a129..107822398e 100644
--- a/src/BOPAlgo/BOPAlgo_PaveFiller_9.cxx
+++ b/src/BOPAlgo/BOPAlgo_PaveFiller_9.cxx
@@ -63,20 +63,8 @@ class BOPAlgo_ShrunkRange : public IntTools_ShrunkRange {
 };
 //
 //=======================================================================
-typedef NCollection_Vector
-  <BOPAlgo_ShrunkRange> BOPAlgo_VectorOfShrunkRange; 
-//
-typedef BOPTools_ContextFunctor 
-  <BOPAlgo_ShrunkRange,
-  BOPAlgo_VectorOfShrunkRange,
-  Handle(IntTools_Context), 
-  IntTools_Context> BOPAlgo_ShrunkRangeFunctor;
-//
-typedef BOPTools_ContextCnt 
-  <BOPAlgo_ShrunkRangeFunctor,
-  BOPAlgo_VectorOfShrunkRange,
-  Handle(IntTools_Context)> BOPAlgo_ShrunkRangeCnt;
-//
+typedef NCollection_Vector<BOPAlgo_ShrunkRange> BOPAlgo_VectorOfShrunkRange;
+
 //=======================================================================
 // function: FillShrunkData
 // purpose: 
@@ -141,7 +129,7 @@ void BOPAlgo_PaveFiller::FillShrunkData(const TopAbs_ShapeEnum aType1,
   //
   aNbVSD=aVSD.Length();
   //=============================================================
-  BOPAlgo_ShrunkRangeCnt::Perform(myRunParallel, aVSD, myContext);
+  BOPTools_Parallel::Perform (myRunParallel, aVSD, myContext);
   //=============================================================
   //
   for (k=0; k < aNbVSD; ++k) {
diff --git a/src/BOPAlgo/BOPAlgo_RemoveFeatures.cxx b/src/BOPAlgo/BOPAlgo_RemoveFeatures.cxx
index 17e18bde46..066d2b0a06 100644
--- a/src/BOPAlgo/BOPAlgo_RemoveFeatures.cxx
+++ b/src/BOPAlgo/BOPAlgo_RemoveFeatures.cxx
@@ -716,12 +716,6 @@ private: //! @name Fields
 
 typedef NCollection_Vector<FillGap> VectorOfFillGap;
 
-typedef BOPTools_Functor <FillGap, VectorOfFillGap> FillGapFunctor;
-
-typedef BOPTools_Cnt <FillGapFunctor, VectorOfFillGap> FillGapCnt;
-
-//=======================================================================
-
 //=======================================================================
 // function: RemoveFeatures
 // purpose: Remove features by filling the gaps by extension of the
@@ -762,7 +756,7 @@ void BOPAlgo_RemoveFeatures::RemoveFeatures()
   }
 
   // Perform the reconstruction of the adjacent faces
-  FillGapCnt::Perform(myRunParallel, aVFG);
+  BOPTools_Parallel::Perform (myRunParallel, aVFG);
 
   // Even if the history is not requested, it is necessary to track:
   // - The solids modification after each feature removal to find
diff --git a/src/BOPAlgo/BOPAlgo_ShellSplitter.cxx b/src/BOPAlgo/BOPAlgo_ShellSplitter.cxx
index 06a86b0d96..631bb61a59 100644
--- a/src/BOPAlgo/BOPAlgo_ShellSplitter.cxx
+++ b/src/BOPAlgo/BOPAlgo_ShellSplitter.cxx
@@ -71,17 +71,8 @@ class BOPAlgo_CBK {
   BOPTools_ConnexityBlock *myPCB;
 };
 //=======================================================================
-typedef NCollection_Vector
-  <BOPAlgo_CBK> BOPAlgo_VectorOfCBK; 
-//
-typedef BOPTools_Functor 
-  <BOPAlgo_CBK,
-  BOPAlgo_VectorOfCBK> BOPAlgo_CBKFunctor;
-//
-typedef BOPTools_Cnt 
-  <BOPAlgo_CBKFunctor,
-  BOPAlgo_VectorOfCBK> BOPAlgo_CBKCnt;
-//
+typedef NCollection_Vector<BOPAlgo_CBK> BOPAlgo_VectorOfCBK;
+
 //=======================================================================
 //function : 
 //purpose  : 
@@ -560,7 +551,7 @@ void BOPAlgo_ShellSplitter::MakeShells()
   //
   aNbVCBK=aVCBK.Length();
   //===================================================
-  BOPAlgo_CBKCnt::Perform(myRunParallel, aVCBK);
+  BOPTools_Parallel::Perform (myRunParallel, aVCBK);
   //===================================================
   for (k=0; k<aNbVCBK; ++k) {
     BOPAlgo_CBK& aCBK=aVCBK(k);
diff --git a/src/BOPAlgo/BOPAlgo_Tools.cxx b/src/BOPAlgo/BOPAlgo_Tools.cxx
index 1d0e217834..fa93d31291 100644
--- a/src/BOPAlgo/BOPAlgo_Tools.cxx
+++ b/src/BOPAlgo/BOPAlgo_Tools.cxx
@@ -958,16 +958,8 @@ Standard_Boolean FindPlane(const TopoDS_Shape& theWire,
 //purpose  : 
 //=======================================================================
 class BOPAlgo_TNV;
-typedef NCollection_Vector
-  <BOPAlgo_TNV> BOPAlgo_VectorOfTNV;
-//
-typedef BOPTools_Functor
-  <BOPAlgo_TNV,
-  BOPAlgo_VectorOfTNV> BOPAlgo_TNVFunctor;
-//
-typedef BOPTools_Cnt
-  <BOPAlgo_TNVFunctor,
-  BOPAlgo_VectorOfTNV> BOPAlgo_TNVCnt;
+typedef NCollection_Vector<BOPAlgo_TNV> BOPAlgo_VectorOfTNV;
+
 //=======================================================================
 class BOPAlgo_TNV : public BOPTools_BoxBndTreeSelector{
  public:
@@ -1090,7 +1082,7 @@ void BOPAlgo_Tools::IntersectVertices(const TopTools_IndexedDataMapOfShapeReal&
   aTreeFiller.Fill();
   //
   // Perform intersection
-  BOPAlgo_TNVCnt::Perform(theRunParallel, aVTNV);
+  BOPTools_Parallel::Perform (theRunParallel, aVTNV);
   //
   // Fence map
   TColStd_MapOfInteger aMFence;
@@ -1529,16 +1521,6 @@ void BOPAlgo_FillIn3DParts::MakeConnexityBlock(const TopoDS_Face& theFStart,
 // Vector of solid classifiers
 typedef NCollection_Vector<BOPAlgo_FillIn3DParts> BOPAlgo_VectorOfFillIn3DParts;
 
-// Functors to perform classification
-typedef BOPTools_ContextFunctor<BOPAlgo_FillIn3DParts,
-                                BOPAlgo_VectorOfFillIn3DParts,
-                                Handle(IntTools_Context),
-                                IntTools_Context> BOPAlgo_FillIn3DPartsFunctor;
-
-typedef BOPTools_ContextCnt<BOPAlgo_FillIn3DPartsFunctor,
-                            BOPAlgo_VectorOfFillIn3DParts,
-                            Handle(IntTools_Context)> BOPAlgo_FillIn3DPartsCnt;
-
 //=======================================================================
 //function : ClassifyFaces
 //purpose  :
@@ -1629,7 +1611,7 @@ void BOPAlgo_Tools::ClassifyFaces(const TopTools_ListOfShape& theFaces,
 
   // Perform classification
   //================================================================
-  BOPAlgo_FillIn3DPartsCnt::Perform(theRunParallel, aVFIP, theContext);
+  BOPTools_Parallel::Perform (theRunParallel, aVFIP, theContext);
   //================================================================
 
   // Analyze the results and fill the resulting map
diff --git a/src/BOPAlgo/BOPAlgo_WireSplitter.cxx b/src/BOPAlgo/BOPAlgo_WireSplitter.cxx
index c251a9d98f..9302342c52 100644
--- a/src/BOPAlgo/BOPAlgo_WireSplitter.cxx
+++ b/src/BOPAlgo/BOPAlgo_WireSplitter.cxx
@@ -169,19 +169,7 @@ protected:
   Handle(IntTools_Context) myContext;
 };
 
-typedef NCollection_Vector<BOPAlgo_WS_ConnexityBlock> \
-  BOPAlgo_VectorOfConnexityBlock;
-//
-typedef BOPTools_ContextFunctor
-  <BOPAlgo_WS_ConnexityBlock,
-  BOPAlgo_VectorOfConnexityBlock,
-  Handle(IntTools_Context),
-  IntTools_Context> BOPAlgo_SplitBlockFunctor;
-//
-typedef BOPTools_ContextCnt
-  <BOPAlgo_SplitBlockFunctor,
-  BOPAlgo_VectorOfConnexityBlock,
-  Handle(IntTools_Context)> BOPAlgo_SplitBlockCnt;
+typedef NCollection_Vector<BOPAlgo_WS_ConnexityBlock> BOPAlgo_VectorOfConnexityBlock;
 
 //=======================================================================
 //function : MakeWires
@@ -214,7 +202,7 @@ void BOPAlgo_WireSplitter::MakeWires()
     }
   }
   //===================================================
-  BOPAlgo_SplitBlockCnt::Perform(myRunParallel, aVCB, myContext);
+  BOPTools_Parallel::Perform (myRunParallel, aVCB, myContext);
   //===================================================
   aNbVCB=aVCB.Length();
   for (k=0; k<aNbVCB; ++k) {
diff --git a/src/BOPDS/BOPDS_Iterator.cxx b/src/BOPDS/BOPDS_Iterator.cxx
index af4124b451..03228384c0 100644
--- a/src/BOPDS/BOPDS_Iterator.cxx
+++ b/src/BOPDS/BOPDS_Iterator.cxx
@@ -73,9 +73,7 @@ class BOPDS_TSR : public BOPTools_BoxBndTreeSelector{
 };
 //
 //=======================================================================
-typedef NCollection_Vector <BOPDS_TSR> BOPDS_VectorOfTSR; 
-typedef BOPTools_Functor <BOPDS_TSR,BOPDS_VectorOfTSR> BOPDS_TSRFunctor;
-typedef BOPTools_Cnt <BOPDS_TSRFunctor, BOPDS_VectorOfTSR> BOPDS_TSRCnt;
+typedef NCollection_Vector<BOPDS_TSR> BOPDS_VectorOfTSR;
 /////////////////////////////////////////////////////////////////////////
 
 
@@ -323,7 +321,7 @@ void BOPDS_Iterator::Intersect(const Handle(IntTools_Context)& theCtx,
   aTreeFiller.Fill();
   //
   //===========================================
-  BOPDS_TSRCnt::Perform(myRunParallel, aVTSR);
+  BOPTools_Parallel::Perform (myRunParallel, aVTSR);
   //===========================================
   //
   BOPDS_MapOfPair aMPFence;
@@ -454,7 +452,7 @@ void BOPDS_Iterator::IntersectExt(const TColStd_MapOfInteger& theIndices)
   }
 
   // Perform selection
-  BOPDS_TSRCnt::Perform(myRunParallel, aVTSR);
+  BOPTools_Parallel::Perform (myRunParallel, aVTSR);
 
   // Treat selections
 
diff --git a/src/BOPTools/BOPTools_AlgoTools_1.cxx b/src/BOPTools/BOPTools_AlgoTools_1.cxx
index 8425994b37..5832bfa90a 100644
--- a/src/BOPTools/BOPTools_AlgoTools_1.cxx
+++ b/src/BOPTools/BOPTools_AlgoTools_1.cxx
@@ -159,15 +159,7 @@ class BOPTools_CPC {
 //
 //=======================================================================
 typedef NCollection_Vector<BOPTools_CPC> BOPTools_VectorOfCPC; 
-//
-typedef BOPTools_Functor 
-  <BOPTools_CPC,
-  BOPTools_VectorOfCPC> BOPTools_CPCFunctor;
-//
-typedef BOPTools_Cnt 
-  <BOPTools_CPCFunctor,
-  BOPTools_VectorOfCPC> BOPTools_CPCCnt;
-//
+
 //=======================================================================
 //class    : BOPTools_CWT
 //purpose  : 
@@ -199,15 +191,7 @@ class BOPTools_CWT {
 };
 //=======================================================================
 typedef NCollection_Vector<BOPTools_CWT> BOPTools_VectorOfCWT; 
-//
-typedef BOPTools_Functor 
-  <BOPTools_CWT,
-  BOPTools_VectorOfCWT> BOPTools_CWTFunctor;
-//
-typedef BOPTools_Cnt 
-  <BOPTools_CWTFunctor,
-  BOPTools_VectorOfCWT> BOPTools_CWTCnt;
-//
+
 //=======================================================================
 //class    : BOPTools_CDT
 //purpose  : 
@@ -250,15 +234,7 @@ class BOPTools_CDT {
 };
 //=======================================================================
 typedef NCollection_Vector<BOPTools_CDT> BOPTools_VectorOfCDT; 
-//
-typedef BOPTools_Functor 
-  <BOPTools_CDT,
-  BOPTools_VectorOfCDT> BOPTools_CDTFunctor;
-//
-typedef BOPTools_Cnt 
-  <BOPTools_CDTFunctor,
-  BOPTools_VectorOfCDT> BOPTools_CDTCnt;
-//
+
 //=======================================================================
 //class    : BOPTools_CVT
 //purpose  : 
@@ -291,15 +267,7 @@ class BOPTools_CVT {
 //
 //=======================================================================
 typedef NCollection_Vector<BOPTools_CVT> BOPTools_VectorOfCVT; 
-//
-typedef BOPTools_Functor 
-  <BOPTools_CVT,
-  BOPTools_VectorOfCVT> BOPTools_CVTFunctor;
-//
-typedef BOPTools_Cnt 
-  <BOPTools_CVTFunctor,
-  BOPTools_VectorOfCVT> BOPTools_CVTCnt;
-//
+
 //=======================================================================
 //class    : BOPTools_CET
 //purpose  : 
@@ -331,18 +299,7 @@ class BOPTools_CET {
 };
 //=======================================================================
 typedef NCollection_Vector<BOPTools_CET> BOPTools_VectorOfCET; 
-//
-typedef BOPTools_Functor 
-  <BOPTools_CET,
-  BOPTools_VectorOfCET> BOPTools_CETFunctor;
-//
-typedef BOPTools_Cnt 
-  <BOPTools_CETFunctor,
-  BOPTools_VectorOfCET> BOPTools_CETCnt;
-//
-//
-//=======================================================================
-  //
+
 //=======================================================================
 // Function : CorrectTolerances
 // purpose : 
@@ -380,7 +337,7 @@ void BOPTools_AlgoTools::CorrectPointOnCurve
   }
   //
   //======================================================
-  BOPTools_CPCCnt::Perform(bRunParallel, aVCPC);
+  BOPTools_Parallel::Perform (bRunParallel, aVCPC);
   //======================================================
 }
 //=======================================================================
@@ -418,9 +375,9 @@ void BOPTools_AlgoTools::CorrectCurveOnSurface
   }
   //
   //======================================================
-  BOPTools_CWTCnt::Perform(bRunParallel, aVCWT);
+  BOPTools_Parallel::Perform (bRunParallel, aVCWT);
   //======================================================
-  BOPTools_CDTCnt::Perform(bRunParallel, aVCDT);
+  BOPTools_Parallel::Perform (bRunParallel, aVCDT);
   //======================================================
 }
 //=======================================================================
@@ -445,7 +402,7 @@ void BOPTools_AlgoTools::CorrectShapeTolerances
   }
   //
   //======================================================
-  BOPTools_CVTCnt::Perform(bRunParallel, aVCVT);
+  BOPTools_Parallel::Perform (bRunParallel, aVCVT);
   //======================================================
   //
   aExp.Init(aShape, TopAbs_FACE);
@@ -457,7 +414,7 @@ void BOPTools_AlgoTools::CorrectShapeTolerances
   }
   //
   //======================================================
-  BOPTools_CETCnt::Perform(bRunParallel, aVCET);
+  BOPTools_Parallel::Perform (bRunParallel, aVCET);
   //======================================================
 }
 //
diff --git a/src/BOPTools/BOPTools_Parallel.hxx b/src/BOPTools/BOPTools_Parallel.hxx
index 0fddce5fbd..58e121bdef 100644
--- a/src/BOPTools/BOPTools_Parallel.hxx
+++ b/src/BOPTools/BOPTools_Parallel.hxx
@@ -18,158 +18,178 @@
 #include <Standard_Macro.hxx>
 #include <Standard_NotImplemented.hxx>
 #include <OSD_Parallel.hxx>
+#include <OSD_ThreadPool.hxx>
 #include <NCollection_DataMap.hxx>
 #include <Standard_Mutex.hxx>
 #include <OSD_Thread.hxx>
 
-//
-// 1. Implementation of Functors/Starters
-//
-// 1.1. Pure version
-//
-
-//=======================================================================
-//class    : BOPTools_Functor
-//purpose  : 
-//=======================================================================
-template <class TypeSolver, class TypeSolverVector>
-class BOPTools_Functor
+//! Implementation of Functors/Starters
+class BOPTools_Parallel
 {
-public:
-  //! Constructor.
-  explicit BOPTools_Functor(TypeSolverVector& theSolverVec) 
-  : mySolvers(theSolverVec) {}
-
-  //! Defines functor interface.
-  void operator() (const Standard_Integer theIndex) const
+  template<class TypeSolverVector>
+  class Functor
   {
-    TypeSolver& aSolver = mySolvers(theIndex);
-    aSolver.Perform();
-  }
+  public:
+    //! Constructor.
+    explicit Functor(TypeSolverVector& theSolverVec) : mySolvers (theSolverVec) {}
 
-private:
-  BOPTools_Functor(const BOPTools_Functor&);
-  BOPTools_Functor& operator= (const BOPTools_Functor&);
-
-private:
-  TypeSolverVector& mySolvers;
-};
-
-//=======================================================================
-//class    : BOPTools_Cnt
-//purpose  : 
-//=======================================================================
-template <class TypeFunctor, class TypeSolverVector>
-class BOPTools_Cnt
-{
-public:
-  static void Perform( const Standard_Boolean isRunParallel,
-                       TypeSolverVector&      theSolverVector )
-  {
-    TypeFunctor aFunctor(theSolverVector);
-    OSD_Parallel::For(0, theSolverVector.Length(), aFunctor, !isRunParallel);
-  }
-};
-
-//
-// 1.2. Context dependent version
-//
-
-//=======================================================================
-//class    : BOPTools_ContextFunctor
-//purpose  : 
-//=======================================================================
-template <class TypeSolver,  class TypeSolverVector,
-          class TypeContext, typename TN>
-class BOPTools_ContextFunctor
-{
-  //! Auxiliary thread ID  hasher.
-  struct Hasher
-  {
-    static Standard_Integer HashCode(const Standard_ThreadId theKey,
-                                     const Standard_Integer  Upper)
+    //! Defines functor interface.
+    void operator() (const Standard_Integer theIndex) const
     {
-      return ::HashCode((Standard_Size)theKey, Upper);
+      typename TypeSolverVector::value_type& aSolver = mySolvers[theIndex];
+      aSolver.Perform();
     }
 
-    static Standard_Boolean IsEqual(const Standard_ThreadId theKey1,
-                                    const Standard_ThreadId theKey2)
-    {
-      return theKey1 == theKey2;
-    }
+  private:
+    Functor(const Functor&);
+    Functor& operator= (const Functor&);
+
+  private:
+    TypeSolverVector& mySolvers;
   };
 
-  typedef NCollection_DataMap<Standard_ThreadId, TypeContext, Hasher> ContextMap;
-
-public:
-
-  //! Constructor
-  explicit BOPTools_ContextFunctor( TypeSolverVector& theVector )
-  : mySolverVector(theVector) {}
-
-  //! Binds main thread context
-  void SetContext( TypeContext& theContext )
+  //! Functor storing map of thread id -> algorithm context
+  template<class TypeSolverVector, class TypeContext>
+  class ContextFunctor
   {
-    myContexts.Bind(OSD_Thread::Current(), theContext);
-  }
-
-  //! Returns current thread context
-  TypeContext& GetThreadContext() const
-  {
-    const Standard_ThreadId aThreadID = OSD_Thread::Current();
-    if ( myContexts.IsBound(aThreadID) )
+    //! Auxiliary thread ID  hasher.
+    struct Hasher
     {
-      TypeContext& aContext = myContexts(aThreadID);
-      if ( aContext.IsNull() == Standard_False )
-        return aContext;
+      static Standard_Integer HashCode(const Standard_ThreadId theKey,
+                                       const Standard_Integer  Upper)
+      {
+        return ::HashCode((Standard_Size)theKey, Upper);
+      }
+
+      static Standard_Boolean IsEqual(const Standard_ThreadId theKey1,
+                                      const Standard_ThreadId theKey2)
+      {
+        return theKey1 == theKey2;
+      }
+    };
+
+  public:
+
+    //! Constructor
+    explicit ContextFunctor (TypeSolverVector& theVector) : mySolverVector(theVector) {}
+
+    //! Binds main thread context
+    void SetContext (const opencascade::handle<TypeContext>& theContext)
+    {
+      myContextMap.Bind (OSD_Thread::Current(), theContext);
     }
 
-    // Create new context
-    TypeContext aContext = new TN
-      ( NCollection_BaseAllocator::CommonBaseAllocator() );
+    //! Returns current thread context
+    const opencascade::handle<TypeContext>& GetThreadContext() const
+    {
+      const Standard_ThreadId aThreadID = OSD_Thread::Current();
+      if (const opencascade::handle<TypeContext>* aContextPtr = myContextMap.Seek (aThreadID))
+      {
+        if (!aContextPtr->IsNull())
+        {
+          return *aContextPtr;
+        }
+      }
 
-    Standard_Mutex::Sentry aLocker(myMutex);
-    myContexts.Bind(aThreadID, aContext);
+      // Create new context
+      opencascade::handle<TypeContext> aContext = new TypeContext (NCollection_BaseAllocator::CommonBaseAllocator());
 
-    return myContexts(aThreadID);
-  }
+      Standard_Mutex::Sentry aLocker (myMutex);
+      myContextMap.Bind (aThreadID, aContext);
+      return myContextMap (aThreadID);
+    }
 
-  //! Defines functor interface
-  void operator()( const Standard_Integer theIndex ) const
+    //! Defines functor interface
+    void operator()( const Standard_Integer theIndex ) const
+    {
+      const opencascade::handle<TypeContext>& aContext = GetThreadContext();
+      typename TypeSolverVector::value_type& aSolver = mySolverVector[theIndex];
+
+      aSolver.SetContext(aContext);
+      aSolver.Perform();
+    }
+
+  private:
+    ContextFunctor(const ContextFunctor&);
+    ContextFunctor& operator= (const ContextFunctor&);
+
+  private:
+    TypeSolverVector& mySolverVector;
+    mutable NCollection_DataMap<Standard_ThreadId, opencascade::handle<TypeContext>, Hasher> myContextMap;
+    mutable Standard_Mutex myMutex;
+  };
+
+  //! Functor storing array of algorithm contexts per thread in pool
+  template<class TypeSolverVector, class TypeContext>
+  class ContextFunctor2
   {
-    TypeContext& aContext = GetThreadContext();
-    TypeSolver&  aSolver  = mySolverVector(theIndex);
+  public:
 
-    aSolver.SetContext(aContext);
-    aSolver.Perform();
-  }
+    //! Constructor
+    explicit ContextFunctor2 (TypeSolverVector& theVector, const OSD_ThreadPool::Launcher& thePoolLauncher)
+    : mySolverVector(theVector),
+      myContextArray (thePoolLauncher.LowerThreadIndex(), thePoolLauncher.UpperThreadIndex()) {}
 
-private:
-  BOPTools_ContextFunctor(const BOPTools_ContextFunctor&);
-  BOPTools_ContextFunctor& operator= (const BOPTools_ContextFunctor&);
+    //! Binds main thread context
+    void SetContext (const opencascade::handle<TypeContext>& theContext)
+    {
+      myContextArray.ChangeLast() = theContext; // OSD_ThreadPool::Launcher::UpperThreadIndex() is reserved for a main thread
+    }
 
-private:
-  TypeSolverVector&      mySolverVector;
-  mutable ContextMap     myContexts;
-  mutable Standard_Mutex myMutex;
-};
+    //! Defines functor interface with serialized thread index.
+    void operator() (int theThreadIndex,
+                     int theIndex) const
+    {
+      opencascade::handle<TypeContext>& aContext = myContextArray.ChangeValue (theThreadIndex);
+      if (aContext.IsNull())
+      {
+        aContext = new TypeContext (NCollection_BaseAllocator::CommonBaseAllocator());
+      }
+      typename TypeSolverVector::value_type& aSolver = mySolverVector[theIndex];
+      aSolver.SetContext (aContext);
+      aSolver.Perform();
+    }
+
+  private:
+    ContextFunctor2(const ContextFunctor2&);
+    ContextFunctor2& operator= (const ContextFunctor2&);
+
+  private:
+    TypeSolverVector& mySolverVector;
+    mutable NCollection_Array1< opencascade::handle<TypeContext> > myContextArray;
+  };
 
-//=======================================================================
-//class    : BOPTools_ContextCnt
-//purpose  : 
-//=======================================================================
-template <class TypeFunctor, class TypeSolverVector, class TypeContext>
-class BOPTools_ContextCnt
-{
 public:
-  static void Perform( const Standard_Boolean isRunParallel,
-                       TypeSolverVector&      theSolverVector,
-                       TypeContext&           theContext )
-  {
-    TypeFunctor aFunctor(theSolverVector);
-    aFunctor.SetContext(theContext);
 
-    OSD_Parallel::For(0, theSolverVector.Length(), aFunctor, !isRunParallel);
+  //! Pure version
+  template<class TypeSolverVector>
+  static void Perform (Standard_Boolean theIsRunParallel,
+                       TypeSolverVector& theSolverVector)
+  {
+    Functor<TypeSolverVector> aFunctor (theSolverVector);
+    OSD_Parallel::For (0, theSolverVector.Length(), aFunctor, !theIsRunParallel);
+  }
+
+  //! Context dependent version
+  template<class TypeSolverVector, class TypeContext>
+  static void Perform (Standard_Boolean  theIsRunParallel,
+                       TypeSolverVector& theSolverVector,
+                       opencascade::handle<TypeContext>& theContext)
+  {
+    if (OSD_Parallel::ToUseOcctThreads())
+    {
+      const Handle(OSD_ThreadPool)& aThreadPool = OSD_ThreadPool::DefaultPool();
+      OSD_ThreadPool::Launcher aPoolLauncher (*aThreadPool, theIsRunParallel ? theSolverVector.Length() : 0);
+      ContextFunctor2<TypeSolverVector, TypeContext> aFunctor (theSolverVector, aPoolLauncher);
+      aFunctor.SetContext (theContext);
+      aPoolLauncher.Perform (0, theSolverVector.Length(), aFunctor);
+    }
+    else
+    {
+      ContextFunctor<TypeSolverVector, TypeContext> aFunctor (theSolverVector);
+      aFunctor.SetContext (theContext);
+      OSD_Parallel::For (0, theSolverVector.Length(), aFunctor, !theIsRunParallel);
+    }
   }
 };
 
diff --git a/src/Draw/Draw_BasicCommands.cxx b/src/Draw/Draw_BasicCommands.cxx
index 7d5be06523..638fcfdd9d 100644
--- a/src/Draw/Draw_BasicCommands.cxx
+++ b/src/Draw/Draw_BasicCommands.cxx
@@ -29,6 +29,8 @@
 #include <OSD_Exception_CTRL_BREAK.hxx>
 #include <OSD_MAllocHook.hxx>
 #include <OSD_MemInfo.hxx>
+#include <OSD_Parallel.hxx>
+#include <OSD_ThreadPool.hxx>
 #include <Standard_Macro.hxx>
 #include <Standard_SStream.hxx>
 #include <Standard_Stream.hxx>
@@ -808,6 +810,82 @@ static int dmeminfo (Draw_Interpretor& theDI,
   return 0;
 }
 
+//==============================================================================
+//function : dparallel
+//purpose  :
+//==============================================================================
+static int dparallel (Draw_Interpretor& theDI,
+                      Standard_Integer  theArgNb,
+                      const char**      theArgVec)
+{
+  const Handle(OSD_ThreadPool)& aDefPool = OSD_ThreadPool::DefaultPool();
+  if (theArgNb <= 1)
+  {
+    theDI << "NbLogicalProcessors: " << OSD_Parallel::NbLogicalProcessors() << "\n"
+          << "NbThreads:           " << aDefPool->NbThreads() << "\n"
+          << "NbDefThreads:        " << aDefPool->NbDefaultThreadsToLaunch() << "\n"
+          << "UseOcct:             " << (OSD_Parallel::ToUseOcctThreads() ? 1 : 0);
+    return 0;
+  }
+
+  for (Standard_Integer anIter = 1; anIter < theArgNb; ++anIter)
+  {
+    TCollection_AsciiString anArg (theArgVec[anIter]);
+    anArg.LowerCase();
+    if (anIter + 1 < theArgNb
+     && (anArg == "-nbthreads"
+      || anArg == "-threads"))
+    {
+      const Standard_Integer aVal = Draw::Atoi (theArgVec[++anIter]);
+      aDefPool->Init (aVal);
+    }
+    else if (anIter + 1 < theArgNb
+          && (anArg == "-nbdefthreads"
+           || anArg == "-defthreads"
+           || anArg == "-nbmaxdefthreads"
+           || anArg == "-maxdefthreads"))
+    {
+      const Standard_Integer aVal = Draw::Atoi (theArgVec[++anIter]);
+      if (aVal <= 0 || aVal > aDefPool->NbThreads())
+      {
+        std::cout << "Syntax error: maximum number of threads to use should be <= of threads in the pool\n";
+        return 1;
+      }
+      aDefPool->SetNbDefaultThreadsToLaunch (aVal);
+    }
+    else if (anIter + 1 < theArgNb
+          && (anArg == "-useocct"
+           || anArg == "-touseocct"
+           || anArg == "-occt"))
+    {
+      const Standard_Integer aVal = Draw::Atoi (theArgVec[++anIter]);
+      OSD_Parallel::SetUseOcctThreads (aVal == 1);
+      if (OSD_Parallel::ToUseOcctThreads() != (aVal == 1))
+      {
+        std::cout << "Warning: unable to switch threads library - no options available\n";
+      }
+    }
+    else if (anIter + 1 < theArgNb
+          && (anArg == "-usetbb"
+           || anArg == "-tousetbb"
+           || anArg == "-tbb"))
+    {
+      const Standard_Integer aVal = Draw::Atoi (theArgVec[++anIter]);
+      OSD_Parallel::SetUseOcctThreads (aVal == 0);
+      if (OSD_Parallel::ToUseOcctThreads() != (aVal == 0))
+      {
+        std::cout << "Warning: unable to switch threads library - no options available\n";
+      }
+    }
+    else
+    {
+      std::cout << "Syntax error: unknown argument '" << anArg << "'\n";
+      return 1;
+    }
+  }
+  return 0;
+}
+
 //==============================================================================
 //function : dperf
 //purpose  :
@@ -977,6 +1055,16 @@ void Draw::BasicCommands(Draw_Interpretor& theCommands)
   theCommands.Add("dsetsignal","dsetsignal [fpe=0] -- set OSD signal handler, with FPE option if argument is given",
 		  __FILE__,dsetsignal,g);
 
+  theCommands.Add("dparallel",
+    "dparallel [-occt {0|1}] [-nbThreads Count] [-nbDefThreads Count]"
+    "\n\t\t: Manages global parallelization parameters:"
+    "\n\t\t:   -occt         use OCCT implementation or external library (if available)"
+    "\n\t\t:   -nbThreads    specify the number of threads in default thread pool"
+    "\n\t\t:   -nbDefThreads specify the upper limit of threads to be used for default thread pool"
+    "\n\t\t:                 within single parallelization call (should be <= of overall number of threads),"
+    "\n\t\t:                 so that nested algorithm can also use this pool",
+      __FILE__,dparallel,g);
+
   // Logging commands; note that their names are hard-coded in the code
   // of Draw_Interpretor, thus should not be changed without update of that code!
   theCommands.Add("dlog", "manage logging of commands and output; run without args to get help",
diff --git a/src/OSD/OSD_Parallel.cxx b/src/OSD/OSD_Parallel.cxx
index b201e8c2b4..97d502aad7 100644
--- a/src/OSD/OSD_Parallel.cxx
+++ b/src/OSD/OSD_Parallel.cxx
@@ -171,6 +171,34 @@ namespace {
   }
 #endif
 
+  static Standard_Boolean OSD_Parallel_ToUseOcctThreads =
+  #ifdef HAVE_TBB
+    Standard_False;
+  #else
+    Standard_True;
+  #endif
+}
+
+//=======================================================================
+//function : ToUseOcctThreads
+//purpose  :
+//=======================================================================
+Standard_Boolean OSD_Parallel::ToUseOcctThreads()
+{
+  return OSD_Parallel_ToUseOcctThreads;
+}
+
+//=======================================================================
+//function : SetUseOcctThreads
+//purpose  :
+//=======================================================================
+void OSD_Parallel::SetUseOcctThreads (Standard_Boolean theToUseOcct)
+{
+#ifdef HAVE_TBB
+  OSD_Parallel_ToUseOcctThreads = theToUseOcct;
+#else
+  (void )theToUseOcct;
+#endif
 }
 
 //=======================================================================
diff --git a/src/OSD/OSD_Parallel.hxx b/src/OSD/OSD_Parallel.hxx
index d39e9d7b47..90708bbc97 100644
--- a/src/OSD/OSD_Parallel.hxx
+++ b/src/OSD/OSD_Parallel.hxx
@@ -14,6 +14,7 @@
 #ifndef OSD_Parallel_HeaderFile
 #define OSD_Parallel_HeaderFile
 
+#include <OSD_ThreadPool.hxx>
 #include <Standard_Type.hxx>
 #include <memory>
 #include <type_traits>
@@ -242,6 +243,24 @@ private:
     const Functor& myFunctor;
   };
 
+  //! Wrapper redirecting functor taking element index to functor taking also thread index.
+  template<class Functor>
+  class FunctorWrapperForThreadPool
+  {
+  public:
+    FunctorWrapperForThreadPool (const Functor& theFunctor) : myFunctor(theFunctor) {}
+
+    void operator() (int theThreadIndex, int theElemIndex) const
+    {
+      (void )theThreadIndex;
+      myFunctor (theElemIndex);
+    }
+  private:
+    FunctorWrapperForThreadPool (const FunctorWrapperForThreadPool&);
+    void operator= (const FunctorWrapperForThreadPool&);
+    const Functor& myFunctor;
+  };
+
 private:
 
   //! Simple primitive for parallelization of "foreach" loops, e.g.:
@@ -250,19 +269,33 @@ private:
   //! @endcode
   //! Implementation of framework-dependent functionality should be provided by
   //! forEach_impl function defined in opencascade::parallel namespace.
-  //! @param theBegin   the first index (incusive)
+  //! @param theBegin   the first index (inclusive)
   //! @param theEnd     the last  index (exclusive)
   //! @param theFunctor functor providing an interface "void operator(InputIterator theIter){}" 
   //!                   performing task for the specified iterator position
   //! @param theNbItems number of items passed by iterator, -1 if unknown
-  Standard_EXPORT static void forEach (UniversalIterator& theBegin,
-                                       UniversalIterator& theEnd,
-                                       const FunctorInterface& theFunctor,
-                                       Standard_Integer theNbItems);
+  Standard_EXPORT static void forEachOcct (UniversalIterator& theBegin,
+                                           UniversalIterator& theEnd,
+                                           const FunctorInterface& theFunctor,
+                                           Standard_Integer theNbItems);
+
+  //! Same as forEachOcct() but can be implemented using external threads library.
+  Standard_EXPORT static void forEachExternal (UniversalIterator& theBegin,
+                                               UniversalIterator& theEnd,
+                                               const FunctorInterface& theFunctor,
+                                               Standard_Integer theNbItems);
 
 public: //! @name public methods
 
-        //! Returns number of logical proccesrs.
+  //! Returns TRUE if OCCT threads should be used instead of auxiliary threads library;
+  //! default value is FALSE if alternative library has been enabled while OCCT building and TRUE otherwise.
+  Standard_EXPORT static Standard_Boolean ToUseOcctThreads();
+
+  //! Sets if OCCT threads should be used instead of auxiliary threads library.
+  //! Has no effect if OCCT has been built with no auxiliary threads library.
+  Standard_EXPORT static void SetUseOcctThreads (Standard_Boolean theToUseOcct);
+
+  //! Returns number of logical processors.
   Standard_EXPORT static Standard_Integer NbLogicalProcessors();
 
   //! Simple primitive for parallelization of "foreach" loops, equivalent to:
@@ -271,7 +304,7 @@ public: //! @name public methods
   //!     theFunctor(*anIter);
   //!   }
   //! @endcode
-  //! @param theBegin   the first index (incusive)
+  //! @param theBegin   the first index (inclusive)
   //! @param theEnd     the last  index (exclusive)
   //! @param theFunctor functor providing an interface "void operator(InputIterator theIter){}" 
   //!                   performing task for specified iterator position
@@ -294,7 +327,14 @@ public: //! @name public methods
       UniversalIterator aBegin(new IteratorWrapper<InputIterator>(theBegin));
       UniversalIterator aEnd  (new IteratorWrapper<InputIterator>(theEnd));
       FunctorWrapperIter<InputIterator,Functor> aFunctor (theFunctor);
-      forEach(aBegin, aEnd, aFunctor, theNbItems);
+      if (ToUseOcctThreads())
+      {
+        forEachOcct (aBegin, aEnd, aFunctor, theNbItems);
+      }
+      else
+      {
+        forEachExternal (aBegin, aEnd, aFunctor, theNbItems);
+      }
     }
   }
 
@@ -304,7 +344,7 @@ public: //! @name public methods
   //!     theFunctor(anIter);
   //!   }
   //! @endcode
-  //! @param theBegin   the first index (incusive)
+  //! @param theBegin   the first index (inclusive)
   //! @param theEnd     the last  index (exclusive)
   //! @param theFunctor functor providing an interface "void operator(int theIndex){}" 
   //!                   performing task for specified index
@@ -315,17 +355,25 @@ public: //! @name public methods
                   const Functor&         theFunctor,
                   const Standard_Boolean isForceSingleThreadExecution = Standard_False)
   {
-    if (isForceSingleThreadExecution || (theEnd - theBegin) == 1)
+    const Standard_Integer aRange = theEnd - theBegin;
+    if (isForceSingleThreadExecution || aRange == 1)
     {
       for (Standard_Integer it (theBegin); it != theEnd; ++it)
         theFunctor(it);
     }
+    else if (ToUseOcctThreads())
+    {
+      const Handle(OSD_ThreadPool)& aThreadPool = OSD_ThreadPool::DefaultPool();
+      OSD_ThreadPool::Launcher aPoolLauncher (*aThreadPool, aRange);
+      FunctorWrapperForThreadPool<Functor> aFunctor (theFunctor);
+      aPoolLauncher.Perform (theBegin, theEnd, aFunctor);
+    }
     else
     {
       UniversalIterator aBegin(new IteratorWrapper<Standard_Integer>(theBegin));
       UniversalIterator aEnd  (new IteratorWrapper<Standard_Integer>(theEnd));
       FunctorWrapperInt<Functor> aFunctor (theFunctor);
-      forEach(aBegin, aEnd, aFunctor, theEnd - theBegin);
+      forEachExternal (aBegin, aEnd, aFunctor, aRange);
     }
   }
 
diff --git a/src/OSD/OSD_Parallel_TBB.cxx b/src/OSD/OSD_Parallel_TBB.cxx
index 425fdf2ea6..43b6ec178b 100644
--- a/src/OSD/OSD_Parallel_TBB.cxx
+++ b/src/OSD/OSD_Parallel_TBB.cxx
@@ -27,14 +27,14 @@
 #include <tbb/task_scheduler_init.h>
 
 //=======================================================================
-//function : forEach
+//function : forEachExternal
 //purpose  : 
 //=======================================================================
 
-void OSD_Parallel::forEach (UniversalIterator& theBegin,
-                            UniversalIterator& theEnd,
-                            const FunctorInterface& theFunctor,
-                            Standard_Integer theNbItems)
+void OSD_Parallel::forEachExternal (UniversalIterator& theBegin,
+                                    UniversalIterator& theEnd,
+                                    const FunctorInterface& theFunctor,
+                                    Standard_Integer theNbItems)
 {
   try
   {
diff --git a/src/OSD/OSD_Parallel_Threads.cxx b/src/OSD/OSD_Parallel_Threads.cxx
index 0ffb38fa71..5041dee8b7 100644
--- a/src/OSD/OSD_Parallel_Threads.cxx
+++ b/src/OSD/OSD_Parallel_Threads.cxx
@@ -14,9 +14,6 @@
 // Alternatively, this file may be used under the terms of Open CASCADE
 // commercial license or contractual agreement.
 
-// Version of parallel executor used when TBB is not available
-#ifndef HAVE_TBB
-
 #include <OSD_Parallel.hxx>
 
 #include <OSD_ThreadPool.hxx>
@@ -142,13 +139,13 @@ namespace
 }
 
 //=======================================================================
-//function : forEach
-//purpose  : 
+//function : forEachOcct
+//purpose  :
 //=======================================================================
-void OSD_Parallel::forEach (UniversalIterator& theBegin,
-                            UniversalIterator& theEnd,
-                            const FunctorInterface& theFunctor,
-                            Standard_Integer theNbItems)
+void OSD_Parallel::forEachOcct (UniversalIterator& theBegin,
+                                UniversalIterator& theEnd,
+                                const FunctorInterface& theFunctor,
+                                Standard_Integer theNbItems)
 {
   const Handle(OSD_ThreadPool)& aThreadPool = OSD_ThreadPool::DefaultPool();
   const Standard_Integer aNbThreads = theNbItems != -1 ? Min (theNbItems, aThreadPool->NbDefaultThreadsToLaunch()) : -1;
@@ -156,4 +153,18 @@ void OSD_Parallel::forEach (UniversalIterator& theBegin,
   aLauncher.Perform (theBegin, theEnd, theFunctor);
 }
 
+// Version of parallel executor used when TBB is not available
+#ifndef HAVE_TBB
+//=======================================================================
+//function : forEachExternal
+//purpose  :
+//=======================================================================
+void OSD_Parallel::forEachExternal (UniversalIterator& theBegin,
+                                    UniversalIterator& theEnd,
+                                    const FunctorInterface& theFunctor,
+                                    Standard_Integer theNbItems)
+{
+  forEachOcct (theBegin, theEnd, theFunctor, theNbItems);
+}
+
 #endif /* ! HAVE_TBB */
diff --git a/src/OSD/OSD_ThreadPool.cxx b/src/OSD/OSD_ThreadPool.cxx
index 70ad50b31a..17c5370cf1 100644
--- a/src/OSD/OSD_ThreadPool.cxx
+++ b/src/OSD/OSD_ThreadPool.cxx
@@ -16,6 +16,7 @@
 #include <OSD_ThreadPool.hxx>
 
 #include <OSD.hxx>
+#include <OSD_Parallel.hxx>
 #include <Standard_Atomic.hxx>
 #include <TCollection_AsciiString.hxx>
 
diff --git a/src/OSD/OSD_ThreadPool.hxx b/src/OSD/OSD_ThreadPool.hxx
index 4b73100a8c..50b8f006ab 100644
--- a/src/OSD/OSD_ThreadPool.hxx
+++ b/src/OSD/OSD_ThreadPool.hxx
@@ -18,7 +18,6 @@
 
 #include <NCollection_Array1.hxx>
 #include <OSD_Thread.hxx>
-#include <OSD_Parallel.hxx>
 #include <Standard_Atomic.hxx>
 #include <Standard_Condition.hxx>
 #include <Standard_Mutex.hxx>