diff --git a/Plugin/AnalyseCurvedMesh.cpp b/Plugin/AnalyseCurvedMesh.cpp
index 4042d81b64bea0ee0006106530ad6a053e290103..571fd987b98de092587dc774fd006cda9b898b34 100644
--- a/Plugin/AnalyseCurvedMesh.cpp
+++ b/Plugin/AnalyseCurvedMesh.cpp
@@ -10,28 +10,31 @@
 #include "polynomialBasis.h"
 #include "AnalyseCurvedMesh.h"
 #include "Context.h"
+#include <queue>
+#include <cmath>
+#include<fstream>
+#include "OS.h"
+#include "PView.h"
 
 #if defined(HAVE_OPENGL)
 #include "drawContext.h"
 #endif
-
-#include "OS.h"
-
 #if defined(HAVE_FLTK)
 #include "FlGui.h"
 #endif
 
-#define UNDEF_JAC_TAG -999
+//#define UNDEF_JAC_TAG -999
+//#define _ANALYSECURVEDMESH_BLAS_
 
 
 StringXNumber JacobianOptions_Number[] = {
   {GMSH_FULLRC, "Dim", NULL, -1},
-  {GMSH_FULLRC, "Analysis", NULL, 1},
-  {GMSH_FULLRC, "Effect", NULL, 6},
-  {GMSH_FULLRC, "MaxDepth", NULL, 10},
-  {GMSH_FULLRC, "JacBreak", NULL, .0},
-  {GMSH_FULLRC, "BezBreak", NULL, .0},
-  {GMSH_FULLRC, "Tolerance", NULL, 1e-5}
+  {GMSH_FULLRC, "Analysis", NULL, 2},
+  {GMSH_FULLRC, "Effect (1)", NULL, 6},
+  {GMSH_FULLRC, "JacBreak (1)", NULL, .0},
+  {GMSH_FULLRC, "BezBreak (1)", NULL, .0},
+  {GMSH_FULLRC, "MaxDepth (1,2)", NULL, 20},
+  {GMSH_FULLRC, "Tolerance (2)", NULL, 1e-3}
 };
 
 extern "C"
@@ -74,51 +77,6 @@ std::string GMSH_AnalyseCurvedMeshPlugin::getHelp() const
 }
 
 // Miscellaneous method
-/*int max(const std::vector<int> &vec)
-{
-  int max = vec[0];
-  for (unsigned int i = 1; i < vec.size(); i++)
-    if (vec[i] > max) max = vec[i];
-  return max;
-}*/
-
-/*static double computeDeterminant(MElement *el, double jac[3][3])
-{
-  switch (el->getDim()) {
-  case 0:
-    return 1.0;
-  case 1:
-    return jac[0][0];
-  case 2:
-    return jac[0][0] * jac[1][1] - jac[0][1] * jac[1][0];
-  case 3:
-    return jac[0][0] * jac[1][1] * jac[2][2] + jac[0][2] * jac[1][0] * jac[2][1] +
-           jac[0][1] * jac[1][2] * jac[2][0] - jac[0][2] * jac[1][1] * jac[2][0] -
-           jac[0][0] * jac[1][2] * jac[2][1] - jac[0][1] * jac[1][0] * jac[2][2];
-  default:
-    return 1;
-  }
-}
-
-double getJacobian(double gsf[][3], double jac[3][3], MElement *el)
-{
-  jac[0][0] = jac[0][1] = jac[0][2] = 0.;
-  jac[1][0] = jac[1][1] = jac[1][2] = 0.;
-  jac[2][0] = jac[2][1] = jac[2][2] = 0.;
-
-  for (int i = 0; i < el->getNumVertices(); i++) {
-    const MVertex *v = el->getVertex(i);
-    double *gg = gsf[i];
-    for (int j = 0; j < 3; j++) {
-      jac[j][0] += v->x() * gg[j];
-      jac[j][1] += v->y() * gg[j];
-      jac[j][2] += v->z() * gg[j];
-    }
-  }
-
-  return computeDeterminant(el, jac);
-}*/
-
 static void setJacobian(MElement *el, const JacobianBasis *jfs, fullVector<double> &jacobian)
 {
   int numVertices = el->getNumVertices();
@@ -322,6 +280,15 @@ static void setJacobian(MElement *const *el, const JacobianBasis *jfs, fullMatri
   }
 }
 
+static double sum(fullVector<double> &v)
+{
+  double sum = .0;
+  for (int i = 0; i < v.size(); ++i) {
+    sum += v(i);
+  }
+  return sum;
+}
+
 // Execution
 PView *GMSH_AnalyseCurvedMeshPlugin::execute(PView *v)
 {
@@ -329,166 +296,28 @@ PView *GMSH_AnalyseCurvedMeshPlugin::execute(PView *v)
   _dim = (int) JacobianOptions_Number[0].def;
   if (_dim < 0 || _dim > 3)
     _dim = _m->getDim();
-  int analysis = (int) JacobianOptions_Number[1].def % 2;
-  int toDo = (int) JacobianOptions_Number[1].def % 8;
-  _maxDepth = (int) JacobianOptions_Number[2].def;
+  int analysis = (int) JacobianOptions_Number[1].def % 4;
+  int toDo = (int) JacobianOptions_Number[2].def % 8;
+  _maxDepth = (int) JacobianOptions_Number[5].def;
   _jacBreak = (double) JacobianOptions_Number[3].def;
   _bezBreak = (double) JacobianOptions_Number[4].def;
-  _tol = (double) JacobianOptions_Number[5].def;
+  _tol = (double) JacobianOptions_Number[6].def;
   
   if (analysis % 2) {
     double t = Cpu();
-    Msg::Info("Strating validity check...");
+    Msg::Info("Starting validity check...");
     checkValidity(toDo);
     Msg::Info("Done validity check (%fs)", Cpu()-t);
   }
   if (analysis / 2) {
     double t = Cpu();
-    Msg::Info("Strating computation J_min / J_max...");
-    computeMinMax();
-    Msg::Info("Done computation J_min / J_max (%fs)", Cpu()-t);
+    Msg::Info("Starting computation J_min, J_max...");
+    std::map<int, std::vector<double> > data;
+    computeMinMax(&data);
+    new PView("Jmin", "ElementData", _m, data);
+    Msg::Info("Done computation J_min, J_max (%fs)", Cpu()-t);
   }
 }
