diff --git a/Common/GmshDefines.h b/Common/GmshDefines.h
index 7b956b95dbe27252440711cc33130c8aca07fa25..4e2c4ac50579c545d00e5ffde3eb4d28232824b4 100644
--- a/Common/GmshDefines.h
+++ b/Common/GmshDefines.h
@@ -30,6 +30,7 @@
 #define FORMAT_MESH          30
 #define FORMAT_BDF           31
 #define FORMAT_CGNS          32
+#define FORMAT_MED           33
 
 // Element types in .msh file format
 #define MSH_LIN_2  1
diff --git a/Fltk/Callbacks.cpp b/Fltk/Callbacks.cpp
index d881bc84dda6e797a5195a37e8e2787d6dd46713..fcdcdc35cc4a41e827a6bac989e57284176663e5 100644
--- a/Fltk/Callbacks.cpp
+++ b/Fltk/Callbacks.cpp
@@ -1,4 +1,4 @@
-// $Id: Callbacks.cpp,v 1.510 2007-01-28 12:55:00 geuzaine Exp $
+// $Id: Callbacks.cpp,v 1.511 2007-01-29 14:52:57 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -655,6 +655,7 @@ int _save_bdf(char *name){ return bdf_dialog(name); }
 int _save_stl(char *name){ return stl_dialog(name); }
 int _save_vrml(char *name){ return generic_mesh_dialog(name, "VRML Options", FORMAT_VRML); }
 int _save_cgns(char *name){ CreateOutputFile(name, FORMAT_CGNS); return 1; }
+int _save_med(char *name){ return generic_mesh_dialog(name, "MED Options", FORMAT_MED); }
 int _save_eps(char *name){ return gl2ps_dialog(name, "EPS Options", FORMAT_EPS); }
 int _save_gif(char *name){ return gif_dialog(name); }
 int _save_jpeg(char *name){ return jpeg_dialog(name); }
@@ -679,6 +680,7 @@ int _save_auto(char *name)
   case FORMAT_STL  : return _save_stl(name);
   case FORMAT_VRML : return _save_vrml(name);
   case FORMAT_CGNS : return _save_cgns(name);
+  case FORMAT_MED  : return _save_med(name);
   case FORMAT_EPS  : return _save_eps(name);
   case FORMAT_GIF  : return _save_gif(name);
   case FORMAT_JPEG : return _save_jpeg(name);
@@ -717,6 +719,9 @@ void file_save_as_cb(CALLBACK_ARGS)
     {"VRML surface mesh (*.wrl)", _save_vrml},
 #if defined(HAVE_LIBCGNS)
     {"CGNS (*.cgns)", _save_cgns},
+#endif
+#if defined(HAVE_LIBMED)
+    {"MED (*.med)", _save_med},
 #endif
     {"Encapsulated PostScript (*.eps)", _save_eps},
     {"GIF (*.gif)", _save_gif},
diff --git a/Geo/GModel.h b/Geo/GModel.h
index 091fe5c25e6e1c1e741bc9a319c53022bf29259d..c9af9f91ac68019125f5c32b97d6449351285b7d 100644
--- a/Geo/GModel.h
+++ b/Geo/GModel.h
@@ -209,6 +209,9 @@ class GModel
   // CFD General Notation System files
   int readCGNS(const std::string &name);
   int writeCGNS(const std::string &name, double scalingFactor=1.0);
+
+  // Med interface ("Modele d'Echange de Donnees")
+  int writeMED(const std::string &name);
 };
 
 #endif
