diff --git a/Mesh/meshGFaceRecombine.cpp b/Mesh/meshGFaceRecombine.cpp
index 138225d30374b1b937e3aa475797262e9cc8fb82..016556ed7010195739ac903a78276b8643941739 100644
--- a/Mesh/meshGFaceRecombine.cpp
+++ b/Mesh/meshGFaceRecombine.cpp
@@ -237,48 +237,30 @@ bool Recombine2D::recombine()
   return 1;
 }
 
-bool Recombine2D::recombine()
+bool Recombine2D::developTree()
 {
-  Rec2DAction *nextAction;
-  while (nextAction = Rec2DData::getBestAction()) {
-#ifdef REC2D_DRAW
-    FlGui::instance()->check();
-    double time = Cpu();
-    nextAction->color(0, 0, 200);
-    CTX::instance()->mesh.changed = (ENT_ALL);
-    drawContext::global()->draw();
-#endif
-    
-    if (!_remainAllQuad(nextAction)) {
-      nextAction->color(190, 0, 0);
-      delete nextAction;
-      continue;
-    }
-    ++_numChange;
-    std::vector<Rec2DVertex*> newPar;
-    nextAction->apply(newPar);
-    
-    // forall v in newPar : check obsoletes action;
-    
-#ifdef REC2D_DRAW
-    _gf->triangles = _data->_tri;
-    _gf->quadrangles = _data->_quad;
-    CTX::instance()->mesh.changed = (ENT_ALL);
-    drawContext::global()->draw();
-    while (Cpu()-time < REC2D_WAIT_TIME)
-      FlGui::instance()->check();
-#endif
-    
-    delete nextAction;
-  }
+  double bestGlobalValue;
+  Rec2DNode root(NULL, NULL, bestGlobalValue);
   
-  _data->printState();
-#ifdef REC2D_SMOOTH
-    laplaceSmoothing(_gf,100);
-#endif
-    CTX::instance()->mesh.changed = (ENT_ALL);
-    drawContext::global()->draw();
-  return 1;
+  Msg::Info("best global value : %g", bestGlobalValue);
+  Msg::Info("num end node : %d", Rec2DData::getNumEndNode());
+  
+  Rec2DData::sortEndNode();
+  Rec2DData::drawEndNode(10);
+}
+
+void Recombine2D::nextTreeActions(Rec2DAction *ra,
+                                  std::vector<Rec2DAction*> &actions)
+{
+  Rec2DAction *next = Rec2DData::getBestNonHiddenAction();
+  if (!next)
+    return;
+  std::vector<Rec2DElement*> elements;
+  next->getElements(elements);
+  for (int i = 0; i < elements[0]->getNumActions(); ++i) {
+    if (!Rec2DData::isOutOfDate(elements[0]->getAction(i)))
+      actions.push_back(elements[0]->getAction(i));
+  }
 }
 
 double Recombine2D::_geomAngle(MVertex *v,
@@ -838,6 +820,44 @@ Rec2DAction* Rec2DData::getBestAction()
                            _current->_actions.end(), lessRec2DAction());
 }
 
+Rec2DAction* Rec2DData::getBestNonHiddenAction()
+{
+  _current->_actions.sort(lessRec2DAction());
+  std::list<Rec2DAction*>::iterator it = _current->_actions.begin();
+  while (it != _current->_actions.end() && Rec2DData::isOutOfDate(*it)) ++it;
+  if (it == _current->_actions.end())
+    return NULL;
+  return *it;
+}
+
+bool Rec2DData::isOutOfDate(Rec2DAction *ra)
+{
+  std::vector<Rec2DElement*> elements;
+  ra->getElements(elements);
+  bool b = false;
+  for (unsigned int i = 0; i < elements.size(); ++i) {
+    if (_current->_hiddenElements.find(elements[i]) !=
+        _current->_hiddenElements.end()               ) {
+      b = true;
+      break;
+    }
+  }
+  return b;
+}
+
+void Rec2DData::drawEndNode(int num)
+{
+  /*std::list<Rec2DNode*>::iterator it = _endNodes.begin();
+  for (int i = 0; i < num && it != _endNodes.end(); ++i, ++it) {
+    std::map<int, std::vector<double> > data;
+    Rec2DNode *currentNode = *it;
+    
+    for (unsigned int i = 0; i < invalids.size(); ++i)
+      computeMinMax(&invalids[i], 1, &data);
+    
+  }
+  new PView("Jmin_bad", "ElementData", _m, data);*/
+}
 
 /**  Rec2DAction  **/
 /*******************/