-  
-//{
-//  Msg::Info("AnalyseCurvedMeshPlugin : Starting analysis.");
-//  int numBadEl = 0;
-//  int numUncertain = 0;
-//  int numAnalysedEl = 0;
-//  std::vector<int> tag;
-//  int method = (int)JacobianOptions_Number[0].def % 4;
-//  int maxDepth = (int)JacobianOptions_Number[1].def;
-//
-//  if (method < 1 || method > 2) {
-//#if defined(HAVE_BLAS)
-//    method = 2;
-//#else
-//    method = 1;
-//#endif
-//  } 
-//
-//  GModel *m = GModel::current();
-//  switch (m->getDim()) {
-//
-//    case 3 :
-//      Msg::Info("Only 3D elements will be analyse.");
-//      for(GModel::riter it = m->firstRegion(); it != m->lastRegion(); it++) {
-//        GRegion *r = *it;
-//        
-//        unsigned int numType[5] = {0, 0, 0, 0, 0};
-//        r->getNumMeshElements(numType);
-//
-//        for(int type = 0; type < 5; type++) {
-//          MElement *const *el = r->getStartElementType(type);
-//          
-//          int *a;
-//          a = checkJacobian(el, numType[type], maxDepth, method);
-//          numUncertain += a[0];
-//          numBadEl += a[1];
-//          numAnalysedEl += numType[type];
-//          delete[] a;
-//
-//          /*for(unsigned int i = 0; i < numType[type]; i++) {
-//            numAnalysedEl++;
-//            if (checkJacobian(el[i], maxDepth) <= 0) numBadEl++;
-//          }*/
-//        }
-//      }
-//      break;
-//
-//    case 2 :
-//      Msg::Info("Only 2D elements will be analyse.");
-//      Msg::Warning("2D elements must be in a z=cst plane ! If they aren't, results won't be correct.");
-//      for (GModel::fiter it = m->firstFace(); it != m->lastFace(); it++) {
-//        GFace *f = *it;
-//        
-//        unsigned int numType[3] = {0, 0, 0};
-//        f->getNumMeshElements(numType);
-//
-//        for (int type = 0; type < 3; type++) {
-//          MElement *const *el = f->getStartElementType(type);
-//
-//          int *a;
-//          a = checkJacobian(el, numType[type], maxDepth, method);
-//          numUncertain += a[0];
-//          numBadEl += a[1];
-//          numAnalysedEl += numType[type];
-//          delete[] a;
-//
-//          /*for (unsigned int i = 0; i < numType[type]; i++) {
-//            numAnalysedEl++;
-//            if (checkJacobian(el[i], maxDepth) <= 0) numBadEl++;
-//          }*/
-//        }
-//      }
-//      break;
-//
-//    case 1 :
-//      Msg::Info("Only 1D elements will be analyse.");
-//      Msg::Warning("1D elements must be on a y=cst & z=cst line ! If they aren't, results won't be correct.");
-//      for (GModel::eiter it = m->firstEdge(); it != m->lastEdge(); it++) {
-//        GEdge *e = *it;
-//        
-//        unsigned int numElement = e->getNumMeshElements();
-//        MElement *const *el = e->getStartElementType(0);
-//
-//        int *a;
-//        a = checkJacobian(el, numElement, maxDepth, method);
-//        numUncertain += a[0];
-//        numBadEl += a[1];
-//        numAnalysedEl += numElement;
-//        delete[] a;
-//
-//        /*for (unsigned int i = 0; i < numElement; i++) {
-//          numAnalysedEl++;
-//          if (checkJacobian(el[i], maxDepth) <= 0) numBadEl++;
-//        }*/
-//      }
-//      break;
-//
-//    default :
-//      Msg::Error("I can't analyse any element.");
-//  }
-//
-//
-//  //Set all visibility of smaller dimension elements to 0
-//  switch (m->getDim()) {
-//    case 2 :
-//      for (GModel::fiter it = m->firstFace(); it != m->lastFace(); it++) {
-//        GFace *f = *it;
-//        
-//        unsigned int numType[3] = {0, 0, 0};
-//        f->getNumMeshElements(numType);
-//
-//        for (int type = 0; type < 3; type++) {
-//          MElement *const *el = f->getStartElementType(type);
-//          for (unsigned int i = 0; i < numType[type]; i++) {
-//            el[i]->setVisibility(0);
-//          }
-//        }
-//      }
-//    case 1 :
-//      for (GModel::eiter it = m->firstEdge(); it != m->lastEdge(); it++) {
-//        GEdge *e = *it;
-//        
-//        unsigned int numElement = e->getNumMeshElements();
-//        MElement *const *el = e->getStartElementType(0);
-//
-//        for (unsigned int i = 0; i < numElement; i++) {
-//          el[i]->setVisibility(0);
-//        }
-//      }
-//      break;
-//  }
-//  
-//  Msg::Info("%d elements have been analysed.", numAnalysedEl);
-//  Msg::Info("%d elements were bad.", numBadEl);
-//  Msg::Info("%d elements were undetermined.", numUncertain);
-//  Msg::Info("AnalyseCurvedMeshPlugin : Job finished.");
-//
-//  return 0;
-//}
-
 
 void GMSH_AnalyseCurvedMeshPlugin::checkValidity(int toDo)
 {
@@ -527,7 +356,7 @@ void GMSH_AnalyseCurvedMeshPlugin::checkValidity(int toDo)
 						for (int jo = 0; jo < numType[type]; jo++)
 							el[jo]->setVolumePositive();
 					}
-				}		
+				}
       for (GModel::fiter it = _m->firstFace(); it != _m->lastFace(); it++) {
         GFace *f = *it;
         unsigned int numType[3] = {0, 0, 0};
@@ -590,162 +419,59 @@ void GMSH_AnalyseCurvedMeshPlugin::checkValidity(int toDo)
   }
 }
 
