diff --git a/Geo/CellComplex.cpp b/Geo/CellComplex.cpp
index d7823ca2fbf12f0d142f47655ef9648f105c467e..f5f2c7b446aa365da1b8fd55de11cd0ba0d1bdcc 100644
--- a/Geo/CellComplex.cpp
+++ b/Geo/CellComplex.cpp
@@ -272,6 +272,8 @@ void CellComplex::removeCell(Cell* cell){
     bdCell->removeCoboundaryCell(cell);
   }
 
+  //cell->clearBoundary();
+  //cell->clearCoboundary();
   
 }
 
@@ -283,7 +285,8 @@ void CellComplex::enqueueCells(std::list<Cell*>& cells, std::queue<Cell*>& Q, st
   for(std::list<Cell*>::iterator cit = cells.begin(); cit != cells.end(); cit++){
     Cell* cell = *cit;
     citer it = Qset.find(cell);
-    if(it == Qset.end()){
+    //citer it2 = _cells[cell->getDim()].find(cell);
+    if(it == Qset.end()){// && it2 != _cells[cell->getDim()].end()){
       Qset.insert(cell);
       Q.push(cell);
     }
@@ -519,6 +522,23 @@ void CellComplex::replaceCells(Cell* c1, Cell* c2, Cell* newCell, bool orMatch,
     cbdCell->removeBoundaryCell(c1);
     cbdCell->addBoundaryCell(ori, newCell, true);
   }
+  /*
+  for(std::list< std::pair<int, Cell*> >::iterator it = coboundary1.begin(); it != coboundary1.end(); it++){
+    Cell* cbdCell = (*it).second;
+    int ori  = (*it).first;
+    cbdCell->removeBoundaryCell(c1);
+    if(!co){
+      bool old = false;
+      for(std::list< std::pair<int, Cell* > >::iterator it2 = coboundary2.begin(); it2 != coboundary2.end(); it2++){
+        Cell* cell2 = (*it2).second;
+        if(*cell2 == *cbdCell) old = true;
+      }
+      if(!old) cbdCell->addBoundaryCell(ori, newCell, true);
+    }
+    else cbdCell->addBoundaryCell(ori, newCell, true);
+  }
+  */
+  
   for(std::list< std::pair<int, Cell*> >::iterator it = coboundary2.begin(); it != coboundary2.end(); it++){
     Cell* cbdCell = (*it).second;
     int ori  = (*it).first;
@@ -535,12 +555,31 @@ void CellComplex::replaceCells(Cell* c1, Cell* c2, Cell* newCell, bool orMatch,
     else cbdCell->addBoundaryCell(ori, newCell, true);
   }
   
+  
   for(std::list< std::pair<int, Cell* > >::iterator it = boundary1.begin(); it != boundary1.end(); it++){
     Cell* bdCell = (*it).second;
     int ori = (*it).first;
     bdCell->removeCoboundaryCell(c1);
     bdCell->addCoboundaryCell(ori, newCell, true);
   }
+  /*
+  for(std::list< std::pair<int, Cell* > >::iterator it = boundary1.begin(); it != boundary1.end(); it++){
+    Cell* bdCell = (*it).second;
+    int ori = (*it).first;
+    bdCell->removeCoboundaryCell(c1);
+    if(co){
+      bool old = false;
+      for(std::list< std::pair<int, Cell* > >::iterator it2 = boundary2.begin(); it2 != boundary2.end(); it2++){
+        Cell* cell2 = (*it2).second;
+        if(*cell2 == *bdCell) old = true;
+      }
+      if(!old)  bdCell->addCoboundaryCell(ori, newCell, true);
+    }
+    else bdCell->addCoboundaryCell(ori, newCell, true);
+    
+  }
+  */
+  
   for(std::list< std::pair<int, Cell* > >::iterator it = boundary2.begin(); it != boundary2.end(); it++){
     Cell* bdCell = (*it).second;
     int ori = (*it).first;
@@ -560,6 +599,8 @@ void CellComplex::replaceCells(Cell* c1, Cell* c2, Cell* newCell, bool orMatch,
   
   _cells[dim].erase(c1);
   _cells[dim].erase(c2);
+  //removeCell(c1);
+  //removeCell(c2);
   //_trash.insert(c1);
   //_trash.insert(c2);
   _cells[dim].insert(newCell);
@@ -601,19 +642,21 @@ int CellComplex::cocombine(int dim){
         int or2 = bd_c.back().first;
         Cell* c1 = bd_c.front().second;
         Cell* c2 = bd_c.back().second;
+        if( c1->getNumVertices() < getSize(dim) && c2->getNumVertices() < getSize(dim) ){
+        
+        removeCell(s);
         
         cbd_c = c1->getCoboundary();
         enqueueCells(cbd_c, Q, Qset);
         cbd_c = c2->getCoboundary();
         enqueueCells(cbd_c, Q, Qset);
           
-        removeCell(s);
         CombinedCell* newCell = new CombinedCell(c1, c2, (or1 != or2), true );
         replaceCells(c1, c2, newCell, (or1 != or2), true);
         
         cit = firstCell(dim);
         count++;
-
+        }
       }
       removeCellQset(s, Qset);
       
@@ -653,23 +696,28 @@ int CellComplex::combine(int dim){
       cbd_c = s->getOrientedCoboundary();
         
       if(cbd_c.size() == 2 && !(*(cbd_c.front().second) == *(cbd_c.back().second)) 
-         && inSameDomain(s, cbd_c.front().second) && inSameDomain(s, cbd_c.back().second) ){
+         && inSameDomain(s, cbd_c.front().second) && inSameDomain(s, cbd_c.back().second)){
         int or1 = cbd_c.front().first;
         int or2 = cbd_c.back().first;
         Cell* c1 = cbd_c.front().second;
         Cell* c2 = cbd_c.back().second;
-                            
+        if( c1->getNumVertices() < getSize(dim) && c2->getNumVertices() < getSize(dim)){
+                  
+        removeCell(s);
         bd_c = c1->getBoundary();
         enqueueCells(bd_c, Q, Qset);
         bd_c = c2->getBoundary();
         enqueueCells(bd_c, Q, Qset);
           
-        removeCell(s);
+        
         CombinedCell* newCell = new CombinedCell(c1, c2, (or1 != or2) );
         replaceCells(c1, c2, newCell, (or1 != or2));
+        //removeCell(s);
         cit = firstCell(dim);
         //cit++;
         count++;
+          
+        }
 
       }
       removeCellQset(s, Qset);
@@ -807,10 +855,10 @@ int CellComplex::writeComplexMSH(const std::string &name){
 void CellComplex::printComplex(int dim){
   for (citer cit = firstCell(dim); cit != lastCell(dim); cit++){
     Cell* cell = *cit;
-    for(int i = 0; i < cell->getNumVertices(); i++){
-      printf("%d ", cell->getVertex(i)->getNum());
-    }
-    printf("\n");
+    cell->printCell();
+    cell->printBoundary();
+    cell->printCoboundary();
+    printf("--- \n");
   }
 }
 
diff --git a/Geo/CellComplex.h b/Geo/CellComplex.h
index 4a3e8d587785e219fdb77df1dadd35cf6ee2b3de..16f264c6a03fe3e717928d53352869551929c718 100644
--- a/Geo/CellComplex.h
+++ b/Geo/CellComplex.h
@@ -141,7 +141,15 @@ class Cell
      }
      return count;
    }
-      
+   
+   virtual bool hasBoundary(Cell* cell){
+     for(std::list< std::pair<int, Cell*> >::iterator it = _boundary.begin(); it != _boundary.end(); it++){
+       Cell* cell2 = (*it).second;
+       if(*cell2 == *cell) return true;
+     }
+     return false;
+   }
+   
    virtual void clearBoundary() { _boundary.clear(); }
    virtual void clearCoboundary() { _coboundary.clear(); }
    
@@ -160,6 +168,14 @@ class Cell
        cell2->printCell();
      }
    }
+   virtual void printCoboundary() {
+     for(std::list< std::pair<int, Cell*> >::iterator it = _coboundary.begin(); it != _coboundary.end(); it++){
+       printf("Coboundary cell orientation: %d ", (*it).first);
+       Cell* cell2 = (*it).second;
+       cell2->printCell();
+     }
+   }
+   
    
    
    virtual bool inSubdomain() const { return _inSubdomain; }
@@ -435,6 +451,7 @@ class CombinedCell : public Cell{
    std::vector<MVertex*> _v;
    std::vector<int> _vs;
    std::list< std::pair<int, Cell*> > _cells;
+   int _num;
    
   public:
    
@@ -442,10 +459,15 @@ class CombinedCell : public Cell{
      _index = c1->getIndex();
      _tag = c1->getTag();
      _dim = c1->getDim();
+     _num = c1->getNum();
      _inSubdomain = c1->inSubdomain();
      _onDomainBoundary = c1->onDomainBoundary();
      _combined = true;
      
+     _v.reserve(c1->getNumVertices() + c2->getNumVertices());
+     _vs.reserve(c1->getNumVertices() + c2->getNumVertices());
+            
+     
      _v = c1->getVertexVector();
      for(int i = 0; i < c2->getNumVertices(); i++){
        if(!this->hasVertex(c2->getVertex(i)->getNum())) _v.push_back(c2->getVertex(i));
@@ -461,14 +483,31 @@ class CombinedCell : public Cell{
        _cells.push_back(*it);
      }
      
-     _boundary = c1->getOrientedBoundary();
+     if(!co) _boundary = c1->getOrientedBoundary();
+     
+     std::list< std::pair<int, Cell*> > c1Boundary = c1->getOrientedBoundary();
      std::list< std::pair<int, Cell*> > c2Boundary = c2->getOrientedBoundary();
+     /*
+     for(std::list< std::pair<int, Cell*> >::iterator it = c1Boundary.begin(); it != c1Boundary.end(); it++){
+       Cell* cell = (*it).second;
+       if(co){
+         bool old = false;
+         for(std::list< std::pair<int, Cell* > >::iterator it2 = c2Boundary.begin(); it2 != c2Boundary.end(); it2++){
+           Cell* cell2 = (*it2).second;
+           if(*cell2 == *cell) old = true;
+         }
+         if(!old) _boundary.push_back(*it);
+       }
+       else _boundary.push_back(*it);
+     }
+     */
+     
      for(std::list< std::pair<int, Cell*> >::iterator it = c2Boundary.begin(); it != c2Boundary.end(); it++){
        if(!orMatch) (*it).first = -1*(*it).first;
        Cell* cell = (*it).second;
        if(co){
          bool old = false;
-         for(std::list< std::pair<int, Cell* > >::iterator it2 = _boundary.begin(); it2 != _boundary.end(); it2++){
+         for(std::list< std::pair<int, Cell* > >::iterator it2 = c1Boundary.begin(); it2 != c1Boundary.end(); it2++){
            Cell* cell2 = (*it2).second;
            if(*cell2 == *cell) old = true;
          }
@@ -477,14 +516,32 @@ class CombinedCell : public Cell{
        else _boundary.push_back(*it);
      }
      
-     _coboundary = c1->getOrientedCoboundary();
+     if(co) _coboundary = c1->getOrientedCoboundary();
+     std::list< std::pair<int, Cell*> > c1Coboundary = c1->getOrientedCoboundary();
      std::list< std::pair<int, Cell*> > c2Coboundary = c2->getOrientedCoboundary();
+     
+     /*
+     for(std::list< std::pair<int, Cell* > >::iterator it = c1Coboundary.begin(); it != c1Coboundary.end(); it++){
+       
+       Cell* cell = (*it).second;
+       if(!co){
+         bool old = false;
+         for(std::list< std::pair<int, Cell* > >::iterator it2 = c2Coboundary.begin(); it2 != c2Coboundary.end(); it2++){
+           Cell* cell2 = (*it2).second;
+           if(*cell2 == *cell) old = true;
+         }
+         if(!old) _coboundary.push_back(*it);
+       }
+       else _coboundary.push_back(*it);
+     }
+     */
+     
      for(std::list< std::pair<int, Cell* > >::iterator it = c2Coboundary.begin(); it != c2Coboundary.end(); it++){
        if(!orMatch) (*it).first = -1*(*it).first;
        Cell* cell = (*it).second;
        if(!co){
          bool old = false;
-         for(std::list< std::pair<int, Cell* > >::iterator it2 = _coboundary.begin(); it2 != _coboundary.end(); it2++){
+         for(std::list< std::pair<int, Cell* > >::iterator it2 = c1Coboundary.begin(); it2 != c1Coboundary.end(); it2++){
            Cell* cell2 = (*it2).second;
            if(*cell2 == *cell) old = true;
          }
@@ -497,6 +554,7 @@ class CombinedCell : public Cell{
   
    ~CombinedCell(){} 
    
+   int getNum() { return _num; }
    int getNumVertices() const { return _v.size(); } 
    MVertex* getVertex(int vertex) const { return _v.at(vertex); }
    int getSortedVertex(int vertex) const { return _vs.at(vertex); }
@@ -506,6 +564,9 @@ class CombinedCell : public Cell{
    
    // true if this cell has given vertex
    bool hasVertex(int vertex) const {
+     //std::vector<int>::iterator it = std::find(_vs.begin(), _vs.end(), vertex);
+     //if (it == _vs.end()) return false;
+     //else return true;
      for(int i = 0; i < _v.size(); i++){
        if(_v.at(i)->getNum() == vertex) return true;
      }
@@ -522,7 +583,6 @@ class CombinedCell : public Cell{
    
    std::list< std::pair<int, Cell*> > getCells() { return _cells; }
    int getNumCells() {return _cells.size();}
-      
    
 };
 
@@ -626,11 +686,17 @@ class CellComplex
      //}
      
      for(int i = 0; i < 4; i++){
+       
+       for(citer cit = _cells[i].begin(); cit != _cells[i].end(); cit++){
+         Cell* cell = *cit;
+         if(cell->combined()) delete cell;
+       }
        _cells[i].clear();
        for(citer cit = _cells2[i].begin(); cit != _cells2[i].end(); cit++){
          Cell* cell = *cit;
          delete cell;
        }
+        _cells2[i].clear();
      }
      
    }
diff --git a/Geo/ChainComplex.cpp b/Geo/ChainComplex.cpp
index fefc4e10063f08eb952b04073f1276866282f7df..22e44eb8342d09814a528e56877fc4a0badc4bb5 100644
--- a/Geo/ChainComplex.cpp
+++ b/Geo/ChainComplex.cpp
@@ -87,7 +87,7 @@ ChainComplex::ChainComplex(CellComplex* cellComplex){
                 mpz_set_si(elem, old_elem + (*it).first);
                 if( (old_elem + (*it).first) > 1 || (old_elem + (*it).first) < -1 ){
                   printf("Warning: Invalid incidence index: %d! HMatrix: %d. \n", (old_elem + (*it).first), dim);
-                   mpz_set_si(elem, 0);
+                   //mpz_set_si(elem, 0);
                 }
                 gmp_matrix_set_elem(elem, bdCell->getIndex(), cell->getIndex(), _HMatrix[dim]);
               }
diff --git a/Geo/Homology.cpp b/Geo/Homology.cpp
index 18cdc81db9e0968e08602d949da4584eaf92929d..f6edfd5a40c4ba246dfc193461c1722fcc4f9ae1 100644
--- a/Geo/Homology.cpp
+++ b/Geo/Homology.cpp
@@ -72,9 +72,12 @@ Homology::Homology(GModel* model, std::vector<int> physicalDomain, std::vector<i
 
 void Homology::findGenerators(std::string fileName){
   
+  
+  
   Msg::Info("Reducing Cell Complex...");
   double t1 = Cpu();
   int omitted = _cellComplex->reduceComplex(true);
+  
   //_cellComplex->checkCoherence();
   if(getCombine()){
     _cellComplex->combine(3);
@@ -90,6 +93,7 @@ void Homology::findGenerators(std::string fileName){
   Msg::Info("%d volumes, %d faces, %d edges and %d vertices.",
             _cellComplex->getSize(3), _cellComplex->getSize(2), _cellComplex->getSize(1), _cellComplex->getSize(0));
 
+  //for(int i = 0; i < 4; i++) _cellComplex->printComplex(i);
     
   _cellComplex->writeComplexMSH(fileName);