diff --git a/Geo/CellComplex.cpp b/Geo/CellComplex.cpp
index 03031c0b017f46a935717c83626833004a0c069a..176260c60b7c6b70ca4959c0c2e6c2e50359c804 100644
--- a/Geo/CellComplex.cpp
+++ b/Geo/CellComplex.cpp
@@ -114,7 +114,7 @@ CellComplex::CellComplex( std::vector<GEntity*> domain, std::vector<GEntity*> su
 }
 
 void CellComplex::insert_cells(bool subdomain, bool boundary){
-  
+
   // works only for simplcial meshes at the moment!
   
   std::vector<GEntity*> domain;
@@ -215,8 +215,8 @@ int Simplex::kappa(Cell* tau) const{
   int value=1;
   
   for(int i = 0; i < this->getNumFacets(); i++){
-    std::vector<int> vTau = tau->getVertexVector(); 
-    std::vector<int> v;
+    std::vector<MVertex*> vTau = tau->getVertexVector(); 
+    std::vector<MVertex*> v;
     this->getFacetVertices(i, v);
     value = -1;
     
@@ -239,7 +239,8 @@ int Simplex::kappa(Cell* tau) const{
   
   return 0;
 }
-
+*/
+/*
 int OneSimplex::kappa(Cell* tau) const{
   for(int i=0; i < tau->getNumVertices(); i++){
     if( !(this->hasVertex(tau->getVertex(i))) ) return 0;
@@ -255,25 +256,28 @@ int OneSimplex::kappa(Cell* tau) const{
 
 void CellComplex::removeCell(Cell* cell){
   
-  //_trash.insert(cell);
+  std::list< std::pair< int, Cell*> > coboundary = cell->getOrientedCoboundary();
+  std::list< std::pair< int, Cell*> > boundary = cell->getOrientedBoundary();
+  //std::list<Cell*> boundary = cell->getBoundary();
+  //std::list<Cell*> coboundary = cell->getCoboundary();
   
-  _cells[cell->getDim()].erase(cell);
-  
-  std::list<Cell*> coboundary = cell->getCoboundary();
-  std::list<Cell*> boundary = cell->getBoundary();
-  
-  for(std::list<Cell*>::iterator it = coboundary.begin(); it != coboundary.end(); it++){ 
-    Cell* cbdCell = *it;
+  for(std::list< std::pair< int, Cell*> >::iterator it = coboundary.begin(); it != coboundary.end(); it++){
+  //for(std::list<Cell*>::iterator it = coboundary.begin(); it != coboundary.end(); it++){
+    Cell* cbdCell = (*it).second;
+    //Cell* cbdCell = *it;
     cbdCell->removeBoundaryCell(cell);
   }
   
-  for(std::list<Cell*>::iterator it = boundary.begin(); it != boundary.end(); it++){
-    Cell* bdCell = *it;
+  
+  for(std::list< std::pair< int, Cell*> >::iterator it = boundary.begin(); it != boundary.end(); it++){
+  //for(std::list<Cell*>::iterator it = boundary.begin(); it != boundary.end(); it++){
+    Cell* bdCell = (*it).second;
+    //Cell* bdCell = *it;
     bdCell->removeCoboundaryCell(cell);
   }
-
-  //cell->clearBoundary();
-  //cell->clearCoboundary();
+  
+  _cells[cell->getDim()].erase(cell);
+  
   
 }
 
@@ -346,11 +350,11 @@ int CellComplex::reduction(int dim){
     for(citer cit = firstCell(dim-1); cit != lastCell(dim-1); cit++){
       Cell* cell = *cit;
       cbd_c = cell->getCoboundary();
-      if(cbd_c.size() == 1 && inSameDomain(cell, cbd_c.front()) ){
-        
-        removeCell(cell);
+      if( cbd_c.size() == 1 && inSameDomain(cell, cbd_c.front()) ){
         
         removeCell(cbd_c.front());
+        removeCell(cell);
+        //removeCell(cbd_c.front());
         count++;
         reduced = true;
       }
@@ -385,11 +389,8 @@ int CellComplex::reduceComplex(bool omitHighdim){
       removeCell(cell);
 
       reduction(3);
-
       reduction(2);
-
       reduction(1);
-
       omitted++;
       
      }
@@ -451,13 +452,13 @@ int CellComplex::coreduceComplex(bool omitLowdim){
   int omitted = 0;
   if(count == 0 && omitLowdim){
     std::set<Cell*, Less_Cell> generatorCells;
-    
     while (getSize(0) != 0){
       citer cit = firstCell(0);
       Cell* cell = *cit;
       generatorCells.insert(cell);
       removeCell(cell);
-      coreduction(cell);
+      coreduceComplex(false);
+      //coreduction(cell);
       omitted++;
     }
     
@@ -505,111 +506,6 @@ void CellComplex::computeBettiNumbers(){
 }
 
 
-
-void CellComplex::replaceCells(Cell* c1, Cell* c2, Cell* newCell, bool orMatch, bool co){
-
-  int dim = c1->getDim();
-  /*
-  std::list< std::pair<int, Cell*> > coboundary1 = c1->getOrientedCoboundary();
-  std::list< std::pair<int, Cell*> > coboundary2 = c2->getOrientedCoboundary();
-  std::list< std::pair<int, Cell*> > boundary1 = c1->getOrientedBoundary();
-  std::list< std::pair<int, Cell*> > boundary2 = c2->getOrientedBoundary();
-  
-  
-  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);
-    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;
-    if(!orMatch) ori = -1*ori;
-    cbdCell->removeBoundaryCell(c2);
-    if(!co){
-      bool old = false;
-      for(std::list< std::pair<int, Cell* > >::iterator it2 = coboundary1.begin(); it2 != coboundary1.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 = 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;
-    if(!orMatch) ori = -1*ori;
-    bdCell->removeCoboundaryCell(c2);
-    if(co){
-      bool old = false;
-      for(std::list< std::pair<int, Cell* > >::iterator it2 = boundary1.begin(); it2 != boundary1.end(); it2++){
-        Cell* cell2 = (*it2).second;
-        if(*cell2 == *bdCell) old = true;
-      }
-      if(!old)  bdCell->addCoboundaryCell(ori, newCell, true);
-    }
-    else bdCell->addCoboundaryCell(ori, newCell, true);
-    
-  }
-  */
-  _cells[dim].erase(c1);
-  _cells[dim].erase(c2);
-  //removeCell(c1);
-  //removeCell(c2);
-  //_trash.insert(c1);
-  //_trash.insert(c2);
-  _cells[dim].insert(newCell);
-  
-  
-  
-  return;
-}
-
 int CellComplex::cocombine(int dim){
  
   printf("Cell complex before cocombining: %d volumes, %d faces, %d edges and %d vertices.\n",
@@ -635,14 +531,15 @@ int CellComplex::cocombine(int dim){
       
       bd_c = s->getOrientedBoundary();
       
-      if(bd_c.size() == 2 && !(*(bd_c.front().second) == *(bd_c.back().second)) 
-         && inSameDomain(s, bd_c.front().second) && inSameDomain(s, bd_c.back().second) ){
+      if(s->getBoundarySize() == 2 && !(*(bd_c.front().second) == *(bd_c.back().second)) 
+         && inSameDomain(s, bd_c.front().second) && inSameDomain(s, bd_c.back().second)
+         && bd_c.front().second->getNumVertices() < getSize(dim) // heuristics for mammoth cell birth control
+         && bd_c.back().second->getNumVertices() < getSize(dim)){
         
         int or1 = bd_c.front().first;
         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);
         
@@ -652,14 +549,12 @@ int CellComplex::cocombine(int dim){
         enqueueCells(cbd_c, Q, Qset);
           
         CombinedCell* newCell = new CombinedCell(c1, c2, (or1 != or2), true );
-        //replaceCells(c1, c2, newCell, (or1 != or2), true);
-        _cells[dim].erase(c1);
-        _cells[dim].erase(c2);
+        removeCell(c1);
+        removeCell(c2);
         _cells[dim].insert(newCell);
           
         cit = firstCell(dim);
         count++;
-        }
       }
       removeCellQset(s, Qset);
       
@@ -687,44 +582,39 @@ int CellComplex::combine(int dim){
   
   
   for(citer cit = firstCell(dim); cit != lastCell(dim); cit++){
-  
     Cell* cell = *cit;
     bd_c = cell->getBoundary();
     enqueueCells(bd_c, Q, Qset);
     while(Q.size() != 0){
 
       Cell* s = Q.front();
-      Q.pop();
+      Q.pop(); 
       
       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)){
+      if(s->getCoboundarySize() == 2 && !(*(cbd_c.front().second) == *(cbd_c.back().second)) 
+         && inSameDomain(s, cbd_c.front().second) && inSameDomain(s, cbd_c.back().second)
+         && cbd_c.front().second->getNumVertices() < getSize(dim) // heuristics for mammoth cell birth control
+         && cbd_c.back().second->getNumVertices() < getSize(dim)){
         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);
-          
         
         CombinedCell* newCell = new CombinedCell(c1, c2, (or1 != or2) );
-        _cells[dim].erase(c1);
-        _cells[dim].erase(c2);
-        _cells[dim].insert(newCell);
-        //replaceCells(c1, c2, newCell, (or1 != or2));
-        //removeCell(s);
+        removeCell(c1);
+        removeCell(c2);
+        std::pair<citer, bool> insertInfo =  _cells[dim].insert(newCell);
+        if(!insertInfo.second) printf("Warning: Combined cell not inserted! \n");
         cit = firstCell(dim);
-        //cit++;
         count++;
-          
-        }
-
       }
       removeCellQset(s, Qset);
       
@@ -868,4 +758,61 @@ void CellComplex::printComplex(int dim){
   }
 }
 
+bool CellComplex::checkCoherence(){
+  bool coherent = true;
+  for(int i = 0; i < 4; i++){
+    for(citer cit = firstCell(i); cit != lastCell(i); cit++){
+      Cell* cell = *cit;
+      std::list< std::pair<int, Cell*> > boundary = cell->getOrientedBoundary();
+      for(std::list< std::pair<int, Cell* > >::iterator it = boundary.begin(); it != boundary.end(); it++){
+        Cell* bdCell = (*it).second;
+        int ori = (*it).first;
+        citer cit = _cells[bdCell->getDim()].find(bdCell);
+        if(cit == lastCell(bdCell->getDim())){ 
+          printf("Warning! Boundary cell not in cell complex! Boundary removed. \n", cell->getDim());
+          //printf(" "); cell->printCell();
+          //printf(" "); bdCell->printCell();
+          cell->removeBoundaryCell(bdCell);
+          coherent = false;
+        }
+        if(!bdCell->hasCoboundary(cell)){
+          printf("Warning! Incoherent boundary/coboundary pair! Fixed. \n");
+          //printf(" "); cell->printCell();
+          //printf(" "); cell->printBoundary();
+          //printf(" "); bdCell->printCell();
+          //printf(" "); bdCell->printCoboundary();
+          bdCell->addCoboundaryCell(ori, cell);
+          coherent = false;
+        }
+        
+      }
+      std::list< std::pair<int, Cell*> > coboundary = cell->getOrientedCoboundary();
+      for(std::list< std::pair<int, Cell* > >::iterator it = coboundary.begin(); it != coboundary.end(); it++){
+        Cell* cbdCell = (*it).second;
+        int ori = (*it).first;
+        citer cit = _cells[cbdCell->getDim()].find(cbdCell);
+        if(cit == lastCell(cbdCell->getDim())){ 
+          printf("Warning! Coboundary cell not in cell complex! Coboundary removed. \n", cell->getDim());
+          //printf(" "); cell->printCell();
+          //printf(" "); cbdCell->printCell();
+          cell->removeCoboundaryCell(cbdCell);
+          coherent = false;
+        }
+        if(!cbdCell->hasBoundary(cell)){
+          printf("Warning! Incoherent coboundary/boundary pair! Fixed. \n");
+          //printf(" "); cell->printCell();
+          //printf(" "); cell->printCoboundary();
+          //printf(" "); cbdCell->printCell();
+          //printf(" "); cbdCell->printBoundary();
+          cbdCell->addBoundaryCell(ori, cell);
+          coherent = false;
+        }
+        
+      }
+      
+    }
+  }
+  return coherent;
+}
+
 #endif
diff --git a/Geo/CellComplex.h b/Geo/CellComplex.h
index e387628f0b34e95b7335c6e72dbb89c638bd9dee..021437788976d355e60784612fc9f889c2bb3b7e 100644
--- a/Geo/CellComplex.h
+++ b/Geo/CellComplex.h
@@ -52,10 +52,14 @@ class Cell
    // cells on the boundary and on the coboundary of thhis cell
    std::list< std::pair<int, Cell*> > _boundary;
    std::list< std::pair<int, Cell*> > _coboundary;
-   
+   int _bdSize;
+   int _cbdSize;
    
   public:
-   Cell(){}
+   Cell(){
+     _bdSize = 0;
+     _cbdSize = 0;
+   }
    virtual ~Cell(){}
    
    virtual int getDim() const { return _dim; };
@@ -79,8 +83,8 @@ class Cell
    // true if this cell has given vertex
    virtual bool hasVertex(int vertex) const = 0;
   
-   virtual int getBoundarySize() { return _boundary.size(); }
-   virtual int getCoboundarySize() { return _coboundary.size(); }
+   virtual int getBoundarySize() { return _bdSize; }
+   virtual int getCoboundarySize() { return _cbdSize; }
    
    virtual std::list< std::pair<int, Cell*> > getOrientedBoundary() { return _boundary; }
    virtual std::list< Cell* > getBoundary() {
@@ -101,43 +105,65 @@ class Cell
      return coboundary;
    }
    
-   virtual void addBoundaryCell(int orientation, Cell* cell, bool duplicates=false) {
-     if(!duplicates){
-       for(std::list< std::pair<int, Cell*> >::iterator it = _boundary.begin(); it != _boundary.end(); it++){
-         Cell* cell2 = (*it).second;
-         int ori2 = (*it).first;
-         if(*cell2 == *cell && !duplicates) return;
+   virtual bool addBoundaryCell(int orientation, Cell* cell) {
+     _bdSize++;
+     for(std::list< std::pair<int, Cell*> >::iterator it = _boundary.begin(); it != _boundary.end(); it++){
+       Cell* cell2 = (*it).second;
+       if(*cell2 == *cell) {
+         (*it).first = (*it).first + orientation;
+         if((*it).first == 0) { 
+           _boundary.erase(it); _bdSize--;
+           cell2->removeCoboundaryCell(this,false);
+           return false;
+         }
+         return true;
        }
      }
-     _boundary.push_back( std::make_pair(orientation, cell));
-     
+     _boundary.push_back( std::make_pair(orientation, cell ) );
+     return true;
    }
-   virtual void addCoboundaryCell(int orientation, Cell* cell, bool duplicates=false) {
-     if(!duplicates){
-       for(std::list< std::pair<int, Cell*> >::iterator it = _coboundary.begin(); it != _coboundary.end(); it++){
-         Cell* cell2 = (*it).second;
-         int ori2 = (*it).first;
-         if(*cell2 == *cell && !duplicates) return;
+   
+   virtual bool addCoboundaryCell(int orientation, Cell* cell) {
+     _cbdSize++;
+     for(std::list< std::pair<int, Cell*> >::iterator it = _coboundary.begin(); it != _coboundary.end(); it++){
+       Cell* cell2 = (*it).second;
+       if(*cell2 == *cell) {
+         (*it).first = (*it).first + orientation;
+         if((*it).first == 0){ 
+           _coboundary.erase(it); _cbdSize--;
+           cell2->removeBoundaryCell(this,false);
+           return false;
+         }
+         return true;
        }
      }
-     _coboundary.push_back( std::make_pair(orientation, cell));
+     _coboundary.push_back( std::make_pair(orientation, cell) );
+     return true;
    }
    
-   virtual int removeBoundaryCell(Cell* cell) {
-     int count = 0;
+   virtual int removeBoundaryCell(Cell* cell, bool other=true) {
      for(std::list< std::pair<int, Cell*> >::iterator it = _boundary.begin(); it != _boundary.end(); it++){
        Cell* cell2 = (*it).second;
-       if(*cell2 == *cell) { _boundary.erase(it); count++; it = _boundary.begin(); }
+       int ori = (*it).first;
+       if(*cell2 == *cell) {
+         _boundary.erase(it); 
+         if(other) cell2->removeCoboundaryCell(this, false); 
+         _bdSize--;
+         return ori;
+       }
      }
-     return count;
    }
-   virtual int removeCoboundaryCell(Cell* cell) {
-     int count = 0;
+   virtual int removeCoboundaryCell(Cell* cell, bool other=true) {
      for(std::list< std::pair<int, Cell*> >::iterator it = _coboundary.begin(); it != _coboundary.end(); it++){
        Cell* cell2 = (*it).second;
-       if(*cell2 == *cell)  { _coboundary.erase(it); count++; it = _coboundary.begin(); }
+       int ori = (*it).first;
+       if(*cell2 == *cell)  {
+         _coboundary.erase(it); 
+         if(other) cell2->removeBoundaryCell(this, false); 
+         _cbdSize--;
+         return ori;
+       }
      }
-     return count;
    }
    
    virtual bool hasBoundary(Cell* cell){
@@ -147,6 +173,14 @@ class Cell
      }
      return false;
    }
+   virtual bool hasCoboundary(Cell* cell){
+     for(std::list< std::pair<int, Cell*> >::iterator it = _coboundary.begin(); it != _coboundary.end(); it++){
+       Cell* cell2 = (*it).second;
+       if(*cell2 == *cell) return true;
+     }
+     return false;
+   }
+   
    
    virtual void clearBoundary() { _boundary.clear(); }
    virtual void clearCoboundary() { _coboundary.clear(); }
@@ -165,12 +199,14 @@ class Cell
        Cell* cell2 = (*it).second;
        cell2->printCell();
      }
+     if(_boundary.empty()) printf("Cell boundary is empty. \n");
    }
    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);
+       printf("Coboundary cell orientation: %d, ", (*it).first);
        Cell* cell2 = (*it).second;
        cell2->printCell();
+       if(_coboundary.empty()) printf("Cell coboundary is empty. \n");
      }
    }
    
@@ -188,11 +224,12 @@ class Cell
    virtual int getNumFacets() const { return 0; }
    virtual void getFacetVertices(const int num, std::vector<MVertex*> &v) const {};
    
-   virtual bool combined() { return _combined; }
+   virtual bool isCombined() { return _combined; }
    virtual std::list< std::pair<int, Cell*> > getCells() {  std::list< std::pair<int, Cell*> >cells; cells.push_back( std::make_pair(1, this)); return cells; }
    virtual int getNumCells() {return 1;}
    
    bool operator==(const Cell& c2){
+
      if(this->getNumVertices() != c2.getNumVertices()){
        return false;
      }
@@ -202,6 +239,9 @@ class Cell
        }
      }
      return true;
+
+     
+     
    }
    
    bool operator<(const Cell& c2) const {
@@ -261,7 +301,7 @@ class ZeroSimplex : public Simplex, public MPoint
    std::vector<MVertex*> getVertexVector() const { std::vector<MVertex*> v; v.push_back(_v[0]); return v; }
    std::vector<int> getSortedVertexVector() const { return std::vector<int>(1,_v[0]->getNum()); }
    
-   void printCell() const { printf("Vertices: %d, in subdomain: %d \n", _v[0]->getNum(), _inSubdomain); }
+   void printCell() const { printf("Cell dimension: %d, Vertices: %d, in subdomain: %d \n", getDim(), _v[0]->getNum(), _inSubdomain); }
    
 };
 
@@ -306,7 +346,7 @@ class OneSimplex : public Simplex, public MLine
    
    //int kappa(Cell* tau) const;
    
-   void printCell() const { printf("Vertices: %d %d, in subdomain: %d \n", _v[0]->getNum(), _v[1]->getNum(), _inSubdomain); }
+   void printCell() const { printf("Cell dimension: %d, Vertices: %d %d, in subdomain: %d \n", getDim(), _v[0]->getNum(), _v[1]->getNum(), _inSubdomain); }
 };
 
 // Two simplex cell type.
@@ -350,7 +390,7 @@ class TwoSimplex : public Simplex, public MTriangle
      MTriangle::getEdgeVertices(num, v);
    }
    
-   void printCell() const { printf("Vertices: %d %d %d, in subdomain: %d\n", _v[0]->getNum(), _v[1]->getNum(), _v[2]->getNum(), _inSubdomain); }
+   void printCell() const { printf("Cell dimension: %d, Vertices: %d %d %d, in subdomain: %d\n", getDim(), _v[0]->getNum(), _v[1]->getNum(), _v[2]->getNum(), _inSubdomain); }
 };
 
 // Three simplex cell type.
@@ -391,7 +431,7 @@ class ThreeSimplex : public Simplex, public MTetrahedron
      MTetrahedron::getFaceVertices(num, v);
    }
    