-void GMSH_AnalyseCurvedMeshPlugin::hideValid_ShowInvalid(std::vector<MElement*> &invalids)
-{
-  int current = 0;
-  invalids.push_back(NULL);
-  
-  switch (_dim) {
-    case 3 :
-      for(GModel::riter it = _m->firstRegion(); it != _m->lastRegion(); it++) {
-        GRegion *r = *it;
-        unsigned int numType[5] = {0, 0, 0, 0, 0};
-        r->getNumMeshElements(numType);
-        
-        for(int type = 0; type < 5; type++) {
-          MElement *const *el = r->getStartElementType(type);
-          for (int i = 0; i < numType[type]; ++i) {
-            if (el[i] == invalids[current]) {
-              ++current;
-              el[i]->setVisibility(1);
-            }
-            else
-              el[i]->setVisibility(0);
-          }
-        }
-      }
-      break;
-    
-    case 2 :
-      for (GModel::fiter it = _m->firstFace(); it != _m->lastFace(); it++) {
-        GFace *f = *it;
-        unsigned int numType[3] = {0, 0, 0};
-        f->getNumMeshElements(numType);
-        
-        for (int type = 0; type < 3; type++) {
-          MElement *const *el = f->getStartElementType(type);
-          for (int i = 0; i < numType[type]; ++i) {
-            if (el[i] == invalids[current]) {
-              ++current;
-              el[i]->setVisibility(1);
-            }
-            else
-              el[i]->setVisibility(0);
-          }
-        }
-      }
-      break;
-    
-    case 1 :
-      for (GModel::eiter it = _m->firstEdge(); it != _m->lastEdge(); it++) {
-        GEdge *e = *it;
-        unsigned int numElement = e->getNumMeshElements();
-        MElement *const *el = e->getStartElementType(0);
-        for (int i = 0; i < numElement; ++i) {
-          if (el[i] == invalids[current]) {
-            ++current;
-            el[i]->setVisibility(1);
-          }
-          else
-            el[i]->setVisibility(0);
-        }
-      }
-      break;
-    
-    default :
-      break;
-  }
-  invalids.pop_back();
-}
-
-void GMSH_AnalyseCurvedMeshPlugin::
-  checkValidity(MElement *const*el, int numEl, std::vector<MElement*> &invalids)
+void GMSH_AnalyseCurvedMeshPlugin::checkValidity(MElement *const*el,
+                                                 int numEl,
+                                                 std::vector<MElement*> &invalids)
 {
   if (numEl < 1)
     return;
   
   const JacobianBasis *jfs = el[0]->getJacobianFuncSpace(-1);
-  if (!jfs) {
+  const JacobianBasis *jfs1 = el[0]->getJacobianFuncSpace(1);
+  if (!jfs || !jfs1) {
     Msg::Error("Jacobian function space not implemented for type of element %d", el[0]->getNum());
     return;
   }
   const bezierBasis *bb = jfs->bezier;
   
   int numSamplingPt = bb->points.size1();
-  int dim = bb->points.size2();
+  
+#ifdef _ANALYSECURVEDMESH_BLAS_
+  fullMatrix<double> jacobianB(numSamplingPt, numEl);
+  fullMatrix<double> jacBezB(numSamplingPt, numEl);
+  fullVector<double> jac1B(jfs1->bezier->points.size1(), numEl);
+  fullVector<double> jacBez, jacobian, jac1;
+  
+  setJacobian(el, jfs, jacobianB);
+  setJacobian(el, jfs1, jac1B);
+  bb->matrixLag2Bez.mult(jacobianB, jacBezB);
+#else
   fullVector<double> jacobian(numSamplingPt);
   fullVector<double> jacBez(numSamplingPt);
+  fullVector<double> jac1(jfs1->bezier->points.size1());
+#endif
   
   for (int k = 0; k < numEl; ++k) {
+    
+#ifdef _ANALYSECURVEDMESH_BLAS_ 
+    jacBez.setAsProxy(jacBezB, k);
+    jacobian.setAsProxy(jacobianB, k);
+    jac1.setAsProxy(jac1B, k);
+#else
     setJacobian(el[k], jfs, jacobian);
+    setJacobian(el[k], jfs1, jac1);
+#endif
     
-    int i;
-    for (i = 0; i < numSamplingPt && jacobian(i) > _jacBreak; ++i);
-    if (i < numSamplingPt) {
-      invalids.push_back(el[k]);
-      ++_numInvalid;
-      continue;
+    // AmJ : avgJ is not the average Jac for quad, prism or hex
+    double avgJ = sum(jac1) / jac1.size();
+    if (avgJ < 0) {
+      jacBez.scale(-1);
+      jacobian.scale(-1);
+      avgJ *= -1;
     }
     
-    if (_maxDepth < 1) {
-      invalids.push_back(el[k]);
-      ++_numUncertain;
-      continue;
-    }
-    
-    bb->matrixLag2Bez.mult(jacobian, jacBez);
-    
-    for (i = 0; i < jacBez.size() && jacBez(i) > _bezBreak; ++i);
-    if (i >= jacBez.size()) {
-      ++_numValid;
-      continue;
-    }
-    
-    if (_maxDepth < 2) {
-      invalids.push_back(el[k]);
-      ++_numUncertain;
-      continue;
-    }
-    else {
-      int result = subDivision(bb, jacBez, _maxDepth-1);
-      if (result < 0) {
-        invalids.push_back(el[k]);
-        ++_numInvalid;
-        continue;
-      }
-      if (result > 0) {
-        ++_numValid;
-        continue;
-      }
-      invalids.push_back(el[k]);
-      ++_numUncertain;
-      continue;
-    }
-  }
-}
-
-void GMSH_AnalyseCurvedMeshPlugin::
-  checkValidity_BLAS(MElement *const*el, int numEl, std::vector<MElement*> &invalids)
-{
-  if (numEl < 1)
-    return;
-  
-  const JacobianBasis *jfs = el[0]->getJacobianFuncSpace(-1);
-  if (!jfs) {
-    Msg::Error("Jacobian function space not implemented for type of element %d", el[0]->getNum());
-    return;
-  }
-  const bezierBasis *bb = jfs->bezier;
-  
-  int numSamplingPt = bb->points.size1();
-  int dim = bb->points.size2();
-  fullMatrix<double> jacobian(numSamplingPt, numEl);
-  fullVector<double> jacBez(numSamplingPt), proxJac(numSamplingPt);
-  setJacobian(el, jfs, jacobian);
-  
-  for (int k = 0; k < numEl; ++k) {
     int i;
-    for (i = 0; i < numSamplingPt && jacobian(i, k) > _jacBreak; ++i);
+    for (i = 0; i < numSamplingPt && jacobian(i) > _jacBreak * avgJ; ++i);
     if (i < numSamplingPt) {
       invalids.push_back(el[k]);
       ++_numInvalid;
@@ -758,10 +484,11 @@ void GMSH_AnalyseCurvedMeshPlugin::
       continue;
     }
     
-    proxJac.setAsProxy(jacobian, k);
-    bb->matrixLag2Bez.mult(proxJac, jacBez);
+#ifndef _ANALYSECURVEDMESH_BLAS_ 
+    bb->matrixLag2Bez.mult(jacobian, jacBez);
+#endif
     
-    for (i = 0; i < jacBez.size() && jacBez(i) > _bezBreak; ++i);
+    for (i = 0; i < jacBez.size() && jacBez(i) > _bezBreak * avgJ; ++i);
     if (i >= jacBez.size()) {
       ++_numValid;
       continue;
@@ -790,8 +517,9 @@ void GMSH_AnalyseCurvedMeshPlugin::
   }
 }
 
-int GMSH_AnalyseCurvedMeshPlugin::
-  subDivision(const bezierBasis *bb, const fullVector<double> &jacobian, int depth)
+int GMSH_AnalyseCurvedMeshPlugin::subDivision(const bezierBasis *bb,
+                                              const fullVector<double> &jacobian,
+                                              int depth)
 {
   fullVector<double> newJacobian(bb->subDivisor.size1());
   bb->subDivisor.mult(jacobian, newJacobian);
@@ -836,13 +564,13 @@ int GMSH_AnalyseCurvedMeshPlugin::
 }
 
 
-void GMSH_AnalyseCurvedMeshPlugin::computeMinMax()
-{/*
+void GMSH_AnalyseCurvedMeshPlugin::computeMinMax(std::map<int, std::vector<double> > *data)
+{
   _numAnalysedEl = 0;
   _numInvalid = 0;
   _numValid = 0;
   _numUncertain = 0;
-  _min_Javg = .0, _max_Javg = .0;
+  _min_Javg = .0, _max_Javg = .0, _avg_Javg = .0;
   _min_pJmin = .0, _avg_pJmin = .0;
   _min_ratioJ = .0, _avg_ratioJ = .0;
   
@@ -855,7 +583,7 @@ void GMSH_AnalyseCurvedMeshPlugin::computeMinMax()
         
         for(int type = 0; type < 5; type++) {
           MElement *const *el = r->getStartElementType(type);
-          computeMinMax(el, numType[type]);
+          computeMinMax(el, numType[type], data);
           _numAnalysedEl += numType[type];
         }
       }
@@ -870,7 +598,7 @@ void GMSH_AnalyseCurvedMeshPlugin::computeMinMax()
         
         for (int type = 0; type < 3; type++) {
           MElement *const *el = f->getStartElementType(type);
-          computeMinMax(el, numType[type]);
+          computeMinMax(el, numType[type], data);
           _numAnalysedEl += numType[type];
         }
       }
@@ -882,7 +610,7 @@ void GMSH_AnalyseCurvedMeshPlugin::computeMinMax()
         GEdge *e = *it;
         unsigned int numElement = e->getNumMeshElements();
         MElement *const *el = e->getStartElementType(0);
-        computeMinMax(el, numElement);
+        computeMinMax(el, numElement, data);
         _numAnalysedEl += numElement;
       }
       break;
@@ -891,52 +619,89 @@ void GMSH_AnalyseCurvedMeshPlugin::computeMinMax()
       Msg::Error("I can't analyse any element.");
       return;
   }
-  Msg::Info("Extrema of J_avg : %g, %g", _min_Javg, _max_Javg);
+  Msg::Info("Extrema of J_avg : %g, %g (avg: %g)", _min_Javg, _max_Javg, _avg_Javg/_numAnalysedEl);
   Msg::Info("Minimum of min(~distortion) : %g", _min_pJmin);
   Msg::Info("Average of min(~distortion) : %g", _avg_pJmin / _numAnalysedEl);
   Msg::Info("Minimum of min(J) / max(J) : %g", _min_ratioJ);
   Msg::Info("Average of min(J) / max(J) : %g", _avg_ratioJ / _numAnalysedEl);
- */}
+}
 
-void GMSH_AnalyseCurvedMeshPlugin::
-  computeMinMax(MElement *const*el, int numEl)
-{/*
+void GMSH_AnalyseCurvedMeshPlugin::computeMinMax(MElement *const*el, int numEl, std::map<int, std::vector<double> > *data)
+{
   if (numEl < 1)
     return;
   
   const JacobianBasis *jfs = el[0]->getJacobianFuncSpace(-1);
-  if (!jfs) {
+  const JacobianBasis *jfs1 = el[0]->getJacobianFuncSpace(1);
+  if (!jfs || !jfs1) {
     Msg::Error("Jacobian function space not implemented for type of element %d", el[0]->getNum());
     return;
   }
   const bezierBasis *bb = jfs->bezier;
-  
+ 
   int numSamplingPt = bb->points.size1();
-  int dim = bb->points.size2();
   
-  fullMatrix<double> jacobian(numSamplingPt, numEl);
-  fullMatrix<double> jacBez(numSamplingPt, numEl);
-  fullVector<double> proxBez(numSamplingPt);
-  setJacobian(el, jfs, jacobian);
-  bb->matrixLag2Bez.mult(jacobian, jacBez);
+#ifdef _ANALYSECURVEDMESH_BLAS_ 
+  fullMatrix<double> jacobianB(numSamplingPt, numEl);
+  fullMatrix<double> jacBezB(numSamplingPt, numEl);
+  fullVector<double> jac1B(jfs1->bezier->points.size1(), numEl);
+  fullVector<double> jacBez, jacobian, jac1;
   
+  setJacobian(el, jfs, jacobianB);
+  setJacobian(el, jfs1, jac1B);
+  bb->matrixLag2Bez.mult(jacobianB, jacBezB);
+#else
+  fullVector<double> jacobian(numSamplingPt);
+  fullVector<double> jacBez(numSamplingPt);
+  fullVector<double> jac1(jfs1->bezier->points.size1());
+#endif
+  fullVector<double> subJacBez(bb->subDivisor.size1());
+
+  _min_Javg = 1.7e308;
+  _max_Javg = -1.7e308;
+  _min_pJmin = 1.7e308;
+  _min_ratioJ = 1.7e308;
+  
+  std::ofstream fwrite("minDisto.txt");
+	fwrite << numEl << "\r";
+
   for (int k = 0; k < numEl; ++k) {
-    proxBez.setAsProxy(jacBez, k);
-    double minJ, maxJ = minJ = jacobian(0,k);
     
-    for (int i = 1; i < jacobian.size1(); ++i) {
-      if (jacobian(i,k) < minJ) minJ = jacobian(i,k);
-      if (jacobian(i,k) > maxJ) maxJ = jacobian(i,k);
+#ifdef _ANALYSECURVEDMESH_BLAS_ 
+    jacBez.setAsProxy(jacBezB, k);
+    jacobian.setAsProxy(jacobianB, k);
+    jac1.setAsProxy(jac1B, k);
+#else
+    setJacobian(el[k], jfs, jacobian);
+    setJacobian(el[k], jfs1, jac1);
+    bb->matrixLag2Bez.mult(jacobian, jacBez);
+#endif
+    
+    // AmJ : avgJ is not the average Jac for quad, prism or hex
+    double avgJ = sum(jac1) / jac1.size();
+    if (avgJ < 0) {
+      jacBez.scale(-1);
+      jacobian.scale(-1);
+      avgJ *= -1;
+    }
+    
+    double minJ, maxJ = minJ = jacobian(0);
+    
+    for (int i = 1; i < numSamplingPt; ++i) {
+      if (jacobian(i) < minJ) minJ = jacobian(i);
+      if (jacobian(i) > maxJ) maxJ = jacobian(i);
     }
     
-    double minB, maxB = minB = jacBez(0,k), avgJ = .0;
+    double minB, maxB = minB = jacBez(0);//, avgJ = .0;
     
-    for (int i = 1; i < proxBez.size1(); ++i) {
-      if (proxBez(i,k) < minB) minB = proxBez(i,k);
-      if (proxBez(i,k) > maxB) maxB = proxBez(i,k);
-      avgJ += jacBez(i,k);
+    for (int i = 1; i < numSamplingPt; ++i) {
+      if (jacBez(i) < minB) minB = jacBez(i);
+      if (jacBez(i) > maxB) maxB = jacBez(i);
+      //avgJ += jacBez(i);
     }
-    avgJ /= proxBez.size1();
+    //avgJ /= numSamplingPt;
+    
+    _avg_Javg += avgJ;
     _min_Javg = std::min(_min_Javg, avgJ);
     _max_Javg = std::max(_max_Javg, avgJ);
     
@@ -944,452 +709,211 @@ void GMSH_AnalyseCurvedMeshPlugin::
         (minJ - minB > _tol * (std::abs(minJ) + std::abs(minB)) / 2 ||
          maxB - maxJ > _tol * (std::abs(maxJ) + std::abs(maxB)) / 2   )) {
       
-      
-      
-      
-      
-      
-      
-      // Set and map creation :
-      // The set is sorted in such a way that the first key should be the 
-      // better to partition.
-      // The map keep in memory the Bezier minimum and maximum for all part of the element.
-      BezierJacobian *bj = new BezierJacobian(proxBez, jfs, 0);
-      std::list<BezierJacobian> myset;
-      myset.insert(*bj);
-      std::pair<double,double> minmaxB(bj->minB(),bj->maxB());
-      std::map< int, std::pair<double,double> > map_minmaxB;
-      map_minmaxB.insert(std::pair< int, std::pair<double,double> >(bj->num(),minmaxB));
-      
-      bj->setMinMaxBounds(minLB, minUB, maxLB, maxUB);
-      if (min < minUB) minUB = min;
-      if (max > maxLB) maxLB = max;
-      
-      fullVector<double> newJacBez(jfs->divisor.size1());
-      fullVector<double> prox(numSamplingPt);
-      
-      int currentDepth, maxDepth = 0, k = 0;
-      
-      while ((minUB-minLB > tol || maxUB-maxLB > tol)) {
-        // Note that it is not optimized.
-        // When one interval reach tolerance, myset is certainly
-        // no more the more efficiently sorted 
-        // (the fault of BezierJacobian.operator<(...))
-        std::set<BezierJacobian>::iterator it = myset.begin();
-        (*it).partition(newJacBez, jfs);
-        currentDepth = (*it).depth() + 1;
-        if (maxDepth < currentDepth) maxDepth = currentDepth;
-        map_minmaxB.erase((*it).num());
-        myset.erase(it);
-        k++;
+      BezierJacobian *bj = new BezierJacobian(jacBez, jfs, 0);
+      std::set<BezierJacobian*> setBJ;
+      std::priority_queue<BezierJacobian*, std::vector<BezierJacobian*>, lessMinB> pqMin;
+      std::priority_queue<BezierJacobian*, std::vector<BezierJacobian*>, lessMaxB> pqMax;
+      setBJ.insert(bj);
+      pqMin.push(bj);
+      
+      int currentDepth = 0;
+      int p = 0;
+      while(minJ - minB > _tol * (std::abs(minJ) + std::abs(minB)) / 2 &&
+            pqMin.top()->depth() < _maxDepth-1) {
+        bj = pqMin.top();
+        bj->subDivisions(subJacBez);
+        currentDepth = bj->depth() + 1;
+        setBJ.erase(bj);
+        pqMin.pop();
+        delete bj;
         
-        for (int i = 0; i < jfs->numDivisions; i++) {
-          prox.setAsProxy(newJacBez, i * jacBez.size(), jacBez.size());
-          bj = new BezierJacobian(prox, jfs, currentDepth);
-          if (maxLB < bj->maxJ()) maxLB = bj->maxJ();
-          if (minUB > bj->minJ()) minUB = bj->minJ();
-          myset.insert(*bj);
-          minmaxB = std::make_pair(bj->minB(),bj->maxB());
-          map_minmaxB.insert(std::pair< int, std::pair<double,double> >(bj->num(),minmaxB));
-        }
-        
-        // Deletion of obsolet BezierJacobian
-        it = myset.begin();
-        if ((*it).isObsolet(maxLB, minUB, tol))
-          myset.erase(it++);
-        else ++it;
-        while (it != myset.end()) {
-          if ((*it).isObsolet(maxLB, minUB, tol))
-            myset.erase(it++);
-          else
-            ++it;
+        for (int i = 0; i < bb->numDivisions; i++) {
+          jacBez.setAsProxy(subJacBez, i * numSamplingPt, numSamplingPt);
+          bj = new BezierJacobian(jacBez, jfs, currentDepth);
+          pqMin.push(bj);
+          setBJ.insert(bj);
+          minJ = std::min(minJ, bj->minJ());
+          maxJ = std::max(maxJ, bj->maxJ());
         }
         
-        // Update of Bezier bounds
-        minLB = minUB;
-        maxUB = maxLB;
-        std::map< int, std::pair<double,double> >::iterator mit;
-        for (mit = map_minmaxB.begin(); mit != map_minmaxB.end(); mit++) {
-          if (minLB > mit->second.first) minLB = mit->second.first;
-          if (maxUB < mit->second.second) maxUB = mit->second.second;
+        minB = minJ;
+        maxB = maxJ;
+        std::set<BezierJacobian*>::iterator it;
+        for (it = setBJ.begin(); it != setBJ.end(); ++it) {
+          minB = std::min(minB, (*it)->minB());
+          maxB = std::max(maxB, (*it)->maxB());
         }
       }
       
-      double *a = new double[6];
-      a[0] = minLB, a[1] = minUB, a[2] = maxLB, a[3] = maxUB;
-      a[4] = (double)k; a[5] = (double)maxDepth;
-      return a;
-      
-      
-      
-      
-      
-      
+      while (pqMin.size() > 0) {
+        bj = pqMin.top();
+        pqMin.pop();
+        pqMax.push(bj); 
+      }
       
+      while(maxB - maxJ > _tol * (std::abs(maxJ) + std::abs(maxB)) / 2 &&
+            pqMax.top()->depth() < _maxDepth-1) {
+        bj = pqMax.top();
+        bj->subDivisions(subJacBez);
+        currentDepth = bj->depth() + 1;
+        setBJ.erase(bj);
+        pqMax.pop();
+        delete bj;
+        
+        for (int i = 0; i < bb->numDivisions; i++) {
+          jacBez.setAsProxy(subJacBez, i * numSamplingPt, numSamplingPt);
+          bj = new BezierJacobian(jacBez, jfs, currentDepth);
+          pqMax.push(bj);
+          setBJ.insert(bj);
+          minJ = std::min(minJ, bj->minJ());
+          maxJ = std::max(maxJ, bj->maxJ());
+        }
+        
+        minB = minJ;
+        maxB = maxJ;
+        std::set<BezierJacobian*>::iterator it;
+        for (it = setBJ.begin(); it != setBJ.end(); ++it) {
+          minB = std::min(minB, (*it)->minB());
+          maxB = std::max(maxB, (*it)->maxB());
+        }
+      }
       
+      while (pqMax.size() > 0) {
+        bj = pqMax.top();
+        pqMax.pop();
+        delete bj;
+      }
     }
-    _min_pJmin = std::min(_min_pJmin, (minJ+minB)/2);
-    _avg_pJmin += (minJ+minB)/2;
-    _min_ratioJ = std::min(_min_ratioJ, (minJ+minB)/(maxB+maxJ));
-    _avg_ratioJ += (minJ+minB)/(maxB+maxJ);
+		fwrite << minB/avgJ << " " << minB/maxB << "\r";
+    
+    if (data)
+    if (1-minB <= _tol * minJ && maxB-1 <= _tol * maxB)
+      (*data)[el[k]->getNum()].push_back(1.);
+    else if (1-minB/avgJ <= 1e-8)
+      (*data)[el[k]->getNum()].push_back(1.);
+    else
+      (*data)[el[k]->getNum()].push_back(minB/avgJ);
+    
+    _min_pJmin = std::min(_min_pJmin, minB/avgJ);
+    _avg_pJmin += minB/avgJ;
+    _min_ratioJ = std::min(_min_ratioJ, minB/maxB);
+    _avg_ratioJ += minB/maxB;
   }
- */}
+}
 
-//int *GMSH_AnalyseCurvedMeshPlugin::checkJacobian
-//(MElement *const *el, int numEl, int maxDepth, int method)
-//{
-//  int *a = new int[2];
-//  a[0] = a[1] = 0;
-//  if (numEl <= 0) return a;
-//
-//  switch (method) {
-//
-//    case 1 :
-//      for (int i = 0; i < numEl; i++) {
-//        int tag = method_1_2(el[i], maxDepth);
-//        if (tag < 0) {
-//          a[1]++;
-//          if (tag < -1)
-//            Msg::Info("Bad element : %d (with tag %d)", el[i]->getNum(), tag);
-//          else
-//            Msg::Info("Bad element : %d", el[i]->getNum());
-//        }
-//        else if (tag > 0) {
-//          el[i]->setVisibility(0);
-//          if (tag > 1)
-//            Msg::Info("Good element : %d (with tag %d)", el[i]->getNum(), tag);
-//        }
-//        else {
-//          a[0]++;
-//          Msg::Info("Element %d may be bad", el[i]->getNum());
-//        }
-//      }
-//      return a;
-//
-//    case 2 :
-//      std::vector<int> tag(numEl, UNDEF_JAC_TAG);
-//      method_2_2(el, tag, maxDepth);
-//
-//      Msg::Info(" ");
-//      Msg::Info("Bad elements :");
-//      for (unsigned int i = 0; i < tag.size(); i++) {
-//        if (tag[i] < 0) {
-//          if (tag[i] < -1)
-//            Msg::Info("%d (with tag %d)", el[i]->getNum(), tag[i]);
-//          else
-//            Msg::Info("%d", el[i]->getNum());
-//          a[1]++;
-//        }
-//      }
-//
-//      Msg::Info(" ");
-//      Msg::Info("Uncertain elements :");
-//      for (unsigned int i = 0; i < tag.size(); i++) {
-//        if (tag[i] == 0) {
-//          Msg::Info("%d", el[i]->getNum());
-//          a[0]++;
-//        }
-//      }
-//
-//      Msg::Info(" ");
-//      return a;
-//  }
-//}
-//
-//
-//int GMSH_AnalyseCurvedMeshPlugin::method_1_1(MElement *el, int depth)
-//{
-//  const polynomialBasis *fs = el->getFunctionSpace(-1);
-//  if (!fs) {
-//    Msg::Error("Function space not implemented for type of element %d", el->getNum());
-//    return 0;
-//  }
-//  const JacobianBasis *jfs = el->getJacobianFuncSpace(-1);
-//  if (!jfs) {
-//    Msg::Error("Jacobian function space not implemented for type of element %d", el->getNum());
-//    return 0;
-//  }
-//  const bezierBasis *bb = jfs->bezier;
-//
-//  int numSamplingPt = bb->points.size1();
-//  int dim = bb->points.size2();
-//  fullVector<double> jacobian(numSamplingPt);
-//
-//  for (int i = 0; i < numSamplingPt; i++) {
-//    double gsf[256][3];
-//    switch (dim) {
-//      case 1 :
-//        fs->df(bb->points(i,0),0,0, gsf);
-//        break;
-//      case 2 :
-//        fs->df(bb->points(i,0),bb->points(i,1),0, gsf);
-//        break;
-//      case 3 :
-//        fs->df(bb->points(i,0),bb->points(i,1),bb->points(i,2), gsf);
-//        break;
-//      default :
-//        Msg::Error("Can't get the gradient for %dD elements.", dim);
-//        return false;
-//    }
-//    double jac[3][3];
-//    jacobian(i) = getJacobian(gsf, jac, el);
-//  }
-//
-//  for (int i = 0; i < jacobian.size(); i++) {
-//    if (jacobian(i) <= 0.) return -1;
-//  }
-//
-//
-//  fullVector<double> jacBez(jacobian.size());
-//  bb->matrixLag2Bez.mult(jacobian, jacBez);
-//
-//  bool allPtPositive = true;
-//  for (int i = 0; i < jacBez.size(); i++) {
-//    if (jacBez(i) <= 0.) allPtPositive = false;
-//  }
-//  if (allPtPositive) return 1;
-//
-//
-//  if (depth <= 1) {
-//    return 0;
-//  }
-//  else{
-//    int tag = division(bb, jacBez, depth-1);
-//    if (tag < 0)
-//      return tag - 1;
-//    if (tag > 0)
-//      return tag + 1;
-//    return tag;
-//  }
-//}
-//
-//
-//int GMSH_AnalyseCurvedMeshPlugin::method_1_2(MElement *el, int depth)
-//{
-//  const polynomialBasis *fs = el->getFunctionSpace(-1);
-//  if (!fs) {
-//    Msg::Error("Function space not implemented for type of element %d", el->getNum());
-//    return 0;
-//  }
-//  const JacobianBasis *jfs = el->getJacobianFuncSpace(-1);
-//  if (!jfs) {
-//    Msg::Error("Jacobian function space not implemented for type of element %d", el->getNum());
-//    return 0;
-//  }
-//  const bezierBasis *bb = jfs->bezier;
-//
-//  int numSamplingPt = bb->points.size1();
-//  int dim = bb->points.size2();
-//  fullVector<double> jacobian(numSamplingPt);
-//
-//  
-//  setJacobian(el, jfs, jacobian);
-//
-//  {
-//    Msg::Info("Printing vector jac[%d]", el->getNum());
-//    Msg::Info("  ");
-//    for(int I = 0; I < jacobian.size(); I++){
-//      Msg::Info("%lf ", jacobian(I));
-//    }
-//    Msg::Info(" ");
-//  }
-//
-//  for (int i = 0; i < jacobian.size(); i++) {
-//    if (jacobian(i) <= 0.) return -1;
-//  }
-//
-//
-//  fullVector<double> jacBez(jacobian.size());
-//  bb->matrixLag2Bez.mult(jacobian, jacBez);
-//
-//  bool allPtPositive = true;
-//  for (int i = 0; i < jacBez.size(); i++) {
-//    if (jacBez(i) <= 0.) allPtPositive = false;
-//  }
-//  if (allPtPositive) return 1;
-//
-//
-//  if (depth <= 1) {
-//    return 0;
-//  }
-//  else{
-//    int tag = division(bb, jacBez, depth-1);
-//    if (tag < 0)
-//      return tag - 1;
-//    if (tag > 0)
-//      return tag + 1;
-//    return tag;
-//  }
-//}
-//
-//
-//void GMSH_AnalyseCurvedMeshPlugin::method_2_2
-//  (MElement *const *el, std::vector<int> &tags, int depth)
-//{
-//  const polynomialBasis *fs = el[0]->getFunctionSpace(-1);
-//  if (!fs) {
-//    Msg::Error("Function space not implemented for type of element %d", el[0]->getNum());
-//    return;
-//  }
-//  const JacobianBasis *jfs = el[0]->getJacobianFuncSpace(-1);
-//  if (!jfs) {
-//    Msg::Error("Jacobian function space not implemented for type of element %d", el[0]->getNum());
-//    return;
-//  }
-//  const bezierBasis *bb = jfs->bezier;
-//
-//  int numSamplingPt = bb->points.size1();
-//  int dim = bb->points.size2();
-//  int numEl = tags.size();
-//
-//  fullMatrix<double> jacobian(numSamplingPt, numEl);
-//  setJacobian(el, jfs, jacobian);
-//
-//  
-//  int numBad = 0;
-//
-//  for (int i = 0; i < numEl; i++) {
-//    bool isBad = false;
-//    for (int j = 0; j < jacobian.size1(); j++) {
-//      if (jacobian(j,i) <= 0.) isBad = true;
-//    }
-//    if (isBad) {
-//      tags[i] = -1;
-//      numBad++;
-//    }
-//  }
-//
-//
-//  fullMatrix<double> jacBez;
-//  std::vector<int> correspondingEl;
-//
-//  double critere = .2; // � d�finir suivant le temps de chaque op�ration
-//  if ((double) numBad / (double) numEl < critere) {// il vaut mieux calculer les points de controle de chaque �l�ment
-//    jacBez.resize(numSamplingPt, numEl);
-//    bb->matrixLag2Bez.mult(jacobian, jacBez);
-//    correspondingEl.resize(numEl);
-//    for (int i = 0; i < numEl; i++) correspondingEl[i] = i;
-//  }
-//  else {// il vaut mieux ne calculer que les points de controle des �l�ments encore incertains
-//    fullMatrix<double> newJac(numSamplingPt, numEl-numBad);
-//    fullMatrix<double> prox1(numSamplingPt,1);
-//    fullMatrix<double> prox2(numSamplingPt,1);
-//    int index = 0;
-//    correspondingEl.resize(numEl - numBad);
-//    for (int i = 0; i < numEl; i++) {
-//      if (tags[i] == UNDEF_JAC_TAG) {
-//        correspondingEl[index] = i;
-//        prox1.setAsProxy(newJac,index,1);
-//        prox2.setAsProxy(jacobian,i,1);
-//        prox1.copy(prox2);
-//      }
-//    }
-//    jacBez.resize(numSamplingPt, numEl-numBad);
-//    bb->matrixLag2Bez.mult(jacobian, jacBez);
-//  }
-//
-//
-//  int numGood = 0;
-//
-//  for (int i = 0; i < jacBez.size2(); i++) {
-//    bool allPtPositive = true;
-//    for (int j = 0; j < jacBez.size1(); j++) {
-//      if (jacBez(j,i) <= 0.) allPtPositive = false;
-//    }
-//    if (allPtPositive) {
-//      tags[correspondingEl[i]] = 1;
-//      numGood++;
-//    }
-//  }
-//
-//
-//  Msg::Warning("Not yet implemented for maxDepth > 1");
-//  depth = 1;
-//  if (depth <= 1) {
-//    for (int i = 0; i < jacBez.size2(); i++)
-//      if (tags[correspondingEl[i]] == UNDEF_JAC_TAG)
-//        tags[correspondingEl[i]] = 0;
-//    return;
-//  }
-//  /*else{
-//    int tag = division(jfs, jacBez, depth-1);
-//    if (tag < 0)
-//      return tag - 1;
-//    if (tag > 0)
-//      return tag + 1;
-//    return tag;
-//  }*/
-//  
-//}
-//
-//int GMSH_AnalyseCurvedMeshPlugin::division
-//  (const bezierBasis *jfs, const fullVector<double> &jacobian, int depth)
-//{
-//  if (jfs->subDivisor.size2() != jacobian.size()) {
-//    Msg::Error("Wrong sizes in division : [%d,%d] * [%d]",
-//      jfs->subDivisor.size1(), jfs->subDivisor.size2(), jacobian.size());
-//    Msg::Info(" ");
-//    return 0;
-//  }
-//
-//  fullVector<double> newJacobian(jfs->subDivisor.size1());
-//  jfs->subDivisor.mult(jacobian, newJacobian);
-//  
-//  for (int i = 0; i < jfs->numDivisions; i++) {
-//    for (int j = 0; j < jfs->numLagPts; j++)
-//      if (newJacobian(i * jfs->points.size1() + j) <= 0.) return -1;
-//  }
-//
-//  bool allPtPositive = true;
-//  for (int i = 0; i < newJacobian.size(); i++) {
-//    if (newJacobian(i) <= 0.) allPtPositive = false;
-//  }
-//  if (allPtPositive) return 1;
-//
-//
-//   We don't know if the jacobian is positif everywhere or not
-//   We subdivide if we still can do it (if depth > 0).
-//  if (depth <= 0) {
-//    return 0;
-//  }
-//  else{
-//    fullVector<double> subJacobian;
-//    std::vector<int> negTag, posTag;
-//    bool zeroTag = false;
-//
-//    for (int i = 0; i < jfs->numDivisions; i++)
-//    {
-//      subJacobian.setAsProxy(newJacobian, i * jacobian.size(), jacobian.size());
-//      int tag = division(jfs, subJacobian, depth-1);
-//      
-//      if (tag < 0)
-//        negTag.push_back(tag);
-//      else if (tag > 0)
-//        posTag.push_back(tag);
-//      else 
-//        zeroTag = true;
-//    }
-//
-//    if (negTag.size() > 0) return max(negTag) - 1;
-//    
-//    if (zeroTag) return 0;
-//
-//    return max(posTag) - 1;
-//  }
-//}
-//
-//
-//
-//  
-  /*{
-    Msg::Info("Printing matrix %s :", "nodesX");
-    int ni = nodesX.size1();
-    int nj = nodesX.size2();
-    for(int I = 0; I < ni; I++){
-      Msg::Info("  ");
-      for(int J = 0; J < nj; J++){
-        Msg::Info("%lf ", nodesX(I, J));
+void GMSH_AnalyseCurvedMeshPlugin::hideValid_ShowInvalid(std::vector<MElement*> &invalids)
+{
+  unsigned int current = 0;
+  invalids.push_back(NULL);
+  
+  switch (_dim) {
+   case 3 :
+    for(GModel::riter it = _m->firstRegion(); it != _m->lastRegion(); it++) {
+      GRegion *r = *it;
+      unsigned int numType[5] = {0, 0, 0, 0, 0};
+      r->getNumMeshElements(numType);
+      
+      for(int type = 0; type < 5; type++) {
+        MElement *const *el = r->getStartElementType(type);
+        for (int i = 0; i < numType[type]; ++i) {
+          if (el[i] == invalids[current]) {
+            ++current;
+            el[i]->setVisibility(1);
+          }
+          else
+            el[i]->setVisibility(0);
+        }
       }
     }
-    Msg::Info(" ");
-  }*/
+    break;
+    
+   case 2 :
+    for (GModel::fiter it = _m->firstFace(); it != _m->lastFace(); it++) {
+      GFace *f = *it;
+      unsigned int numType[3] = {0, 0, 0};
+      f->getNumMeshElements(numType);
+      
+      for (int type = 0; type < 3; type++) {
+        MElement *const *el = f->getStartElementType(type);
+        for (int i = 0; i < numType[type]; ++i) {
+          if (el[i] == invalids[current]) {
+            ++current;
+            el[i]->setVisibility(1);
+          }
+          else
+            el[i]->setVisibility(0);
+        }
+      }
+    }
+    break;
+    
+   case 1 :
+    for (GModel::eiter it = _m->firstEdge(); it != _m->lastEdge(); it++) {
+      GEdge *e = *it;
+      unsigned int numElement = e->getNumMeshElements();
+      MElement *const *el = e->getStartElementType(0);
+      for (int i = 0; i < numElement; ++i) {
+        if (el[i] == invalids[current]) {
+          ++current;
+          el[i]->setVisibility(1);
+        }
+        else
+          el[i]->setVisibility(0);
+      }
+    }
+    break;
+    
+   default :
+    break;
+  }
+  
+  invalids.pop_back();
+  
+  switch (_dim) {
+   case 3 :
+    for (GModel::fiter it = _m->firstFace(); it != _m->lastFace(); it++)
+      (*it)->setVisibility(0);
+    
+   case 2 :
+    for (GModel::eiter it = _m->firstEdge(); it != _m->lastEdge(); it++)
+      (*it)->setVisibility(0);
+    
+   case 1 :
+    for (GModel::viter it = _m->firstVertex(); it != _m->lastVertex(); it++)
+      (*it)->setVisibility(0);
+      
+   default :
+    break;
+  }
+}
+
+BezierJacobian::BezierJacobian(fullVector<double> &v, const JacobianBasis *jfs, int depth)
+{
+  _jacBez = v;
+  _depthSub = depth;
+  _jfs = jfs;
+  
+  _minJ = _maxJ = v(0);
+  int i = 1;
+  for (; i < jfs->bezier->numLagPts; i++) {
+    if (_minJ > v(i)) _minJ = v(i);
+    if (_maxJ < v(i)) _maxJ = v(i);
+  }
+  _minB = _minJ;
+  _maxB = _maxJ;
+  for (; i < v.size(); i++) {
+    if (_minB > v(i)) _minB = v(i);
+    if (_maxB < v(i)) _maxB = v(i);
+  }
+}
+
+bool lessMinB::operator()(BezierJacobian *bj1, BezierJacobian *bj2) const
+{
+  return bj1->minB() > bj2->minB();
+}
+bool lessMaxB::operator()(BezierJacobian *bj1, BezierJacobian *bj2) const
+{
+  return bj1->maxB() < bj2->maxB();
+}
+
+
diff --git a/Plugin/AnalyseCurvedMesh.h b/Plugin/AnalyseCurvedMesh.h
index 3d4e16fcdd38343425a4168e2aff6d9aa994982a..a1c2f174508b0641e680491f81c362de45dbd607 100644
--- a/Plugin/AnalyseCurvedMesh.h
+++ b/Plugin/AnalyseCurvedMesh.h
@@ -25,16 +25,14 @@ class GMSH_AnalyseCurvedMeshPlugin : public GMSH_PostPlugin
     
     int _numAnalysedEl;
     int _numInvalid, _numValid, _numUncertain;
