diff --git a/src/mesh/GmshReader.cpp b/src/mesh/GmshReader.cpp
index 9eaaea15fad8d0ea1f19b3a7f9bb037acbdb2eb3..ca443f084613785b3823475924ee4d87b800354b 100644
--- a/src/mesh/GmshReader.cpp
+++ b/src/mesh/GmshReader.cpp
@@ -2,12 +2,817 @@
 
 #include <iostream>
 #include <fstream>
+#include <set>
+#include <rang.hpp>
+
+template<typename T> 
+inline std::string stringify(const T & t)
+{
+  std::ostringstream oss;
+  oss << t;
+  return oss.str();
+}
+
+template<> 
+inline std::string stringify<std::string>(const std::string& t)
+{
+  return t;
+}
+
+class ErrorHandler
+{
+public:
+  enum Type {
+    asked,     /**< execution request by the user*/
+    compilation, /**< syntax error in a language */
+    normal,    /**< normal error due to a bad use of ff3d */
+    unexpected /**< Unexpected execution error */
+  };
+
+private:
+  const std::string __filename;	/**< The source file name where the error occured */
+  const size_t __lineNumber;	/**< The line number where exception was raised */
+  const std::string __errorMessage; /**< The reporting message */
+
+  const Type __type;		/**< the type of the error */
+public:
+  /** 
+   * Prints the error message
+   * 
+   */
+  virtual void writeErrorMessage();
+
+  /** 
+   * The copy constructor
+   * 
+   * @param e an handled error
+   */
+  ErrorHandler(const ErrorHandler& e)
+    : __filename(e.__filename),
+      __lineNumber(e.__lineNumber),
+      __errorMessage(e.__errorMessage),
+      __type(e.__type)
+  {
+    ;
+  }
+
+  /** 
+   * Constructor
+   * 
+   * @param filename the source file name
+   * @param lineNumber the source line
+   * @param errorMessage the reported message
+   * @param type the type of the error
+   */
+  ErrorHandler(const std::string& filename,
+	       const size_t& lineNumber,
+	       const std::string& errorMessage,
+	       const Type& type);
+
+  /** 
+   * The destructor
+   * 
+   */
+  virtual ~ErrorHandler()
+  {
+    ;
+  }
+};
+void ErrorHandler::writeErrorMessage()
+{
+  switch(__type) {
+  case asked: {
+    std::cerr << "\nremark: exit command explicitly called\n";
+  }
+  case normal: {
+    std::cerr << '\n' << __filename << ':' << __lineNumber
+	      << ":remark: emitted the following message\n";
+    std::cerr << "error: " << __errorMessage << '\n';
+    break;
+  }
+  case compilation: {
+    std::cerr << "\nline " << __lineNumber << ':' << __errorMessage << '\n';
+    break;
+  }
+  case unexpected: {
+    std::cerr << '\n' << __filename << ':' << __lineNumber << ":\n" << __errorMessage << '\n';
+    std::cerr << "\nUNEXPECTED ERROR: this should not occure, please report it\n";
+    std::cerr << "\nBUG REPORT: Please send bug reports to:\n"
+	     << "  ff3d-dev@nongnu.org or freefem@ann.jussieu.fr\n"
+	     << "or better, use the Bug Tracking System:\n"
+	     << "  http://savannah.nongnu.org/bugs/?group=ff3d\n";
+    break;
+  }
+  default: {
+    std::cerr << __filename << ':' << __lineNumber << ": " << __errorMessage << '\n';
+    std::cerr << __FILE__ << ':' << __LINE__ << ":remark:  error type not implemented!\n";
+  }
+  }
+}
+
+ErrorHandler::
+ErrorHandler(const std::string& filename,
+	     const size_t& lineNumber,
+	     const std::string& errorMessage,
+	     const Type& type)
+  : __filename(filename),
+    __lineNumber(lineNumber),
+    __errorMessage(errorMessage),
+    __type(type)
+{
+  ;
+}
+
 
 GmshReader::GmshReader(const std::string& filename)