-   virtual void printCell() const { printf("Vertices: %d %d %d %d, in subdomain: %d \n", _v[0]->getNum(), _v[1]->getNum(), _v[2]->getNum(), _v[3]->getNum(), _inSubdomain); }
+   virtual void printCell() const { printf("Cell dimension: %d, Vertices: %d %d %d %d, in subdomain: %d \n", getDim(), _v[0]->getNum(), _v[1]->getNum(), _v[2]->getNum(), _v[3]->getNum(), _inSubdomain); }
 };
 
 // Ordering for the cells.
@@ -454,6 +494,14 @@ class CombinedCell : public Cell{
   public:
    
    CombinedCell(Cell* c1, Cell* c2, bool orMatch, bool co=false) : Cell(){
+     
+     // use "smaller" cell as c2
+     if(c1->getNumVertices() < c2->getNumVertices()){
+       Cell* temp = c1;
+       c1 = c2;
+       c2 = temp;
+     }
+     
      _index = c1->getIndex();
      _tag = c1->getTag();
      _dim = c1->getDim();
@@ -481,96 +529,66 @@ class CombinedCell : public Cell{
        _cells.push_back(*it);
      }
      
-     _boundary = c1->getOrientedBoundary();
+     
+     //_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 = c1Boundary.begin(); it != c1Boundary.end(); it++){
        Cell* cell = (*it).second;
        int ori = (*it).first;
-       cell->removeCoboundaryCell(c1);
-       cell->addCoboundaryCell(ori, this, true);
+       cell->removeCoboundaryCell(c1); 
+       if(this->addBoundaryCell(ori, cell)) cell->addCoboundaryCell(ori, this);
      }
-     
      for(std::list< std::pair<int, Cell*> >::iterator it = c2Boundary.begin(); it != c2Boundary.end(); it++){
-       int ori2 = (*it).first;
-       if(!orMatch) (*it).first = -1*(*it).first;
        Cell* cell = (*it).second;
+       if(!orMatch) (*it).first = -1*(*it).first;
        int ori = (*it).first;
        cell->removeCoboundaryCell(c2);
+       //if(this->addBoundaryCell(ori, cell)) cell->addCoboundaryCell(ori, this);       
        if(co){
          bool old = false;
          for(std::list< std::pair<int, Cell* > >::iterator it2 = c1Boundary.begin(); it2 != c1Boundary.end(); it2++){
            Cell* cell2 = (*it2).second;
            if(*cell2 == *cell) old = true;
          }
-         if(!old){  _boundary.push_back(*it); cell->addCoboundaryCell(ori, this, true); }
+         if(!old){  if(this->addBoundaryCell(ori, cell)) cell->addCoboundaryCell(ori, this); }
+       }
+       else{
+         if(this->addBoundaryCell(ori, cell)) cell->addCoboundaryCell(ori, this);
        }
-       else { _boundary.push_back(*it); cell->addCoboundaryCell(ori, this, true); }
      }
      
-     _coboundary = c1->getOrientedCoboundary();
+     //_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 = c1Coboundary.begin(); it != c1Coboundary.end(); it++){
        Cell* cell = (*it).second;
        int ori = (*it).first;
-       cell->removeBoundaryCell(c1);
-       cell->addBoundaryCell(ori, this,true);
+       cell->removeBoundaryCell(c1); 
+       if(this->addCoboundaryCell(ori, cell)) cell->addBoundaryCell(ori, this);
      }