-    double _min_Javg, _max_Javg;
+    double _min_Javg, _max_Javg, _avg_Javg;
     double _min_pJmin, _avg_pJmin;
     double _min_ratioJ, _avg_ratioJ;
-    //
     
   public :
     GMSH_AnalyseCurvedMeshPlugin(){}
     std::string getName() const { return "AnalyseCurvedMesh"; }
-    std::string getShortHelp() const
-    {
+    std::string getShortHelp() const {
       return "Check validity of elements and/or compute min&max of the jacobian";
     }
     std::string getHelp() const;
@@ -43,25 +41,24 @@ class GMSH_AnalyseCurvedMeshPlugin : public GMSH_PostPlugin
     StringXNumber *getOption(int);  
     PView *execute(PView *);
     void checkValidity(MElement *const *, int numEl, std::vector<MElement*> &invalids);
-    void checkValidity_BLAS(MElement *const *, int numEl, std::vector<MElement*> &invalids);
+    
+    //void storeJMin(MElement *const *, int numEl, std::map<int, std::vector<double> > &data);
+    
     
   private :
     void checkValidity(int toDo);
-    void computeMinMax();
-    void computeMinMax(MElement *const *, int numEl);
-    void hideValid_ShowInvalid(std::vector<MElement*> &invalids);
+    void computeMinMax(std::map<int, std::vector<double> > *data = 0);
+    void computeMinMax(MElement *const *, int numEl, std::map<int, std::vector<double> > *data = 0);
     int subDivision(const bezierBasis*, const fullVector<double>&, int depth);
-    /*bool isJacPositive(MElement *);
-    int method_1_1(MElement *, int depth);
-    int method_1_2(MElement *, int depth);
-    int method_1_3(MElement *, int depth);
-    void method_2_2(MElement *const *, std::vector<int> &tags, int depth);
-    void method_2_3(MElement *const *, std::vector<int> &tags, int depth);
-    //int checkJacobian(MElement *, int depth);
-    //int *checkJacobian2(MElement *const *, int numEl, int depth);
-    int *checkJacobian(MElement *const *, int numEl, int depth, int method);
-    int division(const bezierBasis *, const fullVector<double> &, int depth);
-    */
+    void hideValid_ShowInvalid(std::vector<MElement*> &invalids);
+};
+
+class BezierJacobian;
+struct lessMinB {
+  bool operator()(BezierJacobian*, BezierJacobian*) const;
+};
+struct lessMaxB {
+  bool operator()(BezierJacobian*, BezierJacobian*) const;
 };
 
 class BezierJacobian