@@ -975,59 +995,22 @@ void Rec2DTwoTri2Quad::apply(std::vector<Rec2DVertex*> &newPar)
   /*new Rec2DCollapse(*/new Rec2DElement(_edges)/*)*/;
 }
 
-void Rec2DTwoTri2Quad::choose()
-{
-  if (isObsolete()) {
-    Msg::Error("[Rec2DTwoTri2Quad] No way ! I won't apply ! Find someone else...");
-    return;
-  }
+void Rec2DTwoTri2Quad::choose(Rec2DElement *&rel)
+{ 
+  _edges[4]->hide();
+  _triangles[0]->hide();
+  _triangles[1]->hide();
   
-  int min = Rec2DData::getNewParity(), index = -1;
-  for (int i = 0; i < 4; ++i) {
-    if (_vertices[i]->getParity() && min > _vertices[i]->getParity()) {
-      min = _vertices[i]->getParity();
-      index = i;
-    }
-  }
-  if (index == -1) {
-    _vertices[0]->setParity(min);
-    _vertices[1]->setParity(min);
-    _vertices[2]->setParity(min+1);
-    _vertices[3]->setParity(min+1);
-  }
-  else {
-    for (int i = 0; i < 4; i += 2) {
-      int par;
-      if ((index/2) * 2 == i)
-        par = min;
-      else
-        par = otherParity(min);
-      for (int j = 0; j < 2; ++j) {
-        if (!_vertices[i+j]->getParity())
-          _vertices[i+j]->setParity(par);
-        else if (_vertices[i+j]->getParity() != par &&
-                 _vertices[i+j]->getParity() != otherParity(par))
-          Rec2DData::associateParity(_vertices[i+j]->getParity(), par);
-      }
-    }
-  }
-  
-  _triangles[0]->remove(this);
-  _triangles[1]->remove(this);
-  
-  std::vector<Rec2DAction*> actions;
-  _triangles[0]->getUniqueActions(actions);
-  _triangles[1]->getUniqueActions(actions);
-  for (unsigned int i = 0; i < actions.size(); ++i)
-    delete actions[i];
-  
-  delete _triangles[0];
-  delete _triangles[1];
-  _triangles[0] = NULL;
-  _triangles[1] = NULL;
-  delete _edges[4];
+  rel = new Rec2DElement(_edges, true);
+}
+
+void Rec2DTwoTri2Quad::unChoose(Rec2DElement *rel)
+{
+  delete rel;
   
-  /*new Rec2DCollapse(*/new Rec2DElement(_edges)/*)*/;
+  _edges[4]->reveal();
+  _triangles[0]->reveal();
+  _triangles[1]->reveal();
 }
 
 bool Rec2DTwoTri2Quad::isObsolete()
@@ -1107,6 +1090,12 @@ bool Rec2DTwoTri2Quad::whatWouldYouDo
   return true;
 }
 
+void Rec2DTwoTri2Quad::getElements(std::vector<Rec2DElement*> &elem)
+{
+  elem.clear();
+  elem.push_back(_triangles[0]);
+  elem.push_back(_triangles[1]);
+}
 
 /**  Rec2DEdge  **/
 /*****************/
@@ -1129,6 +1118,22 @@ Rec2DEdge::~Rec2DEdge()
   Rec2DData::addEdge(-_weight, -_weight*getQual());
 }
 