-     
-     
-     for(std::list< std::pair<int, Cell* > >::iterator it = c2Coboundary.begin(); it != c2Coboundary.end(); it++){
-       int ori2 = (*it).first;
-       if(!orMatch) (*it).first = -1*(*it).first;
+     for(std::list< std::pair<int, Cell*> >::iterator it = c2Coboundary.begin(); it != c2Coboundary.end(); it++){
        Cell* cell = (*it).second;
+       if(!orMatch) (*it).first = -1*(*it).first;
        int ori = (*it).first;
        cell->removeBoundaryCell(c2);
+       //if(this->addCoboundaryCell(ori, cell)) cell->addBoundaryCell(ori, this);       
        if(!co){
          bool old = false;
          for(std::list< std::pair<int, Cell* > >::iterator it2 = c1Coboundary.begin(); it2 != c1Coboundary.end(); it2++){
            Cell* cell2 = (*it2).second;
            if(*cell2 == *cell) old = true;
          }
-         if(!old) { _coboundary.push_back(*it); cell->addBoundaryCell(ori, this, true); }
-         
+         if(!old) { if(this->addCoboundaryCell(ori, cell)) cell->addBoundaryCell(ori, this); }
+       }
+       else {
+         if(this->addCoboundaryCell(ori, cell)) cell->addBoundaryCell(ori, this);
        }
-       else { _coboundary.push_back(*it); cell->addBoundaryCell(ori, this, true); }
      }
-     
+
    }
   
    ~CombinedCell(){} 
