diff --git a/contrib/HighOrderMeshOptimizer/CMakeLists.txt b/contrib/HighOrderMeshOptimizer/CMakeLists.txt
index f7311c8442876ce9bbe0db1d63d3f2279f75b934..29223ca3cd54a09fcdeafb1d3fa363c22560a162 100644
--- a/contrib/HighOrderMeshOptimizer/CMakeLists.txt
+++ b/contrib/HighOrderMeshOptimizer/CMakeLists.txt
@@ -8,6 +8,7 @@ set(SRC
   OptHOM.cpp 
   OptHomRun.cpp 
   OptHomIntegralBoundaryDist.cpp
+  OptHomCADDist.cpp
   ParamCoord.cpp 
   SuperEl.cpp 
   OptHomElastic.cpp
diff --git a/contrib/HighOrderMeshOptimizer/OptHOM.cpp b/contrib/HighOrderMeshOptimizer/OptHOM.cpp
index b255bcc8a6346e71451d565ec9be09590931b7dd..1b2f0307c019a5d2fbdb3a1e2ccf2fe840e5d2a3 100644
--- a/contrib/HighOrderMeshOptimizer/OptHOM.cpp
+++ b/contrib/HighOrderMeshOptimizer/OptHOM.cpp
@@ -36,7 +36,8 @@ static int NEVAL = 0;
 #include "OptHomRun.h"
 #include "GmshMessage.h"
 #include "GmshConfig.h"
-#include "ConjugateGradients.h"
+#include "OptHomCADDist.h"
+#include "MElement.h"
 #include "MLine.h"
 #include "MTriangle.h"
 #include "GModel.h"
@@ -112,35 +113,6 @@ bool OptHOM::addJacObjGrad(double &Obj, alglib::real_1d_array &gradObj)
   return true;
 }
 
-bool OptHOM::addJacObjGrad(double &Obj, std::vector<double> &gradObj)
-{
-  minJac = 1.e300;
-  maxJac = -1.e300;
-
-  for (int iEl = 0; iEl < mesh.nEl(); iEl++) {
-    // Scaled Jacobians
-    std::vector<double> sJ(mesh.nBezEl(iEl));
-    // Gradients of scaled Jacobians
-    std::vector<double> gSJ(mesh.nBezEl(iEl)*mesh.nPCEl(iEl));
-    mesh.scaledJacAndGradients (iEl,sJ,gSJ);
-
-    for (int l = 0; l < mesh.nBezEl(iEl); l++) {
-      double f1 = compute_f1(sJ[l], jacBar);
-      Obj += compute_f(sJ[l], jacBar);
-      if (_optimizeBarrierMax) {
-        Obj += compute_f(sJ[l], barrier_min);
-        f1 += compute_f1(sJ[l], barrier_min);
-      }
-      for (int iPC = 0; iPC < mesh.nPCEl(iEl); iPC++)
-        gradObj[mesh.indPCEl(iEl,iPC)] += f1*gSJ[mesh.indGSJ(iEl,l,iPC)];
-      minJac = std::min(minJac, sJ[l]);
-      maxJac = std::max(maxJac, sJ[l]);
-    }
-  }
-
-  return true;
-}
-
 
 bool OptHOM::addApproximationErrorObjGrad(double factor, double &Obj, alglib::real_1d_array &gradObj, simpleFunction<double>& fct)
 {
@@ -173,162 +145,6 @@ static void computeGradSFAtNodes (MElement *e, std::vector<std::vector<SVector3>
   }
 }
 
