diff --git a/Geo/Cell.cpp b/Geo/Cell.cpp
index 962a53b3ad9c2239fea66986b1416cfd863c1d34..fdfb1a6fd44c1d9e0c0f1c42b16647a5e4105ef8 100755
--- a/Geo/Cell.cpp
+++ b/Geo/Cell.cpp
@@ -243,7 +243,6 @@ CombinedCell::CombinedCell(Cell* c1, Cell* c2, bool orMatch, bool co) : Cell() {
   }
   
   _index = c1->getIndex();
-  //_tag = c1->getTag();
   _dim = c1->getDim();
   _num = c1->getNum();
   _inSubdomain = c1->inSubdomain();
diff --git a/Geo/Cell.h b/Geo/Cell.h
index 3fb2439e8300f8ffb4c4b76ab0f65a5634216d6a..dd5b41bb3b2f5595df8f44e71062c32741c9f34e 100644
--- a/Geo/Cell.h
+++ b/Geo/Cell.h
@@ -169,7 +169,7 @@ class Cell
    virtual void printOrgCbd(); 
    
    virtual bool inSubdomain() const { return _inSubdomain; }
-   //virtual void setInSubdomain(bool subdomain)  { _inSubdomain = subdomain; }
+   virtual void setInSubdomain(bool subdomain)  { _inSubdomain = subdomain; }
    
    virtual bool onDomainBoundary() const { return _onDomainBoundary; }
    virtual void setOnDomainBoundary(bool domainboundary)  { _onDomainBoundary = domainboundary; }