@@ -595,9 +613,10 @@ class CombinedCell : public Cell{
    }
    
    virtual void printCell() const {
+     printf("Cell dimension: %d, ", getDim() ); 
      printf("Vertices: ");
      for(int i = 0; i < this->getNumVertices(); i++){
-       printf("%d ", this->getVertex(i)->getNum());
+       printf("%d ", this->getSortedVertex(i));
      }
      printf(", in subdomain: %d\n", _inSubdomain);
    }
@@ -626,9 +645,8 @@ class CellComplex
    // one for each dimension
    std::set<Cell*, Less_Cell>  _cells[4];
    
-   // trashbin for cell pointers removed from cell complex
+   // storage for cell pointers to delete them
    std::set<Cell*, Less_Cell>  _cells2[4];
-   std::set<Cell*, Less_Cell> _trash;
    
    //std::set<Cell*, Less_Cell>  _originalCells[4];
    
@@ -654,13 +672,13 @@ class CellComplex
    
    // remove a cell from this cell complex
    void removeCell(Cell* cell);
-   void replaceCells(Cell* c1, Cell* c2, Cell* newCell, bool orMatch, bool co=false);
    void insertCell(Cell* cell);
-
+   
+  public:
    // reduction of this cell complex
    // removes reduction pairs of cell of dimension dim and dim-1
    int reduction(int dim);