-static double MFaceGFaceDistance (MTriangle *t, GFace *gf,  std::vector<std::vector<SVector3> > *gsfT=0,  std::map<MVertex*,SVector3> *normalsToCAD=0) {
-  const double h = t->maxEdge();
-  double jac[3][3];
-  double distFace = 0.0;
-  //  for (int j=0;j<3;j++){
-  for (int j=0;j<t->getNumVertices();j++){
-    // get parametric coordinates of jth vertex
-    // the last line of the jacobian is the normal
-    // to the element @ (u_mesh,v_mesh)
-
-    if (gsfT){
-      double detJ = t->getJacobian((*gsfT)[j],jac);
-    }
-    else{
-      const nodalBasis &elbasis = *t->getFunctionSpace();
-      double u_mesh = elbasis.points(j,0);
-      double v_mesh = elbasis.points(j,1);
-      double detJ = t->getJacobian(u_mesh,v_mesh,0,jac);
-    }
-
-    SVector3 tg_mesh (jac[2][0],jac[2][1],jac[2][2]);
-    tg_mesh.normalize();
-
-    SVector3 tg_cad ;
-    if (normalsToCAD)tg_cad = (*normalsToCAD)[t->getVertex(j)];
-    else {
-      SPoint2 p_cad;
-      reparamMeshVertexOnFace(t->getVertex (j), gf, p_cad);
-      tg_cad = gf->normal(p_cad);
-      tg_cad.normalize();
-    }
-    SVector3 diff1 = (dot(tg_cad, tg_mesh) > 0) ?
-      tg_cad - tg_mesh : tg_cad + tg_mesh;
-    //    printf("%g %g %g vs %g %g %g\n",tg_cad.x(),tg_cad.y(),tg_cad.z(),tg_mesh.x(),tg_mesh.y(),tg_mesh.z());
-    distFace += diff1.norm();
-  }
-  return distFace;
-}
-
-static double MLineGEdgeDistance (MLine *l, GEdge *ge, FILE *f = 0) {
-  const nodalBasis &elbasis = *l->getFunctionSpace();
-  const double h = .25*0.5*distance (l->getVertex (0), l->getVertex (1) ) / (l->getNumVertices()-1);
-  double jac[3][3];
-  double distEdge = 0.0;
-
-  //  if(f)printf("%d\n",l->getNumVertices());
-
-  for (int j=0;j<l->getNumVertices();j++){
-    double t_mesh = elbasis.points(j,0);
-    //    if (f) printf("%g ",t_mesh);
-    double detJ = l->getJacobian(t_mesh,0,0,jac);
-    SVector3 tg_mesh (jac[0][0],jac[0][1],jac[0][2]);
-    tg_mesh.normalize();
-    double t_cad;
-    reparamMeshVertexOnEdge(l->getVertex (j), ge, t_cad);
-    SVector3 tg_cad = ge->firstDer(t_cad);
-    tg_cad.normalize();
-
-    SVector3 diff1 = (dot(tg_cad, tg_mesh) > 0) ?
-      tg_cad - tg_mesh : tg_cad + tg_mesh;
-
-    if (f){
-      fprintf (f,"SP(%g,%g,%g){%g};\n",l->getVertex (j)->x(),
-	       l->getVertex (j)->y(),l->getVertex (j)->z(),h*diff1.norm());
-    }
-
-    //    SVector3 n = crossprod(tg_cad,tg_mesh);
-    //    printf("%g %g vs %g %g\n",tg_cad.x(),tg_cad.y(),tg_mesh.x(),tg_mesh.y());
-    distEdge += diff1.norm();
-  }
-  //  if(f)printf("\n");
-  return h*distEdge;
-}
-
-
-void distanceFromElementsToGeometry(GModel *gm, int dim, std::map<MElement*,double> &distances){
-
-  std::map<MEdge,double,Less_Edge> dist2Edge;
-  for (GModel::eiter it = gm->firstEdge(); it != gm->lastEdge(); ++it){
-    if ((*it)->geomType() == GEntity::Line)continue;
-    for (unsigned int i=0;i<(*it)->lines.size(); i++){
-      double d = MLineGEdgeDistance ( (*it)->lines[i] , *it );
-      MEdge e =  (*it)->lines[i]->getEdge(0);
-      dist2Edge[e] = d;
-    }
-  }
-
-  //  printf("DISTANCE TO GEOMETRY : 1D PART %22.15E\n",Obj);
-
-  std::map<MFace,double,Less_Face> dist2Face;
-  for(GModel::fiter it = gm->firstFace(); it != gm->lastFace(); ++it){
-    if ((*it)->geomType() == GEntity::Plane)continue;
-    for (unsigned int i=0;i<(*it)->triangles.size(); i++){
-      double d = MFaceGFaceDistance ( (*it)->triangles[i] , *it );
-      MFace f =  (*it)->triangles[i]->getFace(0);
-      dist2Face[f] = d;
-    }
-  }
-
-  std::vector<GEntity*> entities;
-  gm->getEntities(entities);
-  for (int iEnt = 0; iEnt < entities.size(); ++iEnt) {
-    GEntity* &entity = entities[iEnt];
-    if (entity->dim() != dim) continue;
-    for (int iEl = 0; iEl < entity->getNumMeshElements();iEl++) {       // Detect bad elements
-      MElement *element = entity->getMeshElement(iEl);
-      double d = 0.0;
-      for (int iEdge = 0; iEdge < element->getNumEdges(); ++iEdge) {
-	MEdge e =  element->getEdge(iEdge);
-	std::map<MEdge,double,Less_Edge>::iterator it = dist2Edge.find(e);
-	if(it != dist2Edge.end())d+=it->second;
-      }
-      for (int iFace = 0; iFace < element->getNumFaces(); ++iFace) {
-	MFace f =  element->getFace(iFace);
-	std::map<MFace,double,Less_Face>::iterator it = dist2Face.find(f);
-	if(it != dist2Face.end())d+=it->second;
-      }
-      distances[element] = d;
-    }
-  }
-}
-
-
-double distanceToGeometry(GModel *gm)
-{
-
-  FILE *f = fopen("toto.pos","w");
-  fprintf(f,"View \"\"{\n");
-
-  double Obj = 0.0;
-
-  for (GModel::eiter it = gm->firstEdge(); it != gm->lastEdge(); ++it){
-    if ((*it)->geomType() == GEntity::Line)continue;
-    for (unsigned int i=0;i<(*it)->lines.size(); i++){
-      //Obj += MLineGEdgeDistance ( (*it)->lines[i] , *it,f );
-      Obj = std::max(MLineGEdgeDistance ( (*it)->lines[i] , *it, f ),Obj);
-    }
-  }
-
-    printf("DISTANCE TO GEOMETRY : 1D PART %22.15E\n",Obj);
-
-  for(GModel::fiter it = gm->firstFace(); it != gm->lastFace(); ++it){
-    if ((*it)->geomType() == GEntity::Plane)continue;
-    //    printf("FACE %d with %d triangles\n",(*it)->tag(),(*it)->triangles.size());
-    for (unsigned int i=0;i<(*it)->triangles.size(); i++){
-      //Obj += MFaceGFaceDistance ( (*it)->triangles[i] , *it );
-      Obj = std::max(Obj,MFaceGFaceDistance ( (*it)->triangles[i] , *it ));
-    }
-  }
-
-  printf("DISTANCE TO GEOMETRY : 1D AND 2D PART %22.15E\n",Obj);
-  fprintf(f,"};\n");
-  fclose(f);
-  return Obj;
-}
-
 
 bool OptHOM::addBndObjGrad(double factor, double &Obj, alglib::real_1d_array &gradObj)
 {
@@ -355,21 +171,21 @@ bool OptHOM::addBndObjGrad(double factor, double &Obj, alglib::real_1d_array &gr
     for (unsigned int i=0;i<(*it)->lines.size(); i++){
       doWeCompute[i] = false;
       for (unsigned int j=0;j<(*it)->lines[i]->getNumVertices(); j++){
-	int index = mesh.getFreeVertexStartIndex((*it)->lines[i]->getVertex(j));
-	if (index >=0){
-	  doWeCompute[i] = true;
-	  continue;
-	}
+        int index = mesh.getFreeVertexStartIndex((*it)->lines[i]->getVertex(j));
+        if (index >=0){
+          doWeCompute[i] = true;
+          continue;
+        }
       }
     }
 
     std::vector<double> dist((*it)->lines.size());
     for (unsigned int i=0;i<(*it)->lines.size(); i++){
       if (doWeCompute[i]){
-	// compute the distance from the geometry to the mesh
-	dist[i] = MLineGEdgeDistance ( (*it)->lines[i] , *it );
-	maxDistCAD = std::max(maxDistCAD,dist[i]);
-	distCAD += dist [i] * factor;
+        // compute the distance from the geometry to the mesh
+        dist[i] = MLineGEdgeDistance ( (*it)->lines[i] , *it );
+        maxDistCAD = std::max(maxDistCAD,dist[i]);
+        distCAD += dist [i] * factor;
       }
     }
     // be clever to compute the derivative : iterate on all
@@ -379,50 +195,50 @@ bool OptHOM::addBndObjGrad(double factor, double &Obj, alglib::real_1d_array &gr
     const double eps = 1.e-6;
     for (unsigned int i=0;i<(*it)->lines.size(); i++){
       if (doWeCompute[i]){
-	for (int j=2 ; j<(*it)->lines[i]->getNumVertices()  ; j++){
-	  MVertex *v = (*it)->lines[i]->getVertex(j);
-	  int index = mesh.getFreeVertexStartIndex(v);
-	  //	printf("%d %d (%d %d)\n",v->getNum(),index,v->onWhat()->tag(),v->onWhat()->dim());
-	  if (index >= 0){
-	    double t;
-	    v->getParameter(0,t);
-	    SPoint3 pp (v->x(),v->y(),v->z());
-	    GPoint gp = (*it)->point(t+eps);
-	    v->setParameter(0,t+eps);
-	    v->setXYZ(gp.x(),gp.y(),gp.z());
-	    double dist2 = MLineGEdgeDistance ( (*it)->lines[i] , *it );
-	    double deriv = (dist2 - dist[i])/eps;
-	    v->setXYZ(pp.x(),pp.y(),pp.z());
-	    v->setParameter(0,t);
-	    //	  printf("%g %g %g\n",dist[i],dist2, MLineGEdgeDistance ( (*it)->lines[i] , *it ));
-	    // get the index of the vertex
-	    gradObj[index] += deriv * factor;
-	  }
-	}
+        for (int j=2 ; j<(*it)->lines[i]->getNumVertices()  ; j++){
+          MVertex *v = (*it)->lines[i]->getVertex(j);
+          int index = mesh.getFreeVertexStartIndex(v);
+          //	printf("%d %d (%d %d)\n",v->getNum(),index,v->onWhat()->tag(),v->onWhat()->dim());
+          if (index >= 0){
+            double t;
+            v->getParameter(0,t);
+            SPoint3 pp (v->x(),v->y(),v->z());
+            GPoint gp = (*it)->point(t+eps);
+            v->setParameter(0,t+eps);
+            v->setXYZ(gp.x(),gp.y(),gp.z());
+            double dist2 = MLineGEdgeDistance ( (*it)->lines[i] , *it );
+            double deriv = (dist2 - dist[i])/eps;
+            v->setXYZ(pp.x(),pp.y(),pp.z());
+            v->setParameter(0,t);
+            //	  printf("%g %g %g\n",dist[i],dist2, MLineGEdgeDistance ( (*it)->lines[i] , *it ));
+            // get the index of the vertex
+            gradObj[index] += deriv * factor;
+          }
+        }
       }
       //    printf("done\n");
       // For a low order vertex classified on the GEdge, we recompute
     // two distances for the two MLines connected to the vertex
       for (unsigned int i=0;i<(*it)->lines.size()-1; i++){
-	MVertex *v =  (*it)->lines[i]->getVertex(1);
-	int index = mesh.getFreeVertexStartIndex(v);
-	if (index >= 0){
-	  double t;
-	  v->getParameter(0,t);
-	  SPoint3 pp (v->x(),v->y(),v->z());
-	  GPoint gp = (*it)->point(t+eps);
-	  v->setParameter(0,t+eps);
-	  v->setXYZ(gp.x(),gp.y(),gp.z());
-	  MLine *l1 = (*it)->lines[i];
-	  MLine *l2 = (*it)->lines[i+1];
-	  //	printf("%d %d -- %d %d\n",l1->getVertex(0)->getNum(),l1->getVertex(1)->getNum(),l2->getVertex(0)->getNum(),l2->getVertex(1)->getNum());
-	  double deriv =
-	    (MLineGEdgeDistance ( l1 , *it ) - dist[i])  /eps +
-	    (MLineGEdgeDistance ( l2 , *it ) - dist[i+1])/eps;
-	  v->setXYZ(pp.x(),pp.y(),pp.z());
-	  v->setParameter(0,t);
-	  gradObj[index] += deriv * factor;
-	}
+        MVertex *v =  (*it)->lines[i]->getVertex(1);
+        int index = mesh.getFreeVertexStartIndex(v);
+        if (index >= 0){
+          double t;
+          v->getParameter(0,t);
+          SPoint3 pp (v->x(),v->y(),v->z());
+          GPoint gp = (*it)->point(t+eps);
+          v->setParameter(0,t+eps);
+          v->setXYZ(gp.x(),gp.y(),gp.z());
+          MLine *l1 = (*it)->lines[i];
+          MLine *l2 = (*it)->lines[i+1];
+          //	printf("%d %d -- %d %d\n",l1->getVertex(0)->getNum(),l1->getVertex(1)->getNum(),l2->getVertex(0)->getNum(),l2->getVertex(1)->getNum());
+          double deriv =
+            (MLineGEdgeDistance ( l1 , *it ) - dist[i])  /eps +
+            (MLineGEdgeDistance ( l2 , *it ) - dist[i+1])/eps;
+          v->setXYZ(pp.x(),pp.y(),pp.z());
+          v->setParameter(0,t);
+          gradObj[index] += deriv * factor;
+        }
       }
     }
   }
@@ -445,32 +261,32 @@ bool OptHOM::addBndObjGrad(double factor, double &Obj, alglib::real_1d_array &gr
     for (unsigned int i=0;i<(*it)->triangles.size(); i++){
       doWeCompute[i] = false;
       for (unsigned int j=0;j<(*it)->triangles[i]->getNumVertices(); j++){
-	int index = mesh.getFreeVertexStartIndex((*it)->triangles[i]->getVertex(j));
-	if (index >=0){
-	  doWeCompute[i] = true;
-	}
+        int index = mesh.getFreeVertexStartIndex((*it)->triangles[i]->getVertex(j));
+        if (index >=0){
+          doWeCompute[i] = true;
+        }
       }
       if (doWeCompute[i]){
-	for (unsigned int j=0;j<(*it)->triangles[i]->getNumVertices(); j++){
-	  MVertex *v = (*it)->triangles[i]->getVertex(j);
-	  if (normalsToCAD.find(v) == normalsToCAD.end()){
-	    SPoint2 p_cad;
-	    reparamMeshVertexOnFace(v, *it, p_cad);
-	    SVector3 tg_cad = (*it)->normal(p_cad);
-	    tg_cad.normalize();
-	    normalsToCAD[v] = tg_cad;
-	  }
-	}
+        for (unsigned int j=0;j<(*it)->triangles[i]->getNumVertices(); j++){
+          MVertex *v = (*it)->triangles[i]->getVertex(j);
+          if (normalsToCAD.find(v) == normalsToCAD.end()){
+            SPoint2 p_cad;
+            reparamMeshVertexOnFace(v, *it, p_cad);
+            SVector3 tg_cad = (*it)->normal(p_cad);
+            tg_cad.normalize();
+            normalsToCAD[v] = tg_cad;
+          }
+        }
       }
     }
 
     for (unsigned int i=0;i<(*it)->triangles.size(); i++){
       // compute the distance from the geometry to the mesh
       if(doWeCompute[i]){
-	const double d = MFaceGFaceDistance ( (*it)->triangles[i] , *it , &gsfT, &normalsToCAD);
-	dist[(*it)->triangles[i]] = d;
-	maxDistCAD = std::max(maxDistCAD,d);
-	distCAD += d * factor;
+        const double d = MFaceGFaceDistance ( (*it)->triangles[i] , *it , &gsfT, &normalsToCAD);
+        dist[(*it)->triangles[i]] = d;
+        maxDistCAD = std::max(maxDistCAD,d);
+        distCAD += d * factor;
       }
     }
 
@@ -478,57 +294,57 @@ bool OptHOM::addBndObjGrad(double factor, double &Obj, alglib::real_1d_array &gr
     const double eps = 1.e-6;
     for (unsigned int i=0;i<(*it)->triangles.size(); i++){
       if(doWeCompute[i]){
-	for (unsigned int j=0;j<(*it)->triangles[i]->getNumVertices(); j++){
-	  //    for (; itm !=v2t.end(); ++itm){
-	  MVertex   *v = (*it)->triangles[i]->getVertex(j);
-	  if(v->onWhat()->dim() == 1){
-	    int index = mesh.getFreeVertexStartIndex(v);
-	    if (index >= 0){
-	      MTriangle *t = (*it)->triangles[i];
-	      GEdge *ge = v->onWhat()->cast2Edge();
-	      double t_;
-	      v->getParameter(0,t_);
-	      SPoint3 pp (v->x(),v->y(),v->z());
-	      GPoint gp = ge->point(t_+eps);
-	      v->setParameter(0,t_+eps);
-	      v->setXYZ(gp.x(),gp.y(),gp.z());
-	      const double distT = dist[t];
-	      double deriv =  (MFaceGFaceDistance ( t , *it , &gsfT, &normalsToCAD) - distT)  /eps;
-	      v->setXYZ(pp.x(),pp.y(),pp.z());
-	      v->setParameter(0,t_);
-	      gradObj[index] += deriv * factor;
-	    }
-	  }
-
-	  if(v->onWhat() == *it){
-	    int index = mesh.getFreeVertexStartIndex(v);
-	    if (index >= 0){
-	      MTriangle *t = (*it)->triangles[i];
-	      double uu,vv;
-	      v->getParameter(0,uu);
-	      v->getParameter(1,vv);
-	      SPoint3 pp (v->x(),v->y(),v->z());
-
-	      const double distT = dist[t];
-
-	      GPoint gp = (*it)->point(uu+eps,vv);
-	      v->setParameter(0,uu+eps);
-	      v->setXYZ(gp.x(),gp.y(),gp.z());
-	      double deriv = (MFaceGFaceDistance ( t , *it, &gsfT, &normalsToCAD ) - distT)  /eps;
-	      v->setXYZ(pp.x(),pp.y(),pp.z());
-	      v->setParameter(0,uu);
-	      gradObj[index] += deriv * factor;
-
-	      gp = (*it)->point(uu,vv+eps);
-	      v->setParameter(1,vv+eps);
-	      v->setXYZ(gp.x(),gp.y(),gp.z());
-	      deriv = (MFaceGFaceDistance ( t , *it, &gsfT, &normalsToCAD ) - distT)  /eps;
-	      v->setXYZ(pp.x(),pp.y(),pp.z());
-	      v->setParameter(1,vv);
-	      gradObj[index+1] += deriv * factor;
-	    }
-	  }
-	}
+        for (unsigned int j=0;j<(*it)->triangles[i]->getNumVertices(); j++){
+          //    for (; itm !=v2t.end(); ++itm){
+          MVertex   *v = (*it)->triangles[i]->getVertex(j);
+          if(v->onWhat()->dim() == 1){
+            int index = mesh.getFreeVertexStartIndex(v);
+            if (index >= 0){
+              MTriangle *t = (*it)->triangles[i];
+              GEdge *ge = v->onWhat()->cast2Edge();
+              double t_;
+              v->getParameter(0,t_);
+              SPoint3 pp (v->x(),v->y(),v->z());
+              GPoint gp = ge->point(t_+eps);
+              v->setParameter(0,t_+eps);
+              v->setXYZ(gp.x(),gp.y(),gp.z());
+              const double distT = dist[t];
+              double deriv =  (MFaceGFaceDistance ( t , *it , &gsfT, &normalsToCAD) - distT)  /eps;
+              v->setXYZ(pp.x(),pp.y(),pp.z());
+              v->setParameter(0,t_);
+              gradObj[index] += deriv * factor;
+            }
+          }
+
+          if(v->onWhat() == *it){
+            int index = mesh.getFreeVertexStartIndex(v);
+            if (index >= 0){
+              MTriangle *t = (*it)->triangles[i];
+              double uu,vv;
+              v->getParameter(0,uu);
+              v->getParameter(1,vv);
+              SPoint3 pp (v->x(),v->y(),v->z());
+
+              const double distT = dist[t];
+
+              GPoint gp = (*it)->point(uu+eps,vv);
+              v->setParameter(0,uu+eps);
+              v->setXYZ(gp.x(),gp.y(),gp.z());
+              double deriv = (MFaceGFaceDistance ( t , *it, &gsfT, &normalsToCAD ) - distT)  /eps;
+              v->setXYZ(pp.x(),pp.y(),pp.z());
+              v->setParameter(0,uu);
+              gradObj[index] += deriv * factor;
+
+              gp = (*it)->point(uu,vv+eps);
+              v->setParameter(1,vv+eps);
+              v->setXYZ(gp.x(),gp.y(),gp.z());
+              deriv = (MFaceGFaceDistance ( t , *it, &gsfT, &normalsToCAD ) - distT)  /eps;
+              v->setXYZ(pp.x(),pp.y(),pp.z());
+              v->setParameter(1,vv);
+              gradObj[index+1] += deriv * factor;
+            }
+          }
+        }
       }
     }
   }
@@ -539,53 +355,6 @@ bool OptHOM::addBndObjGrad(double factor, double &Obj, alglib::real_1d_array &gr
   return true;
 }
 
-bool OptHOM::addBndObjGrad2(double factor, double &Obj, alglib::real_1d_array &gradObj)
-{
-  maxDistCAD = 0.0;
-
-  std::vector<double> gradF;
-  double DISTANCE = 0.0;
-  for (int iEl = 0; iEl < mesh.nEl(); iEl++) {
-    double f;
-    if (mesh.bndDistAndGradients(iEl, f, gradF, geomTol)) {
-      maxDistCAD = std::max(maxDistCAD,f);
-      DISTANCE += f;
-      Obj += f * factor;
-      for (size_t i = 0; i < mesh.nPCEl(iEl); ++i){
-        gradObj[mesh.indPCEl(iEl, i)] += gradF[i] * factor;
-	//	printf("gradf[%d] = %12.5E\n",i,gradF[i]*factor);
-      }
-    }
-  }
-  //  printf("DIST = %12.5E\n",DISTANCE);
-  return true;
-
-}
-
-
-bool OptHOM::addBndObjGrad(double factor, double &Obj, std::vector<double> &gradObj)
-{
-  maxDistCAD = 0.0;
-
-  std::vector<double> gradF;
-  double DISTANCE = 0.0;
-  for (int iEl = 0; iEl < mesh.nEl(); iEl++) {
-    double f;
-    if (mesh.bndDistAndGradients(iEl, f, gradF, geomTol)) {
-      maxDistCAD = std::max(maxDistCAD,f);
-      DISTANCE += f;
-      Obj += f * factor;
-      for (size_t i = 0; i < mesh.nPCEl(iEl); ++i){
-        gradObj[mesh.indPCEl(iEl, i)] += gradF[i] * factor;
-	//	printf("gradf[%d] = %12.5E\n",i,gradF[i]*factor);
-      }
-    }
-  }
-  //  printf("DIST = %12.5E\n",DISTANCE);
-  return true;
-
-}
-
 
 
 bool OptHOM::addMetricMinObjGrad(double &Obj, alglib::real_1d_array &gradObj)
@@ -640,30 +409,6 @@ bool OptHOM::addDistObjGrad(double Fact, double &Obj,
   return true;
 }
 
-bool OptHOM::addDistObjGrad(double Fact, double &Obj,
-                            std::vector<double> &gradObj)
-{
-  maxDist = 0;
-  avgDist = 0;
-  int nbBnd = 0;
-
-  for (int iFV = 0; iFV < mesh.nFV(); iFV++) {
-    const double dSq = mesh.distSq(iFV), dist = sqrt(dSq);
-    Obj += Fact * dSq;
-    std::vector<double> gDSq(mesh.nPCFV(iFV));
-    mesh.gradDistSq(iFV,gDSq);
-    for (int iPC = 0; iPC < mesh.nPCFV(iFV); iPC++)
-      gradObj[mesh.indPCFV(iFV,iPC)] += Fact*gDSq[iPC];
-    maxDist = std::max(maxDist, dist);
-    avgDist += dist;
-    nbBnd++;
-  }
-  if (nbBnd != 0) avgDist /= nbBnd;
-
-  return true;
-}
-
-
 // FIXME TEST
 // Assume a unit square centered on 0,0
 // fct is
@@ -678,25 +423,6 @@ bool OptHOM::addDistObjGrad(double Fact, double &Obj,
 //  }
 //};
 
-// Gmsh's (cheaper) version of the optimizer
-void OptHOM::evalObjGrad(std::vector<double> &x,
-			 double &Obj,
-			 bool gradsNeeded,
-                         std::vector<double> &gradObj)
-{
-  mesh.updateMesh(x.data());
-  Obj = 0.;
-  for (unsigned int i = 0; i < gradObj.size(); i++) gradObj[i] = 0.;
-
-  /// control Jacobians
-  addJacObjGrad(Obj, gradObj);
-  /// Control distance to the straight sided mesh
-  addDistObjGrad(lambda, Obj, gradObj);
-  if(_optimizeCAD)
-    addBndObjGrad(lambda3, Obj, gradObj);
-
-}
-
 
 void OptHOM::evalObjGrad(const alglib::real_1d_array &x, double &Obj,
                          alglib::real_1d_array &gradObj)
@@ -734,12 +460,6 @@ void evalObjGradFunc(const alglib::real_1d_array &x, double &Obj,
   (static_cast<OptHOM*>(HOInst))->evalObjGrad(x, Obj, gradObj);
 }
 
-void evalObjGradFunc(std::vector<double> &x, double &Obj, bool needGrad,
-                     std::vector<double> &gradObj, void *HOInst)
-{
-  (static_cast<OptHOM*>(HOInst))->evalObjGrad(x, Obj, true, gradObj);
-}
-
 
 void OptHOM::recalcJacDist()
 {
@@ -803,13 +523,6 @@ void OptHOM::calcScale(alglib::real_1d_array &scale)
   }
 }
 
-void OptHOM::OptimPass(std::vector<double> &x, int itMax)
-{
-  Msg::Info("--- In-house Optimization pass with initial jac. range (%g, %g), jacBar = %g",
-            minJac, maxJac, jacBar);
-  GradientDescent (evalObjGradFunc, x, this);
-}
-
 
 void OptHOM::OptimPass(alglib::real_1d_array &x, int itMax)
 {
@@ -978,100 +691,4 @@ int OptHOM::optimize(double weight, double weightCAD, double b_min,
   return -1;
 }
 
-
-int OptHOM::optimize_inhouse(double weight, double weightCAD, double b_min,
-			     double b_max, bool optimizeMetricMin, int pInt,
-			     int itMax, int optPassMax, int optCAD, double distanceMax, double tolerance)
-{
-  barrier_min = b_min;
-  barrier_max = b_max;
-  distance_max = distanceMax;
-  progressInterv = pInt;
-//  powM = 4;
-//  powP = 3;
-
-  _optimizeMetricMin = optimizeMetricMin;
-  _optimizeCAD = optCAD;
-  // Set weights & length scale for non-dimensionalization
-  lambda = weight;
-  lambda3 = weightCAD;
-  geomTol = tolerance;
-  std::vector<double> dSq(mesh.nEl());
-  mesh.distSqToStraight(dSq);
-  const double maxDSq = *max_element(dSq.begin(),dSq.end());
-  if (maxDSq < 1.e-10) {                                        // Length scale for non-dim. distance
-    std::vector<double> sSq(mesh.nEl());
-    mesh.elSizeSq(sSq);
-    const double maxSSq = *max_element(sSq.begin(),sSq.end());
-    invLengthScaleSq = 1./maxSSq;
-  }
-  else invLengthScaleSq = 1./maxDSq;
-
-  // Set initial guess
-  std::vector<double> x(mesh.nPC());
-  mesh.getUvw(x.data());
-
-  // Calculate initial performance
-  recalcJacDist();
-  initMaxDist = maxDist;
-  initAvgDist = avgDist;
-
-  const double jacBarStart = (minJac > 0.) ? 0.9*minJac : 1.1*minJac;
-  jacBar = jacBarStart;
-
-  _optimizeBarrierMax = false;
-  // Calculate initial objective function value and gradient
-  initObj = 0.;
-  std::vector<double>gradObj(mesh.nPC());
-  for (int i = 0; i < mesh.nPC(); i++) gradObj[i] = 0.;
-  evalObjGrad(x, initObj, true, gradObj);
-
-  Msg::Info("Start optimizing %d elements (%d vertices, %d free vertices, %d variables) "
-            "with min barrier %g and max. barrier %g", mesh.nEl(), mesh.nVert(),
-            mesh.nFV(), mesh.nPC(), barrier_min, barrier_max);
-
-  int ITER = 0;
-  bool minJacOK = true;
-
-  while (minJac < barrier_min || (maxDistCAD > distance_max && _optimizeCAD)) {
-    const double startMinJac = minJac;
-    OptimPass(x, itMax);
-    recalcJacDist();
-    jacBar = (minJac > 0.) ? 0.9*minJac : 1.1*minJac;
-    if (_optimizeCAD)   jacBar = std::min(jacBar,barrier_min);
-    if (ITER ++ > optPassMax) {
-      minJacOK = (minJac > barrier_min && (maxDistCAD < distance_max || !_optimizeCAD));
-      break;
-    }
-    if (fabs((minJac-startMinJac)/startMinJac) < 0.01) {
-      Msg::Info("Stagnation in minJac detected, stopping optimization");
-      minJacOK = false;
-      break;
-    }
-  }
-
-  ITER = 0;
-  if (minJacOK && (!_optimizeMetricMin)) {
-    _optimizeBarrierMax = true;
-    jacBar =  1.1 * maxJac;
-    while (maxJac > barrier_max ) {
-      const double startMaxJac = maxJac;
-      OptimPass(x, itMax);
-      recalcJacDist();
-      jacBar =  1.1 * maxJac;
-      if (ITER ++ > optPassMax) break;
-      if (fabs((maxJac-startMaxJac)/startMaxJac) < 0.01) {
-        Msg::Info("Stagnation in maxJac detected, stopping optimization");
-        break;
-      }
-    }
-  }
-
-  Msg::Info("Optimization done Range (%g,%g)", minJac, maxJac);
-
-  if (minJac > barrier_min && maxJac < barrier_max) return 1;
-  if (minJac > 0.0) return 0;
-  return -1;
-}
-
 #endif
diff --git a/contrib/HighOrderMeshOptimizer/OptHOM.h b/contrib/HighOrderMeshOptimizer/OptHOM.h
index a4927fd7a6596fd01ac085f47e7b9ba0557b3262..7e1c61448989aaf39752ab60fb92538f4f8b8a0b 100644
--- a/contrib/HighOrderMeshOptimizer/OptHOM.h
+++ b/contrib/HighOrderMeshOptimizer/OptHOM.h
@@ -54,15 +54,9 @@ public:
   int optimize(double lambda, double lambda3, double barrier_min, double barrier_max,
                bool optimizeMetricMin, int pInt, int itMax, int optPassMax,
                int optimizeCAD, double optCADDistMax, double tolerance);
-  int optimize_inhouse(double weight, double weightCAD, double b_min, double b_max,
-                       bool optimizeMetricMin, int pInt, int itMax, int optPassMax,
-                       int optCAD, double distanceMax, double tolerance);
   void recalcJacDist();
   inline void getJacDist(double &minJ, double &maxJ, double &maxD, double &avgD);
   void updateMesh(const alglib::real_1d_array &x);
-  void evalObjGrad(std::vector<double> &x, double &Obj, bool gradsNeeded,
-		   std::vector<double> &gradObj);
-
   void evalObjGrad(const alglib::real_1d_array &x, double &Obj,
                    alglib::real_1d_array &gradObj);
   void printProgress(const alglib::real_1d_array &x, double Obj);
@@ -80,16 +74,11 @@ public:
                      // true : minimize the distance between mesh and CAD
   bool addApproximationErrorObjGrad(double Fact, double &Obj, alglib::real_1d_array &gradObj, simpleFunction<double>& fct);
   bool addJacObjGrad(double &Obj, alglib::real_1d_array &gradObj);
-  bool addJacObjGrad(double &Obj, std::vector<double> &);
   bool addBndObjGrad (double Fact, double &Obj, alglib::real_1d_array &gradObj);
-  bool addBndObjGrad2(double Fact, double &Obj, alglib::real_1d_array &gradObj);
-  bool addBndObjGrad(double Fact, double &Obj, std::vector<double> &gradObj);
   bool addMetricMinObjGrad(double &Obj, alglib::real_1d_array &gradObj);
-  bool addDistObjGrad(double Fact, double &Obj, std::vector<double> &gradObj);
   bool addDistObjGrad(double Fact, double &Obj, alglib::real_1d_array &gradObj);
   void calcScale(alglib::real_1d_array &scale);
   void OptimPass(alglib::real_1d_array &x, int itMax);
-  void OptimPass(std::vector<double> &x, int itMax);
 };
 
 void OptHOM::getJacDist(double &minJ, double &maxJ, double &maxD, double &avgD)
diff --git a/contrib/HighOrderMeshOptimizer/OptHomCADDist.cpp b/contrib/HighOrderMeshOptimizer/OptHomCADDist.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4644d77435aa66665fc54eef96b489d76a0fc7ad
--- /dev/null
+++ b/contrib/HighOrderMeshOptimizer/OptHomCADDist.cpp
@@ -0,0 +1,168 @@
+// TODO: Header
+
+#include "MLine.h"
+#include "MTriangle.h"
+#include "GModel.h"
+#include "OptHomCADDist.h"
+
+
+double MFaceGFaceDistance(MTriangle *t, GFace *gf,
+                          std::vector<std::vector<SVector3> > *gsfT,
+                          std::map<MVertex*,SVector3> *normalsToCAD) {
+  const double h = t->maxEdge();
+  double jac[3][3];
+  double distFace = 0.0;
+  //  for (int j=0;j<3;j++){
+  for (int j=0;j<t->getNumVertices();j++){
+    // get parametric coordinates of jth vertex
+    // the last line of the jacobian is the normal
+    // to the element @ (u_mesh,v_mesh)
+
+    if (gsfT){
+      double detJ = t->getJacobian((*gsfT)[j],jac);
+    }
+    else{
+      const nodalBasis &elbasis = *t->getFunctionSpace();
+      double u_mesh = elbasis.points(j,0);
+      double v_mesh = elbasis.points(j,1);
+      double detJ = t->getJacobian(u_mesh,v_mesh,0,jac);
+    }
+
+    SVector3 tg_mesh (jac[2][0],jac[2][1],jac[2][2]);
+    tg_mesh.normalize();
+
+    SVector3 tg_cad ;
+    if (normalsToCAD)tg_cad = (*normalsToCAD)[t->getVertex(j)];
+    else {
+      SPoint2 p_cad;
+      reparamMeshVertexOnFace(t->getVertex (j), gf, p_cad);
+      tg_cad = gf->normal(p_cad);
+      tg_cad.normalize();
+    }
+    SVector3 diff1 = (dot(tg_cad, tg_mesh) > 0) ?
+      tg_cad - tg_mesh : tg_cad + tg_mesh;
+    //    printf("%g %g %g vs %g %g %g\n",tg_cad.x(),tg_cad.y(),tg_cad.z(),tg_mesh.x(),tg_mesh.y(),tg_mesh.z());
+    distFace += diff1.norm();
+  }
+  return distFace;
+}
+
+
+double MLineGEdgeDistance (MLine *l, GEdge *ge, FILE *f) {
+  const nodalBasis &elbasis = *l->getFunctionSpace();
+  const double h = .25*0.5*distance (l->getVertex (0), l->getVertex (1) ) / (l->getNumVertices()-1);
+  double jac[3][3];
+  double distEdge = 0.0;
+
+  //  if(f)printf("%d\n",l->getNumVertices());
+
+  for (int j=0;j<l->getNumVertices();j++){
+    double t_mesh = elbasis.points(j,0);
+    //    if (f) printf("%g ",t_mesh);
+    double detJ = l->getJacobian(t_mesh,0,0,jac);
+    SVector3 tg_mesh (jac[0][0],jac[0][1],jac[0][2]);
+    tg_mesh.normalize();
+    double t_cad;
+    reparamMeshVertexOnEdge(l->getVertex (j), ge, t_cad);
+    SVector3 tg_cad = ge->firstDer(t_cad);
+    tg_cad.normalize();
+
+    SVector3 diff1 = (dot(tg_cad, tg_mesh) > 0) ?
+      tg_cad - tg_mesh : tg_cad + tg_mesh;
+
+    if (f){
+      fprintf (f,"SP(%g,%g,%g){%g};\n",l->getVertex (j)->x(),
+         l->getVertex (j)->y(),l->getVertex (j)->z(),h*diff1.norm());
+    }
+
+    //    SVector3 n = crossprod(tg_cad,tg_mesh);
+    //    printf("%g %g vs %g %g\n",tg_cad.x(),tg_cad.y(),tg_mesh.x(),tg_mesh.y());
+    distEdge += diff1.norm();
+  }
+  //  if(f)printf("\n");
+  return h*distEdge;
+}
+
+
+void distanceFromElementsToGeometry(GModel *gm, int dim, std::map<MElement*,double> &distances){
+
+  std::map<MEdge,double,Less_Edge> dist2Edge;
+  for (GModel::eiter it = gm->firstEdge(); it != gm->lastEdge(); ++it){
+    if ((*it)->geomType() == GEntity::Line)continue;
+    for (unsigned int i=0;i<(*it)->lines.size(); i++){
+      double d = MLineGEdgeDistance ( (*it)->lines[i] , *it );
+      MEdge e =  (*it)->lines[i]->getEdge(0);
+      dist2Edge[e] = d;
+    }
+  }
+
+  //  printf("DISTANCE TO GEOMETRY : 1D PART %22.15E\n",Obj);
+
+  std::map<MFace,double,Less_Face> dist2Face;
+  for(GModel::fiter it = gm->firstFace(); it != gm->lastFace(); ++it){
+    if ((*it)->geomType() == GEntity::Plane)continue;
+    for (unsigned int i=0;i<(*it)->triangles.size(); i++){
+      double d = MFaceGFaceDistance ( (*it)->triangles[i] , *it );
+      MFace f =  (*it)->triangles[i]->getFace(0);
+      dist2Face[f] = d;
+    }
+  }
+
+  std::vector<GEntity*> entities;
+  gm->getEntities(entities);
+  for (int iEnt = 0; iEnt < entities.size(); ++iEnt) {
+    GEntity* &entity = entities[iEnt];
+    if (entity->dim() != dim) continue;
+    for (int iEl = 0; iEl < entity->getNumMeshElements();iEl++) {       // Detect bad elements
+      MElement *element = entity->getMeshElement(iEl);
+      double d = 0.0;
+      for (int iEdge = 0; iEdge < element->getNumEdges(); ++iEdge) {
+  MEdge e =  element->getEdge(iEdge);
+  std::map<MEdge,double,Less_Edge>::iterator it = dist2Edge.find(e);
+  if(it != dist2Edge.end())d+=it->second;
+      }
+      for (int iFace = 0; iFace < element->getNumFaces(); ++iFace) {
+  MFace f =  element->getFace(iFace);
+  std::map<MFace,double,Less_Face>::iterator it = dist2Face.find(f);
+  if(it != dist2Face.end())d+=it->second;
+      }
+      distances[element] = d;
+    }
+  }
+}
+
+
+double distanceToGeometry(GModel *gm)
+{
+
+  FILE *f = fopen("toto.pos","w");
+  fprintf(f,"View \"\"{\n");
+
+  double Obj = 0.0;
+
+  for (GModel::eiter it = gm->firstEdge(); it != gm->lastEdge(); ++it){
+    if ((*it)->geomType() == GEntity::Line)continue;
+    for (unsigned int i=0;i<(*it)->lines.size(); i++){
+      //Obj += MLineGEdgeDistance ( (*it)->lines[i] , *it,f );
+      Obj = std::max(MLineGEdgeDistance ( (*it)->lines[i] , *it, f ),Obj);
+    }
+  }
+
+    printf("DISTANCE TO GEOMETRY : 1D PART %22.15E\n",Obj);
+
+  for(GModel::fiter it = gm->firstFace(); it != gm->lastFace(); ++it){
+    if ((*it)->geomType() == GEntity::Plane)continue;
+    //    printf("FACE %d with %d triangles\n",(*it)->tag(),(*it)->triangles.size());
+    for (unsigned int i=0;i<(*it)->triangles.size(); i++){
+      //Obj += MFaceGFaceDistance ( (*it)->triangles[i] , *it );
+      Obj = std::max(Obj,MFaceGFaceDistance ( (*it)->triangles[i] , *it ));
+    }
+  }
+
+  printf("DISTANCE TO GEOMETRY : 1D AND 2D PART %22.15E\n",Obj);
+  fprintf(f,"};\n");
+  fclose(f);
+  return Obj;
+}
+
+
diff --git a/contrib/HighOrderMeshOptimizer/OptHomCADDist.h b/contrib/HighOrderMeshOptimizer/OptHomCADDist.h
new file mode 100644
index 0000000000000000000000000000000000000000..465335331580b57c2b921c46cdcb6f30d2689031
--- /dev/null
+++ b/contrib/HighOrderMeshOptimizer/OptHomCADDist.h
@@ -0,0 +1,23 @@
+// TODO: Header
+
+#ifndef OPTHOMCADDIST_H_
+#define OPTHOMCADDIST_H_
+
+
+class GModel;
+class MElement;
+class MLine;
+class MTriangle;
+class GEdge;
+class GFace;
+
+double MFaceGFaceDistance(MTriangle *t, GFace *gf,
+                          std::vector<std::vector<SVector3> > *gsfT=0,
+                          std::map<MVertex*,SVector3> *normalsToCAD=0);
+double MLineGEdgeDistance (MLine *l, GEdge *ge, FILE *f = 0);
+
+void distanceFromElementsToGeometry(GModel *gm, int dim, std::map<MElement*, double> &distances);
+double distanceToGeometry(GModel *gm);
+
+
+#endif /* OPTHOMCADDIST_H_ */
diff --git a/contrib/HighOrderMeshOptimizer/OptHomObjContribCADDistOld.h b/contrib/HighOrderMeshOptimizer/OptHomObjContribCADDistOld.h
new file mode 100644
index 0000000000000000000000000000000000000000..944cac46bbb253c870d49a365e58fcacbb9f4e47
--- /dev/null
+++ b/contrib/HighOrderMeshOptimizer/OptHomObjContribCADDistOld.h
@@ -0,0 +1,96 @@
+// TODO: Copyright
+
+#ifndef _OPTHOMOBJCONTRIBCADDISTOLD_H_
+#define _OPTHOMOBJCONTRIBCADDISTOLD_H_
+
+#include "MeshOptObjContrib.h"
+
+
+template<class FuncType>
+class ObjContribCADDistOld : public ObjContrib, public FuncType
+{
+public:
+  ObjContribCADDistOld(double weight, double geomTol);
+  virtual ~ObjContribCADDistOld() {}
+  virtual ObjContrib *copy() const;
+  virtual void initialize(Patch *mesh);
+  virtual bool fail() { return false; }
+  virtual bool addContrib(double &Obj, alglib::real_1d_array &gradObj);
+  virtual void updateParameters() { FuncType::updateParameters(_min, _max); }
+  virtual bool targetReached() { return FuncType::targetReached(_min, _max); }
+  virtual bool stagnated() { return FuncType::stagnated(_min, _max); }
+  virtual void updateMinMax();
+
+protected:
+  Patch *_mesh;
+  double _weight;
+  double _geomTol;
+};
+
+
+template<class FuncType>
+ObjContribCADDistOld<FuncType>::ObjContribCADDistOld(double weight, double geomTol) :
+  ObjContrib("CADDist", FuncType::getNamePrefix()+"CADDist"),
+  _mesh(0), _weight(weight), _geomTol(geomTol)
+{
+}
+
+
+template<class FuncType>
+ObjContrib *ObjContribCADDistOld<FuncType>::copy() const
+{
+  return new ObjContribCADDistOld<FuncType>(*this);
+}
+
+
+template<class FuncType>
+void ObjContribCADDistOld<FuncType>::initialize(Patch *mesh)
+{
+  _mesh = mesh;
+
+  updateMinMax();
+  FuncType::initialize(_min, _max);
+}
+
+
+template<class FuncType>
+bool ObjContribCADDistOld<FuncType>::addContrib(double &Obj, alglib::real_1d_array &gradObj)
+{
+  _min = BIGVAL;
+  _max = -BIGVAL;
+
+  std::vector<double> gradF;
+  for (int iEl = 0; iEl < _mesh->nEl(); iEl++) {
+    double f;
+    if (_mesh->bndDistAndGradients(iEl, f, gradF, _geomTol)) {
+      _min = std::min(_min, f);
+      _max = std::max(_max, f);
+      Obj += FuncType::compute(f) * _weight;
+      const double dFact = _weight * FuncType::computeDiff(f);
+      for (size_t i = 0; i < _mesh->nPCEl(iEl); ++i)
+        gradObj[_mesh->indPCEl(iEl, i)] += gradF[i] * dFact;
+    }
+  }
+
+  return true;
+}
+
+
+template<class FuncType>
+void ObjContribCADDistOld<FuncType>::updateMinMax()
+{
+  _min = BIGVAL;
+  _max = -BIGVAL;
+
+  std::vector<double> dumGradF;
+  for (int iEl = 0; iEl < _mesh->nEl(); iEl++) {
+    double f;
+    if (_mesh->bndDistAndGradients(iEl, f, dumGradF, _geomTol)) {
+      _min = std::min(_min, f);
+      _max = std::max(_max, f);
+    }
+  }
+}
+
+
+#endif /* _OPTHOMOBJCONTRIBCADDISTOLD_H_ */