+void Rec2DEdge::hide()
+{
+  //_rv0->remove(this);
+  //_rv1->remove(this);
+  //Rec2DData::remove(this);
+  Rec2DData::addEdge(-_weight, -_weight*getQual());
+}
+
+void Rec2DEdge::reveal()
+{
+  //_rv0->add(this);
+  //_rv1->add(this);
+  //Rec2DData::remove(this);
+  Rec2DData::addEdge(_weight, _weight*getQual());
+}
+
 void Rec2DEdge::_computeQual() //*
 {
   double adimLength = _straightAdimLength();
@@ -1381,9 +1386,9 @@ void Rec2DVertex::setOnBoundary()
   }
 }
 
-void Rec2DVertex::setParity(int p)
+void Rec2DVertex::setParity(int p, bool tree)
 {
-  if (_parity) {
+  if (_parity && !tree) {
     Msg::Warning("[Rec2DVertex] I don't like to do it. Think about that !");
     Rec2DData::removeParity(this, _parity);
   }
@@ -1607,14 +1612,19 @@ Rec2DElement::Rec2DElement(MQuadrangle *q) : _mEl((MElement *)q), _numEdge(4)
   Rec2DData::add(this);
 }
 
-Rec2DElement::Rec2DElement(Rec2DEdge **edges) : _mEl(NULL), _numEdge(4)
+Rec2DElement::Rec2DElement(Rec2DEdge **edges, bool tree) : _mEl(NULL), _numEdge(4)
 {
   for (int i = 0; i < 4; ++i) {
     _edges[i] = edges[i];
     _edges[i]->addHasQuad();
-    _elements[i] = Rec2DEdge::getSingleElement(edges[i]);
-    if (_elements[i])
-      _elements[i]->addNeighbour(_edges[i], this);
+    if (tree) {
+      _elements[i] = NULL;
+    }
+    else {
+      _elements[i] = Rec2DEdge::getSingleElement(edges[i]);
+      if (_elements[i])
+        _elements[i]->addNeighbour(_edges[i], this);
+    }
   }
   std::vector<Rec2DVertex*> vertices(4);
   getVertices(vertices);
@@ -1644,6 +1654,38 @@ Rec2DElement::~Rec2DElement()
   Rec2DData::remove(this);
 }
 
+void Rec2DElement::hide()
+{
+  for (int i = 0; i < _numEdge; ++i) {
+    if (_numEdge == 3)
+      _edges[i]->remHasTri();
+    else
+      _edges[i]->remHasQuad();
+  }
+  std::vector<Rec2DVertex*> vertices(_numEdge);
+  getVertices(vertices);
+  for (unsigned int i = 0; i < _numEdge; ++i) {
+    vertices[i]->remove(this);
+  }
+  Rec2DData::addHidden(this);
+}
+
+void Rec2DElement::reveal()
+{
+  for (int i = 0; i < _numEdge; ++i) {
+    if (_numEdge == 3)
+      _edges[i]->addHasTri();
+    else
+      _edges[i]->addHasQuad();
+  }
+  std::vector<Rec2DVertex*> vertices(_numEdge);
+  getVertices(vertices);
+  for (unsigned int i = 0; i < _numEdge; ++i) {
+    vertices[i]->add(this);
+  }
+  Rec2DData::remHidden(this);
+}
+
 void Rec2DElement::add(Rec2DEdge *re)
 {
   int i;
@@ -1846,28 +1888,40 @@ MQuadrangle* Rec2DElement::_createQuad() const
 
 /**  Rec2DNode  **/
 /*****************/
-Rec2DNode::Rec2DNode(Rec2DNode *father, Rec2DEction *ra, double &bestEndGlobVal)
-: _father(father), _ra(ra), _son0(NULL), _son1(NULL), _son2(NULL),
-  _globalValue(.0), _bestEndGlobVal(.0)
+/*bool lessRec2DNode::operator()(Rec2DNode *rn1, Rec2DNode *rn2) const
 {
-  int parities[4];
-  _ra.choose(parities);
+  return *rn1 < *rn2;
+}
+
+ */Rec2DNode::Rec2DNode(Rec2DNode *father, Rec2DAction *ra, double &bestEndGlobVal)
+: _father(father), _ra(ra), _globalValue(.0), _bestEndGlobVal(.0)
+{
+  _son[0] = NULL;
+  _son[1] = NULL;
+  _son[2] = NULL;
+  Rec2DElement *newElement;
+  if (_ra)
+    _ra->choose(newElement);
   
-  double 2;
-  int k = 0;
-  Rec2DElement *rel = Recombine2D::nextTreeActions(_ra);
-  for (int i = 0; i < rel->getNumActions(); ++i) {
-    if (!rel->getAction(i)->is'Obsolete'()) {
-      son[k] = new Rec2DNode(this, rel->getAction(i), endGlobValSon);
-      _bestEndGlobVal = max(_bestEndGlobVal, endGlobValSon);
-      ++k;
-    }
-  }
+  _globalValue = Rec2DData::getGlobalValue();
+  
+  std::vector<Rec2DAction*> actions;
+  Recombine2D::nextTreeActions(_ra, actions);
   
-  if (k == 0) {
+  if (actions.empty()) {
     Rec2DData::addEndNode(this);
+    _bestEndGlobVal = _globalValue;
   }
+  else
+    for (int i = 0; i < actions.size(); ++i) {
+      double bestSonEndGlobVal;
+      _son[i] = new Rec2DNode(this, actions[i], bestSonEndGlobVal);
+      _bestEndGlobVal = std::max(_bestEndGlobVal, bestSonEndGlobVal);
+    }
+    
   bestEndGlobVal = _bestEndGlobVal;
-  _ra.revert(parities);
+  
+  if (_ra)
+    _ra->unChoose(newElement);
 }
 
diff --git a/Mesh/meshGFaceRecombine.h b/Mesh/meshGFaceRecombine.h
index f800bbc9c47a9faf06e4904d205d5555c63b7804..bff0cd36c73265312a0420865bdcfba183804a80 100644
--- a/Mesh/meshGFaceRecombine.h
+++ b/Mesh/meshGFaceRecombine.h
@@ -19,6 +19,7 @@
 //#include "GModel.h"
 //#include "MEdge.h"
 
+class Rec2DNode;
 class Rec2DVertex;
 class Rec2DEdge;
 class Rec2DElement;
@@ -47,6 +48,7 @@ class Recombine2D {
     
     bool recombine();
     bool developTree();
+    static void nextTreeActions(Rec2DAction*, std::vector<Rec2DAction*>&);
     
     static inline GFace* getGFace() {return _current->_gf;}
     static inline int getNumChange() {return _current->_numChange;}
@@ -68,9 +70,10 @@ class Rec2DData {
     
     std::set<Rec2DEdge*> _edges;
     std::set<Rec2DVertex*> _vertices;
-    std::set<Rec2DElement*> _elements;
+    std::set<Rec2DElement*> _elements, _hiddenElements;
     
     std::list<Rec2DAction*> _actions;
+    std::list<Rec2DNode*> _endNodes;
     
     std::map<int, std::vector<Rec2DVertex*> > _parities;
     std::map<int, std::vector<Rec2DVertex*> > _assumedParities;
@@ -86,6 +89,8 @@ class Rec2DData {
     std::vector<MQuadrangle*> _quad;
 #endif
     
+    static double getNumEndNode() {return _current->_endNodes.size();}
+    
     static double getGlobalValue();
     static double getGlobalValue(int numEdge, double valEdge,
                                  int numVert, double valVert );
@@ -100,6 +105,7 @@ class Rec2DData {
     }
     
     static Rec2DAction* getBestAction();
+    static Rec2DAction* getBestNonHiddenAction();
     
     typedef std::set<Rec2DEdge*>::iterator iter_re;
     typedef std::set<Rec2DVertex*>::iterator iter_rv;
@@ -124,6 +130,21 @@ class Rec2DData {
     static void remove(Rec2DElement*);
     static void remove(Rec2DAction*);
     
+    static inline void addEndNode(Rec2DNode *rn) {
+      _current->_endNodes.push_back(rn);
+    }
+    static inline void sortEndNode() {
+      /*_current->_endNodes.sort(lessRec2DNode());*/
+    }
+    static inline void drawEndNode(int num);
+    static inline void addHidden(Rec2DElement *rel) {
+      _current->_hiddenElements.insert(rel);
+    }
+    static inline void remHidden(Rec2DElement *rel) {
+      _current->_hiddenElements.erase(rel);
+    }
+    static bool isOutOfDate(Rec2DAction*);
+    
     static int getNewParity();
     static void removeParity(Rec2DVertex*, int);
     static inline void addParity(Rec2DVertex *rv, int p) {
@@ -162,6 +183,9 @@ class Rec2DAction {
     virtual void getAssumedParities(int*) = 0;
     virtual bool whatWouldYouDo(std::map<Rec2DVertex*, std::vector<int> >&) = 0;
     virtual Rec2DVertex* getVertex(int) = 0;
+    virtual void choose(Rec2DElement*&) = 0;
+    virtual void unChoose(Rec2DElement*) = 0;
+    virtual void getElements(std::vector<Rec2DElement*>&) = 0;
     
   private :
     virtual void _computeGlobVal() = 0;
@@ -185,6 +209,9 @@ class Rec2DTwoTri2Quad : public Rec2DAction {
     virtual void getAssumedParities(int*);
     virtual bool whatWouldYouDo(std::map<Rec2DVertex*, std::vector<int> >&);
     virtual inline Rec2DVertex* getVertex(int i) {return _vertices[i];} //-
+    virtual void choose(Rec2DElement*&);
+    virtual void unChoose(Rec2DElement*);
+    virtual void getElements(std::vector<Rec2DElement*>&);
     
   private :
     virtual void _computeGlobVal();
@@ -200,6 +227,8 @@ class Rec2DEdge {
   public :
     Rec2DEdge(Rec2DVertex*, Rec2DVertex*);
     ~Rec2DEdge();
+    void hide();
+    void reveal();
     
     double getQual();
     
@@ -257,7 +286,7 @@ class Rec2DVertex {
     bool setBoundaryParity(int p0, int p1);
     
     inline int getParity() const {return _parity;}
-    void setParity(int);
+    void setParity(int, bool tree = false);
     void setParityWD(int pOld, int pNew);
     int getAssumedParity() const;
     bool setAssumedParity(int);
@@ -305,8 +334,10 @@ class Rec2DElement {
   public :
     Rec2DElement(MTriangle*);
     Rec2DElement(MQuadrangle*);
-    Rec2DElement(Rec2DEdge**);
+    Rec2DElement(Rec2DEdge**, bool tree = false);
     ~Rec2DElement();
+    void hide();
+    void reveal();
     
     bool inline isTri() {return _numEdge == 3;}
     bool inline isQuad() {return _numEdge == 4;}
@@ -352,15 +383,19 @@ class Rec2DElement {
     MQuadrangle* _createQuad() const;
 };
 
+/*struct lessRec2DNode {
+  bool operator()(Rec2DNode*, Rec2DNode*) const;
+};
+*/
 class Rec2DNode {
   private :
     Rec2DNode *_father;
-    Rec2DNode *_son0, *_son1, *_son2;
+    Rec2DNode *_son[3];
     Rec2DAction *_ra;
     double _globalValue, _bestEndGlobVal;
     
   public :
-    Rec2DNode(Rec2DAction*);
+    Rec2DNode(Rec2DNode *father, Rec2DAction*, double &bestEndGlobVal);
 };
 
 #endif
\ No newline at end of file