- 
+  private:
    // queued coreduction presented in Mrozek's paper
    int coreduction(Cell* generator);
  
@@ -701,16 +719,11 @@ class CellComplex
    CellComplex( std::vector<GEntity*> domain, std::vector<GEntity*> subdomain );
    CellComplex(){}
    ~CellComplex(){ 
-     //for(std::set<Cell*, Less_Cell>::iterator it = _trash.begin(); it != _trash.end(); it++){
-     //  Cell* cell = *it;
-     //  delete cell;
-     //}
-     
      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;
+         if(cell->isCombined()) delete cell;
        }
        _cells[i].clear();
        for(citer cit = _cells2[i].begin(); cit != _cells2[i].end(); cit++){
@@ -734,6 +747,14 @@ class CellComplex
    citer firstCell(int dim) {return _cells[dim].begin(); }
    citer lastCell(int dim) {return _cells[dim].end(); }
   
+   // true if cell complex has given cell
+   bool hasCell(Cell* cell){
+     citer cit = _cells[cell->getDim()].find(cell);
+     if( cit == lastCell(cell->getDim()) ) return false;
+     else return true;
+   }
+     
+
    // kappa for two cells of this cell complex
    // implementation will vary depending on cell type
    inline int kappa(Cell* sigma, Cell* tau) const { return sigma->kappa(tau); }
@@ -762,19 +783,20 @@ class CellComplex
    // write this cell complex in 2.0 MSH ASCII format
    int writeComplexMSH(const std::string &name); 
    
+   // Cell combining for reduction and coreduction
    int combine(int dim);
    int cocombine(int dim);
    
-   void emptyTrash() {
-     for(std::set<Cell*, Less_Cell>::iterator it = _trash.begin(); it != _trash.end(); it++){
-       Cell* cell = *it;
-       delete cell;
-     }
-   }
    
    void computeBettiNumbers();
    int getBettiNumber(int i) { if(i > -1 && i < 4) return _betti[i]; else return 0; }
    
+   // check whether all boundary cells of a cell has this cell as coboundary cell and vice versa
+   // also check whether all (co)boundary cells of a cell belong to this cell complex
+   bool checkCoherence();
+   
+   // change roles of boundaries and coboundaries of the cells in this cell complex
+   // equivalent to transposing boundary operator matrices
    void makeDualComplex(){
      std::set<Cell*, Less_Cell> temp = _cells[0];
      _cells[0] = _cells[3];
@@ -791,26 +813,8 @@ class CellComplex
      }
    }
    