diff --git a/Geo/GModelIO_MED.cpp b/Geo/GModelIO_MED.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..30296cd57909f89c7483ad770a2bc52eb6d80c46
--- /dev/null
+++ b/Geo/GModelIO_MED.cpp
@@ -0,0 +1,409 @@
+// $Id: GModelIO_MED.cpp,v 1.1 2007-01-29 14:52:57 geuzaine Exp $
+//
+// Copyright (C) 1997-2006 C. Geuzaine, J.-F. Remacle
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA.
+// 
+// Please report all bugs and problems to <gmsh@geuz.org>.
+
+#include "GModel.h"
+#include "MVertex.h"
+#include "MEdge.h"
+#include "Message.h"
+
+#if defined(HAVE_LIBMED)
+
+#include <map>
+#include <string>
+#include <vector>
+#include <iostream>
+#include <sstream>
+#include "GModelIO_MED.h"
+
+extern "C" {
+#include "med.h"
+}
+
+ConversionData Data::MyConversionData;
+
+typedef std::list<int>::const_iterator listIter;
+
+ConversionData::ConversionData()
+{ 
+	// Correspondance des types GMSH et MEd
+	static const med_geometrie_element ValuesTypesOfElts[] = {  MED_SEG2,    MED_TRIA3,  MED_QUAD4,   MED_TETRA4,
+								    MED_HEXA8,   MED_PENTA6, MED_PYRA5,   MED_SEG3, 
+								    MED_TRIA6,   MED_QUAD8,  MED_TETRA10, MED_HEXA20, 
+								    MED_PENTA15, MED_PYRA13, MED_POINT1,  MED_QUAD8,
+								    MED_HEXA20,  MED_PENTA15, MED_PYRA13,  MED_NONE};
+		
+	int i=0;
+	while (ValuesTypesOfElts[i] != MED_NONE)
+	{
+	   typesOfElts[i+1]=ValuesTypesOfElts[i];
+	   ++i;
+	}
+
+	// *****************************************************
+	// elements GMSH avec un nb de noeuds differents en Med
+	// *****************************************************
+	static const int secondOrderElts[] = { 10, 12, 13, 14 , 0};
+	static const int NbNodesInMed[]    = { 8,  20, 15, 13 , 0};
+	i=0;
+	while (secondOrderElts[i] != 0)
+	{
+	   maxEltInMed[secondOrderElts[i]]=NbNodesInMed[i];
+	   ++i;
+	}
+
+	// **************************
+	// Num�rotation des Noeuds
+	// **************************
+	//
+	// line ( 1er et 2nd Ordre)
+	i=1;
+	while ( i!=3 ) { 
+	   medVertexOrder[1].push_back(i);
+	   medVertexOrder[8].push_back(i);
+	   ++i;
+	}
+	medVertexOrder[8].push_back(3);
+
+	// tria
+	i=1;
+	while ( i!=4 ) { 
+	   medVertexOrder[2].push_back(i);
+	   medVertexOrder[9].push_back(i);
+	   ++i;
+	}
+	medVertexOrder[9].push_back(4);
+	medVertexOrder[9].push_back(5);
+	medVertexOrder[9].push_back(6);
+
+	// quad
+	i=1;
+	while ( i!=5 ) { 
+	   medVertexOrder[3].push_back(i);
+	   medVertexOrder[10].push_back(i);
+	   medVertexOrder[16].push_back(i);
+	   ++i;
+	}
+	medVertexOrder[10].push_back(5);
+	medVertexOrder[16].push_back(5);
+	medVertexOrder[10].push_back(6);
+	medVertexOrder[16].push_back(6);
+	medVertexOrder[10].push_back(7);
+	medVertexOrder[16].push_back(7);
+	medVertexOrder[10].push_back(8);
+	medVertexOrder[16].push_back(8);
+
+	// tetra
+	static const int OrderforTetra[] = { 1, 3, 2, 4, 0 };
+	i=0;
+	while ( OrderforTetra[i] != 0 ) { 
+	   medVertexOrder[4].push_back(OrderforTetra[i]);
+	   medVertexOrder[11].push_back(OrderforTetra[i]);
+	   ++i;
+	}
+	static const int OrderforTetra2[] = { 7, 6 , 5, 8 , 9 , 10, 0 }; 
+	i=0;
+	while ( OrderforTetra2[i] != 0 ) { 
+	   medVertexOrder[11].push_back(OrderforTetra2[i]);
+	   ++i;
+	}
+
+	// hexa
+	// le 1 MED est le 1er Gmsh,   le 2nd Med est le 4ieme Gmsh , le 3 le 6 ...
+	static const int OrderforHexa[] = { 1, 5, 8,  4, 2, 6, 7, 3, 0};
+	i=0;
+	while (OrderforHexa[i] != 0)
+	{
+	   medVertexOrder[5].push_back(OrderforHexa[i]);
+	   medVertexOrder[12].push_back(OrderforHexa[i]);
+	   medVertexOrder[17].push_back(OrderforHexa[i]);
+	   ++i;
+	};
+	static const int OrderforHexa2[] = { 11,18,16,10,13,19,15,16,9,17,20,14, 0 }; 
+	i=0;
+	while ( OrderforHexa2[i] != 0 ) { 
+	   medVertexOrder[12].push_back(OrderforHexa2[i]);
+	   medVertexOrder[17].push_back(OrderforHexa2[i]);
+	   ++i;
+	}
+
+	// Prism
+	static const int OrderforPrism[] = { 1, 3, 2, 4, 6, 5, 0};
+	i=0;
+	while (OrderforPrism[i] != 0)
+	{
+	   medVertexOrder[6].push_back(OrderforPrism[i]);
+	   medVertexOrder[13].push_back(OrderforPrism[i]);
+	   medVertexOrder[18].push_back(OrderforPrism[i]);
+	   ++i;
+	};
+	static const int OrderforPrism2[] = { 8, 10, 7, 14, 13, 15, 9, 12, 11, 0};
+	i=0;
+	while ( OrderforPrism2[i] != 0 ) { 
+	   medVertexOrder[13].push_back(OrderforPrism2[i]);
+	   medVertexOrder[18].push_back(OrderforPrism2[i]);
+	   ++i;
+	}
+
+
+	//Pyra
+	static const int OrderforPyra[] = { 1, 4, 3, 2, 5, 0};
+	i=0;
+	while (OrderforPyra[i] != 0)
+	{
+	   medVertexOrder[7].push_back(OrderforPyra[i]);
+	   medVertexOrder[14].push_back(OrderforPyra[i]);
+	   medVertexOrder[19].push_back(OrderforPyra[i]);
+	   ++i;
+	};
+	static const int OrderforPyra2[] = { 7, 11 ,9 , 6, 8, 13, 12 , 10, 0};
+	i=0;
+	while ( OrderforPyra2[i] != 0 ) { 
+	   medVertexOrder[14].push_back(OrderforPyra2[i]);
+	   medVertexOrder[19].push_back(OrderforPyra2[i]);
+	   ++i;
+	}
+};
+
+int ConversionData::inMaxEltInMed(int clef)
+{
+	std::map<int,int>::const_iterator MyIter;
+	MyIter = maxEltInMed.find(clef);
+	if ( MyIter != maxEltInMed.end() )
+		return 1;
+	return 0;
+};
+
+
+
+
+MedIO::MedIO() : _numOfNode(1), _boolOpen(0), _meshName("monMaillage")
+{ 
+};
+
+// --------------------------------------------
+int MedIO::SetFile(const std::string &FileName)
+// --------------------------------------------
+// Open Med File
+// Headers Creation in Med File 
+// Mesh Creation in Med File
+{
+   _FileName = FileName;
+   // All Meshes are 3D and unstructured Meshes
+   med_err ret = 0;
+   char des[MED_TAILLE_DESC+1]="Med file generated by  Gmsh";
+
+   _fid = MEDouvrir((char *) _FileName.c_str(),MED_CREATION);
+   if (_fid < 0) {
+       Msg(GERROR, "Unable to open file '%s'", _FileName.c_str());
+       return 0;
+   }
+
+   if (MEDfichDesEcr(_fid,des) < 0) {
+       Msg(GERROR, "Unable to write descriptor in file '%s'", _FileName.c_str());
+       return 0;
+   }
+
+   std::string description = "gmsh";
+   if (MEDmaaCr(_fid,(char *) _meshName.c_str(),3,MED_NON_STRUCTURE,(char *) description.c_str()) < 0) 
+   {
+       Msg(GERROR, "Error in Mesh Creation '%s'", _FileName.c_str());
+       return 0;
+   }
+   _boolOpen=1;
+    Msg(INFO,"File Open");
+   return 1;
+}
+ 
+// -------------------------------------------------
+int MedIO::AddVertex(MVertex* v, const int famille)
+// -------------------------------------------------
+{ 
+   // Msg(INFO, "Creation ");
+   coordonnees.push_back((med_float)v->x());
+   coordonnees.push_back((med_float)v->y());
+   coordonnees.push_back((med_float)v->z());
+
+   numOpt.push_back(v->getNum());
+   elements[v->getNum()] = _numOfNode ;
+   _numOfNode = _numOfNode + 1;
+
+   families.push_back(famille);
+   numFamilles.insert(famille);
+   return 1;
+}
+
+// -------------------------------
+int MedIO::CreateNodeFam( )
+// -------------------------------
+{
+   numFamilles.insert(0);
+   std::set<int>::const_iterator itFam;
+   for (itFam = numFamilles.begin(); itFam != numFamilles.end(); ++itFam) {
+	med_err CR;
+	if (*itFam != 0 )
+	{ std::ostringstream oss;
+          oss << *itFam;
+          std::string fam = "Famille" + oss.str();
+          std::string group = "Groupe" + oss.str();
+	  while (group.size() < 80) group = group + " ";
+          CR = MEDfamCr (_fid, (char *) _meshName.c_str(),(char *)fam.c_str(),*itFam, 0,0,0,0,(char *)group.c_str(),1);
+	  CR=0;
+	}
+	else
+	{
+          std::string fam = "Famille0";
+          CR = MEDfamCr (_fid, (char *) _meshName.c_str(),(char *)fam.c_str(),*itFam, 0,0,0,0,0,0);
+	}
+        if ( CR < 0 )
+        {
+            Msg(GERROR, "Error in Family Creation '%d'", *itFam );
+            return 0;
+         }
+   }
+   return 1;
+}
+
+int MedIO::CreateElemtFam( )
+{}
+
+
+// -------------------------------
+int MedIO::CreateElemt()
+// -------------------------------
+{
+    std::map<int,med_geometrie_element>::const_iterator eltIter = Data::MyConversionData.typesOfElts.begin();
+    for ( ; eltIter != Data::MyConversionData.typesOfElts.end(); ++eltIter ) {
+       med_geometrie_element typemed =(*eltIter).second;
+       if (typemed == MED_POINT1) continue;
+       int nbNoeudElt = typemed % 100 ;
+       int nbElements = connectivities[typemed].size() / nbNoeudElt;
+       if (nbElements != 0 )
+           med_err CR = MEDelementsEcr (_fid, (char*) _meshName.c_str(),(med_int) 3, 
+		         &connectivities[typemed][0], MED_FULL_INTERLACE,
+			 NULL, MED_FAUX, NULL, MED_FAUX,
+			 &famElts[typemed][0],nbElements,
+			   MED_MAILLE,typemed,MED_NOD);
+
+    }
+};
+// ------------------------------------------
+int MedIO::Ecrit()
+// ------------------------------------------
+{
+    if (_boolOpen != 1)
+    {
+        Msg(GERROR, "File not Open");
+	return 0;
+    }
+
+    int nbNoeuds=coordonnees.size() / 3;
+    if (nbNoeuds != families.size())
+    {
+        Msg(GERROR, "bad Vectors");
+	return 0;
+    }
+
+    // *********************
+    // Creation des Familles
+    // *********************
+    int CRFam = CreateNodeFam();
+    if ( CRFam < 0 )
+    {
+       Msg(GERROR, "Error in Nodes Families Creation ");
+       return 0;
+    }
+
+    int CRFamElt = CreateElemtFam();
+    if ( CRFamElt < 0 )
+    {
+       Msg(GERROR, "Error in Elements Families Creation ");
+       return 0;
+    }
+
+    // *************************
+    // Creation des Coordonnees
+    // *************************
+    char nomcoo[3*MED_TAILLE_PNOM+1] = "x               y               z               ";
+    char unicoo[3*MED_TAILLE_PNOM+1] = "inconnu         inconnu         inconnu         ";
+
+    med_err CR = MEDnoeudsEcr(_fid, (char*) _meshName.c_str(),(med_int) 3, 
+		              &coordonnees[0], MED_FULL_INTERLACE, MED_CART,
+		              nomcoo,unicoo, NULL, MED_FAUX, 
+			      &numOpt[0], MED_VRAI, 
+			      &families[0], nbNoeuds);
+    Msg(INFO, "%d ", CR);
+    if ( CR < 0 )
+    {
+       Msg(GERROR, "Error in Nodes Creation ");
+       return 0;
+    }
+    // ***************************
+    // Creation des connectivit�s
+    // ***************************
+    int CRElt = CreateElemt();
+    if ( CRElt < 0 )
+    {
+       Msg(GERROR, "Error in Elements Creation ");
+       return 0;
+    }
+    return 1;
+}
+
+//--------------------
+int MedIO::CloseFile()
+//--------------------
+{
+   if (MEDfermer(_fid) < 0) 
+   {
+       Msg(GERROR, "Unable to close file '%s'",(char * ) _FileName.c_str());
+       return 0;
+   }
+  return 1;
+}
+
+
+int GModel::writeMED(const std::string &name)
+{
+
+   MedIO MedDriver=MedIO();
+   int CR1 =MedDriver.SetFile(name);
+
+   MedDriver.WriteNodes(vertices);
+   MedDriver.WriteNodes(edges);
+   MedDriver.WriteNodes(faces);
+   MedDriver.WriteNodes(regions);
+
+   int CR2 = MedDriver.Ecrit();
+   int CR3 = MedDriver.CloseFile();
+
+   return CR1 * CR2 * CR3 ;
+}
+
+#else
+
+int GModel::writeMED(const std::string &name)
+{
+  Msg(GERROR,"Gmsh has to be compiled with MED support to write %s",
+      name.c_str());
+  return 0;
+}
+
+#endif
diff --git a/Geo/GModelIO_MED.h b/Geo/GModelIO_MED.h
new file mode 100644
index 0000000000000000000000000000000000000000..b7cd3341638537b67ef4fdbf6bfbfa5794dc6b50
--- /dev/null
+++ b/Geo/GModelIO_MED.h
@@ -0,0 +1,241 @@
+#ifndef _GMODELIO_MED_H_
+#define _GMODELIO_MED_H_
+
+#include <string>
+#include <map>
+#include <vector>
+#include <set>
+#include <typeinfo>
+
+#include "GEntity.h"
+#include "GRegion.h"
+#include "GEdge.h"
+#include "GFace.h"
+#include "Message.h"
+
+#if defined(HAVE_LIBMED)
+
+extern "C"
+{
+	   #include "med.h"
+}
+
+typedef std::map<med_geometrie_element,std::vector<int> >  connectivities;
+typedef std::list<int>::const_iterator listIter;
+typedef std::map<int,int>numero;
+typedef std::set<int>setFamille;
+
+class ConversionData 
+{
+	public :
+
+ 	   ConversionData();
+	   int inMaxEltInMed(int clef);
+
+           std::map<int,med_geometrie_element> typesOfElts;
+           std::map<int,int> maxEltInMed;
+           std::map<int,std::list<int> > medVertexOrder;
+
+	   std::map<int,int> familleParDimension;
+	   std::map<int,int> famillefamille;
+
+};
+
+class Data 
+{
+    public :
+    static ConversionData MyConversionData ;
+};
+
+
+template<class T>
+class MontraitementDeBase : Data
+{
+  protected:
+  static inline int RecupereFamille(const T &ele, setFamille & numFamilles, const int dimension)
+  {
+     int famille = 0;
+     if (ele.physicals.size() != 0) 
+        famille=ele.physicals[0];
+     if (famille == 0) return 0; 
+
+     if (famille > 0)  famille = -1 * famille;
+
+     // On verifie qu il s agit de la bonne dimension 
+     int familleInitiale=famille;
+     while (MyConversionData.familleParDimension[famille] != dimension)
+     {
+        if (numFamilles.find(famille) == numFamilles.end())
+        {
+     	    numFamilles.insert(famille);
+	    MyConversionData.familleParDimension[famille]=dimension;
+        }
+	 else 
+	{
+           famille=famille-1000;
+        }
+	//Msg(INFO, "famille %d", famille);
+     }
+
+     MyConversionData.famillefamille[familleInitiale]=famille;
+     return famille;
+  }
+
+  template < class G>
+  static void RecupereElement(const std::vector<G*> &ele , connectivities &maMap, connectivities &mesFamilles, 
+		              numero& elements , const int famille) {
+     if (ele.size() == 0) return;
+     const int type=ele[0]->getTypeForMSH();
+     const med_geometrie_element medType= Data::MyConversionData.typesOfElts[type];
+
+     for (unsigned int elt = 0; elt < ele.size(); ++elt) {
+	const int monNum=ele[elt]->getNum();
+	for (listIter monIter  = Data::MyConversionData.medVertexOrder[type].begin(); 
+	              monIter != Data::MyConversionData.medVertexOrder[type].end(); 
+		      ++monIter) {
+	      const int NoeudATraiter = *monIter - 1;
+	      const int Noeud = ele[elt]->getVertex(NoeudATraiter)->getNum();
+	      maMap[medType].push_back(elements[Noeud]);
+           }
+
+	mesFamilles[medType].push_back(famille);
+        }
+  }
+ };
+
+template <class T>
+struct MonTraitement : public MontraitementDeBase<T>{
+  static inline  void AddElement(const T & ele,connectivities  & maMap, connectivities &mesFamilles, numero& elements ,setFamille& numFamilles)
+   {
+	 Msg(GERROR, "Wrong Call : basic Method AddElt");
+   }
+};
+
+template <>
+struct MonTraitement<GVertex> : public MontraitementDeBase<GVertex>{
+  static inline  void AddElement(const GVertex & ele, connectivities  & maMap, connectivities &mesFamilles, numero& elements ,setFamille & numFamilles) {
+  // Pour les Noeuds on ne fait rien ni sur la connectivite ni sur les familles
+  }
+};
+
+template <>
+struct MonTraitement<GEdge> : public MontraitementDeBase<GEdge>{
+  static inline void AddElement(const GEdge & ele, connectivities  & maMap, connectivities &mesFamilles, numero& elements, setFamille & numFamilles) {
+	   RecupereElement (ele.lines,  maMap, mesFamilles, elements, RecupereFamille(ele, numFamilles, 1));
+     }
+};
+
+template <>
+struct MonTraitement<GFace> : public MontraitementDeBase<GFace>{
+  static inline void AddElement(const GFace & ele, connectivities  & maMap, connectivities &mesFamilles, numero& elements , setFamille & numFamilles) {
+	   RecupereElement (ele.triangles,   maMap, mesFamilles, elements, RecupereFamille(ele, numFamilles, 2));
+	   RecupereElement (ele.quadrangles, maMap, mesFamilles, elements, RecupereFamille(ele, numFamilles, 2));
+     }
+};
+
+template <>
+struct MonTraitement<GRegion> : public MontraitementDeBase<GRegion>{
+  static inline void AddElement(const GRegion & ele, connectivities  & maMap, connectivities &mesFamilles, numero& elements, setFamille & numFamilles) {
+	   RecupereElement (ele.tetrahedra, maMap, mesFamilles, elements, RecupereFamille(ele, numFamilles, 3));
+	   RecupereElement (ele.hexahedra,  maMap, mesFamilles, elements, RecupereFamille(ele, numFamilles, 3));
+	   RecupereElement (ele.prisms,     maMap, mesFamilles, elements, RecupereFamille(ele, numFamilles, 3));
+	   RecupereElement (ele.pyramids,   maMap, mesFamilles, elements, RecupereFamille(ele, numFamilles, 3));
+     }
+};
+
+template<class T> struct TraiteFamille
+{
+   static inline int GetFamille (const T& element)
+   {
+     // On ne traite pas les familles d 'elements a ce stade
+     return 0;
+   }
+};
+
+template<>
+struct TraiteFamille<GVertex>
+{
+  static inline int GetFamille (const GVertex& element)
+ {
+     int famille = 0;
+     if (element.physicals.size() != 0 ) famille = element.physicals[0];
+     return famille;
+ }
+};
+
+class MVertex;
+class MEdge;
+class MedIO 
+{
+   public:
+      MedIO();
+      int SetFile     (const std::string& theFileName);
+      int AddVertex   (MVertex* const v, const int famille );
+      int AddEdge     (MEdge* const e );
+      int Ecrit	      ();
+      int CloseFile   ();
+
+   private :
+      int CreateNodeFam();
+      int CreateElemtFam();
+      int CreateElemt();
+
+   private :
+      std::string  _FileName;
+      std::map<med_geometrie_element,std::vector<int> > connectivities;
+      std::map<med_geometrie_element,std::vector<int> > famElts;
+
+      std::vector<med_float> coordonnees;
+      std::vector<int> families;
+      std::vector<med_int> numOpt;
+      std::map<int,int> elements;
+  
+      std::set<int> numFamilles;
+      int _numOfNode;
+
+      int _boolOpen;
+      med_idt _fid;
+      std::string _meshName;
+
+   public : 
+     static ConversionData MyConversionData ;
+    
+      
+template<class T>
+void WriteNodes(const std::set<T*,GEntityLessThan> & seq) 
+{
+  typename std::set<T*,GEntityLessThan>::const_iterator iter=seq.begin();
+
+  for ( ; iter != seq.end() ; ++iter)
+  {
+    const T& element= *(*iter);
+
+    //Msg(INFO," Type d element  %s", typeid(element).name());
+
+    // Traitement des Noeuds
+    // Calcul du nombre de noeuds a stocker dans Med
+    unsigned int thisSize=element.mesh_vertices.size();
+    if (Data::MyConversionData.inMaxEltInMed(element.tag()) == 1) 
+    {
+         const unsigned int maxSize  = Data::MyConversionData.maxEltInMed[element.tag()];
+         if (maxSize < thisSize) thisSize = maxSize ;
+    };
+
+    // stockage du Noeud
+    int famille=TraiteFamille<T>::GetFamille(element);
+    for (unsigned int i = 0; i < thisSize; ++i)
+    {
+    	AddVertex (element.mesh_vertices[i], famille);
+    };
+
+    // Stockage des Egdes
+    MonTraitement<T>::AddElement(element,connectivities,famElts,elements,numFamilles);
+
+  }
+}
+};
+
+
+# endif
+
+#endif
diff --git a/Geo/Makefile b/Geo/Makefile
index 9a52238902e4d15d7b2e12b4aa1c0ee51fbc13f1..cecdcdfb43302aa0ee204190bebcb2891b9df23a 100644
--- a/Geo/Makefile
+++ b/Geo/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.125 2007-01-28 13:56:19 geuzaine Exp $
+# $Id: Makefile,v 1.126 2007-01-29 14:52:57 geuzaine Exp $
 #
 # Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 #