+  : m_filename(filename)
+{
+  m_fin.open(m_filename);
+  if (not m_fin) {
+    std::cerr << "cannot read file '" << m_filename << "'\n";
+    std::exit(0);
+  }
+
+  // gmsh 2.2 format keywords
+  __keywordList["$MeshFormat"]    = MESHFORMAT;
+  __keywordList["$EndMeshFormat"] = ENDMESHFORMAT;
+  __keywordList["$Nodes"]         = NODES;
+  __keywordList["$EndNodes"]      = ENDNODES;
+  __keywordList["$Elements"]      = ELEMENTS;
+  __keywordList["$EndElements"]   = ENDELEMENTS;
+
+  __numberOfPrimitiveNodes.resize(16);
+  __numberOfPrimitiveNodes[ 0] =  2; // edge
+  __numberOfPrimitiveNodes[ 1] =  3; // triangle
+  __numberOfPrimitiveNodes[ 2] =  4; // quadrangle
+  __numberOfPrimitiveNodes[ 3] =  4; // Tetrahedron
+  __numberOfPrimitiveNodes[ 4] =  8; // Hexaredron
+  __numberOfPrimitiveNodes[ 5] =  6; // Prism
+  __numberOfPrimitiveNodes[ 6] =  5; // Pyramid
+  __numberOfPrimitiveNodes[ 7] =  3; // second order edge
+  __numberOfPrimitiveNodes[ 8] =  6; // second order triangle
+  __numberOfPrimitiveNodes[ 9] =  9; // second order quadrangle
+  __numberOfPrimitiveNodes[10] = 10; // second order tetrahedron
+  __numberOfPrimitiveNodes[11] = 27; // second order hexahedron
+  __numberOfPrimitiveNodes[12] = 18; // second order prism
+  __numberOfPrimitiveNodes[13] = 14; // second order pyramid
+  __numberOfPrimitiveNodes[14] =  1; // point                    
+
+  __primitivesNames[0]     = "edges";
+  __supportedPrimitives[0] = false;
+  __primitivesNames[1]     = "triangles";
+  __supportedPrimitives[1] = true;
+  __primitivesNames[2]     = "quadrangles";
+  __supportedPrimitives[2] = true;
+  __primitivesNames[3]     = "tetrahedra";
+  __supportedPrimitives[3] = true;
+  __primitivesNames[4]     = "hexahedra";
+  __supportedPrimitives[4] = true;
+  __primitivesNames[5]     = "prisms";
+  __supportedPrimitives[5] = false;
+  __primitivesNames[6]     = "pyramids";
+  __supportedPrimitives[6] = false;
+  __primitivesNames[7]     = "second order edges";
+  __supportedPrimitives[7] = false;
+  __primitivesNames[8]     = "second order triangles";
+  __supportedPrimitives[8] = false;
+  __primitivesNames[9]     = "second order quadrangles";
+  __supportedPrimitives[9] = false;
+  __primitivesNames[10]    = "second order tetrahedra";
+  __supportedPrimitives[10]= false;
+  __primitivesNames[11]    = "second order hexahedra";
+  __supportedPrimitives[11]= false;
+  __primitivesNames[12]    = "second order prisms";
+  __supportedPrimitives[12]= false;
+  __primitivesNames[13]    = "second order pyramids";
+  __supportedPrimitives[13]= false;
+  __primitivesNames[14]    = "point";
+  __supportedPrimitives[14]= false;
+
+  std::cout << "Reading file '" << m_filename << "'\n";
+
+  // Getting vertices list
+  GmshReader::Keyword kw = this->__nextKeyword();
+  switch(kw.second) {
+  // case NOD: {
+  //   this->__readGmsh1();
+  //   break;
+  // }
+  case MESHFORMAT: {
+    double fileVersion = this->_getReal();
+    if (fileVersion != 2.2) {
+      throw ErrorHandler(__FILE__,__LINE__,
+      			 "Cannot read Gmsh format '"+stringify(fileVersion)+"'",
+      			 ErrorHandler::normal);
+    }
+    int fileType = this->_getInteger();
+    __binary = (fileType == 1);
+    if ((fileType < 0) or (fileType > 1)) {
+      throw ErrorHandler(__FILE__,__LINE__,
+      			 "Cannot read Gmsh file type '"+stringify(fileType)+"'",
+      			 ErrorHandler::normal);
+    }
+
+    int dataSize = this->_getInteger();
+    if (dataSize != sizeof(double)) {
+      throw ErrorHandler(__FILE__,__LINE__,
+      			 "Data size not supported '"+stringify(dataSize)+"'",
+      			 ErrorHandler::normal);
+    }
+
+    if (__binary) {
+//       int one=0;
+
+//       fseek(__ifh,1L,SEEK_CUR);
+//       fread(reinterpret_cast<char*>(&one),sizeof(int),1,__ifh);
+
+//       if (one == 1) {
+// 	__convertEndian = false;
+//       } else {
+// 	invertEndianess(one);
+
+// 	if (one == 1) {
+// 	  __convertEndian = true;
+// 	} else {
+// 	  throw ErrorHandler(__FILE__,__LINE__,
+// 	  		     "Cannot determine endianess",
+// 	  		     ErrorHandler::normal);
+// 	}
+// }
+
+//       std::cout << "- Binary format: ";
+// #ifdef    WORDS_BIGENDIAN
+//       if (not __convertEndian) {
+// 	std::cout << "big endian\n";
+//       } else {
+// 	std::cout << "little endian\n";
+//       }
+// #else  // WORDS_BIGENDIAN
+//       if (not __convertEndian) {
+// 	std::cout << "little endian\n";
+//       } else {
+// 	std::cout << "big endian\n";
+//       }
+// #endif // WORDS_BIGENDIAN
+    }
+
+    kw = this->__nextKeyword();
+    if (kw.second != ENDMESHFORMAT) {
+      throw ErrorHandler(__FILE__,__LINE__,
+      			 "reading file '"+m_filename
+      			 +"': expecting $EndMeshFormat, '"+kw.first+"' was found",
+      			 ErrorHandler::normal);
+    }
+
+    this->__readGmshFormat2_2();
+
+    break;
+  }
+  default: {
+    throw ErrorHandler(__FILE__,__LINE__,
+    		       "cannot determine format version of '"+m_filename+"'",
+    		       ErrorHandler::normal);
+  }
+  }
+  
+  this->__proceedData();
+  // this->__createMesh();
+}
+
+void GmshReader::__readVertices()
+{
+  const int numberOfVerices = this->_getInteger();
+  std::cout << "- Number Of Vertices: " << numberOfVerices << '\n';
+  if (numberOfVerices<0) {
+    throw ErrorHandler(__FILE__,__LINE__,
+    		       "reading file '"+this->m_filename
+    		       +"': number of vertices is negative",
+    		       ErrorHandler::normal);
+  }
+
+  __verticesNumbers.resize(numberOfVerices);
+  __vertices = Kokkos::View<R3*>("vertices",numberOfVerices);
+  
+  if (not __binary) {
+    for (int i=0; i<numberOfVerices; ++i) {
+      __verticesNumbers[i] = this->_getInteger();
+      const double x = this->_getReal();
+      const double y = this->_getReal();
+      const double z = this->_getReal();
+      __vertices[i] = TinyVector<3, double>(x,y,z);
+    } 
+  } else {
+    // fseek(m_fin.file()__ifh,1L,SEEK_CUR);
+    // for (int i=0; i<numberOfVerices; ++i) {
+    //   int number = 0;
+    //   fread(reinterpret_cast<char*>(&number),sizeof(int),1,__ifh);
+    //   __verticesNumbers[i] = number;
+    //   TinyVector<3,double> x;
+    //   fread(reinterpret_cast<char*>(&(x[0])),sizeof(double),3,__ifh);
+    //   for (size_t j=0; j<3; ++j) {
+    // 	__vertices[i][j] = x[j];
+    //   }
+    // }
+
+    // if (__convertEndian) {
+    //   for (int i=0; i<numberOfVerices; ++i) {
+    // 	invertEndianess(__verticesNumbers[i]);
+    // 	for (size_t j=0; j<3; ++j) {
+    // 	  invertEndianess(vertices[i][j]);
+    // 	}
+    //   }
+    // }
+  }
+}
+
+// void
+// GmshReader::__readElements1()
+// {
+//   const int numberOfElements = this->_getInteger();
+//   std::cout << "- Number Of Elements: " << numberOfElements << '\n';
+//   if (numberOfElements<0) {
+//     throw ErrorHandler(__FILE__,__LINE__,
+// 		       "reading file '"+m_filename
+// 		       +"': number of elements is negative",
+// 		       ErrorHandler::normal);
+//   }
+
+//   __elementType.resize(numberOfElements);
+//   __references.resize(numberOfElements);
+//   __elementVertices.resize(numberOfElements);
+
+//   for (int i=0; i<numberOfElements; ++i) {
+//     this->_getInteger(); // drops element number
+//     const int elementType = this->_getInteger()-1;
+
+//     if ((elementType < 0) or (elementType > 14)) {
+//       throw ErrorHandler(__FILE__,__LINE__,
+// 			 "reading file '"+m_filename
+// 			 +"': unknown element type '"+stringify(elementType)+"'",
+// 			 ErrorHandler::normal);
+//     }
+//     __elementType[i] = elementType;
+//     __references[i] = this->_getInteger(); // physical reference
+//     this->_getInteger(); // drops entity reference
+
+//     const int numberOfVertices = this->_getInteger();
+//     if (numberOfVertices != __numberOfPrimitiveNodes[elementType]) {
+//       std::stringstream errorMsg;
+//       errorMsg << "reading file '" <<m_filename
+// 	       << "':number of vertices (" << numberOfVertices
+// 	       << ") does not match expected ("
+// 	       << __numberOfPrimitiveNodes[elementType] << ")" << std::ends;
+
+//       throw ErrorHandler(__FILE__,__LINE__,
+// 			 errorMsg.str(),
+// 			 ErrorHandler::normal);
+//     }
+//     __elementVertices[i].resize(numberOfVertices);
+//     for (int j=0; j<numberOfVertices; ++j) {
+//       __elementVertices[i][j] = this->_getInteger();
+//     }
+//   }
+// }
+
+void
+GmshReader::__readElements2_2()
+{
+  const int numberOfElements = this->_getInteger();
+  std::cout << "- Number Of Elements: " << numberOfElements << '\n';
+  if (numberOfElements<0) {
+    throw ErrorHandler(__FILE__,__LINE__,
+    		       "reading file '"+m_filename
+    		       +"': number of elements is negative",
+    		       ErrorHandler::normal);
+  }
+
+  __elementType.resize(numberOfElements);
+  __references.resize(numberOfElements);
+  __elementVertices.resize(numberOfElements);
+
+  if (not __binary) {
+    for (int i=0; i<numberOfElements; ++i) {
+      this->_getInteger(); // drops element number
+      const int elementType = this->_getInteger()-1;
+
+      if ((elementType < 0) or (elementType > 14)) {
+	throw ErrorHandler(__FILE__,__LINE__,
+			   "reading file '"+m_filename
+			   +"': unknown element type '"+stringify(elementType)+"'",
+			   ErrorHandler::normal);
+      }
+      __elementType[i] = elementType;
+      const int numberOfTags =  this->_getInteger();
+      __references[i] = this->_getInteger(); // physical reference
+      for (int tag=1; tag<numberOfTags; ++tag) {
+	this->_getInteger(); // drops remaining tags
+      }
+
+      const int numberOfVertices = __numberOfPrimitiveNodes[elementType];
+      __elementVertices[i].resize(numberOfVertices);
+      for (int j=0; j<numberOfVertices; ++j) {
+	__elementVertices[i][j] = this->_getInteger();
+      }
+    }
+  } else {
+    // fseek(__ifh,1L,SEEK_CUR);
+    // int i=0;
+    // for (;i<numberOfElements;) {
+    //   int elementType = 0;
+    //   fread(reinterpret_cast<char*>(&elementType),sizeof(int),1,__ifh);
+    //   if (__convertEndian) {
+    // 	invertEndianess(elementType);
+    //   }
+    //   --elementType;
+
+    //   if ((elementType < 0) or (elementType > 14)) {
+    // 	 throw ErrorHandler(__FILE__,__LINE__,
+    // 	 		   "reading file '"+m_filename
+    // 	 		   +"': unknown element type '"+stringify(elementType)+"'",
+    // 	 		   ErrorHandler::normal);
+    //   }
+
+    //   int elementTypeNumber = 0;
+    //   fread(reinterpret_cast<char*>(&elementTypeNumber),sizeof(int),1,__ifh);
+    //   if (__convertEndian) {
+    // 	invertEndianess(elementTypeNumber);
+    //   }
+
+    //   int numberOfTags = 0;
+    //   fread(reinterpret_cast<char*>(&numberOfTags),sizeof(int),1,__ifh);
+    //   if (__convertEndian) {
+    // 	invertEndianess(numberOfTags);
+    //   }
+
+    //   for (int k=0; k<elementTypeNumber; ++k) {
+    // 	__elementType[i] = elementType;
+
+    // 	int elementNumber = 0;
+    // 	fread(reinterpret_cast<char*>(&elementNumber),sizeof(int),1,__ifh);
+
+    // 	int reference = 0;
+    // 	fread(reinterpret_cast<char*>(&reference),sizeof(int),1,__ifh);
+
+    // 	__references[i] = reference; // physical reference
+    // 	for (int tag=1; tag<numberOfTags; ++tag) {
+    // 	  int t;
+    // 	  fread(reinterpret_cast<char*>(&t),sizeof(int),1,__ifh);
+    // 	}
+
+    // 	const int numberOfVertices = __numberOfPrimitiveNodes[elementType];
+    // 	__elementVertices[i].resize(numberOfVertices);
+    // 	fread(reinterpret_cast<char*>(&(__elementVertices[i][0])),sizeof(int),numberOfVertices,__ifh);
+    // 	++i;
+    //   }
+    // }
+
+    // if (__convertEndian) {
+    //   for (size_t i=0; i<__references.size(); ++i) {
+    // 	invertEndianess(__references[i]);
+    //   }
+    //   for (size_t i=0; i<__elementVertices.size(); ++i) {
+    // 	for (size_t j=0; j<__elementVertices[i].size(); ++i) {
+    // 	  invertEndianess(__elementVertices[i][j]);
+    // 	}
+    //   }
+    // }
+  }
+}
+
+void
+GmshReader::__proceedData()
 {
-  std::ifstream fin(filename);
-  if (not fin) {
-    std::cerr << "cannot read file '" << filename << "'\n";
+  TinyVector<15,int> elementNumber = zero;
+  std::vector<std::set<size_t> > elementReferences(15);
+
+  for (size_t i=0; i<__elementType.size(); ++i) {
+    const int elementType = __elementType[i];
+    elementNumber[elementType]++;
+    elementReferences[elementType].insert(__references[i]);
+  }
+
+  for (size_t i=0; i<elementNumber.dimension(); ++i) {
+    if (elementNumber[i]>0) {
+      std::cout << "  - Number of "
+	       << __primitivesNames[i]
+	       << ": " << elementNumber[i];
+      if (not(__supportedPrimitives[i])) {
+	std::cout << " [IGNORED]";
+      } else {
+	std::cout << " references: ";
+	for(std::set<size_t>::const_iterator iref
+	      = elementReferences[i].begin();
+	    iref != elementReferences[i].end(); ++iref) {
+	  if (iref != elementReferences[i].begin()) std::cout << ',';
+	  std::cout << *iref;
+	}
+
+	switch (i) {
+	  // Supported entities
+	case 1: { // triangles
+	  __triangles
+	    = Kokkos::View<Triangle*>("triangles",
+				      elementNumber[i]);
+	  __triangles_ref.resize(elementNumber[i]);
+	  break;
+	}
+	case  2: { // quadrangles
+	  __quadrangles
+	    = Kokkos::View<Quadrangle*>("quadrangles",
+					elementNumber[i]);
+	  __quadrangles_ref.resize(elementNumber[i]);
+	  break;
+	}
+	case 3: { // tetrahedra
+	  __tetrahedra
+	    = Kokkos::View<Tetrahedron*>("tetrahedra",
+					 elementNumber[i]);
+	  __tetrahedra_ref.resize(elementNumber[i]);
+	  break;
+	}
+	case  4: {// hexahedra
+	  __hexahedra
+	    = Kokkos::View<Hexahedron*>("hexahedra",
+					elementNumber[i]);
+	  __hexahedra_ref.resize(elementNumber[i]);
+	}
+	  // Ignored entities
+	case  0:  // edge
+	case 14: {// point
+	  break; 
+	}
+	  // Unsupported entities
+	case  5: // prism
+	case  6: // pyramid
+	case  7: // second order edge
+	case  8: // second order triangle
+	case  9: // second order quadrangle
+	case 10: // second order tetrahedron
+	case 11: // second order hexahedron
+	case 12: // second order prism
+	case 13: // second order pyramid
+	default: {
+	  throw ErrorHandler(__FILE__,__LINE__,
+	  		     "reading file '"+m_filename
+	  		     +"': ff3d cannot read this kind of element",
+	  		     ErrorHandler::normal);
+	}
+	}
+      }
+      std::cout << '\n';
+    }
+  }
+
+  std::cout << "- Building correspondance table\n";
+  int minNumber = std::numeric_limits<int>::max();
+  int maxNumber = std::numeric_limits<int>::min();
+  for (size_t i=0; i<__verticesNumbers.size(); ++i) {
+    const int& vertexNumber = __verticesNumbers[i];
+    minNumber = std::min(minNumber,vertexNumber);
+    maxNumber = std::max(maxNumber,vertexNumber);
+  }
+
+  if (minNumber<0) {
+    throw ErrorHandler(__FILE__,__LINE__,
+    		       "reading file '"+m_filename
+    		       +"': ff3d does not implement negative vertices number",
+    		       ErrorHandler::normal);
+  }
+
+ // A value of -1 means that the vertex is unknown
+  __verticesCorrepondance.resize(maxNumber+1,-1);
+
+  for (size_t i=0; i<__verticesNumbers.size(); ++i) {
+    
+    __verticesCorrepondance[__verticesNumbers[i]] = i;
+  }
+
+  // reset element number to count them while filling structures
+  elementNumber = zero;
+
+  // Element structures filling
+  for (size_t i=0; i<__elementType.size(); ++i) {
+    std::vector<int>& elementVertices = __elementVertices[i];
+    switch (__elementType[i]) {
+      // Supported entities
+    case 1: { // triangles
+      int& triangleNumber = elementNumber[1];
+
+      const int a = __verticesCorrepondance[elementVertices[0]];
+      const int b = __verticesCorrepondance[elementVertices[1]];
+      const int c = __verticesCorrepondance[elementVertices[2]];
+      if ((a<0) or (b<0) or (c<0)) {
+	throw ErrorHandler(__FILE__,__LINE__,
+			   "reading file '"+m_filename
+			   +"': error reading element "+stringify(i)
+			   +" [bad vertices definition]",
+			   ErrorHandler::normal);
+      }
+      __triangles[triangleNumber]
+	= Triangle(a, b, c);
+      __triangles_ref[triangleNumber] = __references[i];
+      triangleNumber++; // one more triangle
+      break;
+    }
+    case 2: { // quadrangle
+      int& quadrilateralNumber = elementNumber[2];
+
+      const int a = __verticesCorrepondance[elementVertices[0]];
+      const int b = __verticesCorrepondance[elementVertices[1]];
+      const int c = __verticesCorrepondance[elementVertices[2]];
+      const int d = __verticesCorrepondance[elementVertices[3]];
+      if ((a<0) or (b<0) or (c<0) or (d<0)) {
+	throw ErrorHandler(__FILE__,__LINE__,
+			   "reading file '"+m_filename
+			   +"': error reading element "+stringify(i)
+			   +" [bad vertices definition]",
+			   ErrorHandler::normal);
+      }
+      __quadrangles[quadrilateralNumber] = Quadrangle(a,b,c,d);
+      __quadrangles_ref[quadrilateralNumber] = __references[i];
+      quadrilateralNumber++; // one more quadrangle
+      break;
+    }
+    case 3: { // tetrahedra
+      int& tetrahedronNumber = elementNumber[3];
+
+      const int a = __verticesCorrepondance[elementVertices[0]];
+      const int b = __verticesCorrepondance[elementVertices[1]];
+      const int c = __verticesCorrepondance[elementVertices[2]];
+      const int d = __verticesCorrepondance[elementVertices[3]];
+      if ((a<0) or (b<0) or (c<0) or (d<0)) {
+	throw ErrorHandler(__FILE__,__LINE__,
+			   "reading file '"+m_filename
+			   +"': error reading element "+stringify(i)
+			   +" [bad vertices definition]",
+			   ErrorHandler::normal);
+      }
+      __tetrahedra[tetrahedronNumber] = Tetrahedron(a, b, c, d);
+      __tetrahedra_ref[tetrahedronNumber] = __references[i];
+      tetrahedronNumber++; // one more tetrahedron
+      break;
+    }
+    case  4: { // hexaredron
+      int& hexahedronNumber = elementNumber[4];
+
+      const int a = __verticesCorrepondance[elementVertices[0]];
+      const int b = __verticesCorrepondance[elementVertices[1]];
+      const int c = __verticesCorrepondance[elementVertices[2]];
+      const int d = __verticesCorrepondance[elementVertices[3]];
+      const int e = __verticesCorrepondance[elementVertices[4]];
+      const int f = __verticesCorrepondance[elementVertices[5]];
+      const int g = __verticesCorrepondance[elementVertices[6]];
+      const int h = __verticesCorrepondance[elementVertices[7]];
+      if ((a<0) or (b<0) or (c<0) or (d<0) or (e<0) or (f<0) or (g<0) or (h<0)) {
+	throw ErrorHandler(__FILE__,__LINE__,
+			   "reading file '"+m_filename
+			   +"': error reading element "+stringify(i)
+			   +" [bad vertices definition]",
+			   ErrorHandler::normal);
+      }
+      __hexahedra[hexahedronNumber]
+	= Hexahedron(a, b, c, d,
+		     e, f, g, h);
+      __hexahedra_ref[hexahedronNumber] = __references[i];
+      hexahedronNumber++; // one more hexahedron
+      break;    }
+      // Unsupported entities
+    case  0: // edge
+    case 14:{// point
+      break;
+    }
+    case  5: // prism
+    case  6: // pyramid
+    case  7: // second order edge
+    case  8: // second order triangle
+    case  9: // second order quadrangle
+    case 10: // second order tetrahedron
+    case 11: // second order hexahedron
+    case 12: // second order prism
+    case 13:{// second order pyramid
+    }
+    default: {
+	  throw ErrorHandler(__FILE__,__LINE__,
+	  		     "reading file '"+m_filename
+	  		     +"': ff3d cannot read this kind of element",
+	  		     ErrorHandler::normal);
+    }
+    }
+  }
+
+  TinyVector<15,int> dimension0_mask = zero;
+  dimension0_mask[14]=1;
+  TinyVector<15,int> dimension1_mask = zero;
+  dimension1_mask[0]=1;
+  dimension1_mask[7]=1;
+  TinyVector<15,int> dimension2_mask = zero;
+  dimension2_mask[1]=1;
+  dimension2_mask[2]=1;
+  dimension2_mask[8]=1;
+  dimension2_mask[9]=1;
+  TinyVector<15,int> dimension3_mask = zero;
+  dimension3_mask[3]=1;
+  dimension3_mask[4]=1;
+  dimension3_mask[5]=1;
+  dimension3_mask[6]=1;
+  dimension3_mask[10]=1;
+  dimension3_mask[11]=1;
+  dimension3_mask[12]=1;
+  dimension3_mask[13]=1;
+
+  std::cout << "- dimension 0 entities : " << (dimension0_mask, elementNumber) << '\n';
+  std::cout << "- dimension 1 entities : " << (dimension1_mask, elementNumber) << '\n';
+  std::cout << "- dimension 2 entities : " << (dimension2_mask, elementNumber) << '\n';
+  std::cout << "- dimension 3 entities : " << (dimension3_mask, elementNumber) << '\n';
+  if ((dimension3_mask, elementNumber)>0) {
+    std::cerr << "*** using a 3d mesh (NIY)\n";
+    std::exit(0);
+  } else if ((dimension2_mask, elementNumber)>0) {
+    std::cerr << "*** using a 2d mesh (NIY)\n";
+    std::exit(0);
+  } else if ((dimension1_mask, elementNumber)>0) {
+    std::cerr << "*** using a 1d mesh (NIY)\n";
     std::exit(0);
+  } else {
+    std::cerr << "*** using a dimension 0 mesh is forbidden!\n";
+    std::exit(0);
+  }
+}
+
+GmshReader::Keyword
+GmshReader::__nextKeyword()
+{
+  GmshReader::Keyword kw;
+
+  std::cerr << "warning: " << rang::fg::red << __PRETTY_FUNCTION__ << rang::fg::reset << " keyword validity not checked!\n";
+  int retval = 1;
+  std::string aKeyword;
+  m_fin >> aKeyword;
+  if (retval < 0)  {
+    kw.second = EndOfFile;
+    return kw;
+  } else if (retval == 0) {
+    kw.second = Unknown;
+    return kw;
+  }
+
+  KeywordList::iterator i = __keywordList.find(aKeyword.c_str());
+
+  if (i != __keywordList.end()) {
+    kw.first = (*i).first;
+    kw.second = (*i).second;
+    return kw;
+  }
+
+  // throw ErrorHandler(__FILE__,__LINE__,
+  // 		     "reading file '"+m_filename
+  // 		     +"': unknown keyword '"+aKeyword+"'",
+  // 		     ErrorHandler::normal);
+
+  kw.first = aKeyword;
+  kw.second = Unknown;
+  return kw;
+}
+
+void GmshReader::
+__readGmshFormat2_2()
+{
+  std::cout << "- Reading Gmsh format 2.2\n";
+  GmshReader::Keyword kw;
+  kw = this->__nextKeyword();
+  if (kw.second != NODES) {
+    // throw ErrorHandler(__FILE__,__LINE__,
+    // 		       "reading file '"+m_filename
+    // 		       +"': expecting $Nodes, '"+kw.first+"' was found",
+    // 		       ErrorHandler::normal);
+  }
+
+  this->__readVertices();
+
+  kw = this->__nextKeyword();
+  if (kw.second != ENDNODES) {
+    // throw ErrorHandler(__FILE__,__LINE__,
+    // 		       "reading file '"+m_filename
+    // 		       +"': expecting $EndNodes, '"+kw.first+"' was found",
+    // 		       ErrorHandler::normal);
+  }
+
+  // Getting elements list
+  kw = this->__nextKeyword();
+  if (kw.second != ELEMENTS) {
+    // throw ErrorHandler(__FILE__,__LINE__,
+    // 		       "reading file '"+m_filename
+    // 		       +"': expecting $Elements, '"+kw.first+"' was found",
+    // 		       ErrorHandler::normal);
+  }
+
+  this->__readElements2_2();
+
+  kw = this->__nextKeyword();
+  if (kw.second != ENDELEMENTS) {
+    // throw ErrorHandler(__FILE__,__LINE__,
+    // 		       "reading file '"+m_filename
+    // 		       +"': expecting $EndElements, '"+kw.first+"' was found",
+    // 		       ErrorHandler::normal);
   }
 }
diff --git a/src/mesh/GmshReader.hpp b/src/mesh/GmshReader.hpp
index eafacfeaceaf055f5344542165beec55f9473623..61aba7d4f24d6e55afad6fdf9936b9737f34a750 100644
--- a/src/mesh/GmshReader.hpp
+++ b/src/mesh/GmshReader.hpp
@@ -2,9 +2,182 @@
 #define GMSH_READER_HPP
 
 #include <string>
+#include <array>
+#include <vector>
+#include <map>
+#include <fstream>
+#include <Kokkos_Core.hpp>
+#include <TinyVector.hpp>
 
 class GmshReader
 {
+public:
+  typedef TinyVector<3, double> R3;
+private:
+  std::ifstream m_fin;
+  const std::string m_filename;
+
+  int _getInteger()
+  {
+    int i;
+    m_fin >> i;
+
+    return std::move(i);
+  }
+
+  double _getReal()
+  {
+    double d;
+    m_fin >> d;
+
+    return std::move(d);
+  }
+
+  /** 
+   * Gmsh format provides a numbered, none ordrered and none dense
+   * vertices list, this stores the number of read vertices.
+   */
+  std::vector<int> __verticesNumbers;
+
+  Kokkos::View<R3*> __vertices;
+  typedef TinyVector<3,unsigned int> Triangle;
+  Kokkos::View<Triangle*> __triangles;
+  std::vector<int> __triangles_ref;
+  typedef TinyVector<4,unsigned int> Quadrangle;
+  Kokkos::View<Quadrangle*> __quadrangles;
+  std::vector<int> __quadrangles_ref;
+  typedef TinyVector<4,unsigned int> Tetrahedron;
+  Kokkos::View<Tetrahedron*> __tetrahedra;
+  std::vector<int> __tetrahedra_ref;
+  typedef TinyVector<8,unsigned int> Hexahedron;
+  Kokkos::View<Hexahedron*> __hexahedra;
+  std::vector<int> __hexahedra_ref;
+
+  /** 
+   * Gmsh format provides a numbered, none ordrered and none dense
+   * vertices list, this provides vertices renumbering correspondance
+   */
+  std::vector<int> __verticesCorrepondance;
+
+  /** 
+   * elements types
+   */
+  std::vector<short> __elementType;
+
+  /** 
+   * References
+   */
+  std::vector<int> __references;
+
+  /** 
+   * References
+   */
+  std::vector<std::vector<int> > __elementVertices;
+
+  /** 
+   * Stores the number of nodes associated to each primitive
+   * 
+   */
+  std::vector<int> __numberOfPrimitiveNodes;
+
+  /** 
+   * Array of boolean describing gmsh supported primitives by ff3d
+   * 
+   */
+  std::array<bool, 15> __supportedPrimitives;
+
+  /** 
+   * Primitives names according to there number
+   * 
+   */
+  std::map<int, std::string> __primitivesNames;
+
+  bool __binary;		/**< true if binary format */
+  bool __convertEndian;		/**< true if needs to adapt endianess */
+
+  /** 
+   * Adapts gmsh data to ff3d's structures 
+   * 
+   */
+  void __proceedData();
+
+  /** 
+   * Reads data in format 2.2
+   * 
+   */
+  void __readGmshFormat2_2();
+
+  /**
+   * List of allowed keyword in mesh file
+   * 
+   */
+  enum KeywordType {
+    // gmsh 2.2
+    MESHFORMAT,
+    ENDMESHFORMAT,
+    NODES,
+    ENDNODES,
+    ELEMENTS,
+    ENDELEMENTS,
+
+    Unknown,
+    EndOfFile
+  };
+
+  /**
+   * List of known keywords
+   * 
+   */
+  typedef std::map<std::string, int> KeywordList;
+
+  KeywordList __keywordList;	/**< The keyword list */
+
+  /**
+   * Type for keyword
+   * 
+   */
+  typedef std::pair<std::string, int> Keyword;
+
+  /** 
+   * Skips next comments if exists
+   * 
+   */
+  void __skipComments();
+
+  /** 
+   * Reads the next keyword and returns its token
+   * 
+   * @return KeywordToken
+   */
+  Keyword __nextKeyword();
+
+  /** 
+   * get list of vertices
+   * 
+   */
+  void __getVertices();
+
+  /**
+   * Read list of vertices
+   * 
+   */
+  void __readVertices();
+
+  /**
+   * Read all elements in format 2.0
+   * 
+   */
+  void __readElements2_2();
+
+  // /** 
+  //  * Common interface for writing references
+  //  * 
+  //  * @param references the set of computed references
+  //  * @param objectName the type of refernces
+  //  */
+  // void __writeReferences(const std::set<size_t>& references,
+  // 			 std::string objectName);
+
 public:
   GmshReader(const std::string& filename);
   ~GmshReader() = default;