-   void checkCoherence(){
-     for(int i = 0; i < 4; i++){
-       for(citer cit = firstCell(i); cit != lastCell(i); cit++){
-         Cell* cell = *cit;
-         std::list< std::pair<int, Cell*> > boundary;
-         for(std::list< std::pair<int, Cell* > >::iterator it = boundary.begin(); it != boundary.end(); it++){
-           Cell* bdCell = (*it).second;
-           citer cit = _cells[bdCell->getDim()].find(bdCell);
-           if(cit == lastCell(bdCell->getDim())) printf("Warning! Incoherent boundary!");
-         }
-         std::list< std::pair<int, Cell*> > coboundary;
-         for(std::list< std::pair<int, Cell* > >::iterator it = coboundary.begin(); it != coboundary.end(); it++){
-           Cell* cbdCell = (*it).second;
-           citer cit = _cells[cbdCell->getDim()].find(cbdCell);
-           if(cit == lastCell(cbdCell->getDim())) printf("Warning! Incoherent coboundary!");
-         }
-         
-       }
-     }
-   }
+   
+   
    
 };
 
diff --git a/Geo/ChainComplex.cpp b/Geo/ChainComplex.cpp
index 22e44eb8342d09814a528e56877fc4a0badc4bb5..56091c0688b0328cbe06be61d675d6bec9de4919 100644
--- a/Geo/ChainComplex.cpp
+++ b/Geo/ChainComplex.cpp
@@ -86,8 +86,9 @@ ChainComplex::ChainComplex(CellComplex* cellComplex){
                 old_elem = mpz_get_si(elem);
                 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);