@@ -37,6 +37,7 @@ SRC = GEntity.cpp\
         GModelIO_Fourier.cpp\
         GModelIO_OCC.cpp\
         GModelIO_CGNS.cpp\
+        GModelIO_MED.cpp\
       ExtrudeParams.cpp \
       Geo.cpp \
 	GeoStringInterface.cpp GeoInterpolation.cpp\
diff --git a/Parser/CreateFile.cpp b/Parser/CreateFile.cpp
index 1946f471764e2322864ae3f6a69296085b2e41ef..5483fc65700b7c4a25f218a62339fb7e3580b6a1 100644
--- a/Parser/CreateFile.cpp
+++ b/Parser/CreateFile.cpp
@@ -1,4 +1,4 @@
-// $Id: CreateFile.cpp,v 1.13 2006-12-19 05:22:20 geuzaine Exp $
+// $Id: CreateFile.cpp,v 1.14 2007-01-29 14:52:58 geuzaine Exp $
 //
 // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 //
@@ -60,6 +60,7 @@ int GuessFileFormatFromFileName(char *name)
   else if(!strcmp(ext, ".unv"))  return FORMAT_UNV;
   else if(!strcmp(ext, ".stl"))  return FORMAT_STL;
   else if(!strcmp(ext, ".cgns")) return FORMAT_CGNS;
