#include <Standard_OutOfRange.hxx>
 #include <math_FunctionWithDerivative.hxx>
 #include <math_NewtonFunctionRoot.hxx>
+#include <Precision.hxx>
 
 
 class MyTrigoFunction: public math_FunctionWithDerivative
   if ((Abs(A) <= Eps) && (Abs(B) <= Eps)) {
     if (Abs(C) <= Eps) {
       if (Abs(D) <= Eps) {
-       if (Abs(E) <= Eps) {
-         InfiniteStatus = Standard_True;   // infinite de solutions.
-         return;
-       }
-       else {
-         NbSol = 0;
-         return;
-       }
+        if (Abs(E) <= Eps) {
+          InfiniteStatus = Standard_True;   // infinite de solutions.
+          return;
+        }
+        else {
+          NbSol = 0;
+          return;
+        }
       }
       else { 
-// Equation du type d*sin(x) + e = 0
-// =================================   
-       NbSol = 0;
-       AA = -E/D;
-       if (Abs(AA) > 1.) {
-         return;
-       }
-
-       Zer(1) = ASin(AA);
-       Zer(2) = M_PI - Zer(1);
-       NZer = 2;
-       for (i = 1; i <= NZer; i++) {
-         if (Zer(i) <= -Eps) {
-           Zer(i) = Depi - Abs(Zer(i));
-         }
-         // On rend les solutions entre InfBound et SupBound:
-         // =================================================
-         Zer(i) += IntegerPart(Mod)*Depi;
-         X = Zer(i)-MyBorneInf;
-         if ((X > (-Epsilon(Delta))) && (X < Delta+ Epsilon(Delta))) {
-           NbSol++;
-           Sol(NbSol) = Zer(i);
-         }
-       }
+        // Equation du type d*sin(x) + e = 0
+        // =================================   
+        NbSol = 0;
+        AA = -E/D;
+        if (Abs(AA) > 1.) {
+          return;
+        }
+
+        Zer(1) = ASin(AA);
+        Zer(2) = M_PI - Zer(1);
+        NZer = 2;
+        for (i = 1; i <= NZer; i++) {
+          if (Zer(i) <= -Eps) {
+            Zer(i) = Depi - Abs(Zer(i));
+          }
+          // On rend les solutions entre InfBound et SupBound:
+          // =================================================
+          Zer(i) += IntegerPart(Mod)*Depi;
+          X = Zer(i)-MyBorneInf;
+          if ((X > (-Epsilon(Delta))) && (X < Delta+ Epsilon(Delta))) {
+            NbSol++;
+            Sol(NbSol) = Zer(i);
+          }
+        }
       }
       return;
     }
     else if (Abs(D) <= Eps)  {
 
-// Equation du premier degre de la forme c*cos(x) + e = 0
-// ======================================================        
+      // Equation du premier degre de la forme c*cos(x) + e = 0
+      // ======================================================          
       NbSol = 0;
       AA = -E/C;
       if (Abs(AA) >1.) {
-       return;
+        return;
       }
       Zer(1) = ACos(AA);
       Zer(2) = -Zer(1);
       NZer = 2;
 
       for (i = 1; i <= NZer; i++) {
-       if (Zer(i) <= -Eps) {
-         Zer(i) = Depi-Abs(Zer(i));
-       }
-       // On rend les solutions entre InfBound et SupBound:
-       // =================================================
-       Zer(i) += IntegerPart(Mod)*2.*M_PI;
-       X = Zer(i)-MyBorneInf;
-       if ((X >= (-Epsilon(Delta))) && (X <= Delta+ Epsilon(Delta))) {
-         NbSol++;
-         Sol(NbSol) = Zer(i);
-       }
+        if (Zer(i) <= -Eps) {
+          Zer(i) = Depi - Abs(Zer(i));
+        }
+        // On rend les solutions entre InfBound et SupBound:
+        // =================================================
+        Zer(i) += IntegerPart(Mod)*2.*M_PI;
+        X = Zer(i)-MyBorneInf;
+        if ((X >= (-Epsilon(Delta))) && (X <= Delta+ Epsilon(Delta))) {
+          NbSol++;
+          Sol(NbSol) = Zer(i);
+        }
       }
       return;
     }
     else {
 
-// Equation du second degre:
-// =========================
+      // Equation du second degre:
+      // =========================
       AA = E - C;
       BB = 2.0*D;
       CC = E + C;
 
       math_DirectPolynomialRoots Resol(AA, BB, CC);
       if (!Resol.IsDone()) {
-       Done = Standard_False;
-       return;
+        Done = Standard_False;
+        return;
       }
       else if(!Resol.InfiniteRoots()) {
-       NZer = Resol.NbSolutions();
-       for (i = 1; i <= NZer; i++) {
-         Zer(i) = Resol.Value(i);
-       }
+        NZer = Resol.NbSolutions();
+        for (i = 1; i <= NZer; i++) {
+          Zer(i) = Resol.Value(i);
+        }
       }
       else if (Resol.InfiniteRoots()) {
-       InfiniteStatus = Standard_True;
-       return;
+        InfiniteStatus = Standard_True;
+        return;
       }
     }
   }
   else {
+    // Two additional analytical cases.
+    if ((Abs(A) <= Eps) && 
+        (Abs(E) <= Eps))
+    {
+      if (Abs(C) <= Eps)
+      {
+        // 2 * B * sin * cos + D * sin = 0
+        NZer = 2;
+        Zer(1) = 0.0;
+        Zer(2) = M_PI;
+
+        AA = -D/(B * 2);
+        if (Abs(AA) <= 1.0 + Precision::PConfusion())
+        {
+          NZer = 4;
+          if (AA >= 1.0)
+          {
+            Zer(3)= 0.0;
+            Zer(4)= 0.0;
+          }
+          else if (AA <= -1.0)
+          {
+            Zer(3)= M_PI;
+            Zer(4)= M_PI;
+          }
+          else
+          {
+            Zer(3)= ACos(AA);
+            Zer(4) = Depi - Zer(3);
+          }
+        }
+
+        NbSol = 0;
+        for (i = 1; i <= NZer; i++) 
+        {
+          if (Zer(i) <= MyBorneInf - Eps)
+          {
+            Zer(i) += Depi;
+          }
+          // On rend les solutions entre InfBound et SupBound:
+          // =================================================
+          Zer(i) += IntegerPart(Mod)*2.*M_PI;
+          X = Zer(i)-MyBorneInf;
+          if ((X >= (-Precision::PConfusion())) && 
+              (X <= Delta + Precision::PConfusion()))
+          {
+            if (Zer(i) < InfBound)
+              Zer(i) = InfBound;
+            if (Zer(i) > SupBound)
+              Zer(i) = SupBound;
+            NbSol++;
+            Sol(NbSol) = Zer(i);
+          }
+        }
+        return;
+      }
+      if (Abs(D) <= Eps)
+      {
+        // 2 * B * sin * cos + C * cos = 0
+        NZer = 2;
+        Zer(1) = M_PI / 2.0;
+        Zer(2) = M_PI * 3.0 / 2.0;
+
+        AA = -C/(B * 2);
+        if (Abs(AA) <= 1.0 + Precision::PConfusion())
+        {
+          NZer = 4;
+          if (AA >= 1.0)
+          {
+            Zer(3) = M_PI / 2.0;
+            Zer(4) = M_PI / 2.0;
+          }
+          else if (AA <= -1.0)
+          {
+            
+            Zer(3) = M_PI * 3.0 / 2.0;
+            Zer(4) = M_PI * 3.0 / 2.0;
+          }
+          else
+          {
+            Zer(3)= ASin(AA);
+            Zer(4) = M_PI - Zer(3);
+          }
+        }
+
+        NbSol = 0;
+        for (i = 1; i <= NZer; i++) 
+        {
+          if (Zer(i) <= MyBorneInf - Eps)
+          {
+            Zer(i) += Depi;
+          }
+          // On rend les solutions entre InfBound et SupBound:
+          // =================================================
+          Zer(i) += IntegerPart(Mod)*2.*M_PI;
+          X = Zer(i)-MyBorneInf;
+          if ((X >= (-Precision::PConfusion())) && 
+              (X <= Delta + Precision::PConfusion()))
+          {
+            if (Zer(i) < InfBound)
+              Zer(i) = InfBound;
+            if (Zer(i) > SupBound)
+              Zer(i) = SupBound;
+            NbSol++;
+            Sol(NbSol) = Zer(i);
+          }
+        }
+        return;
+      }
+    }
 
 // Equation du 4 ieme degre
 // ========================