+                  printf("Warning: Invalid incidence index: %d! HMatrix: %d.", (old_elem + (*it).first), dim);
+                  printf(" Set to %d. \n", (old_elem + (*it).first) % 2);
+                  mpz_set_si(elem, (old_elem + (*it).first) % 2);
                 }
                 gmp_matrix_set_elem(elem, bdCell->getIndex(), cell->getIndex(), _HMatrix[dim]);
               }
@@ -351,6 +352,7 @@ void ChainComplex::computeHomology(bool dual){
                                          gmp_matrix_cols(getKerHMatrix(lowDim))) );
     }
     
+   
     // 5) General case:
     //   1) Find the bases of boundaries B and cycles Z 
     //   2) find j: B -> Z and
diff --git a/Geo/Homology.cpp b/Geo/Homology.cpp
index f6edfd5a40c4ba246dfc193461c1722fcc4f9ae1..39b7eba797efbc2a5017d84590e77e7961fdaf6b 100644
--- a/Geo/Homology.cpp
+++ b/Geo/Homology.cpp
@@ -78,23 +78,22 @@ void Homology::findGenerators(std::string fileName){
   double t1 = Cpu();
   int omitted = _cellComplex->reduceComplex(true);
   
-  //_cellComplex->checkCoherence();
   if(getCombine()){
     _cellComplex->combine(3);
-    _cellComplex->reduceComplex(false);
+    _cellComplex->reduction(2);
     _cellComplex->combine(2);
-    _cellComplex->reduceComplex(false);
+    _cellComplex->reduction(1);
     _cellComplex->combine(1);
-    _cellComplex->reduceComplex(false);
   }
-  //_cellComplex->checkCoherence();
+  _cellComplex->checkCoherence();
+  
   double t2 = Cpu();
   Msg::Info("Cell Complex reduction complete (%g s).", t2 - t1);
   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);