+  else if(!strcmp(ext, ".med"))  return FORMAT_MED;
   else if(!strcmp(ext, ".mesh")) return FORMAT_MESH;
   else if(!strcmp(ext, ".bdf"))  return FORMAT_BDF;
   else if(!strcmp(ext, ".nas"))  return FORMAT_BDF;
@@ -91,6 +92,7 @@ void GetDefaultFileName(int format, char *name)
   case FORMAT_UNV:  strcpy(ext, ".unv"); break;
   case FORMAT_STL:  strcpy(ext, ".stl"); break;
   case FORMAT_CGNS: strcpy(ext, ".cgns"); break;
+  case FORMAT_MED:  strcpy(ext, ".med"); break;
   case FORMAT_MESH: strcpy(ext, ".mesh"); break;
   case FORMAT_BDF:  strcpy(ext, ".bdf"); break;
   case FORMAT_VRML: strcpy(ext, ".wrl"); break;
@@ -174,6 +176,10 @@ void CreateOutputFile(char *filename, int format)
     GMODEL->writeCGNS(name, CTX.mesh.scaling_factor);
     break;
 
+  case FORMAT_MED:
+    GMODEL->writeMED(name);
+    break;
+
   case FORMAT_POS:
     GMODEL->writePOS(name, CTX.mesh.save_all, CTX.mesh.scaling_factor);
     break;