diff --git a/Geo/CellComplex.cpp b/Geo/CellComplex.cpp
index cb2b779a5a8bb1914192f955c3044561acfe870f..cd88192b041548c497c53806307439547d7d9018 100644
--- a/Geo/CellComplex.cpp
+++ b/Geo/CellComplex.cpp
@@ -18,9 +18,20 @@ CellComplex::CellComplex( std::vector<GEntity*> domain, std::vector<GEntity*> su
   _dim = 0;
   _simplicial = true;
   
-  // find boundary entities
-  find_boundary(domain, subdomain);
+  _multidim = false;
+  int dim = 0;
+  for(int i = 0; i < domain.size(); i++){
+    GEntity* entity = domain.at(i);
+    if(i == 0) dim = entity->dim();
+    if(dim != entity->dim()){
+      _multidim = true;
+      Msg::Warning("Domain is not a manifold.");
+    }
+  }
   
+  // find boundary entities
+  if(!_multidim) find_boundary(domain, subdomain);
+
   // insert cells into cell complex
   // subdomain need to be inserted first!
   insert_cells(true, true);
@@ -34,7 +45,6 @@ CellComplex::CellComplex( std::vector<GEntity*> domain, std::vector<GEntity*> su
     if(getSize(i) > _dim) _dim = i;
   }
   
-  
 }
 
 void CellComplex::find_boundary(std::vector<GEntity*>& domain, std::vector<GEntity*>& subdomain){
@@ -97,8 +107,6 @@ void CellComplex::find_boundary(std::vector<GEntity*>& domain, std::vector<GEnti
 }
 
 void CellComplex::insert_cells(bool subdomain, bool boundary){
-
-  // works only for simplicial meshes at the moment!
   
   std::vector<GEntity*> domain;
   
@@ -134,17 +142,17 @@ void CellComplex::insert_cells(bool subdomain, bool boundary){
       else if(type == MSH_QUA_4 || type == MSH_QUA_8 || type == MSH_QUA_9){
         cell = new Cell(domain.at(j)->getMeshElement(i), subdomain, boundary);
         _simplicial = false;
-      }/* 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);
+        cell = new Cell(domain.at(j)->getMeshElement(i), subdomain, boundary);
         _simplicial = false;
-      }
+      }/* FIXME: no getFaceInfo methods for these MElements
       else if(type == MSH_PRI_6 || type == MSH_PRI_18 || type == MSH_PRI_15){
-        cell = new CPrism(vertices, tag, subdomain, boundary);
+        cell = new Cell(domain.at(j)->getMeshElement(i), subdomain, boundary);
         _simplicial = false;
       }
       else if(type == MSH_PYR_5 || type == MSH_PYR_14 || type == MSH_PYR_13){
-        cell = new CPyramid(vertices, tag, subdomain, boundary);
+        cell = new Cell(domain.at(j)->getMeshElement(i), subdomain, boundary);
         _simplicial = false;
       }*/
       else Msg::Error("Error: mesh element %d not implemented yet! \n", type); 
@@ -163,23 +171,31 @@ void CellComplex::insert_cells(bool subdomain, bool boundary){
       for(int i = 0; i < cell->getNumFacets(); i++){ 
         cell->getFacetVertices(i, vertices);
         int type = cell->getTypeForMSH();
-        
         int newtype = 0;
         //FIXME: add missing boundary cell type relations
+        //FIXME: high order meshes don't work
         if(dim == 3){
           if(type == MSH_TET_4) newtype = MSH_TRI_3;
-          else if(type == MSH_TET_10) newtype = MSH_TRI_6;
+          /*else if(type == MSH_TET_10) newtype = MSH_TRI_6;
+          else if(type == MSH_TET_20) newtype = MSH_TRI_9;*/
+          else if(type == MSH_HEX_8) newtype = MSH_QUA_4;
+          /*else if(type == MSH_HEX_20) newtype = MSH_QUA_8;
+          else if(type == MSH_HEX_27) newtype = MSH_QUA_9;*/
         }
         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(type == MSH_TRI_6 || type == MSH_QUA_8) newtype = MSH_LIN_3;
+           else if(type == MSH_TRI_9) newtype = MSH_LIN_4;
+           else if(type == MSH_QUA_9) newtype = MSH_LIN_3;*/
         }
         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(type == MSH_LIN_2) newtype = MSH_PNT;
+           /*else if(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); 
         
+        //printf("dim: %d type: %d, newtype: %d, vertices: %d \n", dim, type, newtype, vertices.size());
         MElement* element = factory.create(newtype, vertices, 0, cell->getPartition());
         Cell* newCell = new Cell(element, subdomain, boundary);
         newCell->setImmune(cell->getImmune());
@@ -206,7 +222,6 @@ void CellComplex::insert_cells(bool subdomain, bool boundary){
       }
     }
   }
-  
 }
 
 CellComplex::~CellComplex(){
@@ -893,6 +908,18 @@ bool CellComplex::hasCell(Cell* cell, bool org){
   }
 }
 
+bool CellComplex::swapSubdomain(){
+  if(_multidim) return false;
+  for(int i = 0; i < 4; i++){
+    for(citer cit = firstCell(i); cit != lastCell(i); cit++){
+      Cell* cell = *cit;
+      if(cell->onDomainBoundary() && cell->inSubdomain()) cell->setInSubdomain(false);
+      else if(cell->onDomainBoundary() && !cell->inSubdomain()) cell->setInSubdomain(true);
+    }
+  }
+  return true;
+}
+
 void CellComplex::makeDualComplex(){
   std::set<Cell*, Less_Cell> temp = _cells[0];
   _cells[0] = _cells[3];
diff --git a/Geo/CellComplex.h b/Geo/CellComplex.h
index 49c9ffc07270df86eb1c188ed93d9d21e6157c3d..017925888365673ca31c0b2c4782cfd4c7201318 100644
--- a/Geo/CellComplex.h
+++ b/Geo/CellComplex.h
@@ -59,6 +59,9 @@ class CellComplex
    // is the cell complex simplicial
    bool _simplicial;
    
+   // does the domain contain entities of different dimensions
+   bool _multidim;
+   
    // enqueue cells in queue if they are not there already
    void enqueueCells(std::list<Cell*>& cells, 
                              std::queue<Cell*>& Q, std::set<Cell*, Less_Cell>& Qset);
@@ -129,10 +132,6 @@ class CellComplex
    // print the vertices of cells of certain dimension
    void printComplex(int dim);
    
-   // write this cell complex in 2.0 MSH ASCII format
-   // for debugging only
-   //int writeComplexMSH(const std::string &name); 
-   
    // Cell combining for reduction and coreduction
    int combine(int dim);
    int cocombine(int dim);
@@ -145,6 +144,9 @@ class CellComplex
    // also check whether all (co)boundary cells of a cell belong to this cell complex
    bool checkCoherence();
    
+   // make cells on the domain boundary that are not in the subdomain subdomain cells and vice versa
+   bool swapSubdomain();
+   
    int eulerCharacteristic(){ return getSize(0) - getSize(1) + getSize(2) - getSize(3);}
    void printEuler(){ printf("Euler characteristic: %d. \n", eulerCharacteristic()); }
    
diff --git a/Geo/ChainComplex.cpp b/Geo/ChainComplex.cpp
index 231bee797bbc7685b6601040e13f9ec92fc195cf..cbfd41bb1897c5d54cb0f17563f4473222007dcd 100644
--- a/Geo/ChainComplex.cpp
+++ b/Geo/ChainComplex.cpp
@@ -602,7 +602,6 @@ int Chain::writeChainMSH(const std::string &name){
 void Chain::createPView(){
   
   std::vector<MElement*> elements;
-  MElementFactory factory;
   std::map<int, std::vector<double> > data;
   
   for(citer cit = _cells.begin(); cit != _cells.end(); cit++){
diff --git a/Geo/Homology.cpp b/Geo/Homology.cpp
index fe8850d0dbfc146d6727a6737a6fe8a59d8f2411..1a5344f3ea95c33466c064feb59943c8873bf325 100644
--- a/Geo/Homology.cpp
+++ b/Geo/Homology.cpp
@@ -111,7 +111,6 @@ void Homology::findGenerators(std::string fileName){
             _cellComplex->getSize(3), _cellComplex->getSize(2), _cellComplex->getSize(1), _cellComplex->getSize(0));
   Msg::StatusBar(2, false, "%d V, %d F, %d E, %d N.",
             _cellComplex->getSize(3), _cellComplex->getSize(2), _cellComplex->getSize(1), _cellComplex->getSize(0));
-  //for(int i = 0; i < 4; i++) { printf("Dim %d: \n", i); _cellComplex->printComplex(i); }
   
   Msg::Info("Computing homology spaces...");
   Msg::StatusBar(1, false, "Computing...");
@@ -190,7 +189,6 @@ void Homology::findDualGenerators(std::string fileName){
   Msg::StatusBar(1, false, "Reducing...");
   double t1 = Cpu();
   int omitted = _cellComplex->coreduceComplex();
-  //_cellComplex->emptyTrash();
   
   /*
   _cellComplex->makeDualComplex();
@@ -203,14 +201,10 @@ void Homology::findDualGenerators(std::string fileName){
   _cellComplex->makeDualComplex();
   */
   
-
   _cellComplex->cocombine(0);
   _cellComplex->cocombine(1);
   _cellComplex->cocombine(2);
   
-  
-  //_cellComplex->emptyTrash();
-  
   _cellComplex->checkCoherence();
   double t2 = Cpu();
   Msg::Info("Cell Complex reduction complete (%g s).", t2 - t1);
@@ -220,8 +214,6 @@ void Homology::findDualGenerators(std::string fileName){
             _cellComplex->getSize(3), _cellComplex->getSize(2), _cellComplex->getSize(1), _cellComplex->getSize(0));
   
   
-  //_cellComplex->writeComplexMSH(fileName);
-  
   Msg::Info("Computing homology spaces...");
   Msg::StatusBar(1, false, "Computing...");
   t1 = Cpu();
@@ -360,16 +352,8 @@ void Homology::createPViews(){
 
 bool Homology::writeGeneratorsMSH(std::string fileName, bool binary){
   if(!_model->writeMSH(fileName, 2.0, binary)) return false;
-  /*
-   for(int i = 0; i < 4; i++){
-   for(int j = 0; j < _generators[i].size(); j++){
-   Chain* chain = _generators[i].at(j);
-   if(!chain->writeChainMSH(fileName)) return false;
-   }
-   }*/
   Msg::Info("Wrote homology computation results to %s.", fileName.c_str());
-  Msg::Debug("Wrote homology computation results to %s. \n", fileName.c_str());
-  
+  Msg::Debug("Wrote homology computation results to %s. \n", fileName.c_str());  
   return true;
 }
 
diff --git a/Geo/Homology.h b/Geo/Homology.h
index fbc47be58c61358189172e4a422f9c0e423f5a59..0443ba40fdcf4f486572dc36440350953100b8b0 100644
--- a/Geo/Homology.h
+++ b/Geo/Homology.h
@@ -47,9 +47,8 @@ class Homology
    void findGenerators(std::string fileName);
    void findDualGenerators(std::string fileName);
    void computeBettiNumbers();
-   
-   
-   //void swapSubdomain() { _cellComplex->swapSubdomain(); }
+      
+   bool swapSubdomain() { return _cellComplex->swapSubdomain(); }
    
    // Restore the cell complex to its original state before cell reductions
    void restoreHomology();
diff --git a/Parser/Gmsh.y b/Parser/Gmsh.y
index 813628da5e1c52a00239fb044f13eabe0c2e2d52..dd1cf5962c28f125a76e5e18ee03e20795a85955 100644
--- a/Parser/Gmsh.y
+++ b/Parser/Gmsh.y
@@ -3333,7 +3333,7 @@ Homology :
     
     #if defined(HAVE_KBIPACK)
     Homology* homology = new Homology(GModel::current(), domain, subdomain);
-    homology->findGenerators(fileName);
+    homology->findGenerators(fileName);  
     delete homology;
     #else
     yymsg(0, "Gmsh needs to be configured with option Kbipack to use homology computation.");