@@ -70,31 +67,18 @@ private:
   fullVector<double> _jacBez;
   double _minJ, _maxJ, _minB, _maxB; //Extremum of Jac at corners and of bezier values
   int _depthSub;
-  int _num; // Used for map of minmaxB
-  static int _globalNum;
+  const JacobianBasis *_jfs;
   
 public:
   BezierJacobian(fullVector<double> &, const JacobianBasis *, int depth);
-  inline bool operator<(const BezierJacobian &other) const
-    {return other._maxB - _maxB - other._minB + _minB < 0;}
-  void partition(fullVector<double> &, const JacobianBasis *) const;
-  inline bool isObsolet(double maxLB, double minUB, double tol) const
-    {return _maxB - maxLB < tol &&  minUB - _minB < tol;}
+  void subDivisions(fullVector<double> &vect) const
+    {_jfs->bezier->subDivisor.mult(_jacBez, vect);}
   
-  int num() const {return _num;}
-  int depth() const {return _depthSub;}
-  double minJ() const {return _minJ;}
-  double minB() const {return _minB;}
-  double maxJ() const {return _maxJ;}
-  double maxB() const {return _maxB;}
-  double setMinMaxBounds(double &minLB, double &minUB, double &maxLB, double &maxUB) const
-  {
-    /*Msg::Info("setminmax : %g = %g - %g",_minJ-_minB,_minJ,_minB);
-    Msg::Info("setminmax : %g = %g - %g",_maxB-_maxJ,_maxB,_maxJ);Msg::Info(" ");
-    
-    int g;
-    std::cin >> g;*/
-      minUB = _minJ; minLB = _minB; maxUB = _maxB; maxLB = _maxJ;}
+  inline int depth() const {return _depthSub;}
+  inline double minJ() const {return _minJ;}
+  inline double maxJ() const {return _maxJ;}
+  inline double minB() const {return _minB;}
+  inline double maxB() const {return _maxB;}
 };
 
 #endif