diff --git a/configure b/configure
index b71734f8641bf8ae9deaf36150fded40803d7dc6..5d02aecd1f809d8aede854befa34be5b1ea6da34 100755
--- a/configure
+++ b/configure
@@ -865,6 +865,7 @@ Optional Features:
   --enable-osmesa         use OSMesa for offscreen rendering (default=no)
   --enable-cgns           enable CGNS output (default=no)
   --enable-occ            enable OpenCascade support (default=no)
+  --enable-med            enable MED support (default=yes)
 
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
@@ -881,6 +882,8 @@ Optional Packages:
                           prefix where OSMesa is installed
   --with-cgns-prefix=PFX  prefix where CGNS is installed
   --with-occ-prefix=PFX   prefix where OpenCascade is installed
+  --with-hdf5-prefix=PFX  prefix where OpenCascade is installed
+  --with-med-prefix=PFX   prefix where OpenCascade is installed
 
 Some influential environment variables:
   CC          C compiler command
@@ -1381,6 +1384,18 @@ if test "${with_occ_prefix+set}" = set; then
   OCC_PREFIX=$withval
 fi;
 
+# Check whether --with-hdf5-prefix or --without-hdf5-prefix was given.
+if test "${with_hdf5_prefix+set}" = set; then
+  withval="$with_hdf5_prefix"
+  HDF5_PREFIX=$withval
+fi;
+
+# Check whether --with-med-prefix or --without-med-prefix was given.
+if test "${with_med_prefix+set}" = set; then
+  withval="$with_med_prefix"
+  MED_PREFIX=$withval
+fi;
+
 # Check whether --enable-gsl or --disable-gsl was given.
 if test "${enable_gsl+set}" = set; then
   enableval="$enable_gsl"
