diff --git a/Geo/Cell.cpp b/Geo/Cell.cpp
index 5cdaaba5cf84065da9abffbef17bde3de94d524d..962a53b3ad9c2239fea66986b1416cfd863c1d34 100755
--- a/Geo/Cell.cpp
+++ b/Geo/Cell.cpp
@@ -6,6 +6,7 @@
 // Contributed by Matti Pellikka <matti.pellikka@tut.fi>.
 
 #include "CellComplex.h"
+#include "Cell.h"
 
 #if defined(HAVE_KBIPACK)
 
@@ -27,12 +28,69 @@ bool Less_Cell::operator()(const Cell* c1, const Cell* c2) const {
   return false;
 }
 
+bool Cell::hasVertex(int vertex) const {
+  std::vector<int>::const_iterator it = std::find(_vs.begin(), _vs.end(), vertex);
+  if (it != _vs.end()) return true;
+  else return false;
+}
+
+int Cell::getNumFacets() const { 
+  if(getDim() == 0) return 0;
+  else if(getDim() == 1) return 2;
+  else if(getDim() == 2) return _image->getNumEdges();
+  else if(getDim() == 3) return _image->getNumFaces();
+  else return 0;
+}
+void Cell::getFacetVertices(const int num, std::vector<MVertex*> &v) const {
+  if(getDim() == 0) return;
+  else if(getDim() == 1) { v.resize(1); v[0] = getVertex(num); }
+  else if(getDim() == 2) _image->getEdgeVertices(num, v);
+  else if(getDim() == 3) _image->getFaceVertices(num, v);
+  return;
+}
+
+
+int Cell::getFacetOri(std::vector<MVertex*> &v) {
+  if(getDim() == 0) return 0;
+  else if(getDim() == 1){
+    if(v.size() != 1) return 0;
+    else if(v[0] == getVertex(0)) return -1;
+    else if(v[0] == getVertex(1)) return 1;
+    else return 0;
+  }
+  else if(getDim() == 2){
+    if(v.size() != 2) return 0;
+    MEdge facet = MEdge(v[0], v[1]);
+    int ithFacet = 0;
+    int sign = 0;
+    _image->getEdgeInfo(facet, ithFacet, sign);
+    return sign;
+  }
+  else if(getDim() == 3){
+    if(v.size() != 3) return 0;
+    MFace facet = MFace(v);
+    int ithFacet = 0;
+    int sign = 0;
+    int rot = 0;
+    _image->getFaceInfo(facet, ithFacet, sign, rot);
+    return sign;
+  }
+  else return 0;
+}  
+
+void Cell::printCell() {
+  printf("%d-cell %d: \n" , getDim(), getNum());
+  printf("Vertices: ");
+  for(int i = 0; i < this->getNumVertices(); i++){
+    printf("%d ", this->getSortedVertex(i));
+  }
+  printf(", in subdomain: %d\n", _inSubdomain);
+  printf("Combined: %d \n" , isCombined() );
+};
 
 void Cell::restoreCell(){
   _boundary = _obd;
   _coboundary = _ocbd;
-  _bdSize = _boundary.size();
-  _cbdSize = _coboundary.size();
   _combined = false;
   _index = 0;
   _immune = false;   
@@ -58,12 +116,11 @@ std::list< Cell* > Cell::getCoboundary() {
 
 
 bool Cell::addBoundaryCell(int orientation, Cell* cell) {
-  _bdSize++;
   biter it = _boundary.find(cell);
   if(it != _boundary.end()){
     (*it).second = (*it).second + orientation;
     if((*it).second == 0) {
-      _boundary.erase(it); _bdSize--;
+      _boundary.erase(it);
       (*it).first->removeCoboundaryCell(this,false);
       return false;
     }
@@ -74,12 +131,11 @@ bool Cell::addBoundaryCell(int orientation, Cell* cell) {
 }
 
 bool Cell::addCoboundaryCell(int orientation, Cell* cell) {
-  _cbdSize++;
   biter it = _coboundary.find(cell);
   if(it != _coboundary.end()){
     (*it).second = (*it).second + orientation;
     if((*it).second == 0) {
-      _coboundary.erase(it); _cbdSize--;
+      _coboundary.erase(it);
       (*it).first->removeBoundaryCell(this,false);
       return false;
     }
@@ -94,7 +150,6 @@ int Cell::removeBoundaryCell(Cell* cell, bool other) {
   if(it != _boundary.end()){
     _boundary.erase(it);
     if(other) (*it).first->removeCoboundaryCell(this, false);
-    _bdSize--;
     return (*it).second;
   }
   
@@ -105,7 +160,6 @@ int Cell::removeCoboundaryCell(Cell* cell, bool other) {
   if(it != _coboundary.end()){
     _coboundary.erase(it);
     if(other) (*it).first->removeBoundaryCell(this, false);
-    _cbdSize--;
     return (*it).second;
   }
   return 0;
@@ -189,26 +243,27 @@ CombinedCell::CombinedCell(Cell* c1, Cell* c2, bool orMatch, bool co) : Cell() {
   }
   
   _index = c1->getIndex();
-  _tag = c1->getTag();
+  //_tag = c1->getTag();
   _dim = c1->getDim();
   _num = c1->getNum();
   _inSubdomain = c1->inSubdomain();
   _onDomainBoundary = c1->onDomainBoundary();
   _combined = true;
+  _image = NULL;
   
   _v.reserve(c1->getNumVertices() + c2->getNumVertices());
   _vs.reserve(c1->getNumVertices() + c2->getNumVertices());
   
-     
-  _v = c1->getVertexVector();
+
+  for(int i = 0; i < c1->getNumVertices(); i++) _v.push_back(c1->getVertex(i));
   for(int i = 0; i < c2->getNumVertices(); i++){
-    if(!this->hasVertex(c2->getVertex(i)->getNum())) _v.push_back(c2->getVertex(i));
+    if(!this->hasVertex(c2->getVertex(i)->getNum())) _v.push_back(c2->getVertex(i)); 
   }
-  
+
   // sorted vertices
   for(unsigned int i = 0; i < _v.size(); i++) _vs.push_back(_v.at(i)->getNum());
   std::sort(_vs.begin(), _vs.end());
-  
+ 
   // cells
   _cells = c1->getCells();
   std::list< std::pair<int, Cell*> > c2Cells = c2->getCells();
@@ -216,7 +271,7 @@ CombinedCell::CombinedCell(Cell* c1, Cell* c2, bool orMatch, bool co) : Cell() {
     if(!orMatch) (*it).first = -1*(*it).first;
     _cells.push_back(*it);
   }
-  
+
   // boundary cells
   std::map< Cell*, int, Less_Cell > c1Boundary = c1->getOrientedBoundary();
   std::map< Cell*, int, Less_Cell > c2Boundary = c2->getOrientedBoundary();
@@ -242,7 +297,7 @@ CombinedCell::CombinedCell(Cell* c1, Cell* c2, bool orMatch, bool co) : Cell() {
       if(this->addBoundaryCell(ori, cell)) cell->addCoboundaryCell(ori, this);
     }
   }
-  
+
   // coboundary cells
   std::map<Cell*, int, Less_Cell > c1Coboundary = c1->getOrientedCoboundary();
   std::map<Cell*, int, Less_Cell > c2Coboundary = c2->getOrientedCoboundary();
@@ -268,7 +323,7 @@ CombinedCell::CombinedCell(Cell* c1, Cell* c2, bool orMatch, bool co) : Cell() {
       if(this->addCoboundaryCell(ori, cell)) cell->addBoundaryCell(ori, this);
     }
   }
-  
+
 }
 
 
@@ -280,61 +335,4 @@ CombinedCell::~CombinedCell(){
   }
 } 
 
-bool CombinedCell::hasVertex(int vertex) const {
-  /*std::vector<int>::const_iterator it = std::find(_vs.begin(), _vs.end(), vertex);
-  if (it != _vs.end()) return true;
-  else return false;*/
-  for(unsigned int i = 0; i < _v.size(); i++){
-    if(_v.at(i)->getNum() == vertex) return true;
-  }
-  return false;
-}
-
-void CombinedCell::printCell() const {
-  printf("Cell dimension: %d, ", getDim() ); 
-  printf("Vertices: ");
-  for(int i = 0; i < this->getNumVertices(); i++){
-    printf("%d ", this->getSortedVertex(i));
-  }
-  printf(", in subdomain: %d\n", _inSubdomain);
-}
-
-/*
- int Cell::incidence(Cell* tau) const{
- for(int i=0; i < tau->getNumVertices(); i++){
- if( !(this->hasVertex(tau->getVertex(i)->getNum())) ) return 0;
- }
-  
- if(this->getDim() - tau->getDim() != 1) return 0;
-  
- int value=1;
- 
-  for(int i = 0; i < this->getNumFacets(); i++){
-    std::vector<MVertex*> vTau = tau->getVertexVector(); 
-    std::vector<MVertex*> v;
-    this->getFacetVertices(i, v);
-    value = -1;
-    
-    if(v.size() != vTau.size()) printf("Error: invalid facet!");
-    
-    do {
-      value = value*-1;
-      if(v == vTau) return value;
-    }
-    while (std::next_permutation(vTau.begin(), vTau.end()) );
-    
-    vTau = tau->getVertexVector();
-    value = -1;
-    do {
-      value = value*-1;
-      if(v == vTau) return value;
-    }
-    while (std::prev_permutation(vTau.begin(), vTau.end()) );
-    
-    
-  }
-  
-  return 0;
-}*/
-
 #endif
diff --git a/Geo/Cell.h b/Geo/Cell.h
new file mode 100644
index 0000000000000000000000000000000000000000..3fb2439e8300f8ffb4c4b76ab0f65a5634216d6a
--- /dev/null
+++ b/Geo/Cell.h
@@ -0,0 +1,247 @@
+// Gmsh - Copyright (C) 1997-2009 C. Geuzaine, J.-F. Remacle
+//
+// See the LICENSE.txt file for license information. Please report all
+// bugs and problems to <gmsh@geuz.org>.
+//
+// Contributed by Matti Pellikka <matti.pellikka@tut.fi>.
+
+#ifndef _CELL_H_
+#define _CELL_H_
+
+#include "GmshConfig.h"
+
+#if defined(HAVE_KBIPACK)
+
+#include <stdio.h>
+#include <string>
+#include <algorithm>
+#include <set>
+#include <queue>
+#include "CellComplex.h"
+#include "MElement.h"
+#include "MPoint.h"
+#include "MLine.h"
+#include "MTriangle.h"
+#include "MQuadrangle.h"
+#include "MHexahedron.h"
+#include "MPrism.h"
+#include "MPyramid.h"
+#include "MTetrahedron.h"
+#include "GModel.h"
+
+class Cell;
+
+// Ordering of the cells
+class Less_Cell{
+  public:
+   bool operator()(const Cell* c1, const Cell* c2) const;
+};
+
+// Class representing an elementary cell of a cell complex.
+class Cell
+{  
+  protected:
+   
+   // cell dimension
+   int _dim;
+   
+   // whether this cell belongs to a subdomain, immutable
+   // used in relative homology computation
+   bool _inSubdomain;
+   
+   // whether this cell belongs to the boundary of a cell complex
+   bool _onDomainBoundary;
+   
+   // whether this cell a combinded cell of elemetary cells
+   bool _combined; 
+   
+   // mutable index for each cell (used to create boundary operator matrices)
+   int _index; 
+   
+   // for some algorithms to omit this cell
+   bool _immune;
+  
+   // mutable list of cells on the boundary and on the coboundary of this cell
+   std::map< Cell*, int, Less_Cell > _boundary;
+   std::map< Cell*, int, Less_Cell > _coboundary;
+   
+   // immutable original boundary and coboundary before the reduction of the cell complex
+   std::map<Cell*, int, Less_Cell > _obd;
+   std::map<Cell*, int, Less_Cell > _ocbd;
+   
+   // The mesh element that is the image of this cell
+   MElement* _image;
+   // Whether to delete the mesh element when done (created for homology computation only)
+   bool _deleteImage;
+   
+   // sorted vertices of this cell (used for ordering of the cells)
+   std::vector<int> _vs;
+   
+  public:
+   Cell(){
+     _combined = false;
+     _index = 0;
+     _immune = false;
+     _image = NULL;
+     _deleteImage = false;
+   }
+  
+   Cell(MElement* image, bool subdomain, bool boundary){
+     _combined = false;
+     _index = 0;
+     _immune = false;
+     _image = image;
+     _onDomainBoundary = boundary;
+     _inSubdomain = subdomain;
+     _dim = image->getDim();
+     _deleteImage = false;
+     for(int i = 0; i < image->getNumVertices(); i++) _vs.push_back(image->getVertex(i)->getNum()); 
+     std::sort(_vs.begin(), _vs.end());
+   }
+   virtual ~Cell() {if(_deleteImage) delete _image; }
+  
+   virtual MElement* getImageMElement() const { return _image; };
+   
+   virtual int getDim() const { return _dim; };
+   virtual int getIndex() const { return _index; };
+   virtual void setIndex(int index) { _index = index; };
+   virtual int getNum() { return _image->getNum(); }
+   virtual int getType() { return _image->getType(); }
+   virtual int getTypeForMSH() { return _image->getTypeForMSH(); }
+   virtual int getPartition() { return _image->getPartition(); }
+   virtual void setImmune(bool immune) { _immune = immune; };
+   virtual bool getImmune() const { return _immune; };
+   virtual void setDeleteImage(bool deleteImage) { _deleteImage = deleteImage; };
+   virtual bool getDeleteImage() const { return _deleteImage; };
+
+   // get the number of vertices this cell has
+   virtual int getNumVertices() const { return _image->getNumVertices(); }
+   virtual MVertex* getVertex(int vertex) const { return _image->getVertex(vertex); }
+   virtual int getSortedVertex(int vertex) const { return _vs.at(vertex); }
+   
+   // restores the cell information to its original state before reduction
+   virtual void restoreCell();
+   
+   // true if this cell has given vertex
+   virtual bool hasVertex(int vertex) const;
+
+   // (co)boundary cell iterator
+   typedef std::map<Cell*, int, Less_Cell>::iterator biter;
+   
+   virtual int getBoundarySize() { return _boundary.size(); }
+   virtual int getCoboundarySize() { return _coboundary.size(); }
+   
+   // get the cell boundary
+   virtual std::map<Cell*, int, Less_Cell > getOrientedBoundary() { return _boundary; }
+   virtual std::list< Cell* > getBoundary();
+   virtual std::map<Cell*, int, Less_Cell > getOrientedCoboundary() { return _coboundary; }
+   virtual std::list< Cell* > getCoboundary();
+   
+   // add (co)boundary cell
+   virtual bool addBoundaryCell(int orientation, Cell* cell); 
+   virtual bool addCoboundaryCell(int orientation, Cell* cell);
+   
+   // remove (co)boundary cell
+   virtual int removeBoundaryCell(Cell* cell, bool other=true);
+   virtual int removeCoboundaryCell(Cell* cell, bool other=true);
+   
+   // true if has given cell on (original) (co)boundary
+   virtual bool hasBoundary(Cell* cell, bool org=false);
+   virtual bool hasCoboundary(Cell* cell, bool org=false);
+   
+   virtual void clearBoundary() { _boundary.clear(); }
+   virtual void clearCoboundary() { _coboundary.clear(); }
+   
+   // algebraic dual of the cell
+   virtual void makeDualCell();
+   
+   // print cell info
+   virtual void printCell();
+   virtual void printBoundary();
+   virtual void printCoboundary();
+   
+   // original (co)boundary
+   virtual void addOrgBdCell(int orientation, Cell* cell) { _obd.insert( std::make_pair(cell, orientation ) ); };
+   virtual void addOrgCbdCell(int orientation, Cell* cell) { _ocbd.insert( std::make_pair(cell, orientation ) ); };
+   virtual std::map<Cell*, int, Less_Cell > getOrgBd() { return _obd; }
+   virtual std::map<Cell*, int, Less_Cell > getOrgCbd() { return _ocbd; }
+   virtual void printOrgBd();
+   virtual void printOrgCbd(); 
+   
+   virtual bool inSubdomain() const { return _inSubdomain; }
+   //virtual void setInSubdomain(bool subdomain)  { _inSubdomain = subdomain; }
+   
+   virtual bool onDomainBoundary() const { return _onDomainBoundary; }
+   virtual void setOnDomainBoundary(bool domainboundary)  { _onDomainBoundary = domainboundary; }
+   
+   // get the number of facets of this cell
+   virtual int getNumFacets() const;
+   // get the vertices on a facet of this cell
+   virtual void getFacetVertices(const int num, std::vector<MVertex*> &v) const;
+   
+   // get boundary cell orientation
+   virtual int getFacetOri(Cell* cell) { 
+    std::vector<MVertex*> v; 
+    for(int i = 0; i < cell->getNumVertices(); i++) v.push_back(cell->getVertex(i));
+    return getFacetOri(v);
+   } 
+   virtual int getFacetOri(std::vector<MVertex*> &v); 
+
+   // tools for combined cells
+   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;}
+      
+   // equivalence
+   bool operator==(const Cell& c2) const {  
+     if(this->getNumVertices() != c2.getNumVertices()){
+       return false;
+     }
+     for(int i=0; i < this->getNumVertices();i++){
+       if(this->getSortedVertex(i) != c2.getSortedVertex(i)){
+         return false;
+       }
+     }
+     return true;
+   }
+};
+
+// A cell that is a combination of cells of same dimension
+class CombinedCell : public Cell{
+ 
+  private:
+   // vertices
+   std::vector<MVertex*> _v;
+   // sorted list of all vertices
+   std::vector<int> _vs;
+   // list of cells this cell is a combination of
+   std::list< std::pair<int, Cell*> > _cells;
+   int _num;
+   
+  public:
+   
+   CombinedCell(Cell* c1, Cell* c2, bool orMatch, bool co=false);
+   ~CombinedCell();
+   
+   int getNum() { return _num; }
+   int getType() { return 0; }
+   int getTypeForMSH() { return 0; }
+   int getPartition() { return 0; }
+   
+   int getNumVertices() const { return _v.size(); } 
+   MVertex* getVertex(int vertex) const { return _v.at(vertex); }
+   int getSortedVertex(int vertex) const { return _vs.at(vertex); }
+   
+   std::list< std::pair<int, Cell*> > getCells() { return _cells; }
+   int getNumCells() {return _cells.size();}
+   
+};
+
+
+#endif
+
+#endif
diff --git a/Geo/CellComplex.cpp b/Geo/CellComplex.cpp
index 8b49f25cee53fdaa0bf5285a8e4d8e4188807a4b..cb2b779a5a8bb1914192f955c3044561acfe870f 100644
--- a/Geo/CellComplex.cpp
+++ b/Geo/CellComplex.cpp
@@ -26,19 +26,9 @@ CellComplex::CellComplex( std::vector<GEntity*> domain, std::vector<GEntity*> su
   insert_cells(true, true);
   insert_cells(false, true);
   insert_cells(false, false);
-
-  // find vertices in domain
-  find_vertices(domain, subdomain);
   
 
-  //int tag = 1;
   for(int i = 0; i < 4; i++){
-    /*
-    for(citer cit = firstCell(i); cit != lastCell(i); cit++){
-      Cell* cell = *cit;
-      cell->setTag(tag);
-      tag++;
-    }*/
     _ocells[i] = _cells[i];
     _betti[i] = 0;
     if(getSize(i) > _dim) _dim = i;
@@ -47,27 +37,6 @@ CellComplex::CellComplex( std::vector<GEntity*> domain, std::vector<GEntity*> su
   
 }
 
-void CellComplex::find_vertices(std::vector<GEntity*>& domain, std::vector<GEntity*>& subdomain){
-    // find mesh vertices in the domain
-  for(unsigned int j=0; j < domain.size(); j++) {  
-    for(unsigned int i=0; i < domain.at(j)->getNumMeshElements(); i++){
-      for(int k=0; k < domain.at(j)->getMeshElement(i)->getNumVertices(); k++){
-        MVertex* vertex = domain.at(j)->getMeshElement(i)->getVertex(k);
-        _domainVertices.insert(vertex);
-      }
-    }
-  }
-
-  for(unsigned int j=0; j < subdomain.size(); j++) {
-    for(unsigned int i=0; i < subdomain.at(j)->getNumMeshElements(); i++){
-      for(int k=0; k < subdomain.at(j)->getMeshElement(i)->getNumVertices(); k++){
-        MVertex* vertex = subdomain.at(j)->getMeshElement(i)->getVertex(k);
-        _domainVertices.insert(vertex);
-      }
-    }
-  } 
-}
-
 void CellComplex::find_boundary(std::vector<GEntity*>& domain, std::vector<GEntity*>& subdomain){
 
   // determine mesh entities on boundary of the domain
@@ -140,7 +109,6 @@ void CellComplex::insert_cells(bool subdomain, bool boundary){
   std::vector<MVertex*> vertices;
   
   std::pair<citer, bool> insertInfo;
-  int tag = 1;
 
   // add highest dimensional cells
   for(unsigned int j=0; j < domain.size(); j++) {
@@ -161,15 +129,12 @@ void CellComplex::insert_cells(bool subdomain, bool boundary){
          type == MSH_TRI_15 || type == MSH_TRI_15I || type == MSH_TRI_21 || type == MSH_LIN_4 ||
          type == MSH_LIN_5 || type == MSH_LIN_6 || type == MSH_TET_20 || type == MSH_TET_35 || type == MSH_TET_56
          || type == MSH_TET_34 || type == MSH_TET_52 ){
-        if(dim == 3) cell = new ThreeSimplex(vertices, tag, subdomain, boundary); 
-        else if(dim == 2) cell = new TwoSimplex(vertices, tag, subdomain, boundary);
-        else if(dim == 1) cell = new OneSimplex(vertices, tag, subdomain, boundary);
-        else cell = new ZeroSimplex(vertices, tag, subdomain, boundary);
+        cell = new Cell(domain.at(j)->getMeshElement(i), subdomain, boundary);
       }
       else if(type == MSH_QUA_4 || type == MSH_QUA_8 || type == MSH_QUA_9){
-        cell = new CQuadrangle(vertices, tag, subdomain, boundary);
+        cell = new Cell(domain.at(j)->getMeshElement(i), subdomain, boundary);
         _simplicial = false;
-      }/* FIXME: reduction doesn't work for these      
+      }/* FIXME: reduction doesn't work for these (but should).      
       else if(type == MSH_HEX_8 || type == MSH_HEX_27 || type == MSH_HEX_20){
         cell = new CHexahedron(vertices, tag, subdomain, boundary);
         _simplicial = false;
@@ -182,10 +147,7 @@ void CellComplex::insert_cells(bool subdomain, bool boundary){
         cell = new CPyramid(vertices, tag, subdomain, boundary);
         _simplicial = false;
       }*/
-      else Msg::Error("Error: mesh element %d not implemented yet! \n", type);
-      tag++;
-      //if(domain.at(j)->getMeshElement(i)->getNum() == 8196) cell->setImmune(true);
-      //else 
+      else Msg::Error("Error: mesh element %d not implemented yet! \n", type); 
       cell->setImmune(false);
       insertInfo = _cells[dim].insert(cell);
       if(!insertInfo.second) delete cell;
@@ -193,28 +155,40 @@ void CellComplex::insert_cells(bool subdomain, bool boundary){
   }
 
   // add lower dimensional cells recursively
+  MElementFactory factory;
   for (int dim = 3; dim > 0; dim--){
     for(citer cit = firstCell(dim); cit != lastCell(dim); cit++){
       Cell* cell = *cit;
       std::vector<MVertex*> vertices;
       for(int i = 0; i < cell->getNumFacets(); i++){ 
         cell->getFacetVertices(i, vertices);
-        Cell* newCell;
+        int type = cell->getTypeForMSH();
+        
+        int newtype = 0;
+        //FIXME: add missing boundary cell type relations
         if(dim == 3){
-          if(vertices.size() == 3) newCell = new TwoSimplex(vertices, tag, subdomain, boundary);
-          else if(vertices.size() == 4) newCell = new CQuadrangle(vertices, tag, subdomain, boundary);
-          else Msg::Debug("Error: invalid face! \n");
+          if(type == MSH_TET_4) newtype = MSH_TRI_3;
+          else if(type == MSH_TET_10) newtype = MSH_TRI_6;
+        }
+        else if(dim == 2){
+           if(type == MSH_TRI_3 || type == MSH_QUA_4) newtype = MSH_LIN_2;
+           else if(type == MSH_TRI_6 || type == MSH_QUA_8) newtype = MSH_LIN_3;
         }
-        else if(dim == 2) newCell = new OneSimplex(vertices, tag, subdomain, boundary);
-        else if(dim == 1) newCell = new ZeroSimplex(vertices, tag, subdomain, boundary);
+        else if(dim == 1){
+           if(type == MSH_LIN_2 || type == MSH_LIN_3 || type == MSH_LIN_4 ||
+              type == MSH_LIN_5 || type == MSH_LIN_6) newtype = MSH_PNT;
+        }  
+        if(newtype == 0) Msg::Error("Error: mesh element %d not implemented yet! \n", type); 
+        
+        MElement* element = factory.create(newtype, vertices, 0, cell->getPartition());
+        Cell* newCell = new Cell(element, subdomain, boundary);
         newCell->setImmune(cell->getImmune());
-        tag++;
+        newCell->setDeleteImage(true);
         insertInfo = _cells[dim-1].insert(newCell);
         if(!insertInfo.second){
-          delete newCell;
+          delete newCell; 
           Cell* oldCell = *(insertInfo.first);
           if(!subdomain && !boundary){
-            //int ori = cell->kappa(oldCell);
             int ori = cell->getFacetOri(oldCell);
             oldCell->addCoboundaryCell( ori, cell );
             oldCell->addOrgCbdCell( ori, cell );
@@ -223,7 +197,6 @@ void CellComplex::insert_cells(bool subdomain, bool boundary){
           }
         }
         else if(!subdomain && !boundary) {
-          //int ori = cell->kappa(newCell);
           int ori = cell->getFacetOri(vertices);
           cell->addBoundaryCell( ori, newCell );
           cell->addOrgBdCell( ori, newCell );
@@ -237,36 +210,35 @@ void CellComplex::insert_cells(bool subdomain, bool boundary){
 }
 
 CellComplex::~CellComplex(){
-     for(int i = 0; i < 4; i++){
-       _cells[i].clear();
-       
-       for(citer cit = _ocells[i].begin(); cit != _ocells[i].end(); cit++){
-         Cell* cell = *cit;
-         delete cell;
-       }
-        _ocells[i].clear();
-       
-     }
-     //emptyTrash();
-   }
+  for(int i = 0; i < 4; i++){
+    _cells[i].clear();
+    
+    for(citer cit = _ocells[i].begin(); cit != _ocells[i].end(); cit++){
+      Cell* cell = *cit;
+      delete cell;
+    }
+    _ocells[i].clear();
+    
+  }
+}
 
-   /*
-   CellComplex::CellComplex(CellComplex* cellComplex){
-     
-     _domain = cellComplex->getDomain();
-     _subdomain = cellComplex->getSubdomain;
-     _boundary = cellComplex->getBoundary;
+/*
+ CellComplex::CellComplex(CellComplex* cellComplex){
+ * 
+ _domain = cellComplex->getDomain();
+ _subdomain = cellComplex->getSubdomain;
+ _boundary = cellComplex->getBoundary;
      _domainVertices = cellComplex->getDomainVertices;
-     
-     for(int i = 0; i < 4; i++){
-       _betti[i] = cellComplex->getBetti(i);
-       _cells[i] = ocells[i];
-       _ocells[i] = ocells[i];
-     }
-     
-     _dim = cellComplex->getDim();
+ * 
+ for(int i = 0; i < 4; i++){
+ _betti[i] = cellComplex->getBetti(i);
+ _cells[i] = ocells[i];
+ _ocells[i] = ocells[i];
+ }
+ * 
+ _dim = cellComplex->getDim();
    }
-   */
+ */
 
 void CellComplex::removeCell(Cell* cell, bool other){
   
@@ -693,12 +665,13 @@ int CellComplex::combine(int dim){
   std::map<Cell*, int, Less_Cell> cbd_c;
   std::list<Cell*> bd_c;
   int count = 0;
-  
+
   
   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();
@@ -725,10 +698,11 @@ int CellComplex::combine(int dim){
           enqueueCells(bd_c, Q, Qset);
           bd_c = c2->getBoundary();
           enqueueCells(bd_c, Q, Qset);
-          
+
           CombinedCell* newCell = new CombinedCell(c1, c2, (or1 != or2) );
           removeCell(c1);
           removeCell(c2);
+          
           std::pair<citer, bool> insertInfo =  _cells[dim].insert(newCell);
           if(!insertInfo.second) Msg::Debug("Warning: Combined cell not inserted! \n");
           cit = firstCell(dim);
@@ -827,152 +801,6 @@ void CellComplex::swapSubdomain(){
 }*/
 
 
-int CellComplex::writeComplexMSH(const std::string &name){
-    
-  FILE *fp = fopen(name.c_str(), "w");
-  
-  if(!fp){
-    Msg::Error("Unable to open file '%s'", name.c_str());
-    Msg::Debug("Unable to open file.");
-    return 0;
-  } 
-  
-  fprintf(fp, "$MeshFormat\n2.1 0 8\n$EndMeshFormat\n");
-  fprintf(fp, "$Nodes\n");
-  fprintf(fp, "%d\n", (int)_domainVertices.size());
-  
-  for(std::set<MVertex*, Less_MVertex>::iterator vit = _domainVertices.begin(); vit != _domainVertices.end(); vit++){
-    MVertex* vertex = *vit;
-    fprintf(fp, "%d %.16g %.16g %.16g\n", vertex->getNum(), vertex->x(), vertex->y(), vertex->z() );
-  }
-  
-      
-  fprintf(fp, "$EndNodes\n");
-  fprintf(fp, "$Elements\n");
-
-  int count = 0;
-  for(int i = 0; i < 4; i++){
-    for(citer cit = firstCell(i); cit != lastCell(i); cit++){
-      Cell* cell = *cit;
-      count = count + cell->getNumCells();
-    }
-  }
-  for(int i = 0; i < _store.size(); i++){    
-    count = count + _store.at(i).size();
-  }
-  
-  fprintf(fp, "%d\n", count);
-
-  int type = -1;
-  int physical = 0;
-  int elementary = 0;
-  int partition = 0;
-  
-  for(citer cit = firstCell(0); cit != lastCell(0); cit++) {
-    Cell* vertex = *cit;
-    if(vertex->inSubdomain()) partition = 3;
-    else if(vertex->onDomainBoundary()) partition = 2;
-    else partition = 1;
-    type = vertex->getTypeForMSH();
-    //vertex->writeMSH(fp, 2.1, false, 0, elementary, physical);
-    fprintf(fp, "%d %d %d %d %d %d %d\n", vertex->getNum(), type, 3, physical, elementary, partition, vertex->getVertex(0)->getNum());
-  }
-  
-  std::list< std::pair<int, Cell*> > cells;
-  for(citer cit = firstCell(1); cit != lastCell(1); cit++) {
-    Cell* edge = *cit;
-    if(edge->inSubdomain()) partition = 3;
-    else if(edge->onDomainBoundary()) partition = 2;
-    else partition = 1;
-    cells = edge->getCells();
-    for(std::list< std::pair<int, Cell*> >::iterator it = cells.begin(); it != cells.end(); it++){
-      Cell* cell = (*it).second;
-      type = cell->getTypeForMSH();
-      //cell->writeMSH(fp, 2.1, false, 0, elementary, physical);
-      fprintf(fp, "%d %d %d %d %d %d %d %d\n", cell->getNum(), type, 3, physical, elementary, partition, cell->getVertex(0)->getNum(), cell->getVertex(1)->getNum());
-    }
-  }
-  
-  for(citer cit = firstCell(2); cit != lastCell(2); cit++) {
-    Cell* face = *cit;
-    if(face->inSubdomain()) partition = 3;
-    else if(face->onDomainBoundary()) partition = 2;
-    else partition = 1;
-    cells = face->getCells();
-    for(std::list< std::pair<int, Cell*> >::iterator it = cells.begin(); it != cells.end(); it++){
-      Cell* cell = (*it).second;
-      type = cell->getTypeForMSH();
-      if(cell->getNumVertices() == 3) fprintf(fp, "%d %d %d %d %d %d %d %d %d\n", cell->getNum(), type, 3, physical, elementary, partition, cell->getVertex(0)->getNum(), cell->getVertex(1)->getNum(), cell->getVertex(2)->getNum());
-      else if (cell->getNumVertices() == 4)  fprintf(fp, "%d %d %d %d %d %d %d %d %d %d\n", cell->getNum(), type, 3, physical, elementary, partition, cell->getVertex(0)->getNum(), cell->getVertex(1)->getNum(), cell->getVertex(2)->getNum(), cell->getVertex(3)->getNum());
-    }
-  }
-  for(citer cit = firstCell(3); cit != lastCell(3); cit++) {
-    Cell* volume = *cit;
-    if(volume->inSubdomain()) partition = 3;
-    else if(volume->onDomainBoundary()) partition = 2;
-    else partition = 1;
-    cells = volume->getCells();
-    for(std::list< std::pair<int, Cell*> >::iterator it = cells.begin(); it != cells.end(); it++){
-      Cell* cell = (*it).second;
-      type = cell->getTypeForMSH();
-      if(cell->getNumVertices() == 4) fprintf(fp, "%d %d %d %d %d %d %d %d %d %d\n", cell->getNum(), type, 3, physical, elementary, partition, cell->getVertex(0)->getNum(), cell->getVertex(1)->getNum(), cell->getVertex(2)->getNum(), cell->getVertex(3)->getNum());
-      if(cell->getNumVertices() == 8) fprintf(fp, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", cell->getNum(), type, 3, physical, elementary, partition, cell->getVertex(0)->getNum(), cell->getVertex(1)->getNum(), cell->getVertex(2)->getNum(), cell->getVertex(3)->getNum(), cell->getVertex(4)->getNum(), cell->getVertex(5)->getNum(), cell->getVertex(6)->getNum(), cell->getVertex(7)->getNum() );
-      if(cell->getNumVertices() == 6) fprintf(fp, "%d %d %d %d %d %d %d %d %d %d %d %d\n", cell->getNum(), type, 3, physical, elementary, partition, cell->getVertex(0)->getNum(), cell->getVertex(1)->getNum(), cell->getVertex(2)->getNum(), cell->getVertex(3)->getNum(),cell->getVertex(4)->getNum(), cell->getVertex(5)->getNum());
-      if(cell->getNumVertices() == 5) fprintf(fp, "%d %d %d %d %d %d %d %d %d %d %d\n", cell->getNum(), type, 3, physical, elementary, partition, cell->getVertex(0)->getNum(), cell->getVertex(1)->getNum(), cell->getVertex(2)->getNum(), cell->getVertex(3)->getNum(), cell->getVertex(4)->getNum());      
-    }
-  }
-  
-  for(int i = 0; i < _store.size(); i++){
-    for(citer cit = _store.at(i).begin(); cit != _store.at(i).end(); cit++){
-      Cell* cell = *cit;
-      type = cell->getTypeForMSH();
-      if(cell->inSubdomain()) partition = 3;
-      else if(cell->onDomainBoundary()) partition = 2;
-      else partition = 1;
-      if(cell->getDim() == 0) fprintf(fp, "%d %d %d %d %d %d %d\n", cell->getNum(), type, 3, physical, elementary, partition, cell->getVertex(0)->getNum());
-      if(cell->getDim() == 1) fprintf(fp, "%d %d %d %d %d %d %d %d\n", cell->getNum(), type, 3, physical, elementary, partition, cell->getVertex(0)->getNum(), cell->getVertex(1)->getNum());
-      if(cell->getDim() == 2){
-        if(cell->getNumVertices() == 3) fprintf(fp, "%d %d %d %d %d %d %d %d %d\n", cell->getNum(), type, 3, physical, elementary, partition, cell->getVertex(0)->getNum(), cell->getVertex(1)->getNum(), cell->getVertex(2)->getNum());
-        else if (cell->getNumVertices() == 4)  fprintf(fp, "%d %d %d %d %d %d %d %d %d %d\n", cell->getNum(), type, 3, physical, elementary, partition, cell->getVertex(0)->getNum(), cell->getVertex(1)->getNum(), cell->getVertex(2)->getNum(), cell->getVertex(3)->getNum());
-      }
-      if(cell->getDim() == 3){
-        if(cell->getNumVertices() == 4) fprintf(fp, "%d %d %d %d %d %d %d %d %d %d\n", cell->getNum(), type, 3, physical, elementary, partition, cell->getVertex(0)->getNum(), cell->getVertex(1)->getNum(), cell->getVertex(2)->getNum(), cell->getVertex(3)->getNum());
-        if(cell->getNumVertices() == 8) fprintf(fp, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", cell->getNum(), type, 3, physical, elementary, partition, cell->getVertex(0)->getNum(), cell->getVertex(1)->getNum(), cell->getVertex(2)->getNum(), cell->getVertex(3)->getNum(), cell->getVertex(4)->getNum(), cell->getVertex(5)->getNum(), cell->getVertex(6)->getNum(), cell->getVertex(7)->getNum() );
-        if(cell->getNumVertices() == 6) fprintf(fp, "%d %d %d %d %d %d %d %d %d %d %d %d\n", cell->getNum(), type, 3, physical, elementary, partition, cell->getVertex(0)->getNum(), cell->getVertex(1)->getNum(), cell->getVertex(2)->getNum(), cell->getVertex(3)->getNum(),cell->getVertex(4)->getNum(), cell->getVertex(5)->getNum());
-        if(cell->getNumVertices() == 5) fprintf(fp, "%d %d %d %d %d %d %d %d %d %d %d\n", cell->getNum(), type, 3, physical, elementary, partition, cell->getVertex(0)->getNum(), cell->getVertex(1)->getNum(), cell->getVertex(2)->getNum(), cell->getVertex(3)->getNum(), cell->getVertex(4)->getNum());
-      }  
-    }
-  }
-  
-  /*
-  for(citer cit = _ecells.begin(); cit != _ecells.end(); cit++){
-    Cell* cell = *cit;
-    type = cell->getTypeForMSH();
-    if(cell->inSubdomain()) partition = 3;
-    else if(cell->onDomainBoundary()) partition = 2;
-    else partition = 1;
-    if(cell->getDim() == 0) fprintf(fp, "%d %d %d %d %d %d %d\n", cell->getNum(), type, 3, physical, elementary, partition, cell->getVertex(0)->getNum());
-    if(cell->getDim() == 1) fprintf(fp, "%d %d %d %d %d %d %d %d\n", cell->getNum(), type, 3, physical, elementary, partition, cell->getVertex(0)->getNum(), cell->getVertex(1)->getNum());
-    if(cell->getDim() == 2){
-      if(cell->getNumVertices() == 3) fprintf(fp, "%d %d %d %d %d %d %d %d %d\n", cell->getNum(), type, 3, physical, elementary, partition, cell->getVertex(0)->getNum(), cell->getVertex(1)->getNum(), cell->getVertex(2)->getNum());
-      else if (cell->getNumVertices() == 4)  fprintf(fp, "%d %d %d %d %d %d %d %d %d %d\n", cell->getNum(), type, 3, physical, elementary, partition, cell->getVertex(0)->getNum(), cell->getVertex(1)->getNum(), cell->getVertex(2)->getNum(), cell->getVertex(3)->getNum());
-    }
-    if(cell->getDim() == 3){
-      if(cell->getNumVertices() == 4) fprintf(fp, "%d %d %d %d %d %d %d %d %d %d\n", cell->getNum(), type, 3, physical, elementary, partition, cell->getVertex(0)->getNum(), cell->getVertex(1)->getNum(), cell->getVertex(2)->getNum(), cell->getVertex(3)->getNum());
-      if(cell->getNumVertices() == 8) fprintf(fp, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", cell->getNum(), type, 3, physical, elementary, partition, cell->getVertex(0)->getNum(), cell->getVertex(1)->getNum(), cell->getVertex(2)->getNum(), cell->getVertex(3)->getNum(), cell->getVertex(4)->getNum(), cell->getVertex(5)->getNum(), cell->getVertex(6)->getNum(), cell->getVertex(7)->getNum() );
-      if(cell->getNumVertices() == 6) fprintf(fp, "%d %d %d %d %d %d %d %d %d %d %d %d\n", cell->getNum(), type, 3, physical, elementary, partition, cell->getVertex(0)->getNum(), cell->getVertex(1)->getNum(), cell->getVertex(2)->getNum(), cell->getVertex(3)->getNum(),cell->getVertex(4)->getNum(), cell->getVertex(5)->getNum());
-      if(cell->getNumVertices() == 5) fprintf(fp, "%d %d %d %d %d %d %d %d %d %d %d\n", cell->getNum(), type, 3, physical, elementary, partition, cell->getVertex(0)->getNum(), cell->getVertex(1)->getNum(), cell->getVertex(2)->getNum(), cell->getVertex(3)->getNum(), cell->getVertex(4)->getNum());
-    }  
-  }*/
-  
-  fprintf(fp, "$EndElements\n");
-  
-  fclose(fp);
-  
-  return 1;
-}
-
-
 void CellComplex::printComplex(int dim){
   for (citer cit = firstCell(dim); cit != lastCell(dim); cit++){
     Cell* cell = *cit;
diff --git a/Geo/CellComplex.h b/Geo/CellComplex.h
index ff2bd3b08cc81892497804f68e15cb19341dd649..49c9ffc07270df86eb1c188ed93d9d21e6157c3d 100644
--- a/Geo/CellComplex.h
+++ b/Geo/CellComplex.h
@@ -17,15 +17,8 @@
 #include <algorithm>
 #include <set>
 #include <queue>
+#include "Cell.h"
 #include "MElement.h"
-#include "MPoint.h"
-#include "MLine.h"
-#include "MTriangle.h"
-#include "MQuadrangle.h"
-#include "MHexahedron.h"
-#include "MPrism.h"
-#include "MPyramid.h"
-#include "MTetrahedron.h"
 #include "GModel.h"
 #include "GEntity.h"
 #include "GRegion.h"
@@ -34,648 +27,6 @@
 
 class Cell;
 
-// Ordering of the cells
-class Less_Cell{
-  public:
-   bool operator()(const Cell* c1, const Cell* c2) const;
-};
-
-// Abstract class representing an elementary cell of a cell complex.
-class Cell
-{  
-  protected:
-   
-   // cell dimension
-   int _dim;
-   
-   // whether this cell belongs to a subdomain, immutable
-   // used in relative homology computation
-   bool _inSubdomain;
-   
-   // whether this cell belongs to the boundary of a cell complex
-   bool _onDomainBoundary;
-   
-   // whether this cell a combinded cell of elemetary cells
-   bool _combined; 
-   
-   // unused
-   int _tag;
-   
-   // mutable index for each cell
-   int _index; 
-   
-   // for some algorithms to omit this cell
-   bool _immune;
-  
-   // mutable list of cells on the boundary and on the coboundary of this cell
-   std::map< Cell*, int, Less_Cell > _boundary;
-   std::map< Cell*, int, Less_Cell > _coboundary;
-   int _bdSize;
-   int _cbdSize;
-   
-   // immutable original boundary and coboundary before the reduction of the cell complex
-   std::map<Cell*, int, Less_Cell > _obd;
-   std::map<Cell*, int, Less_Cell > _ocbd;
-   
-  public:
-   Cell(){
-     _bdSize = 0;
-     _cbdSize = 0;
-     _combined = false;
-     _index = 0;
-     _immune = false;
-   }
-   virtual ~Cell(){}
-   
-   virtual int getDim() const { return _dim; };
-   virtual int getTag() const { return _tag; };
-   virtual void setTag(int tag) { _tag = tag; };
-   virtual int getIndex() const { return _index; };
-   virtual void setIndex(int index) { _index = index; };
-   virtual int getNum() { return -1; }
-   virtual int getType() { return -1; }
-   virtual int getTypeForMSH() { return -1; }
-   virtual int getPartition() { return -1; }
-   virtual void setPartition(int num){}
-   virtual void setImmune(bool immune) { _immune = immune; };
-   virtual bool getImmune() const { return _immune; };
-
-   // get the number of vertices this cell has
-   virtual int getNumVertices() const = 0;
-   virtual MVertex* getVertex(int vertex) const = 0; //{return _vertices.at(vertex);}
-   virtual int getSortedVertex(int vertex) const = 0; 
-   virtual std::vector<MVertex*> getVertexVector() const = 0;
-   
-   // restores the cell information to its original state before reduction
-   virtual void restoreCell();
-   
-   // true if this cell has given vertex
-   virtual bool hasVertex(int vertex) const = 0;
-
-   // (co)boundary cell iterator
-   typedef std::map<Cell*, int, Less_Cell>::iterator biter;
-   
-   virtual int getBoundarySize() { return _boundary.size(); }
-   virtual int getCoboundarySize() { return _coboundary.size(); }
-   
-   // get the cell boundary
-   virtual std::map<Cell*, int, Less_Cell > getOrientedBoundary() { return _boundary; }
-   virtual std::list< Cell* > getBoundary();
-   virtual std::map<Cell*, int, Less_Cell > getOrientedCoboundary() { return _coboundary; }
-   virtual std::list< Cell* > getCoboundary();
-   
-   // add (co)boundary cell
-   virtual bool addBoundaryCell(int orientation, Cell* cell); 
-   virtual bool addCoboundaryCell(int orientation, Cell* cell);
-   
-   // remove (co)boundary cell
-   virtual int removeBoundaryCell(Cell* cell, bool other=true);
-   virtual int removeCoboundaryCell(Cell* cell, bool other=true);
-   
-   // true if has given cell on (original) (co)boundary
-   virtual bool hasBoundary(Cell* cell, bool org=false);
-   virtual bool hasCoboundary(Cell* cell, bool org=false);
-   
-   virtual void clearBoundary() { _boundary.clear(); }
-   virtual void clearCoboundary() { _coboundary.clear(); }
-   
-   // algebraic dual of the cell
-   virtual void makeDualCell();
-   
-   virtual void printBoundary();
-   virtual void printCoboundary();
-   
-   // original (co)boundary
-   virtual void addOrgBdCell(int orientation, Cell* cell) { _obd.insert( std::make_pair(cell, orientation ) ); };
-   virtual void addOrgCbdCell(int orientation, Cell* cell) { _ocbd.insert( std::make_pair(cell, orientation ) ); };
-   virtual std::map<Cell*, int, Less_Cell > getOrgBd() { return _obd; }
-   virtual std::map<Cell*, int, Less_Cell > getOrgCbd() { return _ocbd; }
-   virtual void printOrgBd();
-   virtual void printOrgCbd(); 
-   
-   virtual bool inSubdomain() const { return _inSubdomain; }
-   //virtual void setInSubdomain(bool subdomain)  { _inSubdomain = subdomain; }
-   
-   virtual bool onDomainBoundary() const { return _onDomainBoundary; }
-   virtual void setOnDomainBoundary(bool domainboundary)  { _onDomainBoundary = domainboundary; }
-   
-   // print cell vertices
-   virtual void printCell() const = 0;
-   
-   virtual int getNumFacets() const { return 0; }
-   virtual void getFacetVertices(const int num, std::vector<MVertex*> &v) const {};
-   
-   // get boundary cell orientation
-   virtual int getFacetOri(Cell* cell) { std::vector<MVertex*> v = cell->getVertexVector(); return getFacetOri(v); } 
-   virtual int getFacetOri(std::vector<MVertex*> &v) { return 0; }   
-
-   // tools for combined cells
-   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;
-     }
-     for(int i=0; i < this->getNumVertices();i++){
-       if(this->getSortedVertex(i) != c2.getSortedVertex(i)){
-         return false;
-       }
-     }
-     return true;
-   }
-   
-   bool operator<(const Cell& c2) const {
-     
-     if(this->getNumVertices() != c2.getNumVertices()){
-       return (this->getNumVertices() < c2.getNumVertices());
-     }
-     for(int i=0; i < this->getNumVertices();i++){
-       if(this->getSortedVertex(i) < c2.getSortedVertex(i)) return true;
-       else if (this->getSortedVertex(i) > c2.getSortedVertex(i)) return false;
-     }
-     return false;
-   }
-   
-   //virtual void writeMSH(FILE *fp, double version=1.0, bool binary=false,  int num=0, int elementary=1, int physical=1, int parentNum=0) {}
-};
-
-
-// Simplicial cell type.
-class Simplex : public Cell
-{    
- public:
-   Simplex() : Cell() {}
-   ~Simplex(){}    
-};
-
-// Zero simplex cell type.
-class ZeroSimplex : public Simplex, public MPoint
-{
- private:
-
- public:
-   
-   ZeroSimplex(std::vector<MVertex*> v, int tag=0, bool subdomain=false, bool boundary=false, int num=0, int part=0)
-     : MPoint(v, num, part){
-       _tag = tag;
-       _inSubdomain = subdomain;
-       _onDomainBoundary = boundary;
-     }
-   ~ZeroSimplex(){}
-   
-   int getDim() const { return 0; }
-   int getNum() { return MPoint::getNum(); }
-   int getType() { return MPoint::getType(); }
-   int getTypeForMSH() { return MPoint::getTypeForMSH(); }
-   int getPartition() { return MPoint::getPartition(); }
-   int getNumVertices() const { return 1; }
-   MVertex* getVertex(int vertex) const {return _v[0]; }
-   int getSortedVertex(int vertex) const {return _v[0]->getNum(); }
-   bool hasVertex(int vertex) const {return (_v[0]->getNum() == vertex); }
-   
-   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("Cell dimension: %d, Vertices: %d, in subdomain: %d \n", getDim(), _v[0]->getNum(), _inSubdomain); }
-   
-};
-
-// One simplex cell type.
-class OneSimplex : public Simplex, public MLine
-{
-  private:
-   // sorted list of vertices
-   int _vs[2];
-  public: 
-   OneSimplex(std::vector<MVertex*> v, int tag=0, bool subdomain=false, bool boundary=false, int num=0, int part=0)
-     : MLine(v, num, part){
-       _tag = tag;
-       _inSubdomain = subdomain;
-       _onDomainBoundary = boundary;
-       _vs[0] = v.at(0)->getNum();
-       _vs[1] = v.at(1)->getNum();
-       std::sort(_vs, _vs+2);
-     }
-   
-   ~OneSimplex(){}
-   
-   int getDim() const { return 1; }
-   int getNum() { return MLine::getNum(); }
-   int getType() { return MLine::getType(); }
-   int getTypeForMSH() { return MLine::getTypeForMSH(); }
-   int getPartition() { return MLine::getPartition(); }
-   int getNumVertices() const { return 2; }
-   int getNumFacets() const {  return 2; }
-   MVertex* getVertex(int vertex) const {return _v[vertex]; }
-   int getSortedVertex(int vertex) const {return _vs[vertex]; }
-   bool hasVertex(int vertex) const {return (_v[0]->getNum() == vertex || _v[1]->getNum() == vertex); }
-   
-   std::vector<MVertex*> getVertexVector() const { 
-     return std::vector<MVertex*>(_v, _v + sizeof(_v)/sizeof(MVertex*) ); }
-   std::vector<int> getSortedVertexVector() const {
-     return std::vector<int>(_vs, _vs + sizeof(_vs)/sizeof(int) ); 
-   }
-   
-   void getFacetVertices(const int num, std::vector<MVertex*> &v) const {
-     v.resize(1);
-     v[0] = _v[num];
-   }
-   int getFacetOri(std::vector<MVertex*> &v){
-     if(v.size() != 1) return 0;
-     else if(v[0] == _v[0]) return -1;
-     else if(v[0] == _v[1]) return 1;
-     else return 0;
-   }
-   
-   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.
-class TwoSimplex : public Simplex, public MTriangle
-{
-  private:
-   // sorted list of vertices
-   int _vs[3];
-   
-  public:
-
-   TwoSimplex(std::vector<MVertex*> v, int tag=0, bool subdomain=false, bool boundary=false, int num=0, int part=0)
-     : MTriangle(v, num, part){
-       _tag = tag;
-       _inSubdomain = subdomain;
-       _onDomainBoundary = boundary;
-       _vs[0] = v.at(0)->getNum();
-       _vs[1] = v.at(1)->getNum();
-       _vs[2] = v.at(2)->getNum();
-       std::sort(_vs, _vs+3);
-     }
-   
-   ~TwoSimplex(){}
-   
-   int getDim() const { return 2; }
-   int getNum() { return MTriangle::getNum(); }
-   int getType() { return MTriangle::getType(); }
-   int getTypeForMSH() { return MTriangle::getTypeForMSH(); }
-   int getPartition() { return MTriangle::getPartition(); }
-   int getNumVertices() const { return 3; }
-   int getNumFacets() const { return 3; }
-   MVertex* getVertex(int vertex) const {return _v[vertex]; }
-   int getSortedVertex(int vertex) const {return _vs[vertex]; }
-   bool hasVertex(int vertex) const {return 
-       (_v[0]->getNum() == vertex || _v[1]->getNum() == vertex || _v[2]->getNum() == vertex); }
-   
-   std::vector<MVertex*> getVertexVector() const { 
-     return std::vector<MVertex*>(_v, _v + sizeof(_v)/sizeof(MVertex*) ); }
-   std::vector<int> getSortedVertexVector() const {
-     return std::vector<int>(_vs, _vs + sizeof(_vs)/sizeof(int) ); 
-   }
-   
-   void getFacetVertices(const int num, std::vector<MVertex*> &v) const {
-     MTriangle::getEdgeVertices(num, v);
-   }
-   int getFacetOri(std::vector<MVertex*> &v){
-     if(v.size() != 2) return 0;
-     MEdge facet = MEdge(v[0], v[1]);
-     int ithFacet = 0;
-     int sign = 0;
-     MTriangle::getEdgeInfo(facet, ithFacet, sign);
-     return sign;
-   }    
-
-   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); }
-};
-
-// Quadrangle cell type.
-class CQuadrangle : public Cell, public MQuadrangle
-{
-  private:
-   // sorted list of vertices
-   int _vs[4];
-   
-  public:
-
-   CQuadrangle(std::vector<MVertex*> v, int tag=0, bool subdomain=false, bool boundary=false, int num=0, int part=0)
-     : MQuadrangle(v, num, part){
-       _tag = tag;
-       _inSubdomain = subdomain;
-       _onDomainBoundary = boundary;
-       _vs[0] = v.at(0)->getNum();
-       _vs[1] = v.at(1)->getNum();
-       _vs[2] = v.at(2)->getNum();
-       _vs[3] = v.at(3)->getNum();
-       std::sort(_vs, _vs+3);
-     }
-   
-   ~CQuadrangle(){}
-   
-   int getDim() const { return 2; }
-   int getNum() { return MQuadrangle::getNum(); }
-   int getType() { return MQuadrangle::getType(); }
-   int getTypeForMSH() { return MQuadrangle::getTypeForMSH(); }
-   int getPartition() { return MQuadrangle::getPartition(); }
-   int getNumVertices() const { return 4; }
-   int getNumFacets() const { return 4; }
-   MVertex* getVertex(int vertex) const {return _v[vertex]; }
-   int getSortedVertex(int vertex) const {return _vs[vertex]; }
-   bool hasVertex(int vertex) const {return 
-       (_v[0]->getNum() == vertex || _v[1]->getNum() == vertex || _v[2]->getNum() == vertex || _v[3]->getNum() == vertex); } 
-   
-   std::vector<MVertex*> getVertexVector() const { 
-     return std::vector<MVertex*>(_v, _v + sizeof(_v)/sizeof(MVertex*) ); }
-   std::vector<int> getSortedVertexVector() const {
-     return std::vector<int>(_vs, _vs + sizeof(_vs)/sizeof(int) ); 
-   }
-   
-   void getFacetVertices(const int num, std::vector<MVertex*> &v) const {
-     MQuadrangle::getEdgeVertices(num, v);
-   }
-   int getFacetOri(std::vector<MVertex*> &v){
-     if(v.size() != 2) return 0;
-     MEdge facet = MEdge(v[0], v[1]);
-     int ithFacet = 0;
-     int sign = 0;
-     MQuadrangle::getEdgeInfo(facet, ithFacet, sign);
-     return sign;
-   }  
-   
-   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); }
-};
-
-
-// ThreeSimplex cell type.
-class ThreeSimplex : public Simplex, public MTetrahedron
-{
-  private:
-   // sorted list of vertices
-   int _vs[4];
-      
-  public:
-   ThreeSimplex(std::vector<MVertex*> v, int tag=0, bool subdomain=false, bool boundary=false, int num=0, int part=0)
-     : MTetrahedron(v, num, part){
-       _tag = tag;
-       _inSubdomain = subdomain;
-       _onDomainBoundary = boundary;
-       _vs[0] = v.at(0)->getNum();
-       _vs[1] = v.at(1)->getNum();
-       _vs[2] = v.at(2)->getNum();
-       _vs[3] = v.at(3)->getNum();
-       std::sort(_vs, _vs+4);
-     }
-   
-   ~ThreeSimplex(){}
-   
-   int getDim() const { return 3; }
-   int getNum() { return MTetrahedron::getNum(); }
-   int getType() { return MTetrahedron::getType(); }
-   int getTypeForMSH() { return MTetrahedron::getTypeForMSH(); }
-   int getPartition() { return MTetrahedron::getPartition(); }
-   int getNumVertices() const { return 4; }
-   int getNumFacets() const { return 4; }
-   MVertex* getVertex(int vertex) const {return _v[vertex]; }
-   int getSortedVertex(int vertex) const {return _vs[vertex]; }
-   bool hasVertex(int vertex) const {return 
-       (_v[0]->getNum() == vertex || _v[1]->getNum() == vertex || _v[2]->getNum() == vertex || _v[3]->getNum() == vertex); }
-   std::vector<MVertex*> getVertexVector() const { 
-     return std::vector<MVertex*>(_v, _v + sizeof(_v)/sizeof(MVertex*) ); }
-   std::vector<int> getSortedVertexVector() const {
-     return std::vector<int>(_vs, _vs + sizeof(_vs)/sizeof(int) ); }
-   
-   void getFacetVertices(const int num, std::vector<MVertex*> &v) const {
-     MTetrahedron::getFaceVertices(num, v);
-   }
-   int getFacetOri(std::vector<MVertex*> &v){
-     if(v.size() != 3) return 0;
-     MFace facet = MFace(v);
-     int ithFacet = 0;
-     int sign = 0;
-     int rot = 0;
-     MTetrahedron::getFaceInfo(facet, ithFacet, sign, rot);
-     return sign;
-   }
-
-   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); }
-};
-
-// Hexahedron cell type.
-class CHexahedron : public Cell, public MHexahedron
-{
-  private:
-   // sorted list of vertices
-   int _vs[8];
-      
-  public:
-   CHexahedron(std::vector<MVertex*> v, int tag=0, bool subdomain=false, bool boundary=false, int num=0, int part=0)
-     : MHexahedron(v, num, part){
-       _tag = tag;
-       _inSubdomain = subdomain;
-       _onDomainBoundary = boundary;
-       _vs[0] = v.at(0)->getNum();
-       _vs[1] = v.at(1)->getNum();
-       _vs[2] = v.at(2)->getNum();
-       _vs[3] = v.at(3)->getNum();
-       _vs[4] = v.at(4)->getNum();
-       _vs[5] = v.at(5)->getNum();
-       _vs[6] = v.at(6)->getNum();
-       _vs[7] = v.at(7)->getNum();
-       std::sort(_vs, _vs+8);
-     }
-   
-   ~CHexahedron(){}
-   
-   int getDim() const { return 3; }
-   int getNum() { return MHexahedron::getNum(); }
-   int getType() { return MHexahedron::getType(); }
-   int getTypeForMSH() { return MHexahedron::getTypeForMSH(); }
-   int getPartition() { return MHexahedron::getPartition(); }
-   int getNumVertices() const { return 8; }
-   int getNumFacets() const { return 6; }
-   MVertex* getVertex(int vertex) const {return _v[vertex]; }
-   int getSortedVertex(int vertex) const {return _vs[vertex]; }
-   bool hasVertex(int vertex) const {return 
-       (_v[0]->getNum() == vertex || _v[1]->getNum() == vertex || _v[2]->getNum() == vertex || _v[3]->getNum() == vertex ||
-        _v[4]->getNum() == vertex || _v[5]->getNum() == vertex || _v[6]->getNum() == vertex || _v[7]->getNum() == vertex ); }
-   std::vector<MVertex*> getVertexVector() const { 
-     return std::vector<MVertex*>(_v, _v + sizeof(_v)/sizeof(MVertex*) ); }
-   std::vector<int> getSortedVertexVector() const {
-     return std::vector<int>(_vs, _vs + sizeof(_vs)/sizeof(int) ); }
-   
-   void getFacetVertices(const int num, std::vector<MVertex*> &v) const {
-     MHexahedron::getFaceVertices(num, v);
-   }
-   int getFacetOri(std::vector<MVertex*> &v){
-     if(v.size() != 4) return 0;
-     MFace facet = MFace(v);
-     int ithFacet = 0;
-     int sign = 0;
-     int rot = 0;
-     MHexahedron::getFaceInfo(facet, ithFacet, sign, rot);
-     return sign;
-   }
-   
-   virtual void printCell() const { printf("Cell dimension: %d, Vertices: %d %d %d %d %d %d %d %d, in subdomain: %d \n", getDim(), _v[0]->getNum(), _v[1]->getNum(), _v[2]->getNum(), _v[3]->getNum(), _v[4]->getNum(), _v[5]->getNum(), _v[6]->getNum(), _v[7]->getNum(), _inSubdomain); }
-};
-
-
-// Prism cell type.
-class CPrism : public Cell, public MPrism
-{
-  private:
-   // sorted list of vertices
-   int _vs[6];
-      
-  public:
-   CPrism(std::vector<MVertex*> v, int tag=0, bool subdomain=false, bool boundary=false, int num=0, int part=0)
-     : MPrism(v, num, part){
-       _tag = tag;
-       _inSubdomain = subdomain;
-       _onDomainBoundary = boundary;
-       _vs[0] = v.at(0)->getNum();
-       _vs[1] = v.at(1)->getNum();
-       _vs[2] = v.at(2)->getNum();
-       _vs[3] = v.at(3)->getNum();
-       _vs[4] = v.at(4)->getNum();
-       _vs[5] = v.at(5)->getNum();
-       std::sort(_vs, _vs+6);
-     }
-   
-   ~CPrism(){}
-   
-   int getDim() const { return 3; }
-   int getNum() { return MPrism::getNum(); }
-   int getType() { return MPrism::getType(); }
-   int getTypeForMSH() { return MPrism::getTypeForMSH(); }
-   int getPartition() { return MPrism::getPartition(); }
-   int getNumVertices() const { return 6; }
-   int getNumFacets() const { return 5; }
-   MVertex* getVertex(int vertex) const {return _v[vertex]; }
-   int getSortedVertex(int vertex) const {return _vs[vertex]; }
-   bool hasVertex(int vertex) const {return 
-       (_v[0]->getNum() == vertex || _v[1]->getNum() == vertex || _v[2]->getNum() == vertex || _v[3]->getNum() == vertex ||
-       _v[4]->getNum() == vertex || _v[5]->getNum() == vertex); }
-   std::vector<MVertex*> getVertexVector() const { 
-     return std::vector<MVertex*>(_v, _v + sizeof(_v)/sizeof(MVertex*) ); }
-   std::vector<int> getSortedVertexVector() const {
-     return std::vector<int>(_vs, _vs + sizeof(_vs)/sizeof(int) ); }
-   
-   void getFacetVertices(const int num, std::vector<MVertex*> &v) const {
-     MPrism::getFaceVertices(num, v);
-   }
-   int getFacetOri(std::vector<MVertex*> &v){
-     if(v.size() != 4 && v.size() != 3) return 0;
-     MFace facet = MFace(v);
-     int ithFacet = 0;
-     int sign = 0;
-     int rot = 0;
-     MPrism::getFaceInfo(facet, ithFacet, sign, rot);
-     return sign;
-   }
-   
-   virtual void printCell() const { printf("Cell dimension: %d, Vertices: %d %d %d %d %d %d, in subdomain: %d \n", getDim(), _v[0]->getNum(), _v[1]->getNum(), _v[2]->getNum(), _v[3]->getNum(), _v[4]->getNum(), _v[5]->getNum(),  _inSubdomain); }
-};
-
-
-// Pyramid cell type.
-class CPyramid : public Cell, public MPyramid
-{
-  private:
-   // sorted list of vertices
-   int _vs[5];
-      
-  public:
-   CPyramid(std::vector<MVertex*> v, int tag=0, bool subdomain=false, bool boundary=false, int num=0, int part=0)
-     : MPyramid(v, num, part){
-       _tag = tag;
-       _inSubdomain = subdomain;
-       _onDomainBoundary = boundary;
-       _vs[0] = v.at(0)->getNum();
-       _vs[1] = v.at(1)->getNum();
-       _vs[2] = v.at(2)->getNum();
-       _vs[3] = v.at(3)->getNum();
-       _vs[4] = v.at(4)->getNum();
-       std::sort(_vs, _vs+5);
-     }
-   
-   ~CPyramid(){}
-   
-   int getDim() const { return 3; }
-   int getNum() { return MPyramid::getNum(); }
-   int getType() { return MPyramid::getType(); }
-   int getTypeForMSH() { return MPyramid::getTypeForMSH(); }
-   int getPartition() { return MPyramid::getPartition(); }
-   int getNumVertices() const { return 5; }
-   int getNumFacets() const { return 5; }
-   MVertex* getVertex(int vertex) const {return _v[vertex]; }
-   int getSortedVertex(int vertex) const {return _vs[vertex]; }
-   bool hasVertex(int vertex) const {return 
-       (_v[0]->getNum() == vertex || _v[1]->getNum() == vertex || _v[2]->getNum() == vertex || _v[3]->getNum() == vertex ||
-        _v[4]->getNum() == vertex); }
-   std::vector<MVertex*> getVertexVector() const { 
-     return std::vector<MVertex*>(_v, _v + sizeof(_v)/sizeof(MVertex*) ); }
-   std::vector<int> getSortedVertexVector() const {
-     return std::vector<int>(_vs, _vs + sizeof(_vs)/sizeof(int) ); }
-   
-   void getFacetVertices(const int num, std::vector<MVertex*> &v) const {
-     MPyramid::getFaceVertices(num, v);
-   }
-   int getFacetOri(std::vector<MVertex*> &v){
-     if(v.size() != 4 && v.size() != 3) return 0;
-     MFace facet = MFace(v);
-     int ithFacet = 0;
-     int sign = 0;
-     int rot = 0;
-     MPyramid::getFaceInfo(facet, ithFacet, sign, rot);
-     return sign;
-   }
-   
-   virtual void printCell() const { printf("Cell dimension: %d, Vertices: %d %d %d %d %d, in subdomain: %d \n", getDim(), _v[0]->getNum(), _v[1]->getNum(), _v[2]->getNum(), _v[3]->getNum(), _v[4]->getNum(), _inSubdomain); }
-};
-
-// Ordering for the finite element mesh vertices.
-class Less_MVertex{
-  public:
-   bool operator()(const MVertex* v1, const MVertex* v2) const {
-     return (v1->getNum() < v2->getNum());
-   }
-};
-
-// A cell that is a combination of cells of same dimension
-class CombinedCell : public Cell{
- 
-  private:
-   // vertices
-   std::vector<MVertex*> _v;
-   // sorted list of all vertices
-   std::vector<int> _vs;
-   // list of cells this cell is a combination of
-   std::list< std::pair<int, Cell*> > _cells;
-   int _num;
-   
-  public:
-   
-   CombinedCell(Cell* c1, Cell* c2, bool orMatch, bool co=false);
-   ~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); }
-   std::vector<MVertex*> getVertexVector() const { return _v; }
-   
-   // true if this cell has given vertex
-   bool hasVertex(int vertex) const;
-   
-   virtual void printCell() const;
-   
-   std::list< std::pair<int, Cell*> > getCells() { return _cells; }
-   int getNumCells() {return _cells.size();}
-   
-};
-
 // A class representing a cell complex made out of a finite element mesh.
 class CellComplex
 {
@@ -690,9 +41,6 @@ class CellComplex
    // entities on the boundary of the homology computation domain
    std::vector<GEntity*> _boundary;
    
-   // mesh vertices in this domain
-   std::set<MVertex*, Less_MVertex> _domainVertices;
-   
    // sorted containers of unique cells in this cell complex 
    // one for each dimension
    std::set<Cell*, Less_Cell>  _cells[4];
@@ -720,7 +68,6 @@ class CellComplex
    // for constructor 
    void insert_cells(bool subdomain, bool boundary);
    void find_boundary(std::vector<GEntity*>& domain, std::vector<GEntity*>& subdomain);
-   void find_vertices(std::vector<GEntity*>& domain, std::vector<GEntity*>& subdomain);
    
    // remove a cell from this cell complex
    void removeCell(Cell* cell, bool other=true);
@@ -784,7 +131,7 @@ class CellComplex
    
    // write this cell complex in 2.0 MSH ASCII format
    // for debugging only
-   int writeComplexMSH(const std::string &name); 
+   //int writeComplexMSH(const std::string &name); 
    
    // Cell combining for reduction and coreduction
    int combine(int dim);
diff --git a/Geo/ChainComplex.cpp b/Geo/ChainComplex.cpp
index 73c36f04bacfe481ab406900ef330798a0e8624d..231bee797bbc7685b6601040e13f9ec92fc195cf 100644
--- a/Geo/ChainComplex.cpp
+++ b/Geo/ChainComplex.cpp
@@ -566,8 +566,6 @@ void Chain::smoothenChain(){
 
 int Chain::writeChainMSH(const std::string &name){
   
-  //_cellComplex->writeComplexMSH(name);
-  
   if(getSize() == 0) return 1;
   
   FILE *fp = fopen(name.c_str(), "a");
@@ -610,20 +608,11 @@ void Chain::createPView(){
   for(citer cit = _cells.begin(); cit != _cells.end(); cit++){
     Cell* cell = (*cit).first;
     int coeff = (*cit).second;
-    std::vector<MVertex*> v = cell->getVertexVector();
-    if(cell->getDim() > 0 && coeff < 0){ // flip orientation
-      if(getDim() != 1){
-        MVertex* temp = v[1];
-        v[1] = v[v.size()-1];
-        v[v.size()-1] = temp;
-      }
-      else{
-        MVertex* temp = v[0];
-        v[0] = v[1];
-        v[1] = temp;
-      }
-    }
-    MElement *e = factory.create(cell->getTypeForMSH(), v, cell->getNum(), cell->getPartition());
+
+    MElement *e = cell->getImageMElement();
+    cell->setDeleteImage(false);
+    
+    if(cell->getDim() > 0 && coeff < 0) e->revert(); // flip orientation
     for(int i = 0; i < abs(coeff); i++) elements.push_back(e);
     
     std::vector<double> coeffs (1,abs(coeff));
@@ -638,11 +627,9 @@ void Chain::createPView(){
   setNum(physicalNum);
   
   std::map<int, std::vector<MElement*> > entityMap;
-  //int entityNum = _model->getMaxElementaryNumber(getDim())+1;
   entityMap[entityNum] = elements;
   std::map<int, std::map<int, std::string> > physicalMap;
   std::map<int, std::string> physicalInfo;
-  //int physicalNum = _model->getMaxPhysicalNumber(getDim())+1; 
   physicalInfo[physicalNum]=getName();
   physicalMap[entityNum] = physicalInfo;
   
diff --git a/Geo/Homology.cpp b/Geo/Homology.cpp
index 0a8d7bc04cd617d86c78c779add13b08f33219c7..fe8850d0dbfc146d6727a6737a6fe8a59d8f2411 100644
--- a/Geo/Homology.cpp
+++ b/Geo/Homology.cpp
@@ -94,9 +94,7 @@ void Homology::findGenerators(std::string fileName){
   int omitted = _cellComplex->reduceComplex();
   //_cellComplex->printEuler();
   
-  //_cellComplex->emptyTrash();
   
- 
   _cellComplex->combine(3);
   _cellComplex->reduction(2);
   _cellComplex->combine(2);
@@ -106,7 +104,6 @@ void Homology::findGenerators(std::string fileName){
     _cellComplex->checkCoherence();
   //_cellComplex->printEuler();
   
-  //_cellComplex->emptyTrash();
   
   double t2 = Cpu();
   Msg::Info("Cell Complex reduction complete (%g s).", t2 - t1);
diff --git a/tutorial/t10.geo b/tutorial/t10.geo
index a97eb68816713085c9b1090adb2142686598260b..6e8606054f0a3495490e4da8ee6056bc0c835745 100644
--- a/tutorial/t10.geo
+++ b/tutorial/t10.geo
@@ -8,7 +8,7 @@
  
 // Homology computation in Gmsh finds representative chains of (relative) homology spaces using a mesh of a model. Those representatives generate the (relative) homology spaces of the model. Alternatively, Gmsh can only look for the ranks of the (relative) homology spaces, the Betti numbers of the model. 
 
-// The generators chains are stored in a given .msh-file as physical groups, whose mesh elements are oriented such that their coeffecients are 1 in the generator chain.
+// The generators chains are stored in a given .msh-file as physical groups, whose mesh elements are oriented such that their coefficients are 1 in the generator chain.
 
 
 // Create an example geometry