-    
+  //for(int i = 0; i < 4; i++) { printf("Dim %d: \n", i); _cellComplex->printComplex(i); }
+  
   _cellComplex->writeComplexMSH(fileName);
   
   Msg::Info("Computing homology groups...");
@@ -146,16 +145,20 @@ void Homology::findGenerators(std::string fileName){
 
 void Homology::findThickCuts(std::string fileName){
   
+  //for(int i = 0; i < 4; i++) { printf("Dim %d: \n", i); _cellComplex->printComplex(i); }
+  
   Msg::Info("Reducing Cell Complex...");
   double t1 = Cpu();
   int omitted = _cellComplex->coreduceComplex(true);
+  //for(int i = 0; i < 4; i++) { printf("Dim %d: \n", i); _cellComplex->printComplex(i); }
+  //_cellComplex->coreduceComplex(false);
   //_cellComplex->checkCoherence();
   if(getCombine()){
     _cellComplex->cocombine(0);
     _cellComplex->cocombine(1);
     _cellComplex->cocombine(2);
   }
-  //_cellComplex->checkCoherence();
+  _cellComplex->checkCoherence();
   double t2 = Cpu();
   Msg::Info("Cell Complex reduction complete (%g s).", t2 - t1);
   Msg::Info("%d volumes, %d faces, %d edges and %d vertices.",