@@ -1465,6 +1480,11 @@ fi;
 if test "${enable_occ+set}" = set; then
   enableval="$enable_occ"
 
+fi;
+# Check whether --enable-med or --disable-med was given.
+if test "${enable_med+set}" = set; then
+  enableval="$enable_med"
+
 fi;
 
 UNAME=`uname`
@@ -4599,6 +4619,165 @@ fi
   fi
 fi
 
+if test "x$enable_med" != "xno"; then
+  if test "x${HDF5_PREFIX}" != "x"; then
+    LDFLAGS="-L${HDF5_PREFIX}/lib ${LDFLAGS}"
+  fi
+  echo "$as_me:$LINENO: checking for main in -lhdf5" >&5
+echo $ECHO_N "checking for main in -lhdf5... $ECHO_C" >&6
+if test "${ac_cv_lib_hdf5_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lhdf5  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_hdf5_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_hdf5_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_hdf5_main" >&5
+echo "${ECHO_T}$ac_cv_lib_hdf5_main" >&6
+if test $ac_cv_lib_hdf5_main = yes; then
+  HDF5="yes"
+else
+  HDF5="no"
+fi
+
+  if test "x${HDF5}" = "xyes"; then
+    if test "x${HDF5_PREFIX}" = "x"; then
+      GMSH_LIBS="${GMSH_LIBS} -lhdf5"
+    else
+      GMSH_LIBS="${GMSH_LIBS} -L${HDF5_PREFIX}/lib -lhdf5"
+      FLAGS="${FLAGS} -I${HDF5_PREFIX}/include"
+    fi
+  fi
+fi
+
+if test "x${HDF5}" = "xyes"; then
+  if test "x$enable_med" != "xno"; then
+    if test "x${MED_PREFIX}" != "x"; then
+      LDFLAGS="-L${MED_PREFIX}/lib ${LDFLAGS}"
+    fi
+    echo "$as_me:$LINENO: checking for main in -lmed" >&5
+echo $ECHO_N "checking for main in -lmed... $ECHO_C" >&6
+if test "${ac_cv_lib_med_main+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lmed  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+int
+main ()
+{
+main ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_med_main=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_med_main=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_med_main" >&5
+echo "${ECHO_T}$ac_cv_lib_med_main" >&6
+if test $ac_cv_lib_med_main = yes; then
+  MED="yes"
+else
+  MED="no"
+fi
+
+    if test "x${MED}" = "xyes"; then
+      if test "x${MED_PREFIX}" = "x"; then
+        GMSH_LIBS="${GMSH_LIBS} -lmed"
+        FLAGS="${FLAGS} -DHAVE_LIBMED"
+      else
+        GMSH_LIBS="${GMSH_LIBS} -L${MED_PREFIX}/lib -lmed"
+        FLAGS="${FLAGS} -DHAVE_LIBMED -I${MED_PREFIX}/include"
+      fi
+    fi
+  fi
+fi
+
 if test "x$enable_parallel" = "xyes"; then
   FLAGS="-DHAVE_PARALLEL ${FLAGS}"
 fi
diff --git a/configure.in b/configure.in
index 714bcb7697e62ddc13d995b200f4cd64f8ba6c08..9fa6e6d3c6b67b5afae699df24c1190709a068c9 100644
--- a/configure.in
+++ b/configure.in
@@ -1,4 +1,4 @@
-dnl $Id: configure.in,v 1.117 2007-01-25 15:50:57 geuzaine Exp $
+dnl $Id: configure.in,v 1.118 2007-01-29 14:52:57 geuzaine Exp $
 dnl
 dnl Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle
 dnl
@@ -61,6 +61,14 @@ AC_ARG_WITH(occ-prefix,
             AC_HELP_STRING([--with-occ-prefix=PFX],
                            [prefix where OpenCascade is installed]),
             [OCC_PREFIX=$withval])
+AC_ARG_WITH(hdf5-prefix,
+            AC_HELP_STRING([--with-hdf5-prefix=PFX],
+                           [prefix where OpenCascade is installed]),
+            [HDF5_PREFIX=$withval])
+AC_ARG_WITH(med-prefix,
+            AC_HELP_STRING([--with-med-prefix=PFX],
+                           [prefix where OpenCascade is installed]),
+            [MED_PREFIX=$withval])
 
 dnl Parse '--enable' command line options
 AC_ARG_ENABLE(gsl,
@@ -114,6 +122,9 @@ AC_ARG_ENABLE(cgns,
 AC_ARG_ENABLE(occ,
               AC_HELP_STRING([--enable-occ],
                              [enable OpenCascade support (default=no)]))
+AC_ARG_ENABLE(med,
+              AC_HELP_STRING([--enable-med],
+                             [enable MED support (default=yes)]))
 
 dnl Get the operating system name
 UNAME=`uname`
@@ -581,6 +592,41 @@ if test "x$enable_occ" = "xyes"; then
   fi
 fi
 
+dnl Check for HDF5 (required by MED)
+if test "x$enable_med" != "xno"; then
+  if test "x${HDF5_PREFIX}" != "x"; then
+    LDFLAGS="-L${HDF5_PREFIX}/lib ${LDFLAGS}"
+  fi
+  AC_CHECK_LIB(hdf5,main,HDF5="yes",HDF5="no")
+  if test "x${HDF5}" = "xyes"; then
+    if test "x${HDF5_PREFIX}" = "x"; then
+      GMSH_LIBS="${GMSH_LIBS} -lhdf5"
+    else
+      GMSH_LIBS="${GMSH_LIBS} -L${HDF5_PREFIX}/lib -lhdf5"
+      FLAGS="${FLAGS} -I${HDF5_PREFIX}/include"
+    fi
+  fi
+fi
+
+dnl Check for MED
+if test "x${HDF5}" = "xyes"; then
+  if test "x$enable_med" != "xno"; then
+    if test "x${MED_PREFIX}" != "x"; then
+      LDFLAGS="-L${MED_PREFIX}/lib ${LDFLAGS}"
+    fi
+    AC_CHECK_LIB(med,main,MED="yes",MED="no")
+    if test "x${MED}" = "xyes"; then
+      if test "x${MED_PREFIX}" = "x"; then
+        GMSH_LIBS="${GMSH_LIBS} -lmed"
+        FLAGS="${FLAGS} -DHAVE_LIBMED"
+      else
+        GMSH_LIBS="${GMSH_LIBS} -L${MED_PREFIX}/lib -lmed"
+        FLAGS="${FLAGS} -DHAVE_LIBMED -I${MED_PREFIX}/include"
+      fi
+    fi
+  fi
+fi
+
 dnl Check if we should build the parallel version
 if test "x$enable_parallel" = "xyes"; then
   FLAGS="-DHAVE_PARALLEL ${FLAGS}"