Salome HOME
Add to med30 convertor.
[tools/medcoupling.git] / src / MEDLoader / MEDFileMesh.cxx
index a2ae032871d70674789e26da910fcacff1ad5cdc..27c1836a55fb40a3fda4eb50e375eaa6272e76cf 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2015  CEA/DEN, EDF R&D
+// Copyright (C) 2007-2020  CEA/DEN, EDF R&D
 //
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // Author : Anthony Geay (CEA/DEN)
 
 #include "MEDFileMesh.hxx"
-#include "MEDFileUtilities.hxx"
 #include "MEDFileFieldOverView.hxx"
 #include "MEDFileField.hxx"
 #include "MEDLoader.hxx"
+#include "MEDLoaderNS.hxx"
 #include "MEDFileSafeCaller.txx"
 #include "MEDLoaderBase.hxx"
 
 #include "MEDCouplingUMesh.hxx"
+#include "MEDCouplingMappedExtrudedMesh.hxx"
+#include "MEDCouplingMemArray.txx"
 
 #include "InterpKernelAutoPtr.hxx"
 
 #include <limits>
 #include <cmath>
 
-extern med_geometry_type typmai3[34];
+// From MEDLOader.cxx TU
+extern med_geometry_type                 typmai[MED_N_CELL_FIXED_GEO];
+extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO];
+extern med_geometry_type typmai3[INTERP_KERNEL::NORM_MAXTYPE];
 
-using namespace ParaMEDMEM;
+using namespace MEDCoupling;
 
 const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO";
 
-MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true)
+const char MEDFileUMesh::SPE_FAM_STR_EXTRUDED_MESH[]="HIDDEN_FAM_EXT_MESH@";
+
+MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true),_axis_type(AX_CART)
 {
 }
 
@@ -52,14 +59,16 @@ std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const
       for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++)
         ret+=(*it2).capacity();
     }
-  for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
-    ret+=(*it).first.capacity()+sizeof(int);
+  for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
+    ret+=(*it).first.capacity()+sizeof(mcIdType);
   return ret;
 }
 
 std::vector<const BigMemoryObject *> MEDFileMesh::getDirectChildrenWithNull() const
 {
-  return std::vector<const BigMemoryObject *>();
+  std::vector<const BigMemoryObject *> ret(1);
+  ret[0]=(const MEDFileEquivalences *)_equiv;
+  return ret;
 }
 
 /*!
@@ -74,40 +83,40 @@ std::vector<const BigMemoryObject *> MEDFileMesh::getDirectChildrenWithNull() co
  */
 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
 {
-  std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
+  MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+  return New(fid,mrs);
+}
+
+MEDFileMesh *MEDFileMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
+{
+  std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
   if(ms.empty())
     {
-      std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << fileName << "\" !";
+      std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << FileNameFromFID(fid) << "\" !";
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
-  MEDFileUtilities::CheckFileForRead(fileName);
-  ParaMEDMEM::MEDCouplingMeshType meshType;
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
+  MEDCoupling::MEDCouplingMeshType meshType;
   int dt,it;
   std::string dummy2;
-  MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
+  MEDCoupling::MEDCouplingAxisType dummy3;
+  MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
+  MCAuto<MEDFileMesh> ret;
   switch(meshType)
   {
     case UNSTRUCTURED:
       {
-        MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
-        ret->loadUMeshFromFile(fid,ms.front(),dt,it,mrs);
-        ret->loadJointsFromFile(fid);
-        return (MEDFileUMesh *)ret.retn();
+        ret=MEDFileUMesh::New();
+        break;
       }
     case CARTESIAN:
       {
-        MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
-        ret->loadCMeshFromFile(fid,ms.front(),dt,it,mrs);
-        ret->loadJointsFromFile(fid);
-        return (MEDFileCMesh *)ret.retn();
+        ret=MEDFileCMesh::New();
+        break;
       }
     case CURVE_LINEAR:
       {
-        MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
-        ret->loadCLMeshFromFile(fid,ms.front(),dt,it,mrs);
-        ret->loadJointsFromFile(fid);
-        return (MEDFileCurveLinearMesh *)ret.retn();
+        ret=MEDFileCurveLinearMesh::New();
+        break;
       }
     default:
       {
@@ -115,6 +124,8 @@ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelect
         throw INTERP_KERNEL::Exception(oss.str().c_str());
       }
   }
+  ret->loadLLWithAdditionalItems(fid,ms.front(),dt,it,mrs);
+  return ret.retn();
 }
 
 /*!
@@ -136,34 +147,34 @@ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelect
  */
 MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints)
 {
-  MEDFileUtilities::CheckFileForRead(fileName);
-  ParaMEDMEM::MEDCouplingMeshType meshType;
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
+  MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+  return New(fid,mName,dt,it,mrs,joints);
+}
+
+MEDFileMesh *MEDFileMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints)
+{
+  MEDCoupling::MEDCouplingMeshType meshType;
   int dummy0,dummy1;
   std::string dummy2;
-  MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2);
+  MEDCoupling::MEDCouplingAxisType dummy3;
+  MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2);
+  MCAuto<MEDFileMesh> ret;
   switch(meshType)
   {
     case UNSTRUCTURED:
       {
-        MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New();
-        ret->loadUMeshFromFile(fid,mName,dt,it,mrs);
-        ret->loadJointsFromFile(fid,joints);
-        return (MEDFileUMesh *)ret.retn();
+        ret=MEDFileUMesh::New();
+        break;
       }
     case CARTESIAN:
       {
-        MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New();
-        ret->loadCMeshFromFile(fid,mName,dt,it,mrs);
-        ret->loadJointsFromFile(fid,joints);
-        return (MEDFileCMesh *)ret.retn();
+        ret=MEDFileCMesh::New();
+        break;
       }
     case CURVE_LINEAR:
       {
-        MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New();
-        ret->loadCLMeshFromFile(fid,mName,dt,it,mrs);
-        ret->loadJointsFromFile(fid,joints);
-        return (MEDFileCurveLinearMesh *)ret.retn();
+        ret=MEDFileCurveLinearMesh::New();
+        break;
       }
     default:
       {
@@ -171,6 +182,8 @@ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mN
         throw INTERP_KERNEL::Exception(oss.str().c_str());
       }
   }
+  ret->loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
+  return ret.retn();
 }
 
 /*!
@@ -180,32 +193,17 @@ MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mN
  *  \throw If the file is open for reading only.
  *  \throw If the writing mode == 1 and the same data is present in an existing file.
  */
-void MEDFileMesh::write(med_idt fid) const
+void MEDFileMesh::writeLL(med_idt fid) const
 {
   if(!existsFamily(0))
     const_cast<MEDFileMesh *>(this)->addFamily(DFT_FAM_NAME,0);
   if(_name.empty())
     throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !");
-  writeLL(fid);
-}
-
-/*!
- * Writes \a this mesh into a MED file specified by its name.
- *  \param [in] fileName - the MED file name.
- *  \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics.
- * - 2 - erase; an existing file is removed.
- * - 1 - append; same data should not be present in an existing file.
- * - 0 - overwrite; same data present in an existing file is overwritten.
- *  \throw If the mesh name is not set.
- *  \throw If \a mode == 1 and the same data is present in an existing file.
- */
-void MEDFileMesh::write(const std::string& fileName, int mode) const
-{
-  med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
-  std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\""; 
-  MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
-  write(fid);
+  writeMeshLL(fid);
+  writeJoints(fid);
+  const MEDFileEquivalences *eqs(_equiv);
+  if(eqs)
+    eqs->writeLL(fid);
 }
 
 /*!
@@ -252,6 +250,8 @@ bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& wha
     return false;
   if(!areFamsEqual(other,what))
     return false;
+  if(!areEquivalencesEqual(other,what))
+    return false;
   return true;
 }
 
@@ -381,7 +381,7 @@ std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std:
  *  \return std::vector<int> - sequence of ids of the families.
  *  \throw If the name of a nonexistent group is specified.
  */
-std::vector<int> MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const
+std::vector<mcIdType> MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const
 {
   std::string oname(name);
   std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname);
@@ -408,7 +408,7 @@ void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector<
   _groups[oname]=fams;
   for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++)
     {
-      std::map<std::string,int>::iterator it2=_families.find(*it1);
+      std::map<std::string,mcIdType>::iterator it2=_families.find(*it1);
       if(it2==_families.end())
         _families[*it1]=0;
     }
@@ -422,12 +422,12 @@ void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector<
  *  \param [in] famIds - a sequence of ids of families constituting the group.
  *  \throw If a family name is not found by its id.
  */
-void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector<int>& famIds)
+void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector<mcIdType>& famIds)
 {
   std::string oname(name);
   std::vector<std::string> fams(famIds.size());
   int i=0;
-  for(std::vector<int>::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++)
+  for(std::vector<mcIdType>::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++)
     {
       std::string name2=getFamilyNameGivenId(*it1);
       fams[i]=name2;
@@ -464,7 +464,7 @@ std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const std::string& name)
 void MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector<std::string>& grps)
 {
   std::string fName(famName);
-  const std::map<std::string,int>::const_iterator it=_families.find(fName);
+  const std::map<std::string,mcIdType>::const_iterator it=_families.find(fName);
   if(it==_families.end())
     {
       std::vector<std::string> fams=getFamiliesNames();
@@ -506,11 +506,117 @@ std::vector<std::string> MEDFileMesh::getFamiliesNames() const
 {
   std::vector<std::string> ret(_families.size());
   int i=0;
-  for(std::map<std::string, int >::const_iterator it=_families.begin();it!=_families.end();it++,i++)
+  for(std::map<std::string, mcIdType >::const_iterator it=_families.begin();it!=_families.end();it++,i++)
     ret[i]=(*it).first;
   return ret;
 }
 
+/*!
+ * Returns names of all families of \a this mesh but like they would be in file.
+ * This method is here only for MED file families gurus. If you are a kind user forget this method :-)
+ * This method is only useful for aggressive users that want to have in their file a same family lying both on cells and on nodes. This is not a good idea for lisibility !
+ * For your information internally in memory such families are renamed to have a nicer API.
+ */
+std::vector<std::string> MEDFileMesh::getFamiliesNamesWithFilePointOfView() const
+{
+  std::vector<std::string> ret(getFamiliesNames());
+  MEDFileMeshL2::RenameFamiliesFromMemToFile(ret);
+  return ret;
+}
+
+/*!
+ * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
+ *  \param [in] meshDimRelToMaxExt - a relative dimension of interest.
+ *  \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
+ *          level. 
+ */
+std::vector<std::string> MEDFileMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const
+{
+  std::vector<std::string> ret;
+  std::vector<std::string> allGrps(getGroupsNames());
+  for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
+    {
+      std::vector<mcIdType> levs(getGrpNonEmptyLevelsExt((*it)));
+      if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
+        ret.push_back(*it);
+    }
+  return ret;
+}
+
+/*!
+ * Returns all relative mesh levels (including nodes) where a given group is defined.
+ *  \param [in] grp - the name of the group of interest.
+ *  \return std::vector<mcIdType> - a sequence of the relative dimensions.
+ */
+std::vector<mcIdType> MEDFileMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const
+{
+  std::vector<std::string> fams(getFamiliesOnGroup(grp));
+  return getFamsNonEmptyLevelsExt(fams);
+}
+
+/*!
+ * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
+ * To include nodes, call getGrpsNonEmptyLevelsExt() method.
+ *  \param [in] grps - a sequence of names of the groups of interest.
+ *  \return std::vector<mcIdType> - a sequence of the relative dimensions.
+ */
+std::vector<mcIdType> MEDFileMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const
+{
+  std::vector<std::string> fams(getFamiliesOnGroups(grps));
+  return getFamsNonEmptyLevels(fams);
+}
+
+/*!
+ * Returns all relative mesh levels (including nodes) where given groups are defined.
+ *  \param [in] grps - a sequence of names of the groups of interest.
+ *  \return std::vector<mcIdType> - a sequence of the relative dimensions.
+ */
+std::vector<mcIdType> MEDFileMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const
+{
+  std::vector<std::string> fams(getFamiliesOnGroups(grps));
+  return getFamsNonEmptyLevelsExt(fams);
+}
+
+/*!
+ * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
+ * To include nodes, call getGrpNonEmptyLevelsExt() method.
+ *  \param [in] grp - the name of the group of interest.
+ *  \return std::vector<mcIdType> - a sequence of the relative dimensions.
+ */
+std::vector<mcIdType> MEDFileMesh::getGrpNonEmptyLevels(const std::string& grp) const
+{
+  std::vector<std::string> fams(getFamiliesOnGroup(grp));
+  return getFamsNonEmptyLevels(fams);
+}
+
+/*!
+ * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
+ * To include nodes, call getFamNonEmptyLevelsExt() method.
+ *  \param [in] fam - the name of the family of interest.
+ *  \return std::vector<mcIdType> - a sequence of the relative dimensions.
+ */
+std::vector<mcIdType> MEDFileMesh::getFamNonEmptyLevels(const std::string& fam) const
+{
+  std::vector<std::string> fams(1,std::string(fam));
+  return getFamsNonEmptyLevels(fams);
+}
+
+/*!
+ * Returns all relative mesh levels (including nodes) where a given family is defined.
+ *  \param [in] fam - the name of the family of interest.
+ *  \return std::vector<mcIdType> - a sequence of the relative dimensions.
+ */
+std::vector<mcIdType> MEDFileMesh::getFamNonEmptyLevelsExt(const std::string& fam) const
+{
+  std::vector<std::string> fams(1,std::string(fam));
+  return getFamsNonEmptyLevelsExt(fams);
+}
+
+std::string MEDFileMesh::GetMagicFamilyStr()
+{
+  return std::string(MEDFileMeshL2::ZE_SEP_FOR_FAMILY_KILLERS);
+}
+
 /*!
  * Changes a name of every family, included in one group only, to be same as the group name.
  *  \throw If there are families with equal names in \a this mesh.
@@ -518,8 +624,8 @@ std::vector<std::string> MEDFileMesh::getFamiliesNames() const
 void MEDFileMesh::assignFamilyNameWithGroupName()
 {
   std::map<std::string, std::vector<std::string> > groups(_groups);
-  std::map<std::string,int> newFams;
-  for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
+  std::map<std::string,mcIdType> newFams;
+  for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
     {
       std::vector<std::string> grps=getGroupsOnFamily((*it).first);
       if(grps.size()==1 && groups[grps[0]].size()==1)
@@ -569,6 +675,35 @@ std::vector<std::string> MEDFileMesh::removeEmptyGroups()
   return ret;
 }
 
+void MEDFileMesh::removeGroupAtLevel(int meshDimRelToMaxExt, const std::string& name)
+{
+  std::map<std::string, std::vector<std::string> >::iterator it(_groups.find(name));
+  std::vector<std::string> grps(getGroupsNames());
+  if(it==_groups.end())
+    {
+      std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
+      std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," "));
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  const std::vector<std::string> &famsOnGrp((*it).second);
+  std::vector<mcIdType> famIds(getFamiliesIdsOnGroup(name));
+  const DataArrayIdType *famArr(getFamilyFieldAtLevel(meshDimRelToMaxExt));
+  if(!famArr)
+    return ;
+  MCAuto<DataArrayIdType> vals(famArr->getDifferentValues());
+  MCAuto<DataArrayIdType> famIds2(DataArrayIdType::NewFromStdVector(famIds));
+  MCAuto<DataArrayIdType> idsToKill(famIds2->buildIntersection(vals));
+  if(idsToKill->empty())
+    return ;
+  std::vector<std::string> newFamsOnGrp;
+  for(std::vector<std::string>::const_iterator itt=famsOnGrp.begin();itt!=famsOnGrp.end();itt++)
+    {
+      if(!idsToKill->presenceOfValue(getFamilyId(*itt)))
+         newFamsOnGrp.push_back(*itt);
+    }
+  (*it).second=newFamsOnGrp;
+}
+
 /*!
  * Removes a group from \a this mesh.
  *  \param [in] name - the name of the group to remove.
@@ -576,9 +711,8 @@ std::vector<std::string> MEDFileMesh::removeEmptyGroups()
  */
 void MEDFileMesh::removeGroup(const std::string& name)
 {
-  std::string oname(name);
-  std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname);
-  std::vector<std::string> grps=getGroupsNames();
+  std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(name);
+  std::vector<std::string> grps(getGroupsNames());
   if(it==_groups.end())
     {
       std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :";
@@ -596,7 +730,7 @@ void MEDFileMesh::removeGroup(const std::string& name)
 void MEDFileMesh::removeFamily(const std::string& name)
 {
   std::string oname(name);
-  std::map<std::string, int >::iterator it=_families.find(oname);
+  std::map<std::string, mcIdType >::iterator it=_families.find(oname);
   std::vector<std::string> fams=getFamiliesNames();
   if(it==_families.end())
     {
@@ -634,21 +768,21 @@ std::vector<std::string> MEDFileMesh::removeOrphanGroups()
  * family field whatever its level. Groups are updated in consequence, that is to say all groups lying on orphan family, will see their families list modified.
  * 
  * \return - The list of removed families names.
- * \sa MEDFileMesh::removeOrphanGroups.
+ * \sa MEDFileMesh::removeOrphanGroups , MEDFileMesh::removeFamiliesReferedByNoGroups
  */
 std::vector<std::string> MEDFileMesh::removeOrphanFamilies()
 {
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allFamIdsInUse=computeAllFamilyIdsInUse();
+  MCAuto<DataArrayIdType> allFamIdsInUse=computeAllFamilyIdsInUse();
   std::vector<std::string> ret;
-  if(!((DataArrayInt*)allFamIdsInUse))
+  if(!((DataArrayIdType*)allFamIdsInUse))
     {
       ret=getFamiliesNames();
       _families.clear(); _groups.clear();
       return ret;
     }
-  std::map<std::string,int> famMap;
+  std::map<std::string,mcIdType> famMap;
   std::map<std::string, std::vector<std::string> > grps(_groups);
-  for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
+  for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
     {
       if(allFamIdsInUse->presenceOfValue((*it).second))
         famMap[(*it).first]=(*it).second;
@@ -675,12 +809,13 @@ std::vector<std::string> MEDFileMesh::removeOrphanFamilies()
  * this family is orphan or not.
  *
  * \warning this method is different from removeOrphanFamilies that scans family field array to find orphan families.
+ * \sa MEDFileMesh::removeOrphanFamilies
  */
 void MEDFileMesh::removeFamiliesReferedByNoGroups()
 {
-  std::map<std::string,int> fams;
+  std::map<std::string,mcIdType> fams;
   std::set<std::string> sfams;
-  for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
+  for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
     sfams.insert((*it).first);
   for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
     for(std::vector<std::string>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++)
@@ -691,11 +826,13 @@ void MEDFileMesh::removeFamiliesReferedByNoGroups()
 }
 
 /*!
- * This method has no impact on groups. This method only works on families. This method firstly removes families not refered by any groups in \a this, then all unused entities
+ * This method has no impact on groups. This method only works on families. This method firstly removes families not referred by any groups in \a this, then all unused entities
  * are put as belonging to family 0 ("FAMILLE_ZERO"). Finally, all orphanFamilies are killed.
  * This method raises an exception if "FAMILLE_ZERO" is already belonging to a group.
+ * 
+ * This method also raises an exception if a family belonging to a group has also id 0 (which is not right in MED file format). You should never encounter this case using addGroup method.
  *
- * \sa MEDFileMesh::removeOrphanFamilies
+ * \sa MEDFileMesh::removeOrphanFamilies, MEDFileMesh::zipFamilies
  */
 void MEDFileMesh::rearrangeFamilies()
 {
@@ -703,26 +840,36 @@ void MEDFileMesh::rearrangeFamilies()
   removeFamiliesReferedByNoGroups();
   //
   std::vector<int> levels(getNonEmptyLevelsExt());
-  std::set<int> idsRefed;
-  for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
-    idsRefed.insert((*it).second);
+  std::set<mcIdType> idsRefed;
+  for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
+    {
+      idsRefed.insert((*it).second);
+      if((*it).second==0)
+        {
+          if(!getGroupsOnFamily((*it).first).empty())
+            {
+              std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Not orphan family \"" << (*it).first << "\" has id 0 ! This method may alterate groups in this for such a case !";
+              throw INTERP_KERNEL::Exception(oss.str());
+            }
+        }
+    }
   for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
     {
-      const DataArrayInt *fams(0);
+      const DataArrayIdType *fams(0);
       try
       {
           fams=getFamilyFieldAtLevel(*it);
       }
-      catch(INTERP_KERNEL::Exception& e) { }
+      catch(INTERP_KERNEL::Exception& ) { }
       if(!fams)
         continue;
       std::vector<bool> v(fams->getNumberOfTuples(),false);
-      for(std::set<int>::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++)
+      for(std::set<mcIdType>::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++)
         fams->switchOnTupleEqualTo(*pt,v);
-      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> unfetchedIds(DataArrayInt::BuildListOfSwitchedOff(v));
+      MCAuto<DataArrayIdType> unfetchedIds(DataArrayIdType::BuildListOfSwitchedOff(v));
       if(!unfetchedIds->empty())
         {
-          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFams(fams->deepCpy());
+          MCAuto<DataArrayIdType> newFams(fams->deepCopy());
           newFams->setPartOfValuesSimple3(0,unfetchedIds->begin(),unfetchedIds->end(),0,1,1);
           setFamilyFieldArr(*it,newFams);
         }
@@ -730,6 +877,83 @@ void MEDFileMesh::rearrangeFamilies()
   removeOrphanFamilies();
 }
 
+/*!
+ * This method has no impact on existing groups. This method has only impact on families behind the groups.
+ * This method is especially useful for MED file structures having used too much families to define their groups and that need to be merged without modification of their groups.
+ * To zip families, firstly this method first removes families refered by no groups (see MEDFileMesh::removeFamiliesReferedByNoGroups), then this method puts together families lying on a same set of groups. If the set of families having same groups has a length higher than 1, the families are merged into a single family
+ * having the name of the first family appearing in family definition and with the corresponding family ID.
+ */
+void MEDFileMesh::zipFamilies()
+{
+  checkOrphanFamilyZero();
+  removeFamiliesReferedByNoGroups();
+  std::map< std::set<std::string> , std::vector<std::string> > setOfFamilies;
+  // firstly, store in setOfFamilies as key the common set of groups, and as value the families having such same set of groups
+  for(auto fam : _families)
+    {
+      std::vector<std::string> grps( this->getGroupsOnFamily( fam.first ) );
+      std::set<std::string> sgrps(grps.begin(),grps.end());
+      setOfFamilies[sgrps].push_back(fam.first);
+    }
+  //
+  std::map<std::string, std::vector<std::string> > newGroups(_groups);
+  std::map<std::string,mcIdType> newFams(_families);
+  std::vector<int> levels(getNonEmptyLevelsExt());
+  std::map<mcIdType, std::vector<mcIdType> > famIdsToSubstitute;
+  // iterate on all different set of groups
+  std::set<std::string> familiesToKill;
+  for(auto setOfCommonGrp : setOfFamilies)
+    {
+      if( setOfCommonGrp.second.size()<=1 )
+        continue;
+      for(auto fam=setOfCommonGrp.second.begin()+1 ; fam != setOfCommonGrp.second.end() ; fam++)
+        familiesToKill.insert(*fam);
+    }
+  // iterate on all different set of groups
+  for(auto setOfCommonGrp : setOfFamilies)
+    {
+      if( setOfCommonGrp.second.size()<=1 )
+        continue;
+      std::string newFamName(setOfCommonGrp.second[0]);
+      auto newFamID(_families[newFamName]);
+      for(auto grpToBeModified : setOfCommonGrp.first)
+        {
+          std::vector<std::string> newFamiliesForCurGrp(1,newFamName);
+          const std::vector<std::string>& familiesOnCurGrp(_groups[grpToBeModified]);
+          const std::vector<std::string>& familiesToZip(setOfCommonGrp.second);
+          std::for_each(familiesToZip.begin(),familiesToZip.end(),[&famIdsToSubstitute,this,newFamID](const std::string& elt) { famIdsToSubstitute[newFamID].push_back(this->getFamilyId(elt)); });
+          // for each family shared by the current group only keep those not sharing setOfCommonGrp.second
+          std::for_each(familiesOnCurGrp.begin(),familiesOnCurGrp.end(),[&familiesToKill,&newFamiliesForCurGrp](const std::string& elt)
+                        { if( familiesToKill.find(elt) == familiesToKill.end() ) { newFamiliesForCurGrp.push_back(elt); } });
+          newGroups[grpToBeModified] = newFamiliesForCurGrp;
+        }
+      for(auto familyToKill = setOfCommonGrp.second.begin()+1 ; familyToKill != setOfCommonGrp.second.end(); ++familyToKill)
+        {
+          newFams.erase( newFams.find(*familyToKill) );
+        }
+      
+    }
+  // apply modifications in datastructure
+  for(auto famIdsSubstSession : famIdsToSubstitute)
+    {
+      for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++)
+        {
+          DataArrayIdType *fams(nullptr);
+          try
+            {
+              fams=getFamilyFieldAtLevel(*it);
+            }
+          catch(INTERP_KERNEL::Exception& ) { }
+          if(!fams)
+            continue;
+          MCAuto<DataArrayIdType> idsToModif(fams->findIdsEqualList(famIdsSubstSession.second.data(),famIdsSubstSession.second.data()+famIdsSubstSession.second.size()));
+          fams->setPartOfValuesSimple3(famIdsSubstSession.first,idsToModif->begin(),idsToModif->end(),0,1,1);
+        }
+    }
+  _groups = newGroups;
+  _families = newFams;
+}
+
 /*!
  * This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group).
  */
@@ -781,11 +1005,11 @@ void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string&
  *  \param [in] oldId - a current id of the family.
  *  \param [in] newId - a new family id.
  */
-void MEDFileMesh::changeFamilyId(int oldId, int newId)
+void MEDFileMesh::changeFamilyId(mcIdType oldId, mcIdType newId)
 {
   changeFamilyIdArr(oldId,newId);
-  std::map<std::string,int> fam2;
-  for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
+  std::map<std::string,mcIdType> fam2;
+  for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
     {
       if((*it).second==oldId)
         fam2[(*it).first]=newId;
@@ -805,7 +1029,7 @@ void MEDFileMesh::changeFamilyId(int oldId, int newId)
 void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName)
 {
   std::string oname(oldName);
-  std::map<std::string, int >::iterator it=_families.find(oname);
+  std::map<std::string, mcIdType >::iterator it=_families.find(oname);
   std::vector<std::string> fams=getFamiliesNames();
   if(it==_families.end())
     {
@@ -814,13 +1038,13 @@ void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
   std::string nname(newName);
-  std::map<std::string, int >::iterator it2=_families.find(nname);
+  std::map<std::string, mcIdType >::iterator it2=_families.find(nname);
   if(it2!=_families.end())
     {
       std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !";
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
-  int cpy=(*it).second;
+  mcIdType cpy=(*it).second;
   _families.erase(it);
   _families[newName]=cpy;
   for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++)
@@ -843,12 +1067,12 @@ bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) cons
 {
   if(_families==other->_families)
     return true;
-  std::map<std::string,int> fam0;
-  std::map<std::string,int> fam1;
-  for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
+  std::map<std::string,mcIdType> fam0;
+  std::map<std::string,mcIdType> fam1;
+  for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
     if((*it).second!=0)
       fam0[(*it).first]=(*it).second;
-  for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
+  for(std::map<std::string,mcIdType>::const_iterator it=other->_families.begin();it!=other->_families.end();it++)
     if((*it).second!=0)
       fam1[(*it).first]=(*it).second;
   return fam0==fam1;
@@ -930,9 +1154,9 @@ bool MEDFileMesh::existsGroup(const std::string& groupName) const
  *  \param [in] famId - the family id.
  *  \return bool - \c true the family with the id \a famId exists in \a this mesh.
  */
-bool MEDFileMesh::existsFamily(int famId) const
+bool MEDFileMesh::existsFamily(mcIdType famId) const
 {
-  for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
+  for(std::map<std::string,mcIdType>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
     if((*it2).second==famId)
       return true;
   return false;
@@ -954,16 +1178,16 @@ bool MEDFileMesh::existsFamily(const std::string& familyName) const
  *  \param [in] familyName - the family name.
  *  \param [in] id - a new id of the family.
  */
-void MEDFileMesh::setFamilyId(const std::string& familyName, int id)
+void MEDFileMesh::setFamilyId(const std::string& familyName, mcIdType id)
 {
   std::string fname(familyName);
   _families[fname]=id;
 }
 
-void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id)
+void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, mcIdType id)
 {
   std::string fname(familyName);
-  for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
+  for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
     if((*it).second==id)
       {
         if((*it).first!=familyName)
@@ -981,13 +1205,13 @@ void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id)
  *  \param [in] famId - an id of the family.
  *  \throw If a family with the same name or id already exists in \a this mesh.
  */
-void MEDFileMesh::addFamily(const std::string& familyName, int famId)
+void MEDFileMesh::addFamily(const std::string& familyName, mcIdType famId)
 {
   std::string fname(familyName);
-  std::map<std::string,int>::const_iterator it=_families.find(fname);
+  std::map<std::string,mcIdType>::const_iterator it=_families.find(fname);
   if(it==_families.end())
     {
-      for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
+      for(std::map<std::string,mcIdType>::const_iterator it2=_families.begin();it2!=_families.end();it2++)
         if((*it2).second==famId)
           {
             std::ostringstream oss;
@@ -1039,12 +1263,12 @@ void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& gr
       oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !";
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
-  const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
+  const DataArrayIdType *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt);
   if(fieldFamIds==0)
     throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !");
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=fieldFamIds->getDifferentValues();
+  MCAuto<DataArrayIdType> famIds=fieldFamIds->getDifferentValues();
   std::vector<std::string> familiesOnWholeGroup;
-  for(const int *it=famIds->begin();it!=famIds->end();it++)
+  for(const mcIdType *it=famIds->begin();it!=famIds->end();it++)
     {
       bool tmp;
       familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp));
@@ -1061,28 +1285,28 @@ void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& gr
  *          famIds should exclusively belong.
  *  \return bool - \c true if no modification is done in \a this mesh by this method.
  */
-bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
+bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<mcIdType>& famIds, const std::vector<int>& vMeshDimRelToMaxExt)
 {
   std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end());
   std::vector<int> levs=getNonEmptyLevelsExt();
   std::set<int> levs2(levs.begin(),levs.end());
   std::vector<int> levsToTest;
   std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest));
-  std::set<int> famIds2(famIds.begin(),famIds.end());
+  std::set<mcIdType> famIds2(famIds.begin(),famIds.end());
   bool ret=true;
-  int maxFamId=1;
+  mcIdType maxFamId=1;
   if(!_families.empty())
     maxFamId=getMaxFamilyId()+1;
   std::vector<std::string> allFams=getFamiliesNames();
   for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++)
     {
-      const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it);
+      const DataArrayIdType *fieldFamIds=getFamilyFieldAtLevel(*it);
       if(fieldFamIds)
         {
-          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds3=fieldFamIds->getDifferentValues();
-          std::vector<int> tmp;
-          std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp));
-          for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
+          MCAuto<DataArrayIdType> famIds3=fieldFamIds->getDifferentValues();
+          std::vector<mcIdType> tmp;
+          std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<mcIdType> >(tmp));
+          for(std::vector<mcIdType>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++)
             {
               ret=false;
               std::string famName=getFamilyNameGivenId(*it2);
@@ -1090,7 +1314,7 @@ bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std
               std::string zeName=CreateNameNotIn(oss.str(),allFams);
               addFamilyOnAllGroupsHaving(famName,zeName);
               _families[zeName]=maxFamId;
-              (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId);
+              (const_cast<DataArrayIdType *>(fieldFamIds))->changeValue(*it2,maxFamId);
               maxFamId++;
             }
         }
@@ -1152,11 +1376,24 @@ void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const s
     }
 }
 
+void MEDFileMesh::checkNoGroupClash(const DataArrayIdType *famArr, const std::string& grpName) const
+{
+  std::vector<std::string> grpsNames(getGroupsNames());
+  if(std::find(grpsNames.begin(),grpsNames.end(),grpName)==grpsNames.end())
+    return ;
+  std::vector<mcIdType> famIds(getFamiliesIdsOnGroup(grpName));
+  if(famArr->presenceOfValue(famIds))
+    {
+      std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists at specified level ! Destroy it before calling this method !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+}
+
 /*!
  * \param [in] ids ids and group name of the new group to add. The ids should be sorted and different each other (MED file norm).
- * \parma [in,out] famArr family array on level of interest to be renumbered. The input pointer should be not \c NULL (no check of that will be performed)
+ * \param [in,out] famArr family array on level of interest to be renumbered. The input pointer should be not \c NULL (no check of that will be performed)
  */
-void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr)
+void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayIdType *ids, DataArrayIdType *famArr)
 {
   if(!ids)
     throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !");
@@ -1164,36 +1401,31 @@ void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids,
   if(grpName.empty())
     throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !");
   ids->checkStrictlyMonotonic(true);
-  famArr->incrRef(); MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famArrTmp(famArr);
-  std::vector<std::string> grpsNames=getGroupsNames();
-  if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end())
-    {
-      std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !";
-      throw INTERP_KERNEL::Exception(oss.str().c_str());
-    }
-  std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > allFamIds(getAllNonNullFamilyIds());
+  checkNoGroupClash(famArr,grpName);
+  MCAuto<DataArrayIdType> famArrTmp; famArrTmp.takeRef(famArr);
+  std::list< MCAuto<DataArrayIdType> > allFamIds(getAllNonNullFamilyIds());
   allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp));
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diffFamIds=famIds->getDifferentValues();
-  std::vector<int> familyIds;
-  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerfamiliyIds;
-  int maxVal=getTheMaxAbsFamilyId()+1;
-  std::map<std::string,int> families(_families);
+  MCAuto<DataArrayIdType> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end());
+  MCAuto<DataArrayIdType> diffFamIds=famIds->getDifferentValues();
+  std::vector<mcIdType> familyIds;
+  std::vector< MCAuto<DataArrayIdType> > idsPerfamiliyIds;
+  mcIdType maxVal=getTheMaxAbsFamilyId()+1;
+  std::map<std::string,mcIdType> families(_families);
   std::map<std::string, std::vector<std::string> > groups(_groups);
   std::vector<std::string> fams;
   bool created(false);
-  for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
+  for(const mcIdType *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++)
     {
-      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2Tmp=famIds->getIdsEqual(*famId);
-      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
-      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1=famArr->getIdsEqual(*famId);
-      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2));
+      MCAuto<DataArrayIdType> ids2Tmp=famIds->findIdsEqual(*famId);
+      MCAuto<DataArrayIdType> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end());
+      MCAuto<DataArrayIdType> ids1=famArr->findIdsEqual(*famId);
+      MCAuto<DataArrayIdType> ret0(ids1->buildSubstractionOptimized(ids2));
       if(ret0->empty())
         {
           bool isFamPresent=false;
-          for(std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
+          for(std::list< MCAuto<DataArrayIdType> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++)
             isFamPresent=(*itl)->presenceOfValue(*famId);
-          if(!isFamPresent)
+          if(!isFamPresent && *famId!=0)
             { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp
           else
             {
@@ -1223,12 +1455,19 @@ void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids,
     }
   for(std::size_t i=0;i<familyIds.size();i++)
     {
-      DataArrayInt *da=idsPerfamiliyIds[i];
+      DataArrayIdType *da=idsPerfamiliyIds[i];
       famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1);
     }
   _families=families;
+  std::map<std::string, std::vector<std::string> >::iterator itt(groups.find(grpName));
+  if(itt!=groups.end())
+    {
+      std::vector<std::string>& famsOnGrp((*itt).second);
+      famsOnGrp.insert(famsOnGrp.end(),fams.begin(),fams.end());
+    }
+  else
+    groups[grpName]=fams;
   _groups=groups;
-  _groups[grpName]=fams;
 }
 
 void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames)
@@ -1259,7 +1498,7 @@ void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vec
  *  \return std::string - the name of the existing or the created family.
  *  \throw If it is not possible to create a unique family name.
  */
-std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created)
+std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(mcIdType id, bool& created)
 {
   return FindOrCreateAndGiveFamilyWithId(_families,id,created);
 }
@@ -1272,11 +1511,11 @@ std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created)
  * will be modified.
  * This method will throws an exception if it is not possible to create a unique family name.
  */
-std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created)
+std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,mcIdType>& families, mcIdType id, bool& created)
 {
   std::vector<std::string> famAlreadyExisting(families.size());
   int ii=0;
-  for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++)
+  for(std::map<std::string,mcIdType>::const_iterator it=families.begin();it!=families.end();it++,ii++)
     {
       if((*it).second!=id)
         {
@@ -1299,7 +1538,7 @@ std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,in
  * Sets names and ids of all families in \a this mesh.
  *  \param [in] info - a map of a family name to a family id.
  */
-void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info)
+void MEDFileMesh::setFamilyInfo(const std::map<std::string,mcIdType>& info)
 {
   _families=info;
 }
@@ -1317,16 +1556,15 @@ void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::stri
 /*!
  * Returns an id of the family having a given name.
  *  \param [in] name - the name of the family of interest.
- *  \return int - the id of the family of interest.
+ *  \return mcIdType - the id of the family of interest.
  *  \throw If no family with such a \a name exists.
  */
-int MEDFileMesh::getFamilyId(const std::string& name) const
+mcIdType MEDFileMesh::getFamilyId(const std::string& name) const
 {
-  std::string oname(name);
-  std::map<std::string, int>::const_iterator it=_families.find(oname);
-  std::vector<std::string> fams=getFamiliesNames();
+  std::map<std::string, mcIdType>::const_iterator it=_families.find(name);
   if(it==_families.end())
     {
+      std::vector<std::string> fams(getFamiliesNames());
       std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :";
       std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," "));
       throw INTERP_KERNEL::Exception(oss.str().c_str());
@@ -1337,16 +1575,16 @@ int MEDFileMesh::getFamilyId(const std::string& name) const
 /*!
  * Returns ids of the families having given names.
  *  \param [in] fams - a sequence of the names of families of interest.
- *  \return std::vector<int> - a sequence of the ids of families of interest.
+ *  \return std::vector<mcIdType> - a sequence of the ids of families of interest.
  *  \throw If \a fams contains a name of an inexistent family.
  */
-std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
+std::vector<mcIdType> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const
 {
-  std::vector<int> ret(fams.size());
+  std::vector<mcIdType> ret(fams.size());
   int i=0;
   for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++)
     {
-      std::map<std::string, int>::const_iterator it2=_families.find(*it);
+      std::map<std::string, mcIdType>::const_iterator it2=_families.find(*it);
       if(it2==_families.end())
         {
           std::vector<std::string> fams2=getFamiliesNames();
@@ -1361,15 +1599,15 @@ std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fam
 
 /*!
  * Returns a maximal abs(id) of families in \a this mesh.
- *  \return int - the maximal norm of family id.
+ *  \return mcIdType - the maximal norm of family id.
  *  \throw If there are no families in \a this mesh.
  */
-int MEDFileMesh::getMaxAbsFamilyId() const
+mcIdType MEDFileMesh::getMaxAbsFamilyId() const
 {
   if(_families.empty())
     throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
-  int ret=-std::numeric_limits<int>::max();
-  for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
+  mcIdType ret=-std::numeric_limits<mcIdType>::max();
+  for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
     {
       ret=std::max(std::abs((*it).second),ret);
     }
@@ -1378,15 +1616,15 @@ int MEDFileMesh::getMaxAbsFamilyId() const
 
 /*!
  * Returns a maximal id of families in \a this mesh.
- *  \return int - the maximal family id.
+ *  \return mcIdType - the maximal family id.
  *  \throw If there are no families in \a this mesh.
  */
-int MEDFileMesh::getMaxFamilyId() const
+mcIdType MEDFileMesh::getMaxFamilyId() const
 {
   if(_families.empty())
     throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !");
-  int ret=-std::numeric_limits<int>::max();
-  for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
+  mcIdType ret=-std::numeric_limits<mcIdType>::max();
+  for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
     {
       ret=std::max((*it).second,ret);
     }
@@ -1395,15 +1633,15 @@ int MEDFileMesh::getMaxFamilyId() const
 
 /*!
  * Returns a minimal id of families in \a this mesh.
- *  \return int - the minimal family id.
+ *  \return mcIdType - the minimal family id.
  *  \throw If there are no families in \a this mesh.
  */
-int MEDFileMesh::getMinFamilyId() const
+mcIdType MEDFileMesh::getMinFamilyId() const
 {
   if(_families.empty())
     throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !");
-  int ret=std::numeric_limits<int>::max();
-  for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
+  mcIdType ret=std::numeric_limits<mcIdType>::max();
+  for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
     {
       ret=std::min((*it).second,ret);
     }
@@ -1413,42 +1651,42 @@ int MEDFileMesh::getMinFamilyId() const
 /*!
  * Returns a maximal id of families in \a this mesh. Not only named families are
  * considered but all family fields as well.
- *  \return int - the maximal family id.
+ *  \return mcIdType - the maximal family id.
  */
-int MEDFileMesh::getTheMaxAbsFamilyId() const
+mcIdType MEDFileMesh::getTheMaxAbsFamilyId() const
 {
-  int m1=-std::numeric_limits<int>::max();
-  for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
+  mcIdType m1=-std::numeric_limits<mcIdType>::max();
+  for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
     m1=std::max(std::abs((*it).second),m1);
-  int m2=getMaxAbsFamilyIdInArrays();
+  mcIdType m2=getMaxAbsFamilyIdInArrays();
   return std::max(m1,m2);
 }
 
 /*!
  * Returns a maximal id of families in \a this mesh. Not only named families are
  * considered but all family fields as well.
- *  \return int - the maximal family id.
+ *  \return mcIdType - the maximal family id.
  */
-int MEDFileMesh::getTheMaxFamilyId() const
+mcIdType MEDFileMesh::getTheMaxFamilyId() const
 {
-  int m1=-std::numeric_limits<int>::max();
-  for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
+  mcIdType m1=-std::numeric_limits<mcIdType>::max();
+  for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
     m1=std::max((*it).second,m1);
-  int m2=getMaxFamilyIdInArrays();
+  mcIdType m2=getMaxFamilyIdInArrays();
   return std::max(m1,m2);
 }
 
 /*!
  * Returns a minimal id of families in \a this mesh. Not only named families are
  * considered but all family fields as well.
- *  \return int - the minimal family id.
+ *  \return mcIdType - the minimal family id.
  */
-int MEDFileMesh::getTheMinFamilyId() const
+mcIdType MEDFileMesh::getTheMinFamilyId() const
 {
-  int m1=std::numeric_limits<int>::max();
-  for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
+  mcIdType m1=std::numeric_limits<mcIdType>::max();
+  for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
     m1=std::min((*it).second,m1);
-  int m2=getMinFamilyIdInArrays();
+  mcIdType m2=getMinFamilyIdInArrays();
   return std::min(m1,m2);
 }
 
@@ -1457,13 +1695,13 @@ int MEDFileMesh::getTheMinFamilyId() const
  * 
  * \sa MEDFileMesh::computeAllFamilyIdsInUse
  */
-DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const
+DataArrayIdType *MEDFileMesh::getAllFamiliesIdsReferenced() const
 {
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
-  std::set<int> v;
-  for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
+  MCAuto<DataArrayIdType> ret=DataArrayIdType::New();
+  std::set<mcIdType> v;
+  for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
     v.insert((*it).second);
-  ret->alloc((int)v.size(),1);
+  ret->alloc((mcIdType)v.size(),1);
   std::copy(v.begin(),v.end(),ret->getPointer());
   return ret.retn();
 }
@@ -1473,15 +1711,15 @@ DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const
  * 
  * \sa MEDFileMesh::getAllFamiliesIdsReferenced
  */
-DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const
+DataArrayIdType *MEDFileMesh::computeAllFamilyIdsInUse() const
 {
   std::vector<int> famLevs=getFamArrNonEmptyLevelsExt();
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret;
+  MCAuto<DataArrayIdType> ret;
   for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++)
     {
-      const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
-      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dv=arr->getDifferentValues();
-      if((DataArrayInt *) ret)
+      const DataArrayIdType *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt
+      MCAuto<DataArrayIdType> dv=arr->getDifferentValues();
+      if((DataArrayIdType *) ret)
         ret=dv->buildUnion(ret);
       else
         ret=dv;
@@ -1496,32 +1734,32 @@ DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const
 bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
 {
   std::vector<int> levs=getNonEmptyLevelsExt();
-  std::set<int> allFamIds;
-  int maxId=getMaxFamilyId()+1;
-  std::map<int,std::vector<int> > famIdsToRenum;
+  std::set<mcIdType> allFamIds;
+  mcIdType maxId=getMaxFamilyId()+1;
+  std::map<int,std::vector<mcIdType> > famIdsToRenum;
   for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
     {
-      const DataArrayInt *fam=getFamilyFieldAtLevel(*it);
+      const DataArrayIdType *fam=getFamilyFieldAtLevel(*it);
       if(fam)
         {
-          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
-          std::set<int> r2;
+          MCAuto<DataArrayIdType> tmp=fam->getDifferentValues();
+          std::set<mcIdType> r2;
           std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end()));
           if(!r2.empty())
             famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end());
-          std::set<int> r3;
+          std::set<mcIdType> r3;
           std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end()));
         }
     }
   if(famIdsToRenum.empty())
     return true;
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
-  for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
+  MCAuto<DataArrayIdType> allIds=getAllFamiliesIdsReferenced();
+  for(std::map<int,std::vector<mcIdType> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++)
     {
-      DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first));
-      int *famIdsToChange=fam->getPointer();
-      std::map<int,int> ren;
-      for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
+      DataArrayIdType *fam=const_cast<DataArrayIdType *>(getFamilyFieldAtLevel((*it2).first));
+      mcIdType *famIdsToChange=fam->getPointer();
+      std::map<mcIdType,mcIdType> ren;
+      for(std::vector<mcIdType>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++)
         {
           if(allIds->presenceOfValue(*it3))
             {
@@ -1534,8 +1772,8 @@ bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
                 addFamilyOnGrp((*it4),newFam);
             }
         }
-      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
-      for(const int *id=ids->begin();id!=ids->end();id++)
+      MCAuto<DataArrayIdType> ids=fam->findIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size());
+      for(const mcIdType *id=ids->begin();id!=ids->end();id++)
         famIdsToChange[*id]=ren[famIdsToChange[*id]];
     }
   return false;
@@ -1551,27 +1789,27 @@ bool MEDFileMesh::ensureDifferentFamIdsPerLevel()
 void MEDFileMesh::normalizeFamIdsTrio()
 {
   ensureDifferentFamIdsPerLevel();
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
+  MCAuto<DataArrayIdType> allIds=getAllFamiliesIdsReferenced();
   std::vector<int> levs=getNonEmptyLevelsExt();
   std::set<int> levsS(levs.begin(),levs.end());
   std::set<std::string> famsFetched;
-  std::map<std::string,int> families;
+  std::map<std::string,mcIdType> families;
   if(std::find(levs.begin(),levs.end(),0)!=levs.end())
     {
       levsS.erase(0);
-      const DataArrayInt *fam=getFamilyFieldAtLevel(0);
+      const DataArrayIdType *fam=getFamilyFieldAtLevel(0);
       if(fam)
         {
-          int refId=1;
-          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
-          std::map<int,int> ren;
-          for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
+          mcIdType refId=1;
+          MCAuto<DataArrayIdType> tmp=fam->getDifferentValues();
+          std::map<mcIdType,mcIdType> ren;
+          for(const mcIdType *it=tmp->begin();it!=tmp->end();it++,refId++)
             ren[*it]=refId;
-          int nbOfTuples=fam->getNumberOfTuples();
-          int *start=const_cast<DataArrayInt *>(fam)->getPointer();
-          for(int *w=start;w!=start+nbOfTuples;w++)
+          mcIdType nbOfTuples=fam->getNumberOfTuples();
+          mcIdType *start=const_cast<DataArrayIdType *>(fam)->getPointer();
+          for(mcIdType *w=start;w!=start+nbOfTuples;w++)
             *w=ren[*w];
-          for(const int *it=tmp->begin();it!=tmp->end();it++)
+          for(const mcIdType *it=tmp->begin();it!=tmp->end();it++)
             {
               if(allIds->presenceOfValue(*it))
                 {
@@ -1585,19 +1823,19 @@ void MEDFileMesh::normalizeFamIdsTrio()
   if(std::find(levs.begin(),levs.end(),-1)!=levs.end())
     {
       levsS.erase(-1);
-      const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
+      const DataArrayIdType *fam=getFamilyFieldAtLevel(-1);
       if(fam)
         {
-          int refId=-1;
-          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
-          std::map<int,int> ren;
-          for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
+          mcIdType refId=-1;
+          MCAuto<DataArrayIdType> tmp=fam->getDifferentValues();
+          std::map<mcIdType,mcIdType> ren;
+          for(const mcIdType *it=tmp->begin();it!=tmp->end();it++,refId--)
             ren[*it]=refId;
-          int nbOfTuples=fam->getNumberOfTuples();
-          int *start=const_cast<DataArrayInt *>(fam)->getPointer();
-          for(int *w=start;w!=start+nbOfTuples;w++)
+          mcIdType nbOfTuples=fam->getNumberOfTuples();
+          mcIdType *start=const_cast<DataArrayIdType *>(fam)->getPointer();
+          for(mcIdType *w=start;w!=start+nbOfTuples;w++)
             *w=ren[*w];
-          for(const int *it=tmp->begin();it!=tmp->end();it++)
+          for(const mcIdType *it=tmp->begin();it!=tmp->end();it++)
             {
               if(allIds->presenceOfValue(*it))
                 {
@@ -1610,12 +1848,12 @@ void MEDFileMesh::normalizeFamIdsTrio()
     }
   for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++)
     {
-      DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2));
+      DataArrayIdType *fam=const_cast<DataArrayIdType*>(getFamilyFieldAtLevel(*it2));
       if(fam)
         {
-          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
+          MCAuto<DataArrayIdType> tmp=fam->getDifferentValues();
           fam->fillWithZero();
-          for(const int *it3=tmp->begin();it3!=tmp->end();it3++)
+          for(const mcIdType *it3=tmp->begin();it3!=tmp->end();it3++)
             if(allIds->presenceOfValue(*it3))
               {
                 std::string famName=getFamilyNameGivenId(*it3);
@@ -1643,27 +1881,27 @@ void MEDFileMesh::normalizeFamIdsTrio()
 void MEDFileMesh::normalizeFamIdsMEDFile()
 {
   ensureDifferentFamIdsPerLevel();
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced();
+  MCAuto<DataArrayIdType> allIds=getAllFamiliesIdsReferenced();
   std::vector<int> levs=getNonEmptyLevelsExt();
   std::set<int> levsS(levs.begin(),levs.end());
   std::set<std::string> famsFetched;
-  std::map<std::string,int> families;
-  int refId=1;
+  std::map<std::string,mcIdType> families;
+  mcIdType refId=1;
   if(std::find(levs.begin(),levs.end(),1)!=levs.end())
     {
       levsS.erase(1);
-      const DataArrayInt *fam=getFamilyFieldAtLevel(1);
+      const DataArrayIdType *fam=getFamilyFieldAtLevel(1);
       if(fam)
         {
-          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
-          std::map<int,int> ren;
-          for(const int *it=tmp->begin();it!=tmp->end();it++,refId++)
+          MCAuto<DataArrayIdType> tmp=fam->getDifferentValues();
+          std::map<mcIdType,mcIdType> ren;
+          for(const mcIdType *it=tmp->begin();it!=tmp->end();it++,refId++)
             ren[*it]=refId;
-          int nbOfTuples=fam->getNumberOfTuples();
-          int *start=const_cast<DataArrayInt *>(fam)->getPointer();
-          for(int *w=start;w!=start+nbOfTuples;w++)
+          mcIdType nbOfTuples=fam->getNumberOfTuples();
+          mcIdType *start=const_cast<DataArrayIdType *>(fam)->getPointer();
+          for(mcIdType *w=start;w!=start+nbOfTuples;w++)
             *w=ren[*w];
-          for(const int *it=tmp->begin();it!=tmp->end();it++)
+          for(const mcIdType *it=tmp->begin();it!=tmp->end();it++)
             {
               if(allIds->presenceOfValue(*it))
                 {
@@ -1677,18 +1915,18 @@ void MEDFileMesh::normalizeFamIdsMEDFile()
   refId=-1;
   for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++)
     {
-      const DataArrayInt *fam=getFamilyFieldAtLevel(*it2);
+      const DataArrayIdType *fam=getFamilyFieldAtLevel(*it2);
       if(fam)
         {
-          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues();
-          std::map<int,int> ren;
-          for(const int *it=tmp->begin();it!=tmp->end();it++,refId--)
+          MCAuto<DataArrayIdType> tmp=fam->getDifferentValues();
+          std::map<mcIdType,mcIdType> ren;
+          for(const mcIdType *it=tmp->begin();it!=tmp->end();it++,refId--)
             ren[*it]=refId;
-          int nbOfTuples=fam->getNumberOfTuples();
-          int *start=const_cast<DataArrayInt *>(fam)->getPointer();
-          for(int *w=start;w!=start+nbOfTuples;w++)
+          mcIdType nbOfTuples=fam->getNumberOfTuples();
+          mcIdType *start=const_cast<DataArrayIdType *>(fam)->getPointer();
+          for(mcIdType *w=start;w!=start+nbOfTuples;w++)
             *w=ren[*w];
-          for(const int *it=tmp->begin();it!=tmp->end();it++)
+          for(const mcIdType *it=tmp->begin();it!=tmp->end();it++)
             {
               if(allIds->presenceOfValue(*it))
                 {
@@ -1716,9 +1954,9 @@ void MEDFileMesh::normalizeFamIdsMEDFile()
  *  \return std::string - the name of the found family.
  *  \throw If no family with the given \a id exists.
  */
-std::string MEDFileMesh::getFamilyNameGivenId(int id) const
+std::string MEDFileMesh::getFamilyNameGivenId(mcIdType id) const
 {
-  for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
+  for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
     if((*it).second==id)
       return (*it).first;
   std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id;
@@ -1743,12 +1981,12 @@ std::string MEDFileMesh::simpleRepr() const
  * This method is nearly like getFamilyFieldAtLevel method. Except that if the array does not exist at the specified level \a meshDimRelToMaxExt
  * an empty one is created.
  */
-DataArrayInt *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt)
+DataArrayIdType *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt)
 {
-  DataArrayInt *ret(getFamilyFieldAtLevel(meshDimRelToMaxExt));
+  DataArrayIdType *ret(getFamilyFieldAtLevel(meshDimRelToMaxExt));
   if(ret)
     return ret;
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr(DataArrayInt::New());
+  MCAuto<DataArrayIdType> arr(DataArrayIdType::New());
   arr->alloc(getSizeAtLevel(meshDimRelToMaxExt),1);
   arr->fillWithZero();
   setFamilyFieldArr(meshDimRelToMaxExt,arr);
@@ -1762,17 +2000,17 @@ DataArrayInt *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToM
  *  \param [in] grp - the name of the group of interest.
  *  \param [in] renum - if \c true, the optional numbers of entities, if available, are
  *          returned instead of ids. 
- *  \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
+ *  \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
  *          numbers, if available and required, of mesh entities of the group. The caller
  *          is to delete this array using decrRef() as it is no more needed. 
  *  \throw If the name of a nonexistent group is specified.
  *  \throw If the family field is missing for \a meshDimRelToMaxExt.
  */
-DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
+DataArrayIdType *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
 {
   std::vector<std::string> tmp(1);
   tmp[0]=grp;
-  DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
+  DataArrayIdType *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum);
   ret->setName(grp);
   return ret;
 }
@@ -1784,13 +2022,13 @@ DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string
  *  \param [in] grps - the names of the groups of interest.
  *  \param [in] renum - if \c true, the optional numbers of entities, if available, are
  *          returned instead of ids.
- *  \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
+ *  \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
  *          numbers, if available and required, of mesh entities of the groups. The caller
  *          is to delete this array using decrRef() as it is no more needed. 
  *  \throw If the name of a nonexistent group is present in \a grps.
  *  \throw If the family field is missing for \a meshDimRelToMaxExt.
  */
-DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
+DataArrayIdType *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
 {
   std::vector<std::string> fams2=getFamiliesOnGroups(grps);
   return getFamiliesArr(meshDimRelToMaxExt,fams2,renum);
@@ -1803,16 +2041,16 @@ DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vecto
  *  \param [in] fam - the name of the family of interest.
  *  \param [in] renum - if \c true, the optional numbers of entities, if available, are
  *          returned instead of ids. 
- *  \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
+ *  \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
  *          numbers, if available and required, of mesh entities of the family. The caller
  *          is to delete this array using decrRef() as it is no more needed. 
  *  \throw If the family field is missing for \a meshDimRelToMaxExt.
  */
-DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
+DataArrayIdType *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
 {
   std::vector<std::string> tmp(1);
   tmp[0]=fam;
-  DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
+  DataArrayIdType *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum);
   ret->setName(fam);
   return ret;
 }
@@ -1822,17 +2060,17 @@ DataArrayInt *MEDFileMesh::getFamilyArr(int meshDimRelToMaxExt, const std::strin
  *  \param [in] grp - the name of the group of interest.
  *  \param [in] renum - if \c true, the optional numbers of nodes, if available, are
  *          returned instead of ids. 
- *  \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
+ *  \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
  *          numbers, if available and required, of nodes of the group. The caller
  *          is to delete this array using decrRef() as it is no more needed. 
  *  \throw If the name of a nonexistent group is specified.
  *  \throw If the family field is missing for nodes.
  */
-DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
+DataArrayIdType *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const
 {
   std::vector<std::string> tmp(1);
   tmp[0]=grp;
-  DataArrayInt *ret=getNodeGroupsArr(tmp,renum);
+  DataArrayIdType *ret=getNodeGroupsArr(tmp,renum);
   ret->setName(grp);
   return ret;
 }
@@ -1842,33 +2080,33 @@ DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) c
  *  \param [in] grps - the names of the groups of interest.
  *  \param [in] renum - if \c true, the optional numbers of nodes, if available, are
  *          returned instead of ids. 
- *  \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
+ *  \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
  *          numbers, if available and required, of nodes of the groups. The caller
  *          is to delete this array using decrRef() as it is no more needed. 
  *  \throw If the name of a nonexistent group is present in \a grps.
  *  \throw If the family field is missing for nodes.
  */
-DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
+DataArrayIdType *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const
 {
   return getGroupsArr(1,grps,renum);
 }
 
 /*!
- * Returns ids of nodes contained in a given group.
- *  \param [in] grp - the name of the group of interest.
+ * Returns ids of nodes contained in a given family.
+ *  \param [in] fam - the name of the family of interest.
  *  \param [in] renum - if \c true, the optional numbers of nodes, if available, are
  *          returned instead of ids. 
- *  \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
- *          numbers, if available and required, of nodes of the group. The caller
+ *  \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
+ *          numbers, if available and required, of nodes of the family. The caller
  *          is to delete this array using decrRef() as it is no more needed. 
- *  \throw If the name of a nonexistent group is specified.
+ *  \throw If the name of a nonexistent family is specified.
  *  \throw If the family field is missing for nodes.
  */
-DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
+DataArrayIdType *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const
 {
   std::vector<std::string> tmp(1);
   tmp[0]=fam;
-  DataArrayInt *ret=getNodeFamiliesArr(tmp,renum);
+  DataArrayIdType *ret=getNodeFamiliesArr(tmp,renum);
   ret->setName(fam);
   return ret;
 }
@@ -1878,12 +2116,12 @@ DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum)
  *  \param [in] fams - the names of the families of interest.
  *  \param [in] renum - if \c true, the optional numbers of nodes, if available, are
  *          returned instead of ids. 
- *  \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
+ *  \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
  *          numbers, if available and required, of nodes of the families. The caller
  *          is to delete this array using decrRef() as it is no more needed. 
  *  \throw If the family field is missing for nodes.
  */
-DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
+DataArrayIdType *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const
 {
   return getFamiliesArr(1,fams,renum);
 }
@@ -1900,7 +2138,7 @@ DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fa
  *  \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ).
  *  \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
  */
-void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum)
+void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayIdType *>& grps, bool renum)
 {
   if(grps.empty())
     return ;
@@ -1908,7 +2146,7 @@ void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<con
   std::vector<std::string> grpsName2(grps.size());
   int i=0;
 
-  for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
+  for(std::vector<const DataArrayIdType *>::const_iterator it=grps.begin();it!=grps.end();it++,i++)
     {
       grpsName.insert((*it)->getName());
       grpsName2[i]=(*it)->getName();
@@ -1917,29 +2155,29 @@ void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<con
     throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !");
   if(grpsName.find(std::string(""))!=grpsName.end())
     throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !");
-  int sz=getSizeAtLevel(meshDimRelToMaxExt);
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam;
-  std::vector< std::vector<int> > fidsOfGroups;
+  mcIdType sz=getSizeAtLevel(meshDimRelToMaxExt);
+  MCAuto<DataArrayIdType> fam;
+  std::vector< std::vector<mcIdType> > fidsOfGroups;
   if(!renum)
     {
-      fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups);
+      fam=DataArrayIdType::MakePartition(grps,sz,fidsOfGroups);
     }
   else
     {
-      std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grps2(grps.size());
+      std::vector< MCAuto<DataArrayIdType> > grps2(grps.size());
       for(unsigned int ii=0;ii<grps.size();ii++)
         {
           grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]);
           grps2[ii]->setName(grps[ii]->getName());
         }
-      std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end());
-      fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups);
+      std::vector<const DataArrayIdType *> grps3(grps2.begin(),grps2.end());
+      fam=DataArrayIdType::MakePartition(grps3,sz,fidsOfGroups);
     }
-  int offset=1;
+  mcIdType offset=1;
   if(!_families.empty())
     offset=getMaxAbsFamilyId()+1;
   TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups);
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getDifferentValues();
+  MCAuto<DataArrayIdType> ids=fam->getDifferentValues();
   appendFamilyEntries(ids,fidsOfGroups,grpsName2);
   setFamilyFieldArr(meshDimRelToMaxExt,fam);
 }
@@ -1949,10 +2187,10 @@ void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<con
  * not in '_families'. Groups information are given in parameters in order to give to families representative names.
  * For the moment, the two last input parameters are not taken into account.
  */
-void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames)
+void MEDFileMesh::appendFamilyEntries(const DataArrayIdType *famIds, const std::vector< std::vector<mcIdType> >& fidsOfGrps, const std::vector<std::string>& grpNames)
 {
-  std::map<int,std::string> famInv;
-  for(const int *it=famIds->begin();it!=famIds->end();it++)
+  std::map<mcIdType,std::string> famInv;
+  for(const mcIdType *it=famIds->begin();it!=famIds->end();it++)
     {
       std::ostringstream oss;
       oss << "Family_" << (*it);
@@ -1960,9 +2198,9 @@ void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vec
       famInv[*it]=oss.str();
     }
   int i=0;
-  for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
+  for(std::vector< std::vector<mcIdType> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++)
     {
-      for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
+      for(std::vector<mcIdType>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++)
         {
           _groups[grpNames[i]].push_back(famInv[*it2]);
         }
@@ -1981,20 +2219,30 @@ std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() con
   return ret;
 }
 
-std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
+/*!
+ * \sa getAllDistributionOfTypes
+ */
+std::vector<mcIdType> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> mLev(getGenMeshAtLevel(meshDimRelToMax));
+  MCAuto<MEDCouplingMesh> mLev(getMeshAtLevel(meshDimRelToMax));
   return mLev->getDistributionOfTypes();
 }
 
-void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp)
+void MEDFileMesh::loadLLWithAdditionalItems(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
+{
+  loadLL(fid,mName,dt,it,mrs);
+  loadJointsFromFile(fid);
+  loadEquivalences(fid);
+}
+
+void MEDFileMesh::TranslateFamilyIds(mcIdType offset, DataArrayIdType *famArr, std::vector< std::vector<mcIdType> >& famIdsPerGrp)
 {
   famArr->applyLin(offset>0?1:-1,offset,0);
-  for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
+  for(std::vector< std::vector<mcIdType> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++)
     {
       if(offset<0)
-        std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>());
-      std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset));
+        std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<mcIdType>());
+      std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind(std::plus<mcIdType>(),std::placeholders::_1,offset));
     }
 }
 
@@ -2019,7 +2267,7 @@ std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::
   //attempt #2
   if(len>=1)
     {
-      for(std::size_t i=1;i<30;i++)
+      for(char i=1;i<30;i++)
         {
           std::string tmp1(nameTry.at(0),i);
           tmp1+=nameTry;
@@ -2036,12 +2284,12 @@ std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::
   throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !");
 }
 
-int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt)
+mcIdType MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<mcIdType>& code, mcIdType strt)
 {
   std::size_t nbOfChunks=code.size()/3;
   if(code.size()%3!=0)
     throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !");
-  int ret=strt;
+  mcIdType ret=strt;
   for(std::size_t i=0;i<nbOfChunks;i++)
     {
       code[3*i+2]=ret;
@@ -2095,7 +2343,7 @@ void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m)
 void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
 {
   oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n";
-  for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
+  for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
     {
       oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl;
       oss << "  - Groups lying on this family : ";
@@ -2121,8 +2369,12 @@ void MEDFileMesh::getFamilyRepr(std::ostream& oss) const
  */
 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
-  MEDFileUtilities::CheckFileForRead(fileName);
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
+  MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+  return New(fid,mName,dt,it,mrs);
+}
+
+MEDFileUMesh *MEDFileUMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
+{
   return new MEDFileUMesh(fid,mName,dt,it,mrs);
 }
 
@@ -2138,19 +2390,49 @@ MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string&
  */
 MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
 {
-  std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
+  MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+  return New(fid,mrs);
+}
+
+template<class T>
+T *NewForTheFirstMeshInFile(med_idt fid, MEDFileMeshReadSelector *mrs)
+{
+  std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
   if(ms.empty())
     {
-      std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
+      std::ostringstream oss; oss << MLMeshTraits<T>::ClassName << "::New : no meshes in file \"" << MEDFileWritable::FileNameFromFID(fid) << "\" !";
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
-  MEDFileUtilities::CheckFileForRead(fileName);
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
   int dt,it;
-  ParaMEDMEM::MEDCouplingMeshType meshType;
+  MEDCoupling::MEDCouplingMeshType meshType;
   std::string dummy2;
-  MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
-  return new MEDFileUMesh(fid,ms.front(),dt,it,mrs);
+  MEDCoupling::MEDCouplingAxisType dummy3;
+  MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
+  return T::New(fid,ms.front(),dt,it,mrs);
+}
+
+MEDFileUMesh *MEDFileUMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
+{
+  return NewForTheFirstMeshInFile<MEDFileUMesh>(fid,mrs);
+}
+
+/*!
+ * \b WARNING this implementation is dependent from MEDCouplingMappedExtrudedMesh::buildUnstructured !
+ * \sa MEDCouplingMappedExtrudedMesh::buildUnstructured , MEDCouplingMappedExtrudedMesh::build3DUnstructuredMesh
+ */
+MEDFileUMesh *MEDFileUMesh::New(const MEDCouplingMappedExtrudedMesh *mem)
+{
+  if(!mem)
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::New : null input vector !");
+  MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
+  MCAuto<MEDCouplingUMesh> m3D(mem->buildUnstructured());
+  MCAuto<MEDCouplingUMesh> m2D(mem->getMesh2D()->deepCopy());
+  m2D->zipCoords();
+  m2D->setCoords(m3D->getCoords());
+  ret->setMeshAtLevel(0,m3D);
+  ret->setMeshAtLevel(-1,m2D);
+  ret->setFamilyId(GetSpeStr4ExtMesh(),std::numeric_limits<med_int>::max()-mem->get2DCellIdForExtrusion());
+  return ret.retn();
 }
 
 /*!
@@ -2173,13 +2455,13 @@ MEDFileUMesh *MEDFileUMesh::New()
  * \param [in] fileName - the name of the file.
  * \param [in] mName - the name of the mesh to be read.
  * \param [in] types - the list of the geo types of which some part will be taken. A geometric type in \a types must appear only once at most.
- * \param [in] slicPerType - an array of size 3 times larger than \a types that specifies for each type in \a types (in the same order) resp the start, the stop and the step.
+ * \param [in] slicPerTyp - an array of size 3 times larger than \a types that specifies for each type in \a types (in the same order) resp the start, the stop and the step.
  * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step.
  * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step.
  * \param [in] mrs - the request for what to be loaded.
  * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed.
  */
-MEDFileUMesh *MEDFileUMesh::LoadPartOf(const std::string& fileName, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
+MEDFileUMesh *MEDFileUMesh::LoadPartOf(const std::string& fileName, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
   MEDFileUtilities::CheckFileForRead(fileName);
   MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY));
@@ -2190,17 +2472,44 @@ MEDFileUMesh *MEDFileUMesh::LoadPartOf(const std::string& fileName, const std::s
  * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first).
  * This method is \b NOT wrapped into python.
  */
-MEDFileUMesh *MEDFileUMesh::LoadPartOf(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
+MEDFileUMesh *MEDFileUMesh::LoadPartOf(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
+  MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
   ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs);
   return ret.retn();
 }
 
+/*!
+ * This method is an helper to load only consecutive nodes chunk of data of MED file pointed by \a fileName.
+ * Consecutive chunk is specified classicaly by start (included) stop (excluded) format with \a startNodeId and \a stopNodeId respectively.
+ * This method returns 5 elements.
+ * 
+ * \param [in] fileName - Name of file nodes to be read of.
+ * \param [in] mName - Name of the mesh inside file pointed be \a fileName nodes to be read of.
+ * \param [in] dt - Time iteration inside file pointed be \a fileName nodes to be read of.
+ * \param [in] it - Time order inside file pointed be \a fileName nodes to be read of.
+ * \param [in] infosOnComp - Components info of nodes to be read of. The size of string vector should be equal to space dimension of mesh to be read.
+ * \param [in] startNodeId - Start Node Id (included) of chunk of data to be read
+ * \param [in] stopNodeId - Start Node Id (included) of chunk of data to be read
+ * \param [out] coords - output coordinates of requested chunk (DataArrayDouble)
+ * \param [out] partCoords - output PartDefinition object of chunk
+ * \param [out] famCoords - output family id field of requested chunk (DataArrayIdType)
+ * \param [out] numCoords - output num id field of requested chunk (DataArrayIdType)
+ * \param [out] nameCoords - output names on nodes of requested chunk (DataArrayAsciiChar)
+ * 
+ * \sa MEDLoaderUMesh::LoadPartOf
+ */
+void MEDFileUMesh::LoadPartCoords(const std::string& fileName, const std::string& mName, int dt, int it, const std::vector<std::string>& infosOnComp, mcIdType startNodeId, mcIdType stopNodeId,
+MCAuto<DataArrayDouble>& coords, MCAuto<PartDefinition>& partCoords, MCAuto<DataArrayIdType>& famCoords, MCAuto<DataArrayIdType>& numCoords, MCAuto<DataArrayAsciiChar>& nameCoords)
+{
+  MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+  MEDFileUMeshL2::LoadPartCoords(fid,infosOnComp,mName,dt,it,startNodeId,stopNodeId,coords,partCoords,famCoords,numCoords,nameCoords);
+}
+
 std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const
 {
   std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren());
-  ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>));
+  ret+=_ms.capacity()*(sizeof(MCAuto<MEDFileUMeshSplitL1>))+_elt_str.capacity()*sizeof(MCAuto<MEDFileEltStruct4Mesh>);
   return ret;
 }
 
@@ -2208,19 +2517,22 @@ std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() c
 {
   std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
   ret.push_back((const DataArrayDouble*)_coords);
-  ret.push_back((const DataArrayInt *)_fam_coords);
-  ret.push_back((const DataArrayInt *)_num_coords);
-  ret.push_back((const DataArrayInt *)_rev_num_coords);
+  ret.push_back((const DataArrayIdType *)_fam_coords);
+  ret.push_back((const DataArrayIdType *)_num_coords);
+  ret.push_back((const DataArrayIdType *)_global_num_coords);
+  ret.push_back((const DataArrayIdType *)_rev_num_coords);
   ret.push_back((const DataArrayAsciiChar *)_name_coords);
   ret.push_back((const PartDefinition *)_part_coords);
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
+  for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
     ret.push_back((const MEDFileUMeshSplitL1*) *it);
+  for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++)
+    ret.push_back((const MEDFileEltStruct4Mesh *)*it);
   return ret;
 }
 
-MEDFileMesh *MEDFileUMesh::shallowCpy() const
+MEDFileUMesh *MEDFileUMesh::shallowCpy() const
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
+  MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
   return ret.retn();
 }
 
@@ -2229,27 +2541,30 @@ MEDFileMesh *MEDFileUMesh::createNewEmpty() const
   return new MEDFileUMesh;
 }
 
-MEDFileMesh *MEDFileUMesh::deepCpy() const
-{
-  MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this);
-  if((const DataArrayDouble*)_coords)
-    ret->_coords=_coords->deepCpy();
-  if((const DataArrayInt*)_fam_coords)
-    ret->_fam_coords=_fam_coords->deepCpy();
-  if((const DataArrayInt*)_num_coords)
-    ret->_num_coords=_num_coords->deepCpy();
-  if((const DataArrayInt*)_rev_num_coords)
-    ret->_rev_num_coords=_rev_num_coords->deepCpy();
-  if((const DataArrayAsciiChar*)_name_coords)
-    ret->_name_coords=_name_coords->deepCpy();
+MEDFileUMesh *MEDFileUMesh::deepCopy() const
+{
+  MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
+  ret->deepCpyEquivalences(*this);
+  if(_coords.isNotNull())
+    ret->_coords=_coords->deepCopy();
+  if(_fam_coords.isNotNull())
+    ret->_fam_coords=_fam_coords->deepCopy();
+  if(_num_coords.isNotNull())
+    ret->_num_coords=_num_coords->deepCopy();
+  if(_global_num_coords.isNotNull())
+    ret->_global_num_coords=_global_num_coords->deepCopy();
+  if(_rev_num_coords.isNotNull())
+    ret->_rev_num_coords=_rev_num_coords->deepCopy();
+  if(_name_coords.isNotNull())
+    ret->_name_coords=_name_coords->deepCopy();
   std::size_t i=0;
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
+  for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
     {
       if((const MEDFileUMeshSplitL1 *)(*it))
-        ret->_ms[i]=(*it)->deepCpy(ret->_coords);
+        ret->_ms[i]=(*it)->deepCopy(ret->_coords);
     }
   if((const PartDefinition*)_part_coords)
-    ret->_part_coords=_part_coords->deepCpy();
+    ret->_part_coords=_part_coords->deepCopy();
   return ret.retn();
 }
 
@@ -2288,54 +2603,74 @@ bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& wh
           return false;
         }
     }
-  const DataArrayInt *famc1=_fam_coords;
-  const DataArrayInt *famc2=otherC->_fam_coords;
-  if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
-    {
-      what="Mismatch of families arr on nodes ! One is defined and not other !";
-      return false;
-    }
-  if(famc1)
-    {
-      bool ret=famc1->isEqual(*famc2);
-      if(!ret)
-        {
-          what="Families arr on node differ !";
-          return false;
-        }
-    }
-  const DataArrayInt *numc1=_num_coords;
-  const DataArrayInt *numc2=otherC->_num_coords;
-  if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
-    {
-      what="Mismatch of numbering arr on nodes ! One is defined and not other !";
-      return false;
-    }
-  if(numc1)
-    {
-      bool ret=numc1->isEqual(*numc2);
-      if(!ret)
-        {
-          what="Numbering arr on node differ !";
-          return false;
-        }
-    }
-  const DataArrayAsciiChar *namec1=_name_coords;
-  const DataArrayAsciiChar *namec2=otherC->_name_coords;
-  if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
-    {
-      what="Mismatch of naming arr on nodes ! One is defined and not other !";
-      return false;
-    }
-  if(namec1)
-    {
-      bool ret=namec1->isEqual(*namec2);
-      if(!ret)
-        {
-          what="Names arr on node differ !";
-          return false;
-        }
-    }
+  {
+    const DataArrayIdType *famc1(_fam_coords),*famc2(otherC->_fam_coords);
+    if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
+      {
+        what="Mismatch of families arr on nodes ! One is defined and not other !";
+        return false;
+      }
+    if(famc1)
+      {
+        bool ret=famc1->isEqual(*famc2);
+        if(!ret)
+          {
+            what="Families arr on node differ !";
+            return false;
+          }
+      }
+  }
+  {
+    const DataArrayIdType *numc1(_num_coords),*numc2(otherC->_num_coords);
+    if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0))
+      {
+        what="Mismatch of numbering arr on nodes ! One is defined and not other !";
+        return false;
+      }
+    if(numc1)
+      {
+        bool ret=numc1->isEqual(*numc2);
+        if(!ret)
+          {
+            what="Numbering arr on node differ !";
+            return false;
+          }
+      }
+  }
+  {
+    const DataArrayIdType *gnumc1(_global_num_coords),*gnumc2(otherC->_global_num_coords);
+    if((gnumc1==0 && gnumc2!=0) || (gnumc1!=0 && gnumc2==0))
+      {
+        what="Mismatch of numbering arr on nodes ! One is defined and not other !";
+        return false;
+      }
+    if(gnumc1)
+      {
+        bool ret=gnumc1->isEqual(*gnumc2);
+        if(!ret)
+          {
+            what="Global numbering arr on node differ !";
+            return false;
+          }
+      }
+  }
+  {
+    const DataArrayAsciiChar *namec1(_name_coords),*namec2(otherC->_name_coords);
+    if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0))
+      {
+        what="Mismatch of naming arr on nodes ! One is defined and not other !";
+        return false;
+      }
+    if(namec1)
+      {
+        bool ret=namec1->isEqual(*namec2);
+        if(!ret)
+          {
+            what="Names arr on node differ !";
+            return false;
+          }
+      }
+  }
   if(_ms.size()!=otherC->_ms.size())
     {
       what="Number of levels differs !";
@@ -2369,36 +2704,127 @@ bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& wh
   return pd0->isEqual(pd1,what);
 }
 
+/*!
+ * Check that the current object MEDFileUMesh is consistent. This does not check the optional renumbering of
+ * nodes and cells. This last item is important for SMESH, see checkSMESHConsistency().
+ * \throw if any internal part (i.e. mesh sub-levels and single geometric-type meshes) are inconsistent
+ * \throw if internal family array is inconsistent
+ * \sa checkSMESHConsistency()
+ */
+void MEDFileUMesh::checkConsistency() const
+{
+  if(!_coords || !_coords->isAllocated())
+    {
+      if(!_ms.size())
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but some mesh parts are present!");
+      if (!_fam_coords)
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node family array!");
+      if (_num_coords.isNotNull() || _rev_num_coords.isNotNull() || _global_num_coords.isNotNull())
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): coords are null but not the internal node numbering array!");
+    }
+  else
+    {
+      mcIdType nbCoo = _coords->getNumberOfTuples();
+      if (_fam_coords.isNotNull())
+        _fam_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node family array!");
+      if (_num_coords.isNotNull())
+        {
+          _num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array!");
+          mcIdType pos;
+          mcIdType maxValue=_num_coords->getMaxValue(pos);
+          if (!_rev_num_coords || _rev_num_coords->getNumberOfTuples() != (maxValue+1))
+            throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal revert node numbering array!");
+        }
+      if (_global_num_coords.isNotNull())
+        {
+          _global_num_coords->checkNbOfTuplesAndComp(nbCoo,1,"MEDFileUMesh::checkConsistency(): inconsistent global node numbering array!");
+        }
+      if ((_num_coords && !_rev_num_coords) || (!_num_coords && _rev_num_coords))
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal numbering arrays (one is null)!");
+      if (_num_coords && !_num_coords->hasUniqueValues())
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent internal node numbering array: duplicates found!");
+      if (_name_coords)
+        _name_coords->checkNbOfTuplesAndComp(nbCoo,MED_SNAME_SIZE,"MEDFileUMesh::checkConsistency(): inconsistent internal coord name array!");
+      // Now sub part check:
+      for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
+          it != _ms.end(); it++)
+        (*it)->checkConsistency();
+    }
+}
+
+/**
+ * Same as checkConsistency() but also checks that optional entities (edges, faces, volumes) numbers are
+ * consistent, i.e. the numbering is either set to null for all sub-levels (thus letting SMESH numbers the
+ * entities as it likes), or non overlapping between all sub-levels.
+ * \throw if the condition above is not respected
+ */
+void MEDFileUMesh::checkSMESHConsistency() const
+{
+  checkConsistency();
+  // For all sub-levels, numbering is either always null or with void intersection:
+  if (_ms.size())
+    {
+      std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();
+      std::vector< const DataArrayIdType * > v;
+      bool voidOrNot = ((*it)->_num == 0);
+      for (it++; it != _ms.end(); it++)
+        if( ((*it)->_num == 0) != voidOrNot )
+          throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): inconsistent numbering between mesh sub-levels!");
+        else if (!voidOrNot)
+          v.push_back((*it)->_num);
+      if (!voidOrNot)
+        {
+          // don't forget the 1st one:
+          v.push_back(_ms[0]->_num);
+          MCAuto<DataArrayIdType> inter = DataArrayIdType::BuildIntersection(v);
+          if (inter->getNumberOfTuples())
+            throw INTERP_KERNEL::Exception("MEDFileUMesh::checkConsistency(): overlapping entity numbering between mesh sub-levels!");
+        }
+    }
+}
+
+/**
+ * Reset optional node and cell numbering for all sub levels in this. This particularly useful to make
+ * sure SMESH will handle the mesh correctly, as it tries to use those numbers if given.
+ */
+void MEDFileUMesh::clearNodeAndCellNumbers()
+{
+  _num_coords.nullify();
+  _rev_num_coords.nullify();
+  _global_num_coords.nullify();
+  for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin(); it != _ms.end(); it++)
+    {
+      (*it)->_num.nullify();
+      (*it)->_rev_num.nullify();
+      (*it)->_global_num.nullify();
+    }
+}
+
 /*!
  * Clears redundant attributes of incorporated data arrays.
  */
 void MEDFileUMesh::clearNonDiscrAttributes() const
 {
   MEDFileMesh::clearNonDiscrAttributes();
-  const DataArrayDouble *coo1=_coords;
-  if(coo1)
-    (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison
-  const DataArrayInt *famc1=_fam_coords;
-  if(famc1)
-    (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison
-  const DataArrayInt *numc1=_num_coords;
-  if(numc1)
-    (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison
-  const DataArrayAsciiChar *namc1=_name_coords;
-  if(namc1)
-    (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
+  if(_coords.isNotNull())
+    _coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
+  if(_fam_coords.isNotNull())
+    _fam_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
+  if(_num_coords.isNotNull())
+    _num_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
+  if(_name_coords.isNotNull())
+    _name_coords.iAmATrollConstCast()->setName("");//This parameter is not discriminant for comparison
+  for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
     {
-      const MEDFileUMeshSplitL1 *tmp=(*it);
-      if(tmp)
-        tmp->clearNonDiscrAttributes();
+      if((*it).isNotNull())
+        (*it)->clearNonDiscrAttributes();
     }
 }
 
 void MEDFileUMesh::setName(const std::string& name)
 {
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
-    if((MEDFileUMeshSplitL1 *)(*it)!=0)
+  for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
+    if((*it).isNotNull())
       (*it)->setName(name);
   MEDFileMesh::setName(name);
 }
@@ -2410,9 +2836,8 @@ MEDFileUMesh::MEDFileUMesh()
 MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 try
 {
-    loadUMeshFromFile(fid,mName,dt,it,mrs);
-    loadJointsFromFile(fid);
-  }
+    loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
+}
 catch(INTERP_KERNEL::Exception& e)
 {
     throw e;
@@ -2422,15 +2847,16 @@ catch(INTERP_KERNEL::Exception& e)
  * This method loads only a part of specified cells (given by range of cell ID per geometric type)
  * See MEDFileUMesh::LoadPartOf for detailed description.
  *
- * \sa loadUMeshFromFile
+ * \sa loadLL
  */
-void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
+void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<mcIdType>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
   MEDFileUMeshL2 loaderl2;
-  ParaMEDMEM::MEDCouplingMeshType meshType;
+  MEDCoupling::MEDCouplingMeshType meshType;
   int dummy0,dummy1;
   std::string dummy2;
-  int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2));
+  MEDCoupling::MEDCouplingAxisType dummy3;
+  INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy3,dummy0,dummy1,dummy2));
   if(meshType!=UNSTRUCTURED)
     {
       std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !";
@@ -2445,8 +2871,8 @@ void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName,
  */
 void MEDFileMesh::writeJoints(med_idt fid) const
 {
-  if ( (const MEDFileJoints*) _joints )
-    _joints->write(fid);
+  if ( _joints.isNotNull() )
+    _joints->writeLL(fid);
 }
 
 /*!
@@ -2470,12 +2896,61 @@ void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfRe
     _joints = MEDFileJoints::New( fid, _name );
 }
 
+void MEDFileMesh::loadEquivalences(med_idt fid)
+{
+  int nbOfEq(MEDFileEquivalences::PresenceOfEquivalences(fid,_name));
+  if(nbOfEq>0)
+    _equiv=MEDFileEquivalences::Load(fid,nbOfEq,this);
+}
+
+void MEDFileMesh::deepCpyEquivalences(const MEDFileMesh& other)
+{
+  const MEDFileEquivalences *equiv(other._equiv);
+  if(equiv)
+    _equiv=equiv->deepCopy(this);
+}
+
+bool MEDFileMesh::areEquivalencesEqual(const MEDFileMesh *other, std::string& what) const
+{
+  const MEDFileEquivalences *thisEq(_equiv),*otherEq(other->_equiv);
+  if(!thisEq && !otherEq)
+    return true;
+  if(thisEq && otherEq)
+    return thisEq->isEqual(otherEq,what);
+  else
+    {
+      what+="Equivalence differs : defined in this and not in other (or reversely) !";
+      return false;
+    }
+}
+
+void MEDFileMesh::getEquivalencesRepr(std::ostream& oss) const
+{
+  const MEDFileEquivalences *equiv(_equiv);
+  if(!equiv)
+    return ;
+  oss << "(******************************)\n(* EQUIVALENCES OF THE MESH : *)\n(******************************)\n";
+  _equiv->getRepr(oss);
+}
+
+void MEDFileMesh::checkCartesian() const
+{
+  if(getAxisType()!=AX_CART)
+    {
+      std::ostringstream oss; oss << "MEDFileMesh::checkCartesian : request for method that is dedicated to a cartesian convention ! But you are not in cartesian convention (" << DataArray::GetAxisTypeRepr(getAxisType()) << ").";
+      oss << std::endl << "To perform operation you have two possibilities :" << std::endl;
+      oss << " - call setAxisType(AX_CART)" << std::endl;
+      oss << " - call cartesianize()";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+}
+
 /*!
  * \brief Return number of joints, which is equal to number of adjacent mesh domains
  */
-int MEDFileMesh::getNumberOfJoints()
+int MEDFileMesh::getNumberOfJoints() const
 {
-  return ( (MEDFileJoints*) _joints ) ? _joints->getNumberOfJoints() : 0;
+  return ( (const MEDFileJoints *) _joints ) ? _joints->getNumberOfJoints() : 0;
 }
 
 /*!
@@ -2501,13 +2976,15 @@ void MEDFileMesh::setJoints( MEDFileJoints* joints )
  *
  * \sa loadPartUMeshFromFile
  */
-void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
+void MEDFileUMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
   MEDFileUMeshL2 loaderl2;
-  ParaMEDMEM::MEDCouplingMeshType meshType;
+  MEDCoupling::MEDCouplingMeshType meshType;
   int dummy0,dummy1;
   std::string dummy2;
-  int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2));
+  MEDCoupling::MEDCouplingAxisType axType;
+  INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dummy2));
+  setAxisType(axType);
   if(meshType!=UNSTRUCTURED)
     {
       std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !";
@@ -2515,6 +2992,17 @@ void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const std::string& mName, int
     }
   loaderl2.loadAll(fid,mid,mName,dt,it,mrs);
   dispatchLoadedPart(fid,loaderl2,mName,mrs);
+  // Structure element part...
+  med_int nModels(-1);
+  {
+    med_bool chgt=MED_FALSE,trsf=MED_FALSE;
+    nModels=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_STRUCT_ELEMENT,MED_GEO_ALL,MED_CONNECTIVITY,MED_NODAL,&chgt,&trsf);
+  }
+  if(nModels<=0)
+    return ;
+  _elt_str.resize(nModels);
+  for(int i=0;i<nModels;i++)
+    _elt_str[i]=MEDFileEltStruct4Mesh::New(fid,mName,dt,it,i,mrs);
 }
 
 void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs)
@@ -2544,22 +3032,23 @@ void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl
     _num_coords=loaderl2.getCoordsNum();
   if(!mrs || mrs->isNodeNameFieldReading())
     _name_coords=loaderl2.getCoordsName();
+  if(!mrs || mrs->isGlobalNodeNumFieldReading())
+    _global_num_coords=loaderl2.getCoordsGlobalNum();
   _part_coords=loaderl2.getPartDefOfCoo();
-  computeRevNum();
 }
 
 MEDFileUMesh::~MEDFileUMesh()
 {
 }
 
-void MEDFileUMesh::writeLL(med_idt fid) const
+void MEDFileUMesh::writeMeshLL(med_idt fid) const
 {
   const DataArrayDouble *coo=_coords;
   INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
   INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
   MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str);
   MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str);
-  int spaceDim=coo?coo->getNumberOfComponents():0;
+  int spaceDim=(int)(coo?coo->getNumberOfComponents():0);
   int mdim(0);
   if(!_ms.empty())
     mdim=getMeshDimension();
@@ -2570,20 +3059,18 @@ void MEDFileUMesh::writeLL(med_idt fid) const
       std::string info=coo->getInfoOnComponent(i);
       std::string c,u;
       MEDLoaderBase::splitIntoNameAndUnit(info,c,u);
-      MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
-      MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
+      MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
+      MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
     }
-  MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit));
+  MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
   if(_univ_wr_status)
     MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
   std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
-  MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords);
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
+  MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords,_global_num_coords);
+  for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
     if((const MEDFileUMeshSplitL1 *)(*it)!=0)
       (*it)->write(fid,meshName,mdim);
   MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str);
-
-  writeJoints(fid);
 }
 
 /*!
@@ -2594,7 +3081,7 @@ std::vector<int> MEDFileUMesh::getNonEmptyLevels() const
 {
   std::vector<int> ret;
   int lev=0;
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
+  for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
     if((const MEDFileUMeshSplitL1 *)(*it)!=0)
       if(!(*it)->empty())
         ret.push_back(lev);
@@ -2621,11 +3108,11 @@ std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const
 std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
 {
   std::vector<int> ret;
-  const DataArrayInt *famCoo(_fam_coords);
+  const DataArrayIdType *famCoo(_fam_coords);
   if(famCoo)
     ret.push_back(1);
   int lev=0;
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
+  for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
     {
       const MEDFileUMeshSplitL1 *cur(*it);
       if(cur)
@@ -2638,11 +3125,10 @@ std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const
 std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const
 {
   std::vector<int> ret;
-  const DataArrayInt *numCoo(_num_coords);
-  if(numCoo)
+  if(_num_coords.isNotNull())
     ret.push_back(1);
   int lev=0;
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
+  for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
     {
       const MEDFileUMeshSplitL1 *cur(*it);
       if(cur)
@@ -2659,7 +3145,7 @@ std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
   if(nameCoo)
     ret.push_back(1);
   int lev=0;
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
+  for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--)
     {
       const MEDFileUMeshSplitL1 *cur(*it);
       if(cur)
@@ -2669,86 +3155,17 @@ std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const
   return ret;
 }
 
-/*!
- * Returns all relative mesh levels (**excluding nodes**) where a given group is defined.
- * To include nodes, call getGrpNonEmptyLevelsExt() method.
- *  \param [in] grp - the name of the group of interest.
- *  \return std::vector<int> - a sequence of the relative dimensions.
- */
-std::vector<int> MEDFileUMesh::getGrpNonEmptyLevels(const std::string& grp) const
-{
-  std::vector<std::string> fams=getFamiliesOnGroup(grp);
-  return getFamsNonEmptyLevels(fams);
-}
-
-/*!
- * Returns all relative mesh levels (including nodes) where a given group is defined.
- *  \param [in] grp - the name of the group of interest.
- *  \return std::vector<int> - a sequence of the relative dimensions.
- */
-std::vector<int> MEDFileUMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const
-{
-  std::vector<std::string> fams=getFamiliesOnGroup(grp);
-  return getFamsNonEmptyLevelsExt(fams);
-}
-
-/*!
- * Returns all relative mesh levels (**excluding nodes**) where a given family is defined.
- * To include nodes, call getFamNonEmptyLevelsExt() method.
- *  \param [in] fam - the name of the family of interest.
- *  \return std::vector<int> - a sequence of the relative dimensions.
- */
-std::vector<int> MEDFileUMesh::getFamNonEmptyLevels(const std::string& fam) const
-{
-  std::vector<std::string> fams(1,std::string(fam));
-  return getFamsNonEmptyLevels(fams);
-}
-
-/*!
- * Returns all relative mesh levels (including nodes) where a given family is defined.
- *  \param [in] fam - the name of the family of interest.
- *  \return std::vector<int> - a sequence of the relative dimensions.
- */
-std::vector<int> MEDFileUMesh::getFamNonEmptyLevelsExt(const std::string& fam) const
-{
-  std::vector<std::string> fams(1,std::string(fam));
-  return getFamsNonEmptyLevelsExt(fams);
-}
-
-/*!
- * Returns all relative mesh levels (**excluding nodes**) where given groups are defined.
- * To include nodes, call getGrpsNonEmptyLevelsExt() method.
- *  \param [in] grps - a sequence of names of the groups of interest.
- *  \return std::vector<int> - a sequence of the relative dimensions.
- */
-std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const
-{
-  std::vector<std::string> fams=getFamiliesOnGroups(grps);
-  return getFamsNonEmptyLevels(fams);
-}
-
-/*!
- * Returns all relative mesh levels (including nodes) where given groups are defined.
- *  \param [in] grps - a sequence of names of the groups of interest.
- *  \return std::vector<int> - a sequence of the relative dimensions.
- */
-std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const
-{
-  std::vector<std::string> fams=getFamiliesOnGroups(grps);
-  return getFamsNonEmptyLevelsExt(fams);
-}
-
 /*!
  * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
  * To include nodes, call getFamsNonEmptyLevelsExt() method.
  *  \param [in] fams - the name of the family of interest.
  *  \return std::vector<int> - a sequence of the relative dimensions.
  */
-std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
+std::vector<mcIdType> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
 {
-  std::vector<int> ret;
-  std::vector<int> levs=getNonEmptyLevels();
-  std::vector<int> famIds=getFamiliesIds(fams);
+  std::vector<mcIdType> ret;
+  std::vector<int> levs(getNonEmptyLevels());
+  std::vector<mcIdType> famIds(getFamiliesIds(fams));
   for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
     if(_ms[-(*it)]->presenceOfOneFams(famIds))
       ret.push_back(*it);
@@ -2760,16 +3177,16 @@ std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::stri
  *  \param [in] fams - the names of the families of interest.
  *  \return std::vector<int> - a sequence of the relative dimensions.
  */
-std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
+std::vector<mcIdType> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
 {
-  std::vector<int> ret0=getFamsNonEmptyLevels(fams);
-  const DataArrayInt *famCoords=_fam_coords;
+  std::vector<mcIdType> ret0(getFamsNonEmptyLevels(fams));
+  const DataArrayIdType *famCoords(_fam_coords);
   if(!famCoords)
     return ret0;
-  std::vector<int> famIds=getFamiliesIds(fams);
+  std::vector<mcIdType> famIds(getFamiliesIds(fams));
   if(famCoords->presenceOfValue(famIds))
     {
-      std::vector<int> ret(ret0.size()+1);
+      std::vector<mcIdType> ret(ret0.size()+1);
       ret[0]=1;
       std::copy(ret0.begin(),ret0.end(),ret.begin()+1);
       return ret;
@@ -2778,41 +3195,22 @@ std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::s
     return ret0;
 }
 
-/*!
- * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt.
- *  \param [in] meshDimRelToMaxExt - a relative dimension of interest.
- *  \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt
- *          level. 
- */
-std::vector<std::string> MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const
-{
-  std::vector<std::string> ret;
-  std::vector<std::string> allGrps=getGroupsNames();
-  for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++)
-    {
-      std::vector<int> levs=getGrpNonEmptyLevelsExt((*it));
-      if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end())
-        ret.push_back(*it);
-    }
-  return ret;
-}
-
-int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
+mcIdType MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
 {
-  int ret=-std::numeric_limits<int>::max(),tmp=-1;
-  if((const DataArrayInt *)_fam_coords)
+  mcIdType ret=-std::numeric_limits<mcIdType>::max(),tmp=-1;
+  if((const DataArrayIdType *)_fam_coords)
     {
-      int val=_fam_coords->getMaxValue(tmp);
+      mcIdType val=_fam_coords->getMaxValue(tmp);
       ret=std::max(ret,std::abs(val));
     }
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
+  for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
     {
       if((const MEDFileUMeshSplitL1 *)(*it))
         {
-          const DataArrayInt *da=(*it)->getFamilyField();
+          const DataArrayIdType *da=(*it)->getFamilyField();
           if(da)
             {
-              int val=da->getMaxValue(tmp);
+              mcIdType val=da->getMaxValue(tmp);
               ret=std::max(ret,std::abs(val));
             }
         }
@@ -2820,22 +3218,22 @@ int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const
   return ret;
 }
 
-int MEDFileUMesh::getMaxFamilyIdInArrays() const
+mcIdType MEDFileUMesh::getMaxFamilyIdInArrays() const
 {
-  int ret=-std::numeric_limits<int>::max(),tmp=-1;
-  if((const DataArrayInt *)_fam_coords)
+  mcIdType ret=-std::numeric_limits<mcIdType>::max(),tmp=-1;
+  if((const DataArrayIdType *)_fam_coords)
     {
-      int val=_fam_coords->getMaxValue(tmp);
+      mcIdType val=_fam_coords->getMaxValue(tmp);
       ret=std::max(ret,val);
     }
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
+  for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
     {
       if((const MEDFileUMeshSplitL1 *)(*it))
         {
-          const DataArrayInt *da=(*it)->getFamilyField();
+          const DataArrayIdType *da=(*it)->getFamilyField();
           if(da)
             {
-              int val=da->getMaxValue(tmp);
+              mcIdType val=da->getMaxValue(tmp);
               ret=std::max(ret,val);
             }
         }
@@ -2843,22 +3241,22 @@ int MEDFileUMesh::getMaxFamilyIdInArrays() const
   return ret;
 }
 
-int MEDFileUMesh::getMinFamilyIdInArrays() const
+mcIdType MEDFileUMesh::getMinFamilyIdInArrays() const
 {
-  int ret=std::numeric_limits<int>::max(),tmp=-1;
-  if((const DataArrayInt *)_fam_coords)
+  mcIdType ret=std::numeric_limits<mcIdType>::max(),tmp=-1;
+  if((const DataArrayIdType *)_fam_coords)
     {
-      int val=_fam_coords->getMinValue(tmp);
+      mcIdType val=_fam_coords->getMinValue(tmp);
       ret=std::min(ret,val);
     }
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
+  for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
     {
       if((const MEDFileUMeshSplitL1 *)(*it))
         {
-          const DataArrayInt *da=(*it)->getFamilyField();
+          const DataArrayIdType *da=(*it)->getFamilyField();
           if(da)
             {
-              int val=da->getMinValue(tmp);
+              mcIdType val=da->getMinValue(tmp);
               ret=std::min(ret,val);
             }
         }
@@ -2874,7 +3272,7 @@ int MEDFileUMesh::getMinFamilyIdInArrays() const
 int MEDFileUMesh::getMeshDimension() const
 {
   int lev=0;
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
+  for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++)
     if((const MEDFileUMeshSplitL1 *)(*it)!=0)
       return (*it)->getMeshDimension()+lev;
   throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !");
@@ -2891,7 +3289,7 @@ int MEDFileUMesh::getSpaceDimension() const
   const DataArrayDouble *coo=_coords;
   if(!coo)
     throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !");
-  return coo->getNumberOfComponents();
+  return (int)coo->getNumberOfComponents();
 }
 
 /*!
@@ -2943,6 +3341,7 @@ std::string MEDFileUMesh::simpleRepr() const
     }
   oss << std::endl << std::endl;
   getFamilyRepr(oss);
+  getEquivalencesRepr(oss);
   return oss.str();
 }
 
@@ -2958,10 +3357,10 @@ std::string MEDFileUMesh::advancedRepr() const
 /*!
  * Returns number of mesh entities of a given relative dimension in \a this mesh.
  *  \param [in] meshDimRelToMaxExt - the relative dimension of interest.
- *  \return int - the number of entities.
+ *  \return mcIdType - the number of entities.
  *  \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
  */
-int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
+mcIdType MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
 {
   if(meshDimRelToMaxExt==1)
     {
@@ -2975,10 +3374,10 @@ int MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
 /*!
  * Returns the family field for mesh entities of a given dimension.
  *  \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
- *  \return const DataArrayInt * - the family field. It is an array of ids of families
+ *  \return const DataArrayIdType * - the family field. It is an array of ids of families
  *          each mesh entity belongs to. It can be \c NULL.
  */
-const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
+const DataArrayIdType *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
 {
   if(meshDimRelToMaxExt==1)
     return _fam_coords;
@@ -2986,7 +3385,7 @@ const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
   return l1->getFamilyField();
 }
 
-DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
+DataArrayIdType *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
 {
   if(meshDimRelToMaxExt==1)
     return _fam_coords;
@@ -2997,10 +3396,10 @@ DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
 /*!
  * Returns the optional numbers of mesh entities of a given dimension.
  *  \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
- *  \return const DataArrayInt * - the array of the entity numbers.
+ *  \return const DataArrayIdType * - the array of the entity numbers.
  *  \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
  */
-const DataArrayInt *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
+const DataArrayIdType *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
 {
   if(meshDimRelToMaxExt==1)
     return _num_coords;
@@ -3016,6 +3415,13 @@ const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxE
   return l1->getNameField();
 }
 
+MCAuto<DataArrayIdType> MEDFileUMesh::getGlobalNumFieldAtLevel(int meshDimRelToMaxExt) const
+{
+  if(meshDimRelToMaxExt!=1)
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::getGlobalNumFieldAtLevel : not implemented yet for structured mesh !");
+  return _global_num_coords;
+}
+
 /*!
  * This method returns for a specified relative level \a meshDimRelToMaxExt the part effectively read (if the instance is the result of the read of a file).
  *
@@ -3031,7 +3437,7 @@ const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, IN
   return l1->getPartDef(gt);
 }
 
-int MEDFileUMesh::getNumberOfNodes() const
+mcIdType MEDFileUMesh::getNumberOfNodes() const
 {
   const DataArrayDouble *coo(_coords);
   if(!coo)
@@ -3039,7 +3445,7 @@ int MEDFileUMesh::getNumberOfNodes() const
   return coo->getNumberOfTuples();
 }
 
-int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
+mcIdType MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
 {
   const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
   return l1->getNumberOfCells();
@@ -3050,7 +3456,7 @@ bool MEDFileUMesh::hasImplicitPart() const
   return false;
 }
 
-int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
+mcIdType MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
 {
   throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !");
 }
@@ -3070,30 +3476,66 @@ void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, con
         m->computeNodeIdsAlg(nodesFetched);
       else
         {
-          const DataArrayInt *arr(globs->getProfile(st[i].getPflName()));
-          MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
+          const DataArrayIdType *arr(globs->getProfile(st[i].getPflName()));
+          MCAuto<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true)));
           m2->computeNodeIdsAlg(nodesFetched);
         }
     }
 }
 
+MEDFileMesh *MEDFileUMesh::cartesianize() const
+{
+  if(getAxisType()==AX_CART)
+    {
+      incrRef();
+      return const_cast<MEDFileUMesh *>(this);
+    }
+  else
+    {
+      MCAuto<MEDFileUMesh> ret(new MEDFileUMesh(*this));
+      const DataArrayDouble *coords(_coords);
+      if(!coords)
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::cartesianize : coordinates are null !");
+      MCAuto<DataArrayDouble> coordsCart(_coords->cartesianize(getAxisType()));
+      for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=ret->_ms.begin();it!=ret->_ms.end();it++)
+        if((const MEDFileUMeshSplitL1 *)(*it))
+          *it=(*it)->shallowCpyUsingCoords(coordsCart);
+      ret->_coords=coordsCart;
+      ret->setAxisType(AX_CART);
+      return ret.retn();
+    }
+}
+
+bool MEDFileUMesh::presenceOfStructureElements() const
+{
+  for(std::vector< MCAuto<MEDFileEltStruct4Mesh> >::const_iterator it=_elt_str.begin();it!=_elt_str.end();it++)
+    if((*it).isNotNull())
+      return true;
+  return false;
+}
+
+void MEDFileUMesh::killStructureElements()
+{
+  _elt_str.clear();
+}
+
 /*!
  * Returns the optional numbers of mesh entities of a given dimension transformed using
- * DataArrayInt::invertArrayN2O2O2N().
+ * DataArrayIdType::invertArrayN2O2O2N().
  *  \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
- *  \return const DataArrayInt * - the array of the entity numbers transformed using
- *          DataArrayInt::invertArrayN2O2O2N().
+ *  \return const DataArrayIdType * - the array of the entity numbers transformed using
+ *          DataArrayIdType::invertArrayN2O2O2N().
  *  \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
  */
-const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
+const DataArrayIdType *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
 {
   if(meshDimRelToMaxExt==1)
     {
-      if(!((const DataArrayInt *)_num_coords))
+      if(_num_coords.isNull())
         throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !");
       return _rev_num_coords;
     }
-  const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
+  const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt));
   return l1->getRevNumberField();
 }
 
@@ -3103,7 +3545,8 @@ const DataArrayInt *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxEx
  */
 DataArrayDouble *MEDFileUMesh::getCoords() const
 {
-  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(_coords);
+  checkCartesian();
+  MCAuto<DataArrayDouble> tmp(_coords);
   if((DataArrayDouble *)tmp)
     {
       return tmp;
@@ -3127,6 +3570,7 @@ DataArrayDouble *MEDFileUMesh::getCoords() const
  */
 MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const
 {
+  checkCartesian();
   synchronizeTinyInfoOnLeaves();
   std::vector<std::string> tmp(1);
   tmp[0]=grp;
@@ -3149,9 +3593,10 @@ MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::stri
  */
 MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const
 {
+  checkCartesian();
   synchronizeTinyInfoOnLeaves();
   std::vector<std::string> fams2=getFamiliesOnGroups(grps);
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
+  MCAuto<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum);
   if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet))
     zeRet->setName(grps[0]);
   return zeRet.retn();
@@ -3173,6 +3618,7 @@ MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vec
  */
 MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const
 {
+  checkCartesian();
   synchronizeTinyInfoOnLeaves();
   std::vector<std::string> tmp(1);
   tmp[0]=fam;
@@ -3195,18 +3641,19 @@ MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::str
  */
 MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
 {
+  checkCartesian();
   synchronizeTinyInfoOnLeaves();
   if(meshDimRelToMaxExt==1)
     {
-      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=getFamiliesArr(1,fams,renum);
-      MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
-      MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
+      MCAuto<DataArrayIdType> arr=getFamiliesArr(1,fams,renum);
+      MCAuto<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
+      MCAuto<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems());
       ret->setCoords(c);
       return ret.retn();
     }
-  std::vector<int> famIds=getFamiliesIds(fams);
+  std::vector<mcIdType> famIds=getFamiliesIds(fams);
   const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt);
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet;
+  MCAuto<MEDCouplingUMesh> zeRet;
   if(!famIds.empty())
     zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum);
   else
@@ -3223,23 +3670,23 @@ MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::v
  *  \param [in] fams - the names of the families of interest.
  *  \param [in] renum - if \c true, the optional numbers of entities, if available, are
  *          returned instead of ids.
- *  \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
+ *  \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
  *          numbers, if available and required, of mesh entities of the families. The caller
  *          is to delete this array using decrRef() as it is no more needed. 
  *  \throw If the family field is missing for \a meshDimRelToMaxExt.
  */
-DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
+DataArrayIdType *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
 {
-  std::vector<int> famIds=getFamiliesIds(fams);
+  std::vector<mcIdType> famIds=getFamiliesIds(fams);
   if(meshDimRelToMaxExt==1)
     {
-      if((const DataArrayInt *)_fam_coords)
+      if((const DataArrayIdType *)_fam_coords)
         {
-          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
+          MCAuto<DataArrayIdType> da;
           if(!famIds.empty())
-            da=_fam_coords->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
+            da=_fam_coords->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
           else
-            da=_fam_coords->getIdsEqualList(0,0);
+            da=_fam_coords->findIdsEqualList(0,0);
           if(renum)
             return MEDFileUMeshSplitL1::Renumber(_num_coords,da);
           else
@@ -3261,23 +3708,23 @@ DataArrayInt *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::ve
  * valid**. This is a feature, because MEDLoader does not create cells that do not exist! 
  * To build a valid MEDCouplingUMesh from the returned one in this case,
  * call MEDCouplingUMesh::Build0DMeshFromCoords().
- *  \param [in] meshDimRelToMax - the relative dimension of interest.
+ *  \param [in] meshDimRelToMaxExt - the relative dimension of interest.
  *  \param [in] renum - if \c true, the returned mesh is permuted according to the
  *          optional numbers of mesh entities.
  *  \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to
  *          delete using decrRef() as it is no more needed. 
  *  \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
- * \sa getGenMeshAtLevel()
  */
 MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const
 {
+  checkCartesian();
   synchronizeTinyInfoOnLeaves();
   if(meshDimRelToMaxExt==1)
     {
       if(!renum)
         {
           MEDCouplingUMesh *umesh=MEDCouplingUMesh::New();
-          MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> cc=_coords->deepCpy();
+          MCAuto<DataArrayDouble> cc=_coords->deepCopy();
           umesh->setCoords(cc);
           MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh);
           umesh->setName(getName());
@@ -3288,26 +3735,7 @@ MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renu
   return l1->getWholeMesh(renum);
 }
 
-/*!
- * Returns a MEDCouplingUMesh of a given relative dimension.
- * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not
- * valid**. This is a feature, because MEDLoader does not create cells that do not exist! 
- * To build a valid MEDCouplingUMesh from the returned one in this case,
- * call MEDCouplingUMesh::Build0DMeshFromCoords().
- *  \param [in] meshDimRelToMax - the relative dimension of interest.
- *  \param [in] renum - if \c true, the returned mesh is permuted according to the
- *          optional numbers of mesh entities.
- *  \return MEDCouplingMesh * - a pointer to MEDCouplingUMesh that the caller is to
- *          delete using decrRef() as it is no more needed. 
- *  \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a this mesh.
- * \sa getMeshAtLevel()
- */
-MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
-{
-  return getMeshAtLevel(meshDimRelToMax,renum);
-}
-
-std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
+std::vector<mcIdType> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const
 {
   const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax));
   return l1->getDistributionOfTypes();
@@ -3368,12 +3796,12 @@ MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const
 /*!
  * This method is for advanced users. There is two storing strategy of mesh in \a this.
  * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances.
- * When assignement is done the first one is done, which is not optimal in write mode for MED file.
+ * When assignment is done the first one is done, which is not optimal in write mode for MED file.
  * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode.
  */
 void MEDFileUMesh::forceComputationOfParts() const
 {
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
+  for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
     {
       const MEDFileUMeshSplitL1 *elt(*it);
       if(elt)
@@ -3389,6 +3817,7 @@ void MEDFileUMesh::forceComputationOfParts() const
  */
 std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const
 {
+  checkCartesian();
   const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax));
   return sp->getDirectUndergroundSingleGeoTypeMeshes();
 }
@@ -3400,12 +3829,37 @@ std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTy
  */
 MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const
 {
-  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
+  checkCartesian();
+  const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(gt));
   int lev=(int)cm.getDimension()-getMeshDimension();
   const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev));
   return sp->getDirectUndergroundSingleGeoTypeMesh(gt);
 }
 
+/*!
+ * This method returns for each geo types in \a this number of cells with this geo type.
+ * This method returns info as a vector of pair. The first element of pair is geo type and the second the number of cells associated.
+ * This method also returns the number of nodes of \a this (key associated is NORM_ERROR)
+ *
+ * \sa getDistributionOfTypes
+ */
+std::vector< std::pair<int,mcIdType> > MEDFileUMesh::getAllDistributionOfTypes() const
+{
+  std::vector< std::pair<int,mcIdType> > ret;
+  std::vector<int> nel(getNonEmptyLevels());
+  for(std::vector<int>::reverse_iterator it=nel.rbegin();it!=nel.rend();it++)
+    {
+      std::vector<INTERP_KERNEL::NormalizedCellType> gt(getGeoTypesAtLevel(*it));
+      for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator it1=gt.begin();it1!=gt.end();it1++)
+        {
+          mcIdType nbCells(getNumberOfCellsWithType(*it1));
+          ret.push_back(std::pair<int,mcIdType>(*it1,nbCells));
+        }
+    }
+  ret.push_back(std::pair<int,mcIdType>(INTERP_KERNEL::NORM_ERROR,getNumberOfNodes()));
+  return ret;
+}
+
 /*!
  * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this.
  * \throw if the reqsuested \a meshDimRelToMax does not exist.
@@ -3416,14 +3870,21 @@ std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(
   return sp->getGeoTypes();
 }
 
+mcIdType MEDFileUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
+{
+  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ct);
+  const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe( ((int)cm.getDimension())-getMeshDimension() ));
+  return sp->getNumberOfCellsWithType(ct);
+}
+
 /*!
  * This method extracts from whole family field ids the part relative to the input parameter \a gt.
  * \param [in] gt - the geometric type for which the family field is asked.
- * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
+ * \return DataArrayIdType * - a pointer to DataArrayIdType that the caller is to
  *          delete using decrRef() as it is no more needed.
  * \sa MEDFileUMesh::extractNumberFieldOnGeoType
  */
-DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
+DataArrayIdType *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
 {
   const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
   int lev=(int)cm.getDimension()-getMeshDimension();
@@ -3434,11 +3895,11 @@ DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::Normalize
 /*!
  * This method extracts from whole number field ids the part relative to the input parameter \a gt.
  * \param [in] gt - the geometric type for which the number field is asked.
- * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to
+ * \return DataArrayIdType * - a pointer to DataArrayIdType that the caller is to
  *          delete using decrRef() as it is no more needed.
  * \sa MEDFileUMesh::extractFamilyFieldOnGeoType
  */
-DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
+DataArrayIdType *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const
 {
   const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt);
   int lev=(int)cm.getDimension()-getMeshDimension();
@@ -3491,7 +3952,7 @@ void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const
   if(-meshDimRelToMax>=(int)_ms.size())
     throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !");
   int i=0;
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
+  for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++)
     {
       if(((const MEDFileUMeshSplitL1*) (*it))!=0)
         {
@@ -3511,14 +3972,45 @@ void MEDFileUMesh::setCoords(DataArrayDouble *coords)
 {
   if(!coords)
     throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !");
+  if(coords==(DataArrayDouble *)_coords)
+    return ;
   coords->checkAllocated();
-  int nbOfTuples=coords->getNumberOfTuples();
-  _coords=coords;
-  coords->incrRef();
-  _fam_coords=DataArrayInt::New();
+  mcIdType nbOfTuples(coords->getNumberOfTuples());
+  _coords.takeRef(coords);
+  _fam_coords=DataArrayIdType::New();
   _fam_coords->alloc(nbOfTuples,1);
   _fam_coords->fillWithZero();
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
+  _num_coords.nullify(); _rev_num_coords.nullify(); _name_coords.nullify(); _global_num_coords.nullify();
+  for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
+    if((MEDFileUMeshSplitL1 *)(*it))
+      (*it)->setCoords(coords);
+}
+
+/*!
+ * Change coords without changing anything concerning families and numbering on nodes.
+ */
+void MEDFileUMesh::setCoordsForced(DataArrayDouble *coords)
+{
+  if(!coords)
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : null pointer in input !");
+  if(coords==(DataArrayDouble *)_coords)
+    return ;
+  coords->checkAllocated();
+  mcIdType nbOfTuples(coords->getNumberOfTuples());
+  if(_coords.isNull())
+    {
+      _coords=coords;
+      coords->incrRef();
+    }
+  else
+    {
+      mcIdType oldNbTuples(_coords->getNumberOfTuples());
+      if(oldNbTuples!=nbOfTuples)
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoordsForced : number of tuples is not the same -> invoke setCoords instead !");
+      _coords=coords;
+      coords->incrRef();
+    }
+  for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
     if((MEDFileUMeshSplitL1 *)(*it))
       (*it)->setCoords(coords);
 }
@@ -3532,7 +4024,7 @@ void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
 {
   if(meshDimRelToMaxExt==1)
     {
-      if((DataArrayInt *)_fam_coords)
+      if((DataArrayIdType *)_fam_coords)
         _fam_coords->fillWithZero();
       return ;
     }
@@ -3547,17 +4039,17 @@ void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt)
 void MEDFileUMesh::optimizeFamilies()
 {
   std::vector<int> levs=getNonEmptyLevelsExt();
-  std::set<int> allFamsIds;
+  std::set<mcIdType> allFamsIds;
   for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
     {
-      const DataArrayInt *ffield=getFamilyFieldAtLevel(*it);
-      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=ffield->getDifferentValues();
-      std::set<int> res;
+      const DataArrayIdType *ffield=getFamilyFieldAtLevel(*it);
+      MCAuto<DataArrayIdType> ids=ffield->getDifferentValues();
+      std::set<mcIdType> res;
       std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin()));
       allFamsIds=res;
     }
   std::set<std::string> famNamesToKill;
-  for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
+  for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
     {
       if(allFamsIds.find((*it).second)!=allFamsIds.end())
         famNamesToKill.insert((*it).first);
@@ -3588,85 +4080,98 @@ void MEDFileUMesh::optimizeFamilies()
  * The boundary is built according to the following method:
  *  - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the
  * coordinates array is extended).
- *  - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated.
+ *  - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated. A new group
+ *  called "<grpNameM1>_dup" containing the effectively duplicated cells is created. Note that in 3D some cells of the group
+ *  might not be duplicated at all.
  *  After this operation a top-level cell bordering the group will loose some neighbors (typically the cell which is  on the
  *  other side of the group is no more a neighbor)
  *   - finally, the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells
  *  bordering the newly created boundary use the newly computed nodes.
+ *  Finally note that optional cell numbers are also affected by this method and might become invalid for SMESH.
+ *  Use clearNodeAndCellNumbers() afterwards to ensure a proper SMESH loading.
  *
  *  \param[in] grpNameM1 name of the (-1)-level group defining the boundary
  *  \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of
  *  the coord array)
  *  \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes)
  *  \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged.
+ *  \sa clearNodeAndCellNumbers()
  */
-void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated,
-                                           DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified)
+void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayIdType *&nodesDuplicated,
+                                           DataArrayIdType *&cellsModified, DataArrayIdType *&cellsNotModified)
 {
+  typedef MCAuto<MEDCouplingUMesh> MUMesh;
+  typedef MCAuto<DataArrayIdType> DAInt;
+
   std::vector<int> levs=getNonEmptyLevels();
   if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end())
-    throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh definied on level 0 and -1 !");
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0=getMeshAtLevel(0);
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1=getMeshAtLevel(-1);
-  int nbNodes=m0->getNumberOfNodes();
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m11=getGroup(-1,grpNameM1);
-  DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0;
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh defined on level 0 and -1 !");
+  MUMesh m0=getMeshAtLevel(0);
+  MUMesh m1=getMeshAtLevel(-1);
+  mcIdType nbNodes=m0->getNumberOfNodes();
+  MUMesh m11=getGroup(-1,grpNameM1);
+  DataArrayIdType *tmp00=0,*tmp11=0,*tmp22=0;
   m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22);
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodeIdsToDuplicate(tmp00);
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn0(tmp11);
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn1(tmp22);
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
+  DAInt nodeIdsToDuplicate(tmp00);
+  DAInt cellsToModifyConn0(tmp11);
+  DAInt cellsToModifyConn1(tmp22);
+  MUMesh tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true));
   // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New();
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
+  DAInt descTmp0=DataArrayIdType::New(),descITmp0=DataArrayIdType::New(),revDescTmp0=DataArrayIdType::New(),revDescITmp0=DataArrayIdType::New();
+  MUMesh tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0);
   descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0;
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
-  DataArrayInt *cellsInM1ToRenumW4Tmp=0;
+  DAInt cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false);
+  MUMesh cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true));
+  DataArrayIdType *cellsInM1ToRenumW4Tmp=0;
   m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp);
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW5=cellsInM1ToRenumW4->getIdsInRange(0,m1->getNumberOfCells());
+  DAInt cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp);
+  DAInt cellsInM1ToRenumW5=cellsInM1ToRenumW4->findIdsInRange(0,m1->getNumberOfCells());
   cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end());
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpIds=getGroupArr(-1,grpNameM1);
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
+  DAInt grpIds=getGroupArr(-1,grpNameM1);
+  DAInt cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds);
+  MUMesh m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true));
   m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes);
   m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part);
   // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1'
   tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end());
   m0->setCoords(tmp0->getCoords());
   m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0);
+  _ms[0]->forceComputationOfParts();  // necessary because we modify the connectivity of some internal part
   m1->setCoords(m0->getCoords());
   _coords=m0->getCoords(); _coords->incrRef();
-  // duplication of cells in group 'grpNameM1' on level -1
+  // duplication of cells in group 'grpNameM1' on level -1, but not duplicating cells for which nothing has changed
   m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords());
-  std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11;
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> szOfCellGrpOfSameType(tmp00);
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idInMsOfCellGrpOfSameType(tmp11);
+  DataArrayIdType * duplCells;
+  m1->areCellsIncludedIn(m11, 0, duplCells);
+  DAInt zeIds = duplCells->findIdsNotInRange(-1, m1->getNumberOfCells()-1); duplCells->decrRef();
+  MUMesh m11Part=static_cast<MEDCouplingUMesh *>(m11->buildPartOfMySelf(zeIds->begin(),zeIds->end(),true));
+  std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11Part;
+  MUMesh newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11);
+  DAInt szOfCellGrpOfSameType(tmp00);
+  DAInt idInMsOfCellGrpOfSameType(tmp11);
   //
   newm1->setName(getName());
-  const DataArrayInt *fam=getFamilyFieldAtLevel(-1);
+  const DataArrayIdType *fam=getFamilyFieldAtLevel(-1);
   if(!fam)
-    throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : internal problem !");
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFam=DataArrayInt::New();
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group(): internal error no family field !");
+  DAInt newFam=DataArrayIdType::New();
   newFam->alloc(newm1->getNumberOfCells(),1);
   // Get a new family ID: care must be taken if we need a positive ID or a negative one:
   // Positive ID for family of nodes, negative for all the rest.
-  int idd;
+  mcIdType idd;
   if (m1->getMeshDimension() == 0)
     idd=getMaxFamilyId()+1;
   else
     idd=getMinFamilyId()-1;
-  int globStart=0,start=0,end,globEnd;
-  int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
-  for(int i=0;i<nbOfChunks;i++)
+  mcIdType globStart=0,start=0,end,globEnd;
+  mcIdType nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples();
+  for(mcIdType i=0;i<nbOfChunks;i++)
     {
       globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0);
       if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0)
         {
           end=start+szOfCellGrpOfSameType->getIJ(i,0);
-          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part=fam->selectByTupleId2(start,end,1);
+          DAInt part=fam->selectByTupleIdSafeSlice(start,end,1);
           newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true);
           start=end;
         }
@@ -3686,69 +4191,81 @@ void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1,
   fam=_fam_coords;
   if(fam)
     {
-      int newNbOfNodes=getCoords()->getNumberOfTuples();
-      newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1);
+      mcIdType newNbOfNodes=getCoords()->getNumberOfTuples();
+      newFam=DataArrayIdType::New(); newFam->alloc(newNbOfNodes,1);
       newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true);
       newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1);
       _fam_coords=newFam;
     }
+
+  _num_coords.nullify(); _rev_num_coords.nullify(); _global_num_coords.nullify();
+  
+  for (std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();
+      it != _ms.end(); it++)
+    {
+      (*it)->_num = 0;
+      (*it)->_rev_num = 0;
+    }
   nodesDuplicated=nodeIdsToDuplicate.retn();
   cellsModified=cellsToModifyConn0.retn();
   cellsNotModified=cellsToModifyConn1.retn();
 }
 
-/*!
+/*! Similar to MEDCouplingUMesh::unPolyze():  converts all polygons (if \a this is a 2D mesh) or polyhedrons
+ * (if \a this is a 3D mesh) to cells of classical types. The cells remain correctly sorted by geometric type
+ * in this method.
+ *
  * \param [out] oldCode retrieves the distribution of types before the call if true is returned
- * \param [out] newCode etrieves the distribution of types after the call if true is returned
+ * \param [out] newCode retrieves the distribution of types after the call if true is returned
  * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells.
  * 
  * \return false if no modification has been performed linked to the unpolyzation. Neither cell type, not cell numbers. When false is returned no need of field on cells or on gauss renumbering.
  * Inversely, if true is returned, it means that distribution of cell by geometric type has changed and field on cell and field on gauss point must be renumbered.
  */
-bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
+bool MEDFileUMesh::unPolyze(std::vector<mcIdType>& oldCode, std::vector<mcIdType>& newCode, DataArrayIdType *& o2nRenumCell)
 {
   o2nRenumCell=0; oldCode.clear(); newCode.clear();
   std::vector<int> levs=getNonEmptyLevels();
   bool ret=false;
-  std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow
-  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
-  int start=0;
-  int end=0;
+  std::vector< const DataArrayIdType* > renumCellsSplited;//same than memorySaverIfThrow
+  std::vector< MCAuto<DataArrayIdType> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw
+  mcIdType start=0;
+  mcIdType end=0;
   for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++)
     {
-      MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*it);
-      std::vector<int> code1=m->getDistributionOfTypes();
+      MCAuto<MEDCouplingUMesh> m=getMeshAtLevel(*it);
+      std::vector<mcIdType> code1=m->getDistributionOfTypes();
       end=PutInThirdComponentOfCodeOffset(code1,start);
       oldCode.insert(oldCode.end(),code1.begin(),code1.end());
       bool hasChanged=m->unPolyze();
-      DataArrayInt *fake=0;
-      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
+      DataArrayIdType *fake=0;
+      MCAuto<DataArrayIdType> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER,
           MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake);
       fake->decrRef();
       renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart);
       if(hasChanged)
         {
-          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
+          MCAuto<DataArrayIdType> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel();
           m->renumberCells(o2nCellsPart2->getConstPointer(),false);
           ret=true;
-          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famField2,numField2;
-          const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); }
-          const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); }
+          MCAuto<DataArrayIdType> famField2,numField2;
+          const DataArrayIdType *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayIdType *>(famField); }
+          const DataArrayIdType *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayIdType *>(numField); }
           setMeshAtLevel(*it,m);
-          std::vector<int> code2=m->getDistributionOfTypes();
+          std::vector<mcIdType> code2=m->getDistributionOfTypes();
           end=PutInThirdComponentOfCodeOffset(code2,start);
           newCode.insert(newCode.end(),code2.begin(),code2.end());
           //
-          if(o2nCellsPart2->isIdentity())
+          if(o2nCellsPart2->isIota(o2nCellsPart2->getNumberOfTuples()))
             continue;
           if(famField)
             {
-              MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
+              MCAuto<DataArrayIdType> newFamField=famField->renumber(o2nCellsPart2->getConstPointer());
               setFamilyFieldArr(*it,newFamField);
             }
           if(numField)
             {
-              MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
+              MCAuto<DataArrayIdType> newNumField=numField->renumber(o2nCellsPart2->getConstPointer());
               setRenumFieldArr(*it,newNumField);
             }
         }
@@ -3760,8 +4277,8 @@ bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode
     }
   if(ret)
     {
-      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited);
-      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
+      MCAuto<DataArrayIdType> renumCells=DataArrayIdType::Aggregate(renumCellsSplited);
+      MCAuto<DataArrayIdType> o2nRenumCellRet=renumCells->buildPermArrPerLevel();
       o2nRenumCell=o2nRenumCellRet.retn();
     }
   return ret;
@@ -3771,28 +4288,28 @@ bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode
 struct MEDLoaderAccVisit1
 {
   MEDLoaderAccVisit1():_new_nb_of_nodes(0) { }
-  int operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
-  int _new_nb_of_nodes;
+  mcIdType operator()(bool val) { return val?_new_nb_of_nodes++:-1; }
+  mcIdType _new_nb_of_nodes;
 };
 /*! \endcond */
 
 /*!
- * Array returned is the correspondance in \b old \b to \b new format. The returned array is newly created and should be dealt by the caller.
+ * Array returned is the correspondence in \b old \b to \b new format. The returned array is newly created and should be dealt by the caller.
  * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method.
  * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes.
  * -1 values in returned array means that the corresponding old node is no more used.
  *
- * \return newly allocated array containing correspondance in \b old \b to \b new format. If all nodes in \a this are fetched \c NULL pointer is returned and nothing
+ * \return newly allocated array containing correspondence in \b old \b to \b new format. If all nodes in \a this are fetched \c NULL pointer is returned and nothing
  *         is modified in \a this.
  * \throw If no coordinates are set in \a this or if there is in any available mesh in \a this a cell having a nodal connectivity containing a node id not in the range of
  *  set coordinates.
  */
-DataArrayInt *MEDFileUMesh::zipCoords()
+DataArrayIdType *MEDFileUMesh::zipCoords()
 {
   const DataArrayDouble *coo(getCoords());
   if(!coo)
     throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !");
-  int nbOfNodes(coo->getNumberOfTuples());
+  mcIdType nbOfNodes(coo->getNumberOfTuples());
   std::vector<bool> nodeIdsInUse(nbOfNodes,false);
   std::vector<int> neLevs(getNonEmptyLevels());
   for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++)
@@ -3807,28 +4324,30 @@ DataArrayInt *MEDFileUMesh::zipCoords()
         }
       else
         {
-          MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
+          MCAuto<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false));
           mesh->computeNodeIdsAlg(nodeIdsInUse);
         }
     }
-  int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
+  mcIdType nbrOfNodesInUse((mcIdType)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true));
   if(nbrOfNodesInUse==nbOfNodes)
     return 0;//no need to update _part_coords
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1);
+  MCAuto<DataArrayIdType> ret(DataArrayIdType::New()); ret->alloc(nbOfNodes,1);
   std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1());
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
-  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamCoords;
-  MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> newNameCoords;
-  if((const DataArrayInt *)_fam_coords)
+  MCAuto<DataArrayIdType> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse));
+  MCAuto<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end()));
+  MCAuto<DataArrayIdType> newFamCoords;
+  MCAuto<DataArrayAsciiChar> newNameCoords;
+  if((const DataArrayIdType *)_fam_coords)
     newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumCoords;
-  if((const DataArrayInt *)_num_coords)
+  MCAuto<DataArrayIdType> newNumCoords,newGlobalNumCoords;
+  if(_num_coords.isNotNull())
     newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
-  if((const DataArrayAsciiChar *)_name_coords)
+  if(_global_num_coords.isNotNull())
+    newGlobalNumCoords=_global_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end());
+  if(_name_coords.isNotNull())
     newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()));
-  _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0;
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
+  _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _global_num_coords=newGlobalNumCoords; _name_coords=newNameCoords; _rev_num_coords.nullify();
+  for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
     {
       if((MEDFileUMeshSplitL1*)*it)
         {
@@ -3840,12 +4359,131 @@ DataArrayInt *MEDFileUMesh::zipCoords()
   const PartDefinition *pc(_part_coords);
   if(pc)
     {
-      MEDCouplingAutoRefCountObjectPtr<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
+      MCAuto<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2));
       _part_coords=tmpPD->composeWith(pc);
     }
   return ret.retn();
 }
 
+/*!
+ * This method is the extension of MEDCouplingUMesh::computeFetchedNodeIds. Except that here all levels are considered here.
+ * 
+ * \return newly allocated array containing all nodes in \a this that are part of nodal connectivity of at least one cell in \a this whatever its level.
+ */
+DataArrayIdType *MEDFileUMesh::computeFetchedNodeIds() const
+{
+  std::vector<int> neLevs(this->getNonEmptyLevels());
+  std::vector<bool> nodesHighlighted(this->getNumberOfNodes(),false);
+  for(auto lev : neLevs)
+  {
+    const MEDFileUMeshSplitL1 *zeLev(this->getMeshAtLevSafe(lev));
+    zeLev->highlightUsedNodes(nodesHighlighted);
+  }
+  return DataArrayIdType::BuildListOfSwitchedOn(nodesHighlighted);
+}
+
+/*!
+ * This method is a const method. It computes the minimal set of node ids covered by the cell extraction of \a this.
+ * The extraction of \a this is specified by the extractDef \a input map.
+ * This map tells for each level of cells, the cells kept in the extraction.
+ * 
+ * \return - a new reference of DataArrayIdType that represents sorted node ids, the extraction is lying on.
+ * \sa MEDFileField1TS::extractPart, MEDFileUMesh::extractPart
+ */
+DataArrayIdType *MEDFileUMesh::deduceNodeSubPartFromCellSubPart(const std::map<int, MCAuto<DataArrayIdType> >& extractDef) const
+{
+  std::vector<int> levs(getNonEmptyLevels());
+  std::vector<bool> fetchedNodes(getNumberOfNodes(),false);
+  for(std::map<int, MCAuto<DataArrayIdType> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
+    {
+      if((*it).first>1)
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid key ! Must be <=1 !");
+      if((*it).second.isNull())
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::deduceNodeSubPartFromCellSubPart : presence of a value with null pointer !");
+      if((*it).first==1)
+        continue;
+      if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
+        {
+          std::ostringstream oss; oss << "MEDFileUMesh::deduceNodeSubPartFromCellSubPart : invalid level " << (*it).first << " ! Not present in this !";
+          throw INTERP_KERNEL::Exception(oss.str());
+        }
+      MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
+      MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
+      mPart->computeNodeIdsAlg(fetchedNodes);
+    }
+  return DataArrayIdType::BuildListOfSwitchedOn(fetchedNodes);
+}
+
+/*!
+ * This method returns a new MEDFileUMesh that is the result of the extraction of cells/nodes in \a this.
+ * 
+ * \return - a new reference of MEDFileUMesh
+ * \sa MEDFileUMesh::deduceNodeSubPartFromCellSubPart, MEDFileFields::extractPart
+ */
+MEDFileUMesh *MEDFileUMesh::extractPart(const std::map<int, MCAuto<DataArrayIdType> >& extractDef) const
+{
+  MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New()); ret->setName(getName()); ret->copyFamGrpMapsFrom(*this);
+  std::vector<int> levs(getNonEmptyLevels());
+  for(std::map<int, MCAuto<DataArrayIdType> >::const_iterator it=extractDef.begin();it!=extractDef.end();it++)
+    {
+      if((*it).first>1)
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : invalid key ! Must be <=1 !");
+      if((*it).second.isNull())
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : presence of a value with null pointer !");
+      if((*it).first==1)
+        continue;
+      if(std::find(levs.begin(),levs.end(),(*it).first)==levs.end())
+        {
+          std::ostringstream oss; oss << "MEDFileUMesh::extractPart : invalid level " << (*it).first << " ! Not present in this !";
+          throw INTERP_KERNEL::Exception(oss.str());
+        }
+      MCAuto<MEDCouplingUMesh> m(getMeshAtLevel((*it).first));
+      MCAuto<MEDCouplingUMesh> mPart(m->buildPartOfMySelf((*it).second->begin(),(*it).second->end(),true));
+      ret->setMeshAtLevel((*it).first,mPart);
+      const DataArrayIdType *fam(getFamilyFieldAtLevel((*it).first)),*num(getNumberFieldAtLevel((*it).first));
+      if(fam)
+        {
+          MCAuto<DataArrayIdType> famPart(fam->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
+          ret->setFamilyFieldArr((*it).first,famPart);
+        }
+      if(num)
+        {
+          MCAuto<DataArrayIdType> numPart(num->selectByTupleIdSafe((*it).second->begin(),(*it).second->end()));
+          ret->setFamilyFieldArr((*it).first,numPart);
+        }
+    }
+  std::map<int, MCAuto<DataArrayIdType> >::const_iterator it2(extractDef.find(1));
+  if(it2!=extractDef.end())
+    {
+      const DataArrayDouble *coo(ret->getCoords());
+      if(!coo)
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::extractPart : trying to extract nodes whereas there is no nodes !");
+      MCAuto<DataArrayIdType> o2nNodes(((*it2).second)->invertArrayN2O2O2N(coo->getNumberOfTuples()));
+      MCAuto<DataArrayDouble> cooPart(coo->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
+      ret->setCoords(cooPart);
+      const DataArrayIdType *fam(getFamilyFieldAtLevel(1)),*num(getNumberFieldAtLevel(1));
+      if(fam)
+        {
+          MCAuto<DataArrayIdType> famPart(fam->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
+          ret->setFamilyFieldArr(1,famPart);
+        }
+      if(num)
+        {
+          MCAuto<DataArrayIdType> numPart(num->selectByTupleIdSafe((*it2).second->begin(),(*it2).second->end()));
+          ret->setFamilyFieldArr(1,numPart);
+        }
+      for(std::map<int, MCAuto<DataArrayIdType> >::const_iterator it3=extractDef.begin();it3!=extractDef.end();it3++)
+        {
+          if((*it3).first==1)
+            continue;
+          MCAuto<MEDCouplingUMesh> m(ret->getMeshAtLevel((*it3).first));
+          m->renumberNodesInConn(o2nNodes->begin());
+          ret->setMeshAtLevel((*it3).first,m);
+        }
+    }
+  return ret.retn();
+}
+
 /*!
  * This method performs an extrusion along a path defined by \a m1D.
  * \a this is expected to be a mesh with max mesh dimension equal to 2.
@@ -3862,34 +4500,35 @@ DataArrayInt *MEDFileUMesh::zipCoords()
  */
 MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const
 {
+  checkCartesian();
   if(getMeshDimension()!=2)
     throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !");
-  MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
-  m1D->checkCoherency();
+  MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
+  m1D->checkConsistencyLight();
   if(m1D->getMeshDimension()!=1)
     throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !");
-  int nbRep(m1D->getNumberOfCells());
+  mcIdType nbRep(m1D->getNumberOfCells());
   std::vector<int> levs(getNonEmptyLevels());
   std::vector<std::string> grps(getGroupsNames());
-  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > zeList;
+  std::vector< MCAuto<MEDCouplingUMesh> > zeList;
   DataArrayDouble *coords(0);
   std::size_t nbOfLevsOut(levs.size()+1);
-  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > o2ns(nbOfLevsOut);
+  std::vector< MCAuto<DataArrayIdType> > o2ns(nbOfLevsOut);
   for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
     {
-      MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
+      MCAuto<MEDCouplingUMesh> item(getMeshAtLevel(*lev));
       item=item->clone(false);
       item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data
-      MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCpy()));
+      MCAuto<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCopy()));
       tmp->changeSpaceDimension(3+(*lev),0.);
-      MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
+      MCAuto<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy));
       zeList.push_back(elt);
       if(*lev==0)
         coords=elt->getCoords();
     }
   if(!coords)
     throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !");
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
+  for(std::vector< MCAuto<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++)
     {
       (*it)->setName(getName());
       (*it)->setCoords(coords);
@@ -3897,12 +4536,12 @@ MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int p
   for(std::size_t ii=0;ii!=zeList.size();ii++)
     {
       int lev(levs[ii]);
-      MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt(zeList[ii]);
+      MCAuto<MEDCouplingUMesh> elt(zeList[ii]);
       if(lev<=-1)
         {
-          MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
-          MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt2(elt1->clone(false));
-          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(elt2->getNodalConnectivity()->deepCpy());
+          MCAuto<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1));
+          MCAuto<MEDCouplingUMesh> elt2(elt1->clone(false));
+          MCAuto<DataArrayIdType> tmp(elt2->getNodalConnectivity()->deepCopy());
           elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex());
           elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes());
           elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords());
@@ -3915,9 +4554,9 @@ MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int p
       o2ns[ii]=elt->sortCellsInMEDFileFrmt();
       ret->setMeshAtLevel(lev,elt);
     }
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
+  MCAuto<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2;
   endLev=endLev->clone(false); endLev->setCoords(coords);
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(endLev->getNodalConnectivity()->deepCpy());
+  MCAuto<DataArrayIdType> tmp(endLev->getNodalConnectivity()->deepCopy());
   endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex());
   endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes());
   endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2);
@@ -3928,18 +4567,18 @@ MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int p
   for(std::size_t ii=0;ii!=zeList.size();ii++)
     {
       int lev(levs[ii]);
-      std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > outGrps;
-      std::vector< const DataArrayInt * > outGrps2;
+      std::vector< MCAuto<DataArrayIdType> > outGrps;
+      std::vector< const DataArrayIdType * > outGrps2;
       if(lev<=-1)
         {
           for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
             {
-              MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr(getGroupArr(lev+1,*grp));
+              MCAuto<DataArrayIdType> grpArr(getGroupArr(lev+1,*grp));
               if(!grpArr->empty())
                 {
-                  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr1(grpArr->deepCpy()),grpArr2(grpArr->deepCpy());
-                  int offset0(zeList[ii]->getNumberOfCells());
-                  int offset1(offset0+getNumberOfCellsAtLevel(lev+1));
+                  MCAuto<DataArrayIdType> grpArr1(grpArr->deepCopy()),grpArr2(grpArr->deepCopy());
+                  mcIdType offset0(zeList[ii]->getNumberOfCells());
+                  mcIdType offset1(offset0+getNumberOfCellsAtLevel(lev+1));
                   grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1);
                   std::ostringstream oss; oss << grpArr2->getName() << "_top";
                   grpArr2->setName(oss.str());
@@ -3953,18 +4592,18 @@ MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int p
       //
       for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
         {
-          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr(getGroupArr(lev,*grp));
+          MCAuto<DataArrayIdType> grpArr(getGroupArr(lev,*grp));
           if(!grpArr->empty())
             {
-              int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
-              std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grpArrs(nbRep);
-              std::vector< const DataArrayInt *> grpArrs2(nbRep);
+              mcIdType nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev));
+              std::vector< MCAuto<DataArrayIdType> > grpArrs(nbRep);
+              std::vector< const DataArrayIdType *> grpArrs2(nbRep);
               for(int iii=0;iii<nbRep;iii++)
                 {
-                  grpArrs[iii]=grpArr->deepCpy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
+                  grpArrs[iii]=grpArr->deepCopy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion);
                   grpArrs2[iii]=grpArrs[iii];
                 }
-              MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArrExt(DataArrayInt::Aggregate(grpArrs2));
+              MCAuto<DataArrayIdType> grpArrExt(DataArrayIdType::Aggregate(grpArrs2));
               grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end());
               std::ostringstream grpName; grpName << *grp << "_extruded";
               grpArrExt->setName(grpName.str());
@@ -3974,14 +4613,14 @@ MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int p
         }
       ret->setGroupsAtLevel(lev,outGrps2);
     }
-  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > outGrps;
-  std::vector< const DataArrayInt * > outGrps2;
+  std::vector< MCAuto<DataArrayIdType> > outGrps;
+  std::vector< const DataArrayIdType * > outGrps2;
   for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++)
     {
-      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr1(getGroupArr(levs.back(),*grp));
+      MCAuto<DataArrayIdType> grpArr1(getGroupArr(levs.back(),*grp));
       if(grpArr1->empty())
         continue;
-      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr2(grpArr1->deepCpy());
+      MCAuto<DataArrayIdType> grpArr2(grpArr1->deepCopy());
       std::ostringstream grpName; grpName << *grp << "_top";
       grpArr2->setName(grpName.str());
       grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back()));
@@ -4006,56 +4645,57 @@ MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int p
  */
 MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
-  int initialNbNodes(getNumberOfNodes());
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCpy()));
+  checkCartesian();
+  MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
+  mcIdType initialNbNodes(getNumberOfNodes());
+  MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
+  MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
   {
-    MEDCouplingAutoRefCountObjectPtr<DataArrayInt> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
+    MCAuto<DataArrayIdType> notUsed(m0->convertLinearCellsToQuadratic(conversionType));
   }
   DataArrayDouble *zeCoords(m0->getCoords());
   ret->setMeshAtLevel(0,m0);
   std::vector<int> levs(getNonEmptyLevels());
-  const DataArrayInt *famField(getFamilyFieldAtLevel(0));
+  const DataArrayIdType *famField(getFamilyFieldAtLevel(0));
   if(famField)
     {
-      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
+      MCAuto<DataArrayIdType> famFieldCpy(famField->deepCopy());
       ret->setFamilyFieldArr(0,famFieldCpy);
     }
   famField=getFamilyFieldAtLevel(1);
   if(famField)
     {
-      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
+      MCAuto<DataArrayIdType> fam(DataArrayIdType::New()); fam->alloc(zeCoords->getNumberOfTuples(),1);
       fam->fillWithZero();
       fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1);
       ret->setFamilyFieldArr(1,fam);
     }
   ret->copyFamGrpMapsFrom(*this);
-  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> partZeCoords(zeCoords->selectByTupleId2(initialNbNodes,zeCoords->getNumberOfTuples(),1));
+  MCAuto<DataArrayDouble> partZeCoords(zeCoords->selectByTupleIdSafeSlice(initialNbNodes,zeCoords->getNumberOfTuples(),1));
   for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++)
     {
       if(*lev==0)
         continue;
-      MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
-      MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCpy()));
+      MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
+      MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
       if(m1->getMeshDimension()!=0)
         {
           {
-            MEDCouplingAutoRefCountObjectPtr<DataArrayInt> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
+            MCAuto<DataArrayIdType> notUsed(m1->convertLinearCellsToQuadratic(conversionType));
           }//kill unused notUsed var
-          MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleId2(initialNbNodes,m1->getNumberOfNodes(),1));
-          DataArrayInt *b(0);
+          MCAuto<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleIdSafeSlice(initialNbNodes,m1->getNumberOfNodes(),1));
+          DataArrayIdType *b(0);
           bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b));
-          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> bSafe(b);
+          MCAuto<DataArrayIdType> bSafe(b);
           if(!a)
             {
               std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !";
               throw INTERP_KERNEL::Exception(oss.str().c_str());
             }
           b->applyLin(1,initialNbNodes);
-          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota();
-          std::vector<const DataArrayInt *> v(2); v[0]=l0; v[1]=b;
-          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renum(DataArrayInt::Aggregate(v));
+          MCAuto<DataArrayIdType> l0(DataArrayIdType::New()); l0->alloc(initialNbNodes,1); l0->iota();
+          std::vector<const DataArrayIdType *> v(2); v[0]=l0; v[1]=b;
+          MCAuto<DataArrayIdType> renum(DataArrayIdType::Aggregate(v));
           m1->renumberNodesInConn(renum->begin());
         }
       m1->setCoords(zeCoords);
@@ -4063,7 +4703,7 @@ MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) co
       famField=getFamilyFieldAtLevel(*lev);
       if(famField)
         {
-          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
+          MCAuto<DataArrayIdType> famFieldCpy(famField->deepCopy());
           ret->setFamilyFieldArr(*lev,famFieldCpy);
         }
     }
@@ -4082,24 +4722,25 @@ MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) co
  */
 MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New());
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCpy()));
+  checkCartesian();
+  MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
+  MCAuto<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0));
+  MCAuto<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCopy()));
   m0->convertQuadraticCellsToLinear();
   m0->zipCoords();
   DataArrayDouble *zeCoords(m0->getCoords());
   ret->setMeshAtLevel(0,m0);
   std::vector<int> levs(getNonEmptyLevels());
-  const DataArrayInt *famField(getFamilyFieldAtLevel(0));
+  const DataArrayIdType *famField(getFamilyFieldAtLevel(0));
   if(famField)
     {
-      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
+      MCAuto<DataArrayIdType> famFieldCpy(famField->deepCopy());
       ret->setFamilyFieldArr(0,famFieldCpy);
     }
   famField=getFamilyFieldAtLevel(1);
   if(famField)
     {
-      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam(famField->selectByTupleId2(0,zeCoords->getNumberOfTuples(),1));
+      MCAuto<DataArrayIdType> fam(famField->selectByTupleIdSafeSlice(0,zeCoords->getNumberOfTuples(),1));
       ret->setFamilyFieldArr(1,fam);
     }
   ret->copyFamGrpMapsFrom(*this);
@@ -4107,13 +4748,13 @@ MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
     {
       if(*lev==0)
         continue;
-      MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
-      MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCpy()));
+      MCAuto<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev));
+      MCAuto<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCopy()));
       m1->convertQuadraticCellsToLinear();
       m1->zipCoords();
-      DataArrayInt *b(0);
+      DataArrayIdType *b(0);
       bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b));
-      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> bSafe(b);
+      MCAuto<DataArrayIdType> bSafe(b);
       if(!a)
         {
           std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !";
@@ -4125,42 +4766,268 @@ MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const
       famField=getFamilyFieldAtLevel(*lev);
       if(famField)
         {
-          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy());
+          MCAuto<DataArrayIdType> famFieldCpy(famField->deepCopy());
           ret->setFamilyFieldArr(*lev,famFieldCpy);
         }
     }
   return ret.retn();
 }
 
-void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD)
+/*!
+ * Computes the symmetry of \a this.
+ * \return a new object.
+ */
+MCAuto<MEDFileUMesh> MEDFileUMesh::symmetry3DPlane(const double point[3], const double normalVector[3]) const
+{
+  MCAuto<MEDFileUMesh> ret(deepCopy());
+  DataArrayDouble *myCoo(getCoords());
+  if(myCoo)
+    {
+      MCAuto<DataArrayDouble> newCoo(myCoo->symmetry3DPlane(point,normalVector));
+      ret->setCoordsForced(newCoo);
+    }
+  return ret;
+}
+
+/*!
+ * Aggregate the given MEDFileUMesh objects into a single mesh. When groups are present, those are
+ * merged in such a way that the final mesh contain all of them.
+ * \return a new object.
+ */
+MCAuto<MEDFileUMesh> MEDFileUMesh::Aggregate(const std::vector<const MEDFileUMesh *>& meshes)
+{
+  if(meshes.empty())
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : empty input vector !");
+  std::size_t sz(meshes.size()),i(0);
+  std::vector<const DataArrayDouble *> coos(sz);
+  std::vector<const DataArrayIdType *> fam_coos(sz),num_coos(sz);
+  for(auto it=meshes.begin();it!=meshes.end();it++,i++)
+    {
+      if(!(*it))
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : presence of NULL pointer in input vector !");
+      coos[i]=(*it)->getCoords();
+      fam_coos[i]=(*it)->getFamilyFieldAtLevel(1);
+      num_coos[i]=(*it)->getNumberFieldAtLevel(1);
+    }
+  const MEDFileUMesh *ref(meshes[0]);
+  int spaceDim(ref->getSpaceDimension()),meshDim(ref->getMeshDimension());
+  std::vector<int> levs(ref->getNonEmptyLevels());
+  std::map<int, std::vector<const DataArrayIdType *> > m_fam,m_renum;
+  std::map<int, std::vector< MCAuto< MEDCouplingUMesh > > > m_mesh2;
+  std::map<int, std::vector<const MEDCouplingUMesh *> > m_mesh;
+  std::map<std::string,mcIdType> famNumMap;
+  std::map<mcIdType, std::string> famNumMap_rev;
+  std::map<std::string, std::vector<std::string> > grpFamMap;
+  std::set< MCAuto<DataArrayIdType> > mem_cleanup;   // Memory clean-up. At set deletion (end of method), arrays will be deallocated.
+
+  // Identify min family number used:
+  mcIdType min_fam_num(0);
+  for(const auto& msh : meshes)
+    {
+      const std::map<std::string,mcIdType>& locMap1(msh->getFamilyInfo());
+      for(const auto& it3 : locMap1)
+        if(it3.second < min_fam_num)
+          min_fam_num = it3.second;
+    }
+
+  for(const auto& msh : meshes)
+    {
+      if(msh->getSpaceDimension()!=spaceDim)
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : space dimension must be homogeneous !");
+      if(msh->getMeshDimension()!=meshDim)
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : mesh dimension must be homogeneous !");
+      if(msh->getNonEmptyLevels()!=levs)
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : levels must be the same for elements in input vector !");
+
+      const std::map<std::string,mcIdType>& locMap1(msh->getFamilyInfo());
+      std::map<std::string, std::string> substitute;
+      std::map<mcIdType, mcIdType> substituteN;
+      bool fam_conflict(false);
+      for(const auto& it3 : locMap1)
+        {
+          const std::string& famName = it3.first;
+          mcIdType famNum = it3.second;
+          if (famNumMap_rev.find(famNum) != famNumMap_rev.end()) // Family number is already used!
+            {
+              // Is it used by a group of the current mesh or a group from a previous mesh?
+              // If not, this is OK (typically -1 familly).
+              bool used = false;
+              //    Current mesh
+              const std::map<std::string, std::vector<std::string> >& locMap2(msh->getGroupInfo());
+              for(const auto& it4 : locMap2)
+                {
+                  const auto& famLst = it4.second;
+                  if (std::find(famLst.begin(), famLst.end(), famName) != famLst.end())
+                    { used = true; break; }
+                }
+              //    Previous meshes ...
+              if (!used)
+                for(const auto& it4 : grpFamMap)
+                  {
+                    const auto& famLst = it4.second;
+                    if (std::find(famLst.begin(), famLst.end(), famName) != famLst.end())
+                      { used = true; break; }
+                  }
+
+              if(used)
+                { // Generate a new family name, and a new family number
+                  fam_conflict = true;
+                  std::ostringstream oss;
+                  oss << "Family_" << --min_fam_num;  // New ID
+                  std::string new_name(oss.str());
+                  substitute[famName] = new_name;
+                  substituteN[famNum] = min_fam_num;
+                  famNumMap[new_name] = min_fam_num;
+                  famNumMap_rev[min_fam_num] = new_name;
+                }
+            }
+          famNumMap[famName] = famNum;
+          famNumMap_rev[famNum] = famName;
+        }
+
+      for(const auto& level : levs)
+        {
+          MCAuto<MEDCouplingUMesh> locMesh(msh->getMeshAtLevel(level));
+          m_mesh[level].push_back(locMesh); m_mesh2[level].push_back(locMesh);
+          m_renum[level].push_back(msh->getNumberFieldAtLevel(level));
+
+          // Family field - substitute new family number if needed:
+          if(fam_conflict)
+            {
+              DataArrayIdType* dai(msh->getFamilyFieldAtLevel(level)->deepCopy());  // Need a copy
+              mem_cleanup.insert(MCAuto<DataArrayIdType>(dai));      // Make sure array will decrRef() at end of method
+              for (const auto& subN : substituteN)
+                dai->changeValue(subN.first, subN.second);
+              m_fam[level].push_back(dai);
+            }
+          else
+            m_fam[level].push_back(msh->getFamilyFieldAtLevel(level));      // No copy needed
+        }
+
+      const std::map<std::string, std::vector<std::string> >& locMap2(msh->getGroupInfo());
+      for(const auto& grpItem : locMap2)
+        {
+          const std::string& grpName = grpItem.first;
+          std::vector<std::string> famLst;
+          // Substitute family name in group description if needed:
+          if (fam_conflict)
+            {
+              famLst = grpItem.second;
+              for (const auto& sub : substitute)
+                std::replace(famLst.begin(), famLst.end(), sub.first, sub.second);
+            }
+          else
+            famLst = grpItem.second;
+
+          // Potentially merge groups (if same name):
+          const auto& it = grpFamMap.find(grpName);
+          if (it != grpFamMap.end())
+            {
+              // Group already exists, merge should be done. Normally we whould never
+              // have twice the same family name in famLstCur and famLst since we dealt with family number
+              // conflict just above ...
+              std::vector<std::string>& famLstCur = (*it).second;
+              famLstCur.insert(famLstCur.end(), famLst.begin(), famLst.end());
+            }
+          else
+            grpFamMap[grpName] = famLst;
+        }
+    }
+  // Easy part : nodes
+  MCAuto<MEDFileUMesh> ret(MEDFileUMesh::New());
+  MCAuto<DataArrayDouble> coo(DataArrayDouble::Aggregate(coos));
+  ret->setCoords(coo);
+  if(std::find(fam_coos.begin(),fam_coos.end(),(const DataArrayIdType *)0)==fam_coos.end())
+    {
+      MCAuto<DataArrayIdType> fam_coo(DataArrayIdType::Aggregate(fam_coos));
+      ret->setFamilyFieldArr(1,fam_coo);
+    }
+  if(std::find(num_coos.begin(),num_coos.end(),(const DataArrayIdType *)0)==num_coos.end())
+    {
+      MCAuto<DataArrayIdType> num_coo(DataArrayIdType::Aggregate(num_coos));
+      ret->setRenumFieldArr(1,num_coo);
+    }
+  // cells
+  for(const auto& level : levs)
+    {
+      auto it2(m_mesh.find(level));
+      if(it2==m_mesh.end())
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 1 !");
+      MCAuto<MEDCouplingUMesh> mesh(MEDCouplingUMesh::MergeUMeshes((*it2).second));
+      mesh->setCoords(coo); mesh->setName(ref->getName());
+      MCAuto<DataArrayIdType> renum(mesh->sortCellsInMEDFileFrmt());
+      ret->setMeshAtLevel(level,mesh);
+      auto it3(m_fam.find(level)),it4(m_renum.find(level));
+      if(it3==m_fam.end()) // Should never happen (all levels exist for all meshes)
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 2!");
+      if(it4==m_renum.end())
+        throw INTERP_KERNEL::Exception("MEDFileUMesh::Aggregate : internal error 3!");
+      // Set new family field if it was defined for all input meshes
+      const std::vector<const DataArrayIdType *>& fams((*it3).second);
+      if(std::find(fams.begin(),fams.end(),(const DataArrayIdType *)0)==fams.end())
+        {
+          MCAuto<DataArrayIdType> famm(DataArrayIdType::Aggregate(fams));
+          famm->renumberInPlace(renum->begin());
+          ret->setFamilyFieldArr(level,famm);
+        }
+      // Set optional number field if defined for all input meshes:
+      const std::vector<const DataArrayIdType *>& renums((*it4).second);
+      if(std::find(renums.begin(),renums.end(),(const DataArrayIdType *)0)==renums.end())
+        {
+          MCAuto<DataArrayIdType> renumm(DataArrayIdType::Aggregate(renums));
+          renumm->renumberInPlace(renum->begin());
+          ret->setRenumFieldArr(level,renumm);
+        }
+    }
+  //
+  ret->setFamilyInfo(famNumMap);
+  ret->setGroupInfo(grpFamMap);
+  ret->setName(ref->getName());
+  return ret;
+}
+
+MEDCouplingMappedExtrudedMesh *MEDFileUMesh::convertToExtrudedMesh() const
+{
+  if(getMeshDimension()!=3)
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : works only for 3D mesh !");
+  MCAuto<MEDCouplingUMesh> m3D(getMeshAtLevel(0)),m2D(getMeshAtLevel(-1));
+  if(m3D.isNull() || m2D.isNull())
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::convertToExtrudedMesh : this must be defined both at level 0 and level -1 !");
+  mcIdType zeId(std::numeric_limits<med_int>::max()-getFamilyId(GetSpeStr4ExtMesh()));
+  MCAuto<MEDCouplingMappedExtrudedMesh> ret(MEDCouplingMappedExtrudedMesh::New(m3D,m2D,zeId));
+  return ret.retn();
+}
+
+void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<mcIdType>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MCAuto<DataArrayIdType> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
 {
   clearNonDiscrAttributes();
   forceComputationOfParts();
   tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0;
-  std::vector<int> layer0;
-  layer0.push_back(_order); //0 i
-  layer0.push_back(_iteration);//1 i
-  layer0.push_back(getSpaceDimension());//2 i
+  std::vector<mcIdType> layer0;
+  layer0.push_back(getAxisType());//0 i
+  layer0.push_back(_order); //1 i
+  layer0.push_back(_iteration);//2 i
+  layer0.push_back(getSpaceDimension());//3 i
   tinyDouble.push_back(_time);//0 d
   tinyStr.push_back(_name);//0 s
   tinyStr.push_back(_desc_name);//1 s
   for(int i=0;i<getSpaceDimension();i++)
     tinyStr.push_back(_coords->getInfoOnComponent(i));
-  layer0.push_back((int)_families.size());//3 i <- key info aa layer#0
-  for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++)
+  layer0.push_back(ToIdType(_families.size()));//4 i <- key info aa layer#0
+  for(std::map<std::string,mcIdType>::const_iterator it=_families.begin();it!=_families.end();it++)
     {
       tinyStr.push_back((*it).first);
       layer0.push_back((*it).second);
     }
-  layer0.push_back((int)_groups.size());//3+aa i <- key info bb layer#0
+  layer0.push_back((mcIdType)_groups.size());//4+aa i <- key info bb layer#0
   for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++)
     {
-      layer0.push_back((int)(*it0).second.size());
+      layer0.push_back(ToIdType((*it0).second.size()));
       tinyStr.push_back((*it0).first);
       for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++)
         tinyStr.push_back(*it1);
     }
-  // sizeof(layer0)==3+aa+1+bb layer#0
+  // sizeof(layer0)==4+aa+1+bb layer#0
   bigArrayD=_coords;// 0 bd
   bigArraysI.push_back(_fam_coords);// 0 bi
   bigArraysI.push_back(_num_coords);// 1 bi
@@ -4169,15 +5036,15 @@ void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>&
     layer0.push_back(-1);
   else
     {
-      std::vector<int> tmp0;
+      std::vector<mcIdType> tmp0;
       pd->serialize(tmp0,bigArraysI);
-      tinyInt.push_back(tmp0.size());
+      tinyInt.push_back(ToIdType(tmp0.size()));
       tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end());
     }
   //
-  std::vector<int> layer1;
+  std::vector<mcIdType> layer1;
   std::vector<int> levs(getNonEmptyLevels());
-  layer1.push_back((int)levs.size());// 0 i <- key
+  layer1.push_back((mcIdType)levs.size());// 0 i <- key
   layer1.insert(layer1.end(),levs.begin(),levs.end());
   for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++)
     {
@@ -4185,19 +5052,19 @@ void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>&
       lev->serialize(layer1,bigArraysI);
     }
   // put layers all together.
-  tinyInt.push_back(layer0.size());
+  tinyInt.push_back(ToIdType(layer0.size()));
   tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end());
-  tinyInt.push_back(layer1.size());
+  tinyInt.push_back(ToIdType(layer1.size()));
   tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end());
 }
 
-void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr,
-                               std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD)
+void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<mcIdType>& tinyInt, std::vector<std::string>& tinyStr,
+                               std::vector< MCAuto<DataArrayIdType> >& bigArraysI, MCAuto<DataArrayDouble>& bigArrayD)
 {
-  int sz0(tinyInt[0]);
-  std::vector<int> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
-  int sz1(tinyInt[sz0+1]);
-  std::vector<int> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
+  mcIdType sz0(tinyInt[0]);
+  std::vector<mcIdType> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0);
+  mcIdType sz1(tinyInt[sz0+1]);
+  std::vector<mcIdType> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1);
   //
   std::reverse(layer0.begin(),layer0.end());
   std::reverse(layer1.begin(),layer1.end());
@@ -4205,9 +5072,10 @@ void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>
   std::reverse(tinyStr.begin(),tinyStr.end());
   std::reverse(bigArraysI.begin(),bigArraysI.end());
   //
-  _order=layer0.back(); layer0.pop_back();
-  _iteration=layer0.back(); layer0.pop_back();
-  int spaceDim(layer0.back()); layer0.pop_back();
+  setAxisType((MEDCouplingAxisType)layer0.back()); layer0.pop_back();
+  _order=FromIdType<int>(layer0.back()); layer0.pop_back();
+  _iteration=FromIdType<int>(layer0.back()); layer0.pop_back();
+  mcIdType spaceDim(layer0.back()); layer0.pop_back();
   _time=tinyDouble.back(); tinyDouble.pop_back();
   _name=tinyStr.back(); tinyStr.pop_back();
   _desc_name=tinyStr.back(); tinyStr.pop_back();
@@ -4217,21 +5085,21 @@ void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>
       _coords->setInfoOnComponent(i,tinyStr.back());
       tinyStr.pop_back();
     }
-  int nbOfFams(layer0.back()); layer0.pop_back();
+  mcIdType nbOfFams(layer0.back()); layer0.pop_back();
   _families.clear();
-  for(int i=0;i<nbOfFams;i++)
+  for(mcIdType i=0;i<nbOfFams;i++)
     {
       _families[tinyStr.back()]=layer0.back();
       tinyStr.pop_back(); layer0.pop_back();
     }
-  int nbGroups(layer0.back()); layer0.pop_back();
+  mcIdType nbGroups(layer0.back()); layer0.pop_back();
   _groups.clear();
-  for(int i=0;i<nbGroups;i++)
+  for(mcIdType i=0;i<nbGroups;i++)
     {
       std::string grpName(tinyStr.back()); tinyStr.pop_back();
-      int nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
+      mcIdType nbOfFamsOnGrp(layer0.back()); layer0.pop_back();
       std::vector<std::string> fams(nbOfFamsOnGrp);
-      for(int j=0;j<nbOfFamsOnGrp;j++)
+      for(mcIdType j=0;j<nbOfFamsOnGrp;j++)
         {
           fams[j]=tinyStr.back(); tinyStr.pop_back();
         }
@@ -4240,32 +5108,32 @@ void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>
   _fam_coords=bigArraysI.back(); bigArraysI.pop_back();
   _num_coords=bigArraysI.back(); bigArraysI.pop_back();
   _part_coords=0;
-  int isPd(layer0.back()); layer0.pop_back();
+  mcIdType isPd(layer0.back()); layer0.pop_back();
   if(isPd!=-1)
     {
-      std::vector<int> tmp0(layer0.begin(),layer0.begin()+isPd);
+      std::vector<mcIdType> tmp0(layer0.begin(),layer0.begin()+isPd);
       layer0.erase(layer0.begin(),layer0.begin()+isPd);
       _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI);
     }
   if(!layer0.empty())
     throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !");
   //
-  int nbLevs(layer1.back()); layer1.pop_back();
-  std::vector<int> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
+  mcIdType nbLevs(layer1.back()); layer1.pop_back();
+  std::vector<mcIdType> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end());
   _ms.clear();
-  int maxLev(-(*std::min_element(levs.begin(),levs.end())));
+  mcIdType maxLev(-(*std::min_element(levs.begin(),levs.end())));
   _ms.resize(maxLev+1);
-  for(int i=0;i<nbLevs;i++)
+  for(mcIdType i=0;i<nbLevs;i++)
     {
-      int lev(levs[i]);
-      int pos(-lev);
+      mcIdType lev(levs[i]);
+      mcIdType pos(-lev);
       _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI);
     }
 }
 
 /*!
  * Adds a group of nodes to \a this mesh.
- *  \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
+ *  \param [in] ids - a DataArrayIdType providing ids and a name of the group to add.
  *          The ids should be sorted and different each other (MED file norm).
  *
  *  \warning this method can alter default "FAMILLE_ZERO" family.
@@ -4277,14 +5145,14 @@ void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>
  *  \throw If \a ids does not respect the MED file norm.
  *  \throw If a group with name \a ids->getName() already exists.
  */
-void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
+void MEDFileUMesh::addNodeGroup(const DataArrayIdType *ids)
 {
   const DataArrayDouble *coords(_coords);
   if(!coords)
     throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !");
-  int nbOfNodes(coords->getNumberOfTuples());
-  if(!((DataArrayInt *)_fam_coords))
-    { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
+  mcIdType nbOfNodes(coords->getNumberOfTuples());
+  if(_fam_coords.isNull())
+    { _fam_coords=DataArrayIdType::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); }
   //
   addGroupUnderground(true,ids,_fam_coords);
 }
@@ -4292,7 +5160,7 @@ void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
 /*!
  * Adds a group of nodes/cells/faces/edges to \a this mesh.
  *
- *  \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
+ *  \param [in] ids - a DataArrayIdType providing ids and a name of the group to add.
  *          The ids should be sorted and different each other (MED file norm).
  *
  * \warning this method can alter default "FAMILLE_ZERO" family.
@@ -4304,7 +5172,7 @@ void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids)
  *  \throw If \a ids does not respect the MED file norm.
  *  \throw If a group with name \a ids->getName() already exists.
  */
-void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
+void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayIdType *ids)
 {
   std::vector<int> levs(getNonEmptyLevelsExt());
   if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end())
@@ -4315,7 +5183,7 @@ void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
   if(meshDimRelToMaxExt==1)
     { addNodeGroup(ids); return ; }
   MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt));
-  DataArrayInt *fam(lev->getOrCreateAndGetFamilyField());
+  DataArrayIdType *fam(lev->getOrCreateAndGetFamilyField());
   addGroupUnderground(false,ids,fam);
 }
 
@@ -4325,7 +5193,7 @@ void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
  *  \param [in] newFamName - the new family name.
  *  \throw If no family with the given \a id exists.
  */
-void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName)
+void MEDFileUMesh::setFamilyNameAttachedOnId(mcIdType id, const std::string& newFamName)
 {
   std::string oldName=getFamilyNameGivenId(id);
   _families.erase(oldName);
@@ -4360,7 +5228,7 @@ void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax)
  */
 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
+  MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m));
   checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
 }
 
@@ -4379,11 +5247,11 @@ void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m)
  */
 void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld)
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
+  MCAuto<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld));
   checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt;
 }
 
-MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
+MCAuto<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m)
 {
   dealWithTinyInfo(m);
   std::vector<int> levSet=getNonEmptyLevels();
@@ -4414,7 +5282,7 @@ MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiv
  *
  * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion.
  * \param [in] renum - the parameter (set to false by default) that tells the beheviour if there is a mesh on \a ms that is not geo type sorted.
- *                     If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false.
+ *                     If false, an exception is thrown. If true the mesh is reordered automatically. It is highly recommended to let this parameter to false.
  *
  * \throw If \a there is a null pointer in \a ms.
  * \sa MEDFileUMesh::setMeshAtLevel
@@ -4464,7 +5332,7 @@ void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bo
  *  \throw If the meshes in \a ms do not share the same node coordinates array.
  *  \throw If the node coordinates array of \a this mesh (if any) is not the same as that
  *         of the given meshes.
- *  \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
+ *  \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
  *  \throw If names of some meshes in \a ms are equal.
  *  \throw If \a ms includes a mesh with an empty name.
  */
@@ -4485,11 +5353,11 @@ void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<c
   else
     if((DataArrayDouble *)_coords!=coo)
       throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !");
-  std::vector<DataArrayInt *> corr;
-  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
-  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr3(corr.begin(),corr.end());
+  std::vector<DataArrayIdType *> corr;
+  MCAuto<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr);
+  std::vector< MCAuto<DataArrayIdType> > corr3(corr.begin(),corr.end());
   setMeshAtLevel(meshDimRelToMax,m,renum);
-  std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
+  std::vector<const DataArrayIdType *> corr2(corr.begin(),corr.end());
   setGroupsAtLevel(meshDimRelToMax,corr2,true);
 }
 
@@ -4508,7 +5376,7 @@ void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<c
  *  \throw If the meshes in \a ms do not share the same node coordinates array.
  *  \throw If the node coordinates array of \a this mesh (if any) is not the same as that
  *         of the given meshes.
- *  \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()).
+ *  \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkConsistencyLight()).
  *  \throw If names of some meshes in \a ms are equal.
  *  \throw If \a ms includes a mesh with an empty name.
  */
@@ -4530,11 +5398,11 @@ void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<con
     if((DataArrayDouble *)_coords!=coo)
       throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !");
   MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum);
-  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr(ms.size());
+  std::vector< MCAuto<DataArrayIdType> > corr(ms.size());
   int i=0;
   for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
     {
-      DataArrayInt *arr=0;
+      DataArrayIdType *arr=0;
       bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr);
       corr[i]=arr;
       if(!test)
@@ -4543,7 +5411,7 @@ void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<con
           throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
     }
-  std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end());
+  std::vector<const DataArrayIdType *> corr2(corr.begin(),corr.end());
   setGroupsAtLevel(meshDimRelToMax,corr2,renum);
 }
 
@@ -4553,7 +5421,7 @@ DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplin
   int mdim=ms[0]->getMeshDimension();
   for(unsigned int i=1;i<ms.size();i++)
     {
-      ms[i]->checkCoherency();
+      ms[i]->checkConsistencyLight();
       if(ms[i]->getCoords()!=ret)
         throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !");
       if(ms[i]->getMeshDimension()!=mdim)
@@ -4570,7 +5438,7 @@ DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplin
  *  \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
  *  \throw If \a famArr has an invalid size.
  */
-void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
+void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayIdType *famArr)
 {
   if(meshDimRelToMaxExt==1)
     {
@@ -4583,8 +5451,7 @@ void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famAr
       if(!coo)
         throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !");
       famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! ");
-      famArr->incrRef();
-      _fam_coords=famArr;
+      _fam_coords.takeRef(famArr);
       return ;
     }
   if(meshDimRelToMaxExt>1)
@@ -4604,23 +5471,20 @@ void MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famAr
  *  \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
  *  \throw If \a renumArr has an invalid size.
  */
-void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
+void MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayIdType *renumArr)
 {
   if(meshDimRelToMaxExt==1)
     {
       if(!renumArr)
         {
-          _num_coords=0;
-          _rev_num_coords=0;
+          _num_coords.nullify();
+          _rev_num_coords.nullify();
           return ;
         }
-      DataArrayDouble *coo(_coords);
-      if(!coo)
+      if(_coords.isNull())
         throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !");
-      renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
-      renumArr->incrRef();
-      _num_coords=renumArr;
-      computeRevNum();
+      renumArr->checkNbOfTuplesAndComp(_coords->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! ");
+      _num_coords.takeRef(renumArr);
       return ;
     }
   if(meshDimRelToMaxExt>1)
@@ -4653,8 +5517,7 @@ void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiCha
       if(!coo)
         throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !");
       nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! ");
-      nameArr->incrRef();
-      _name_coords=nameArr;
+      _name_coords.takeRef(nameArr);
       return ;
     }
   if(meshDimRelToMaxExt>1)
@@ -4667,9 +5530,18 @@ void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiCha
   return _ms[traducedRk]->setNameArr(nameArr);
 }
 
+void MEDFileUMesh::setGlobalNumFieldAtLevel(int meshDimRelToMaxExt, DataArrayIdType *globalNumArr)
+{
+  if(meshDimRelToMaxExt!=1)
+    throw INTERP_KERNEL::Exception("MEDFileUMesh::setGlobalNumFieldAtLevel : Only implemented for meshDimRelToMaxExt==1 for the moment !");
+  if(globalNumArr)
+    globalNumArr->checkNbOfTuplesAndComp(_coords->getNumberOfTuples(),1,"MEDFileUMesh::setGlobalNumFieldAtLevel : Problem in size of node global numbering arr ! ");
+  _global_num_coords.takeRef(globalNumArr);
+}
+
 void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
 {
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
+  for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
     if((const MEDFileUMeshSplitL1 *)(*it))
       (*it)->synchronizeTinyInfo(*this);
 }
@@ -4677,12 +5549,12 @@ void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const
 /*!
  * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification.
  */
-void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
+void MEDFileUMesh::changeFamilyIdArr(mcIdType oldId, mcIdType newId)
 {
-  DataArrayInt *arr=_fam_coords;
+  DataArrayIdType *arr=_fam_coords;
   if(arr)
     arr->changeValue(oldId,newId);
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
+  for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++)
     {
       MEDFileUMeshSplitL1 *sp=(*it);
       if(sp)
@@ -4692,20 +5564,20 @@ void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId)
     }
 }
 
-std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const
+std::list< MCAuto<DataArrayIdType> > MEDFileUMesh::getAllNonNullFamilyIds() const
 {
-  std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
-  const DataArrayInt *da(_fam_coords);
+  std::list< MCAuto<DataArrayIdType> > ret;
+  const DataArrayIdType *da(_fam_coords);
   if(da)
-    { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
+    { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
+  for(std::vector< MCAuto<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++)
     {
       const MEDFileUMeshSplitL1 *elt(*it);
       if(elt)
         {
           da=elt->getFamilyField();
           if(da)
-            { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
+            { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
         }
     }
   return ret;
@@ -4713,10 +5585,10 @@ std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileUMesh::getAll
 
 void MEDFileUMesh::computeRevNum() const
 {
-  if((const DataArrayInt *)_num_coords)
+  if(_num_coords.isNotNull())
     {
-      int pos;
-      int maxValue=_num_coords->getMaxValue(pos);
+      mcIdType pos;
+      mcIdType maxValue=_num_coords->getMaxValue(pos);
       _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1);
     }
 }
@@ -4729,79 +5601,79 @@ std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const
 std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const
 {
   std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull());
-  ret.push_back((const DataArrayInt *)_fam_nodes);
-  ret.push_back((const DataArrayInt *)_num_nodes);
+  ret.push_back((const DataArrayIdType *)_fam_nodes);
+  ret.push_back((const DataArrayIdType *)_num_nodes);
   ret.push_back((const DataArrayAsciiChar *)_names_nodes);
-  ret.push_back((const DataArrayInt *)_fam_cells);
-  ret.push_back((const DataArrayInt *)_num_cells);
+  ret.push_back((const DataArrayIdType *)_fam_cells);
+  ret.push_back((const DataArrayIdType *)_num_cells);
   ret.push_back((const DataArrayAsciiChar *)_names_cells);
-  ret.push_back((const DataArrayInt *)_fam_faces);
-  ret.push_back((const DataArrayInt *)_num_faces);
-  ret.push_back((const DataArrayInt *)_rev_num_nodes);
+  ret.push_back((const DataArrayIdType *)_fam_faces);
+  ret.push_back((const DataArrayIdType *)_num_faces);
+  ret.push_back((const DataArrayIdType *)_rev_num_nodes);
   ret.push_back((const DataArrayAsciiChar *)_names_faces);
-  ret.push_back((const DataArrayInt *)_rev_num_cells);
+  ret.push_back((const DataArrayIdType *)_rev_num_cells);
   ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary);
   return ret;
 }
 
-int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
+mcIdType MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const
 {
-  int ret=-std::numeric_limits<int>::max(),tmp=-1;
-  if((const DataArrayInt *)_fam_nodes)
+  mcIdType ret=-std::numeric_limits<mcIdType>::max(),tmp=-1;
+  if((const DataArrayIdType *)_fam_nodes)
     {
-      int val=_fam_nodes->getMaxValue(tmp);
+      mcIdType val=_fam_nodes->getMaxValue(tmp);
       ret=std::max(ret,std::abs(val));
     }
-  if((const DataArrayInt *)_fam_cells)
+  if((const DataArrayIdType *)_fam_cells)
     {
-      int val=_fam_cells->getMaxValue(tmp);
+      mcIdType val=_fam_cells->getMaxValue(tmp);
       ret=std::max(ret,std::abs(val));
     }
-  if((const DataArrayInt *)_fam_faces)
+  if((const DataArrayIdType *)_fam_faces)
     {
-      int val=_fam_faces->getMaxValue(tmp);
+      mcIdType val=_fam_faces->getMaxValue(tmp);
       ret=std::max(ret,std::abs(val));
     }
   return ret;
 }
 
-int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
+mcIdType MEDFileStructuredMesh::getMaxFamilyIdInArrays() const
 {
-  int ret=-std::numeric_limits<int>::max(),tmp=-1;
-  if((const DataArrayInt *)_fam_nodes)
+  mcIdType ret=-std::numeric_limits<mcIdType>::max(),tmp=-1;
+  if((const DataArrayIdType *)_fam_nodes)
     {
-      int val=_fam_nodes->getMaxValue(tmp);
+      mcIdType val=_fam_nodes->getMaxValue(tmp);
       ret=std::max(ret,val);
     }
-  if((const DataArrayInt *)_fam_cells)
+  if((const DataArrayIdType *)_fam_cells)
     {
-      int val=_fam_cells->getMaxValue(tmp);
+      mcIdType val=_fam_cells->getMaxValue(tmp);
       ret=std::max(ret,val);
     }
-  if((const DataArrayInt *)_fam_faces)
+  if((const DataArrayIdType *)_fam_faces)
     {
-      int val=_fam_faces->getMaxValue(tmp);
+      mcIdType val=_fam_faces->getMaxValue(tmp);
       ret=std::max(ret,val);
     }
   return ret;
 }
 
-int MEDFileStructuredMesh::getMinFamilyIdInArrays() const
+mcIdType MEDFileStructuredMesh::getMinFamilyIdInArrays() const
 {
-  int ret=std::numeric_limits<int>::max(),tmp=-1;
-  if((const DataArrayInt *)_fam_nodes)
+  mcIdType ret=std::numeric_limits<mcIdType>::max(),tmp=-1;
+  if((const DataArrayIdType *)_fam_nodes)
     {
-      int val=_fam_nodes->getMinValue(tmp);
+      mcIdType val=_fam_nodes->getMinValue(tmp);
       ret=std::min(ret,val);
     }
-  if((const DataArrayInt *)_fam_cells)
+  if((const DataArrayIdType *)_fam_cells)
     {
-      int val=_fam_cells->getMinValue(tmp);
+      mcIdType val=_fam_cells->getMinValue(tmp);
       ret=std::min(ret,val);
     }
-  if((const DataArrayInt *)_fam_faces)
+  if((const DataArrayIdType *)_fam_faces)
     {
-      int val=_fam_faces->getMinValue(tmp);
+      mcIdType val=_fam_faces->getMinValue(tmp);
       ret=std::min(ret,val);
     }
   return ret;
@@ -4817,8 +5689,8 @@ bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::s
       what="Mesh types differ ! This is structured and other is NOT !";
       return false;
     }
-  const DataArrayInt *famc1=_fam_nodes;
-  const DataArrayInt *famc2=otherC->_fam_nodes;
+  const DataArrayIdType *famc1=_fam_nodes;
+  const DataArrayIdType *famc2=otherC->_fam_nodes;
   if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0))
     {
       what="Mismatch of families arr on nodes ! One is defined and not other !";
@@ -4967,24 +5839,24 @@ bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::s
 void MEDFileStructuredMesh::clearNonDiscrAttributes() const
 {
   MEDFileMesh::clearNonDiscrAttributes();
-  const DataArrayInt *tmp=_fam_nodes;
+  const DataArrayIdType *tmp=_fam_nodes;
   if(tmp)
-    (const_cast<DataArrayInt *>(tmp))->setName("");
+    (const_cast<DataArrayIdType *>(tmp))->setName("");
   tmp=_num_nodes;
   if(tmp)
-    (const_cast<DataArrayInt *>(tmp))->setName("");
+    (const_cast<DataArrayIdType *>(tmp))->setName("");
   tmp=_fam_cells;
   if(tmp)
-    (const_cast<DataArrayInt *>(tmp))->setName("");
+    (const_cast<DataArrayIdType *>(tmp))->setName("");
   tmp=_num_cells;
   if(tmp)
-    (const_cast<DataArrayInt *>(tmp))->setName("");
+    (const_cast<DataArrayIdType *>(tmp))->setName("");
   tmp=_fam_faces;
   if(tmp)
-    (const_cast<DataArrayInt *>(tmp))->setName("");
+    (const_cast<DataArrayIdType *>(tmp))->setName("");
   tmp=_num_faces;
   if(tmp)
-    (const_cast<DataArrayInt *>(tmp))->setName("");
+    (const_cast<DataArrayIdType *>(tmp))->setName("");
 }
 
 /*!
@@ -4994,25 +5866,25 @@ void MEDFileStructuredMesh::clearNonDiscrAttributes() const
  *  \param [in] fams - the names of the families of interest.
  *  \param [in] renum - if \c true, the optional numbers of entities, if available, are
  *          returned instead of ids.
- *  \return DataArrayInt * - a new instance of DataArrayInt holding either ids or
+ *  \return DataArrayIdType * - a new instance of DataArrayIdType holding either ids or
  *          numbers, if available and required, of mesh entities of the families. The caller
  *          is to delete this array using decrRef() as it is no more needed. 
  *  \throw If the family field is missing for \a meshDimRelToMaxExt.
  */
-DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
+DataArrayIdType *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const
 {
-  std::vector<int> famIds(getFamiliesIds(fams));
+  std::vector<mcIdType> famIds(getFamiliesIds(fams));
   switch(meshDimRelToMaxExt)
   {
     case 1:
       {
-        if((const DataArrayInt *)_fam_nodes)
+        if((const DataArrayIdType *)_fam_nodes)
           {
-            MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
+            MCAuto<DataArrayIdType> da;
             if(!famIds.empty())
-              da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
+              da=_fam_nodes->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
             else
-              da=_fam_nodes->getIdsEqualList(0,0);
+              da=_fam_nodes->findIdsEqualList(0,0);
             if(renum)
               return MEDFileUMeshSplitL1::Renumber(_num_nodes,da);
             else
@@ -5024,13 +5896,13 @@ DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, cons
       }
     case 0:
       {
-        if((const DataArrayInt *)_fam_cells)
+        if((const DataArrayIdType *)_fam_cells)
           {
-            MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
+            MCAuto<DataArrayIdType> da;
             if(!famIds.empty())
-              da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
+              da=_fam_cells->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
             else
-              da=_fam_cells->getIdsEqualList(0,0);
+              da=_fam_cells->findIdsEqualList(0,0);
             if(renum)
               return MEDFileUMeshSplitL1::Renumber(_num_cells,da);
             else
@@ -5042,13 +5914,13 @@ DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, cons
       }
     case -1:
       {
-        if((const DataArrayInt *)_fam_faces)
+        if((const DataArrayIdType *)_fam_faces)
           {
-            MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da;
+            MCAuto<DataArrayIdType> da;
             if(!famIds.empty())
-              da=_fam_faces->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
+              da=_fam_faces->findIdsEqualList(&famIds[0],&famIds[0]+famIds.size());
             else
-              da=_fam_faces->getIdsEqualList(0,0);
+              da=_fam_faces->findIdsEqualList(0,0);
             if(renum)
               return MEDFileUMeshSplitL1::Renumber(_num_faces,da);
             else
@@ -5073,7 +5945,7 @@ DataArrayInt *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, cons
  *  \throw If \a famArr has an invalid size.
  *  \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1.
  */
-void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr)
+void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayIdType *famArr)
 {
   const MEDCouplingStructuredMesh *mesh(getStructuredMesh());
   if(!mesh)
@@ -5082,22 +5954,25 @@ void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayI
   {
     case 0:
       {
-        int nbCells=mesh->getNumberOfCells();
-        famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
+        mcIdType nbCells(mesh->getNumberOfCells());
+        if(famArr)
+          famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !");
         _fam_cells=famArr;
         break;
       }
     case 1:
       {
-        int nbNodes=mesh->getNumberOfNodes();
-        famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
+        mcIdType nbNodes(mesh->getNumberOfNodes());
+        if(famArr)
+          famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
         _fam_nodes=famArr;
         break;
       }
     case -1:
       {
-        int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
-        famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
+        mcIdType nbCells(mesh->getNumberOfCellsOfSubLevelMesh());
+        if(famArr)
+          famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !");
         _fam_faces=famArr;
         break;
       }
@@ -5116,7 +5991,7 @@ void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayI
  *  \throw If \a renumArr has an invalid size.
  *  \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
  */
-void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr)
+void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayIdType *renumArr)
 {
   const MEDCouplingStructuredMesh *mesh=getStructuredMesh();
   if(!mesh)
@@ -5125,21 +6000,21 @@ void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayIn
   {
     case 0:
       {
-        int nbCells=mesh->getNumberOfCells();
+        mcIdType nbCells=mesh->getNumberOfCells();
         renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !");
         _num_cells=renumArr;
         break;
       }
     case 1:
       {
-        int nbNodes=mesh->getNumberOfNodes();
+        mcIdType nbNodes=mesh->getNumberOfNodes();
         renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !");
         _num_nodes=renumArr;
         break;
       }
     case -1:
       {
-        int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
+        mcIdType nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
         renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !");
         _num_faces=renumArr;
         break;
@@ -5167,23 +6042,24 @@ void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArra
   {
     case 0:
       {
-        int nbCells=mesh->getNumberOfCells();
+        mcIdType nbCells=mesh->getNumberOfCells();
         nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !");
         _names_cells=nameArr;
         break;
       }
     case 1:
       {
-        int nbNodes=mesh->getNumberOfNodes();
+        mcIdType nbNodes=mesh->getNumberOfNodes();
         nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !");
         _names_nodes=nameArr;
         break;
       }
     case -1:
       {
-        int nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
+        mcIdType nbCells=mesh->getNumberOfCellsOfSubLevelMesh();
         nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !");
-        _names_cells=nameArr;
+        _names_faces=nameArr;
+        break;
       }
     default:
       throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !");
@@ -5192,9 +6068,14 @@ void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArra
     nameArr->incrRef();
 }
 
+void MEDFileStructuredMesh::setGlobalNumFieldAtLevel(int meshDimRelToMaxExt, DataArrayIdType *globalNumArr)
+{
+  throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setGlobalNumFieldAtLevel : not implemented yet !");
+}
+
 /*!
  * Adds a group of nodes to \a this mesh.
- *  \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
+ *  \param [in] ids - a DataArrayIdType providing ids and a name of the group to add.
  *          The ids should be sorted and different each other (MED file norm).
  *
  *  \warning this method can alter default "FAMILLE_ZERO" family.
@@ -5206,7 +6087,7 @@ void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArra
  *  \throw If \a ids does not respect the MED file norm.
  *  \throw If a group with name \a ids->getName() already exists.
  */
-void MEDFileStructuredMesh::addNodeGroup(const DataArrayInt *ids)
+void MEDFileStructuredMesh::addNodeGroup(const DataArrayIdType *ids)
 {
   addGroup(1,ids);
 }
@@ -5214,7 +6095,7 @@ void MEDFileStructuredMesh::addNodeGroup(const DataArrayInt *ids)
 /*!
  * Adds a group of nodes/cells/faces/edges to \a this mesh.
  *
- *  \param [in] ids - a DataArrayInt providing ids and a name of the group to add.
+ *  \param [in] ids - a DataArrayIdType providing ids and a name of the group to add.
  *          The ids should be sorted and different each other (MED file norm).
  *
  * \warning this method can alter default "FAMILLE_ZERO" family.
@@ -5226,9 +6107,9 @@ void MEDFileStructuredMesh::addNodeGroup(const DataArrayInt *ids)
  *  \throw If \a ids does not respect the MED file norm.
  *  \throw If a group with name \a ids->getName() already exists.
  */
-void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids)
+void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayIdType *ids)
 {
-  DataArrayInt *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt));
+  DataArrayIdType *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt));
   addGroupUnderground(false,ids,fam);
   return ;
 }
@@ -5236,11 +6117,11 @@ void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt
 /*!
  * Returns the family field for mesh entities of a given dimension.
  *  \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
- *  \return const DataArrayInt * - the family field. It is an array of ids of families
+ *  \return const DataArrayIdType * - the family field. It is an array of ids of families
  *          each mesh entity belongs to. It can be \c NULL.
  *  \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
  */
-const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
+const DataArrayIdType *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const
 {
   switch(meshDimRelToMaxExt)
   {
@@ -5258,11 +6139,11 @@ const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelT
 /*!
  * Returns the family field for mesh entities of a given dimension.
  *  \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
- *  \return const DataArrayInt * - the family field. It is an array of ids of families
+ *  \return const DataArrayIdType * - the family field. It is an array of ids of families
  *          each mesh entity belongs to. It can be \c NULL.
  *  \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
  */
-DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
+DataArrayIdType *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt)
 {
   switch(meshDimRelToMaxExt)
   {
@@ -5280,11 +6161,11 @@ DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxEx
 /*!
  * Returns the optional numbers of mesh entities of a given dimension.
  *  \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
- *  \return const DataArrayInt * - the array of the entity numbers.
+ *  \return const DataArrayIdType * - the array of the entity numbers.
  *  \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
  *  \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
  */
-const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
+const DataArrayIdType *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const
 {
   switch(meshDimRelToMaxExt)
   {
@@ -5301,23 +6182,23 @@ const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelT
 
 /*!
  * Returns the optional numbers of mesh entities of a given dimension transformed using
- * DataArrayInt::invertArrayN2O2O2N().
+ * DataArrayIdType::invertArrayN2O2O2N().
  *  \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities.
- *  \return const DataArrayInt * - the array of the entity numbers transformed using
- *          DataArrayInt::invertArrayN2O2O2N().
+ *  \return const DataArrayIdType * - the array of the entity numbers transformed using
+ *          DataArrayIdType::invertArrayN2O2O2N().
  *  \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1.
  *  \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh.
  */
-const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
+const DataArrayIdType *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const
 {
   if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1)
     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !");
   if(meshDimRelToMaxExt==0)
     {
-      if((const DataArrayInt *)_num_cells)
+      if((const DataArrayIdType *)_num_cells)
         {
-          int pos;
-          int maxValue=_num_cells->getMaxValue(pos);
+          mcIdType pos;
+          mcIdType maxValue=_num_cells->getMaxValue(pos);
           _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1);
           return _rev_num_cells;
         }
@@ -5326,10 +6207,10 @@ const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimR
     }
   else
     {
-      if((const DataArrayInt *)_num_nodes)
+      if((const DataArrayIdType *)_num_nodes)
         {
-          int pos;
-          int maxValue=_num_nodes->getMaxValue(pos);
+          mcIdType pos;
+          mcIdType maxValue=_num_nodes->getMaxValue(pos);
           _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1);
           return _rev_num_nodes;
         }
@@ -5353,6 +6234,11 @@ const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDim
   }
 }
 
+MCAuto<DataArrayIdType> MEDFileStructuredMesh::getGlobalNumFieldAtLevel(int meshDimRelToMaxExt) const
+{
+  throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGlobalNumFieldAtLevel : not implemented yet for structured mesh !");
+}
+
 /*!
  * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh.
  *  \return std::vector<int> - a sequence of the relative dimensions: [0].
@@ -5380,7 +6266,7 @@ std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const
 std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
 {
   std::vector<int> ret;
-  const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
+  const DataArrayIdType *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces);
   if(famNodes)
     ret.push_back(1);
   if(famCells)
@@ -5396,7 +6282,7 @@ std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const
 std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const
 {
   std::vector<int> ret;
-  const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
+  const DataArrayIdType *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces);
   if(numNodes)
     ret.push_back(1);
   if(numCells)
@@ -5425,15 +6311,15 @@ std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const
 /*!
  * no implementation here, it is not a bug, but intresically no polyhedra in \a this.
  */
-bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell)
+bool MEDFileStructuredMesh::unPolyze(std::vector<mcIdType>& oldCode, std::vector<mcIdType>& newCode, DataArrayIdType *& o2nRenumCell)
 {
   oldCode.clear(); newCode.clear(); o2nRenumCell=0;
   return false;
 }
 
-void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
+void MEDFileStructuredMesh::changeFamilyIdArr(mcIdType oldId, mcIdType newId)
 {
-  DataArrayInt *arr=_fam_nodes;
+  DataArrayIdType *arr=_fam_nodes;
   if(arr)
     arr->changeValue(oldId,newId);
   arr=_fam_cells;
@@ -5444,49 +6330,49 @@ void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId)
     arr->changeValue(oldId,newId);
 }
 
-std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileStructuredMesh::getAllNonNullFamilyIds() const
+std::list< MCAuto<DataArrayIdType> > MEDFileStructuredMesh::getAllNonNullFamilyIds() const
 {
-  std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret;
-  const DataArrayInt *da(_fam_nodes);
+  std::list< MCAuto<DataArrayIdType> > ret;
+  const DataArrayIdType *da(_fam_nodes);
   if(da)
-    { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
+    { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
   da=_fam_cells;
   if(da)
-    { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
+    { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
   da=_fam_faces;
   if(da)
-    { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); }
+    { da->incrRef(); ret.push_back(MCAuto<DataArrayIdType>(const_cast<DataArrayIdType *>(da))); }
   return ret;
 }
 
 void MEDFileStructuredMesh::deepCpyAttributes()
 {
-  if((const DataArrayInt*)_fam_nodes)
-    _fam_nodes=_fam_nodes->deepCpy();
-  if((const DataArrayInt*)_num_nodes)
-    _num_nodes=_num_nodes->deepCpy();
+  if((const DataArrayIdType*)_fam_nodes)
+    _fam_nodes=_fam_nodes->deepCopy();
+  if((const DataArrayIdType*)_num_nodes)
+    _num_nodes=_num_nodes->deepCopy();
   if((const DataArrayAsciiChar*)_names_nodes)
-    _names_nodes=_names_nodes->deepCpy();
-  if((const DataArrayInt*)_fam_cells)
-    _fam_cells=_fam_cells->deepCpy();
-  if((const DataArrayInt*)_num_cells)
-    _num_cells=_num_cells->deepCpy();
+    _names_nodes=_names_nodes->deepCopy();
+  if((const DataArrayIdType*)_fam_cells)
+    _fam_cells=_fam_cells->deepCopy();
+  if((const DataArrayIdType*)_num_cells)
+    _num_cells=_num_cells->deepCopy();
   if((const DataArrayAsciiChar*)_names_cells)
-    _names_cells=_names_cells->deepCpy();
-  if((const DataArrayInt*)_fam_faces)
-    _fam_faces=_fam_faces->deepCpy();
-  if((const DataArrayInt*)_num_faces)
-    _num_faces=_num_faces->deepCpy();
+    _names_cells=_names_cells->deepCopy();
+  if((const DataArrayIdType*)_fam_faces)
+    _fam_faces=_fam_faces->deepCopy();
+  if((const DataArrayIdType*)_num_faces)
+    _num_faces=_num_faces->deepCopy();
   if((const DataArrayAsciiChar*)_names_faces)
-    _names_faces=_names_faces->deepCpy();
-  if((const DataArrayInt*)_rev_num_nodes)
-    _rev_num_nodes=_rev_num_nodes->deepCpy();
-  if((const DataArrayInt*)_rev_num_cells)
-    _rev_num_cells=_rev_num_cells->deepCpy();
+    _names_faces=_names_faces->deepCopy();
+  if((const DataArrayIdType*)_rev_num_nodes)
+    _rev_num_nodes=_rev_num_nodes->deepCopy();
+  if((const DataArrayIdType*)_rev_num_cells)
+    _rev_num_cells=_rev_num_cells->deepCopy();
 }
 
 /*!
- * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh).
+ * Returns a pointer to mesh at the specified level (here 0 is compulsory for cartesian mesh).
  * 
  * \return a pointer to cartesian mesh that need to be managed by the caller.
  * \warning the returned pointer has to be managed by the caller.
@@ -5499,8 +6385,9 @@ void MEDFileStructuredMesh::deepCpyAttributes()
  *  \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to
  *          delete using decrRef() as it is no more needed. 
  */
-MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const
+MEDCouplingMesh *MEDFileStructuredMesh::getMeshAtLevel(int meshDimRelToMax, bool renum) const
 {
+  checkCartesian();
   if(renum)
     throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !");
   const MEDCouplingStructuredMesh *m(getStructuredMesh());
@@ -5515,9 +6402,9 @@ MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, b
     case -1:
       {
         if(!m)
-          throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGenMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
+          throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !");
         buildMinusOneImplicitPartIfNeeded();
-        MEDCouplingMesh *ret(_faces_if_necessary);
+        MEDCoupling1SGTUMesh *ret(_faces_if_necessary);
         if(ret)
           ret->incrRef();
         return ret;
@@ -5527,13 +6414,46 @@ MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, b
   }
 }
 
+/*!
+ * Returns all relative mesh levels (**excluding nodes**) where given families are defined.
+ * To include nodes, call getFamsNonEmptyLevelsExt() method.
+ *  \param [in] fams - the name of the family of interest.
+ *  \return std::vector<int> - a sequence of the relative dimensions.
+ */
+std::vector<mcIdType> MEDFileStructuredMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const
+{
+  std::vector<mcIdType> lvls;
+  std::vector<mcIdType> famIds(getFamiliesIds(fams));
+  const DataArrayIdType *famCells(_fam_cells),*famFaces(_fam_faces);
+  if(famCells && famCells->presenceOfValue(famIds))
+    lvls.push_back(0);
+  if(famFaces && famFaces->presenceOfValue(famIds))
+    lvls.push_back(-1);
+  return lvls;
+}
+
+/*!
+ * Returns all relative mesh levels (including nodes) where given families are defined.
+ *  \param [in] fams - the names of the families of interest.
+ *  \return std::vector<int> - a sequence of the relative dimensions.
+ */
+std::vector<mcIdType> MEDFileStructuredMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const
+{
+  std::vector<mcIdType> lvls(getFamsNonEmptyLevels(fams));
+  std::vector<mcIdType> famIds(getFamiliesIds(fams));
+  const DataArrayIdType *famNodes(_fam_nodes);
+  if(famNodes && famNodes->presenceOfValue(famIds))
+    lvls.push_back(1);
+  return lvls;
+}
+
 /*!
  * Returns number of mesh entities of a given relative dimension in \a this mesh.
  *  \param [in] meshDimRelToMaxExt - the relative dimension of interest.
- *  \return int - the number of entities.
+ *  \return mcIdType - the number of entities.
  *  \throw If no mesh entities of dimension \a meshDimRelToMaxExt are available in \a this mesh.
  */
-int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
+mcIdType MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
 {
   const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
   if(!cmesh)
@@ -5551,7 +6471,7 @@ int MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const
   }
 }
 
-int MEDFileStructuredMesh::getNumberOfNodes() const
+mcIdType MEDFileStructuredMesh::getNumberOfNodes() const
 {
   const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
   if(!cmesh)
@@ -5559,7 +6479,7 @@ int MEDFileStructuredMesh::getNumberOfNodes() const
   return cmesh->getNumberOfNodes();
 }
 
-int MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
+mcIdType MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const
 {
   const MEDCouplingStructuredMesh *cmesh(getStructuredMesh());
   if(!cmesh)
@@ -5583,7 +6503,7 @@ bool MEDFileStructuredMesh::hasImplicitPart() const
 /*!
  * \sa MEDFileStructuredMesh::getImplicitFaceMesh
  */
-int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
+mcIdType MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const
 {
   static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !";
   const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary);
@@ -5631,6 +6551,7 @@ void MEDFileStructuredMesh::releaseImplicitPartIfAny() const
  */
 MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const
 {
+  checkCartesian();
   return _faces_if_necessary;
 }
 
@@ -5659,27 +6580,35 @@ std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoType
   }
 }
 
+mcIdType MEDFileStructuredMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType ct) const
+{
+  if(ct!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
+    return 0;
+  else
+    return getNumberOfCellsAtLevel(0);
+}
+
 void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const
 {
   if(st.getNumberOfItems()!=1)
     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on single geo type ! it is not managed yet for structured mesh !");
   if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))
     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !");
-  if(getNumberOfNodes()!=(int)nodesFetched.size())
+  if(getNumberOfNodes()!=(mcIdType)nodesFetched.size())
     throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !");
   if(st[0].getPflName().empty())
     {
       std::fill(nodesFetched.begin(),nodesFetched.end(),true);
       return ;
     }
-  const DataArrayInt *arr(globs->getProfile(st[0].getPflName()));
+  const DataArrayIdType *arr(globs->getProfile(st[0].getPflName()));
   const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before
-  int sz(nodesFetched.size());
-  for(const int *work=arr->begin();work!=arr->end();work++)
+  mcIdType sz(ToIdType(nodesFetched.size()));
+  for(const mcIdType *work=arr->begin();work!=arr->end();work++)
     {
-      std::vector<int> conn;
+      std::vector<mcIdType> conn;
       cmesh->getNodeIdsOfCell(*work,conn);
-      for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++)
+      for(std::vector<mcIdType>::const_iterator it=conn.begin();it!=conn.end();it++)
         if(*it>=0 && *it<sz)
           nodesFetched[*it]=true;
         else
@@ -5694,19 +6623,20 @@ med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim)
 }
 
 void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs,
-                                                  MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& famCells, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& numCells, MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar>& namesCells)
+                                                  MCAuto<DataArrayIdType>& famCells, MCAuto<DataArrayIdType>& numCells, MCAuto<DataArrayAsciiChar>& namesCells)
 {
   med_bool chgt=MED_FALSE,trsf=MED_FALSE;
   med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim);
-  int nbOfElt(0);
+  mcIdType nbOfElt(0);
   nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf);
   if(nbOfElt>0)
     {
       if(!mrs || mrs->isCellFamilyFieldReading())
         {
-          famCells=DataArrayInt::New();
-          famCells->alloc(nbOfElt,1);
-          MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer()));
+          MCAuto<DataArrayMedInt> miFamCells=DataArrayMedInt::New();
+          miFamCells->alloc(nbOfElt,1);
+          MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,miFamCells->getPointer()));
+          famCells = FromMedIntArray<mcIdType>( miFamCells );
         }
     }
   nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf);
@@ -5714,9 +6644,10 @@ void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int
     {
       if(!mrs || mrs->isCellNumFieldReading())
         {
-          numCells=DataArrayInt::New();
-          numCells->alloc(nbOfElt,1);
-          MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer()));
+          MCAuto<DataArrayMedInt> miNumCells=DataArrayMedInt::New();
+          miNumCells->alloc(nbOfElt,1);
+          MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,miNumCells->getPointer()));
+          numCells = FromMedIntArray<mcIdType>( miNumCells );
         }
     }
   nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf);
@@ -5743,19 +6674,20 @@ void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt
   setTimeUnit(strm->getTimeUnit());
   MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs);
   med_bool chgt=MED_FALSE,trsf=MED_FALSE;
-  int nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf));
+  mcIdType nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf));
   if(nbOfElt>0)
     {
       if(!mrs || mrs->isNodeFamilyFieldReading())
         {
-          int nbNodes(getNumberOfNodes());
+          mcIdType nbNodes(getNumberOfNodes());
           if(nbOfElt>nbNodes)
             throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !");
-          _fam_nodes=DataArrayInt::New();
-          _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
+          MCAuto<DataArrayMedInt> miFamNodes=DataArrayMedInt::New();
+          miFamNodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line.
           if(nbNodes>nbOfElt)//yes it appends some times... It explains surely the mdump implementation. Bug revealed by PARAVIS EDF #2475 on structured.med file where only 12 first nodes are !=0 so nbOfElt=12 and nbOfNodes=378...
-            _fam_nodes->fillWithZero();
-          MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer()));
+            miFamNodes->fillWithZero();
+          MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,miFamNodes->getPointer()));
+          _fam_nodes = FromMedIntArray<mcIdType>( miFamNodes );
         }
     }
   nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf);
@@ -5763,9 +6695,10 @@ void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt
     {
       if(!mrs || mrs->isNodeNumFieldReading())
         {
-          _num_nodes=DataArrayInt::New();
-          _num_nodes->alloc(nbOfElt,1);
-          MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer()));
+          MCAuto<DataArrayMedInt> miNumNodes=DataArrayMedInt::New();
+          miNumNodes->alloc(nbOfElt,1);
+          MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,miNumNodes->getPointer()));
+          _num_nodes = FromMedIntArray<mcIdType>( miNumNodes );
         }
     }
   nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf);
@@ -5790,18 +6723,18 @@ void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& ma
   int meshDim(getStructuredMesh()->getMeshDimension());
   med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1));
   //
-  if((const DataArrayInt *)_fam_cells)
-    MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer()));
-  if((const DataArrayInt *)_fam_faces)
-    MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer()));
-  if((const DataArrayInt *)_fam_nodes)
-    MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer()));
-  if((const DataArrayInt *)_num_cells)
-    MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer()));
-  if((const DataArrayInt *)_num_faces)
-    MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer()));
-  if((const DataArrayInt *)_num_nodes)
-    MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer()));
+  if((const DataArrayIdType *)_fam_cells)
+    MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,ToMedInt(_fam_cells->getNumberOfTuples()),ToMedIntArray(_fam_cells)->getConstPointer()));
+  if((const DataArrayIdType *)_fam_faces)
+    MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,ToMedInt(_fam_faces->getNumberOfTuples()),ToMedIntArray(_fam_faces)->getConstPointer()));
+  if((const DataArrayIdType *)_fam_nodes)
+    MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,ToMedInt(_fam_nodes->getNumberOfTuples()),ToMedIntArray(_fam_nodes)->getConstPointer()));
+  if((const DataArrayIdType *)_num_cells)
+    MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,ToMedInt(_num_cells->getNumberOfTuples()),ToMedIntArray(_num_cells)->getConstPointer()));
+  if((const DataArrayIdType *)_num_faces)
+    MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,ToMedInt(_num_faces->getNumberOfTuples()),ToMedIntArray(_num_faces)->getConstPointer()));
+  if((const DataArrayIdType *)_num_nodes)
+    MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,ToMedInt(_num_nodes->getNumberOfTuples()),ToMedIntArray(_num_nodes)->getConstPointer()));
   if((const DataArrayAsciiChar *)_names_cells)
     {
       if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE)
@@ -5810,7 +6743,7 @@ void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& ma
           oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
           throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
-      MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer()));
+      MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,ToMedInt(_names_cells->getNumberOfTuples()),_names_cells->getConstPointer()));
     }
   if((const DataArrayAsciiChar *)_names_faces)
     {
@@ -5820,7 +6753,7 @@ void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& ma
           oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !";
           throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
-      MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer()));
+      MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,ToMedInt(_names_faces->getNumberOfTuples()),_names_faces->getConstPointer()));
     }
   if((const DataArrayAsciiChar *)_names_nodes)
     {
@@ -5830,7 +6763,7 @@ void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& ma
           oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !";
           throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
-      MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer()));
+      MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,ToMedInt(_names_nodes->getNumberOfTuples()),_names_nodes->getConstPointer()));
     }
   //
   MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str);
@@ -5858,19 +6791,13 @@ MEDFileCMesh *MEDFileCMesh::New()
  */
 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
 {
-  std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
-  if(ms.empty())
-    {
-      std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
-      throw INTERP_KERNEL::Exception(oss.str().c_str());
-    }
-  MEDFileUtilities::CheckFileForRead(fileName);
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
-  int dt,it;
-  ParaMEDMEM::MEDCouplingMeshType meshType;
-  std::string dummy2;
-  MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
-  return new MEDFileCMesh(fid,ms.front(),dt,it,mrs);
+  MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+  return New(fid,mrs);
+}
+
+MEDFileCMesh *MEDFileCMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
+{
+  return NewForTheFirstMeshInFile<MEDFileCMesh>(fid,mrs);
 }
 
 /*!
@@ -5889,8 +6816,12 @@ MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSele
  */
 MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
-  MEDFileUtilities::CheckFileForRead(fileName);
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
+  MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+  return New(fid,mName,dt,it,mrs);
+}
+
+MEDFileCMesh *MEDFileCMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
+{
   return new MEDFileCMesh(fid,mName,dt,it,mrs);
 }
 
@@ -5948,9 +6879,9 @@ std::string MEDFileCMesh::advancedRepr() const
   return simpleRepr();
 }
 
-MEDFileMesh *MEDFileCMesh::shallowCpy() const
+MEDFileCMesh *MEDFileCMesh::shallowCpy() const
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
+  MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
   return ret.retn();
 }
 
@@ -5959,11 +6890,12 @@ MEDFileMesh *MEDFileCMesh::createNewEmpty() const
   return new MEDFileCMesh;
 }
 
-MEDFileMesh *MEDFileCMesh::deepCpy() const
+MEDFileCMesh *MEDFileCMesh::deepCopy() const
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this);
+  MCAuto<MEDFileCMesh> ret(new MEDFileCMesh(*this));
+  ret->deepCpyEquivalences(*this);
   if((const MEDCouplingCMesh*)_cmesh)
-    ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCpy());
+    ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCopy());
   ret->deepCpyAttributes();
   return ret.retn();
 }
@@ -6022,20 +6954,20 @@ MEDFileCMesh::MEDFileCMesh()
 MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 try
 {
-    loadCMeshFromFile(fid,mName,dt,it,mrs);
-    loadJointsFromFile(fid);
+    loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
 }
 catch(INTERP_KERNEL::Exception& e)
 {
     throw e;
 }
 
-void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
+void MEDFileCMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
-  ParaMEDMEM::MEDCouplingMeshType meshType;
+  MEDCoupling::MEDCouplingMeshType meshType;
   int dummy0,dummy1;
   std::string dtunit;
-  int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
+  MEDCoupling::MEDCouplingAxisType axType;
+  INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
   if(meshType!=CARTESIAN)
     {
       std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !";
@@ -6043,6 +6975,7 @@ void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const std::string& mName, int
     }
   MEDFileCMeshL2 loaderl2;
   loaderl2.loadAll(fid,mid,mName,dt,it);
+  setAxisType(axType);
   MEDCouplingCMesh *mesh=loaderl2.getMesh();
   mesh->incrRef();
   _cmesh=mesh;
@@ -6079,7 +7012,30 @@ void MEDFileCMesh::setMesh(MEDCouplingCMesh *m)
   _cmesh=m;
 }
 
-void MEDFileCMesh::writeLL(med_idt fid) const
+MEDFileMesh *MEDFileCMesh::cartesianize() const
+{
+  if(getAxisType()==AX_CART)
+    {
+      incrRef();
+      return const_cast<MEDFileCMesh *>(this);
+    }
+  else
+    {
+      const MEDCouplingCMesh *cmesh(getMesh());
+      if(!cmesh)
+        throw INTERP_KERNEL::Exception("MEDFileCMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
+      MCAuto<MEDCouplingCurveLinearMesh> clmesh(cmesh->buildCurveLinear());
+      MCAuto<DataArrayDouble> coords(clmesh->getCoords()->cartesianize(getAxisType()));
+      clmesh->setCoords(coords);
+      MCAuto<MEDFileCurveLinearMesh> ret(MEDFileCurveLinearMesh::New());
+      ret->MEDFileStructuredMesh::operator=(*this);
+      ret->setMesh(clmesh);
+      ret->setAxisType(AX_CART);
+      return ret.retn();
+    }
+}
+
+void MEDFileCMesh::writeMeshLL(med_idt fid) const
 {
   INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
   INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
@@ -6098,20 +7054,18 @@ void MEDFileCMesh::writeLL(med_idt fid) const
       MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
       MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
     }
-  MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit));
+  MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
   if(_univ_wr_status)
     MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
-  MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CARTESIAN_GRID));
+  MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MEDFileMeshL2::TraduceAxisTypeRevStruct(getAxisType())));
   for(int i=0;i<spaceDim;i++)
     {
       const DataArrayDouble *da=_cmesh->getCoordsAt(i);
-      MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer()));
+      MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,ToMedInt(da->getNumberOfTuples()),da->getConstPointer()));
     }
   //
   std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
   MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
-
-  writeJoints(fid);
 }
 
 void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const
@@ -6130,27 +7084,25 @@ MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New()
   return new MEDFileCurveLinearMesh;
 }
 
+MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, MEDFileMeshReadSelector *mrs)
+{
+  return NewForTheFirstMeshInFile<MEDFileCurveLinearMesh>(fid,mrs);
+}
+
 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs)
 {
-  std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
-  if(ms.empty())
-    {
-      std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
-      throw INTERP_KERNEL::Exception(oss.str().c_str());
-    }
-  MEDFileUtilities::CheckFileForRead(fileName);
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
-  int dt,it;
-  ParaMEDMEM::MEDCouplingMeshType meshType;
-  std::string dummy2;
-  MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
-  return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs);
+  MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+  return New(fid,mrs);
 }
 
 MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
-  MEDFileUtilities::CheckFileForRead(fileName);
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
+  MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+  return New(fid,mName,dt,it,mrs);
+}
+
+MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
+{
   return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs);
 }
 
@@ -6166,9 +7118,9 @@ std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWi
   return ret;
 }
 
-MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const
+MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::shallowCpy() const
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
+  MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
   return ret.retn();
 }
 
@@ -6177,11 +7129,12 @@ MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const
   return new MEDFileCurveLinearMesh;
 }
 
-MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const
+MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::deepCopy() const
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this);
+  MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
+  ret->deepCpyEquivalences(*this);
   if((const MEDCouplingCurveLinearMesh*)_clmesh)
-    ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCpy());
+    ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCopy());
   ret->deepCpyAttributes();
   return ret.retn();
 }
@@ -6189,10 +7142,17 @@ MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const
 int MEDFileCurveLinearMesh::getMeshDimension() const
 {
   if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
-    throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !");
+    throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get mesh dimension because no mesh set !");
   return _clmesh->getMeshDimension();
 }
 
+int MEDFileCurveLinearMesh::getSpaceDimension() const
+{
+  if(!((const MEDCouplingCurveLinearMesh*)_clmesh))
+    throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get space dimension because no mesh set !");
+  return _clmesh->getSpaceDimension();
+}
+
 std::string MEDFileCurveLinearMesh::simpleRepr() const
 {
   return MEDFileStructuredMesh::simpleRepr();
@@ -6265,6 +7225,31 @@ void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m)
   _clmesh=m;
 }
 
+MEDFileMesh *MEDFileCurveLinearMesh::cartesianize() const
+{
+  if(getAxisType()==AX_CART)
+    {
+      incrRef();
+      return const_cast<MEDFileCurveLinearMesh *>(this);
+    }
+  else
+    {
+      const MEDCouplingCurveLinearMesh *mesh(getMesh());
+      if(!mesh)
+        throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : impossible to turn into cartesian because the mesh is null !");
+      const DataArrayDouble *coords(mesh->getCoords());
+      if(!coords)
+        throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::cartesianize : coordinate pointer in mesh is null !");
+      MCAuto<MEDFileCurveLinearMesh> ret(new MEDFileCurveLinearMesh(*this));
+      MCAuto<MEDCouplingCurveLinearMesh> mesh2(mesh->clone(false));
+      MCAuto<DataArrayDouble> coordsCart(coords->cartesianize(getAxisType()));
+      mesh2->setCoords(coordsCart);
+      ret->setMesh(mesh2);
+      ret->setAxisType(AX_CART);
+      return ret.retn();
+    }
+}
+
 const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const
 {
   synchronizeTinyInfoOnLeaves();
@@ -6278,15 +7263,14 @@ MEDFileCurveLinearMesh::MEDFileCurveLinearMesh()
 MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 try
 {
-    loadCLMeshFromFile(fid,mName,dt,it,mrs);
-    loadJointsFromFile(fid);
+    loadLLWithAdditionalItems(fid,mName,dt,it,mrs);
 }
 catch(INTERP_KERNEL::Exception& e)
 {
     throw e;
 }
 
-void MEDFileCurveLinearMesh::writeLL(med_idt fid) const
+void MEDFileCurveLinearMesh::writeMeshLL(med_idt fid) const
 {
   INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE);
   INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE);
@@ -6300,7 +7284,7 @@ void MEDFileCurveLinearMesh::writeLL(med_idt fid) const
   INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE);
   const DataArrayDouble *coords=_clmesh->getCoords();
   if(!coords)
-    throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !");
+    throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeMeshLL : no coordinates set !");
   for(int i=0;i<spaceDim;i++)
     {
       std::string info(_clmesh->getCoords()->getInfoOnComponent(i));
@@ -6309,27 +7293,27 @@ void MEDFileCurveLinearMesh::writeLL(med_idt fid) const
       MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
       MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo
     }
-  MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit));
+  MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MEDFileMeshL2::TraduceAxisTypeRev(getAxisType()),comp,unit));
   if(_univ_wr_status)
     MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa));
   MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID));
-  std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure();
-  MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,&nodeGridSt[0]));
+  std::vector<mcIdType> nodeGridSt=_clmesh->getNodeGridStructure();
+  MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,ToMedIntArray(nodeGridSt)->getConstPointer()));
 
-  MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin()));
+  MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,ToMedInt(coords->getNumberOfTuples()),coords->begin()));
   //
   std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE));
   MEDFileStructuredMesh::writeStructuredLL(fid,meshName);
-
-  writeJoints(fid);
 }
 
-void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
+void MEDFileCurveLinearMesh::loadLL(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs)
 {
-  ParaMEDMEM::MEDCouplingMeshType meshType;
+  MEDCoupling::MEDCouplingMeshType meshType;
   int dummy0,dummy1;
   std::string dtunit;
-  int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit);
+  MEDCoupling::MEDCouplingAxisType axType;
+  INTERP_KERNEL::AutoCppPtr<MeshOrStructMeshCls> mid(MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,axType,dummy0,dummy1,dtunit));
+  setAxisType(axType);
   if(meshType!=CURVE_LINEAR)
     {
       std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !";
@@ -6348,37 +7332,49 @@ MEDFileMeshMultiTS *MEDFileMeshMultiTS::New()
   return new MEDFileMeshMultiTS;
 }
 
+MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid)
+{
+  return new MEDFileMeshMultiTS(fid);
+}
+
 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName)
 {
-  return new MEDFileMeshMultiTS(fileName);
+  MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+  return New(fid);
+}
+
+MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(med_idt fid, const std::string& mName)
+{
+  return new MEDFileMeshMultiTS(fid,mName);
 }
 
 MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName)
 {
-  return new MEDFileMeshMultiTS(fileName,mName);
+  MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+  return New(fid,mName);
 }
 
-MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const
+MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCopy() const
 {
-  MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New();
-  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
-  std::size_t i=0;
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
+  MCAuto<MEDFileMeshMultiTS> ret(MEDFileMeshMultiTS::New());
+  std::vector< MCAuto<MEDFileMesh> > meshOneTs(_mesh_one_ts.size());
+  std::size_t i(0);
+  for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++)
     if((const MEDFileMesh *)*it)
-      meshOneTs[i]=(*it)->deepCpy();
+      meshOneTs[i]=(*it)->deepCopy();
   ret->_mesh_one_ts=meshOneTs;
   return ret.retn();
 }
 
 std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const
 {
-  return _mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMesh>);
+  return _mesh_one_ts.capacity()*sizeof(MCAuto<MEDFileMesh>);
 }
 
 std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const
 {
   std::vector<const BigMemoryObject *> ret;
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
+  for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
     ret.push_back((const MEDFileMesh *)*it);
   return ret;
 }
@@ -6401,7 +7397,7 @@ void MEDFileMeshMultiTS::setName(const std::string& newMeshName)
 bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
 {
   bool ret=false;
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
+  for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
     {
       MEDFileMesh *cur(*it);
       if(cur)
@@ -6410,6 +7406,19 @@ bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,st
   return ret;
 }
 
+void MEDFileMeshMultiTS::cartesianizeMe()
+{
+  for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
+    {
+      MEDFileMesh *cur(*it);
+      if(cur)
+        {
+          MCAuto<MEDFileMesh> ccur(cur->cartesianize());// Attention ! Do not wrap these two lines because memory leak !
+          *it=ccur;
+        }
+    }
+}
+
 MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const
 {
   if(_mesh_one_ts.empty())
@@ -6423,7 +7432,7 @@ void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep)
     throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !");
   _mesh_one_ts.resize(1);
   mesh1TimeStep->incrRef();
-  //MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> toto=mesh1TimeStep;
+  //MCAuto<MEDFileMesh> toto=mesh1TimeStep;
   _mesh_one_ts[0]=mesh1TimeStep;
 }
 
@@ -6439,18 +7448,34 @@ MEDFileJoints * MEDFileMeshMultiTS::getJoints() const
  */
 void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints )
 {
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
+  for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
     {
       (*it)->setJoints( joints );
     }
 }
 
-void MEDFileMeshMultiTS::write(med_idt fid) const
+bool MEDFileMeshMultiTS::presenceOfStructureElements() const
+{
+  for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
+    if((*it).isNotNull())
+      if((*it)->presenceOfStructureElements())
+        return true;
+  return false;
+}
+
+void MEDFileMeshMultiTS::killStructureElements()
+{
+  for(std::vector< MCAuto<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
+    if((*it).isNotNull())
+      (*it)->killStructureElements();
+}
+
+void MEDFileMeshMultiTS::writeLL(med_idt fid) const
 {
   MEDFileJoints *joints(getJoints());
   bool jointsWritten(false);
 
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
+  for(std::vector< MCAuto<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++)
     {
       if ( jointsWritten )
         const_cast<MEDFileMesh&>(**it).setJoints( 0 );
@@ -6458,64 +7483,53 @@ void MEDFileMeshMultiTS::write(med_idt fid) const
         jointsWritten = true;
 
       (*it)->copyOptionsFrom(*this);
-      (*it)->write(fid);
+      (*it)->writeLL(fid);
     }
 
   (const_cast<MEDFileMeshMultiTS*>(this))->setJoints( joints ); // restore joints
 }
 
-void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) const
-{
-  med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
-  std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\""; 
-  MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
-  write(fid);
-}
-
-void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, const std::string& mName)
+void MEDFileMeshMultiTS::loadFromFile(med_idt fid, const std::string& mName)
 {
-  MEDFileJoints* joints = 0;
+  MEDFileJoints *joints(0);
   if ( !_mesh_one_ts.empty() && getOneTimeStep() )
     {
       // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading
       joints = getOneTimeStep()->getJoints();
     }
-
   _mesh_one_ts.clear();  //for the moment to be improved
-  _mesh_one_ts.push_back( MEDFileMesh::New(fileName,mName,-1,-1,0, joints ));
+  _mesh_one_ts.push_back( MEDFileMesh::New(fid,mName,-1,-1,0, joints ));
 }
 
 MEDFileMeshMultiTS::MEDFileMeshMultiTS()
 {
 }
 
-MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName)
+MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid)
 try
 {
-    std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
+  std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
     if(ms.empty())
       {
-        std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !";
+        std::ostringstream oss; oss << "MEDFileMeshMultiTS : no meshes in file \"" << FileNameFromFID(fid) << "\" !";
         throw INTERP_KERNEL::Exception(oss.str().c_str());
       }
-    MEDFileUtilities::CheckFileForRead(fileName);
-    MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY);
     int dt,it;
-    ParaMEDMEM::MEDCouplingMeshType meshType;
+    MEDCoupling::MEDCouplingMeshType meshType;
     std::string dummy2;
-    MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2);
-    loadFromFile(fileName,ms.front());
+    MEDCoupling::MEDCouplingAxisType dummy3;
+    MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dummy3,dt,it,dummy2);
+    loadFromFile(fid,ms.front());
 }
 catch(INTERP_KERNEL::Exception& e)
 {
     throw e;
 }
 
-MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName)
+MEDFileMeshMultiTS::MEDFileMeshMultiTS(med_idt fid, const std::string& mName)
 try
 {
-    loadFromFile(fileName,mName);
+    loadFromFile(fid,mName);
 }
 catch(INTERP_KERNEL::Exception& e)
 {
@@ -6527,34 +7541,32 @@ MEDFileMeshes *MEDFileMeshes::New()
   return new MEDFileMeshes;
 }
 
+MEDFileMeshes *MEDFileMeshes::New(med_idt fid)
+{
+  return new MEDFileMeshes(fid);
+}
+
 MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName)
 {
-  return new MEDFileMeshes(fileName);
+  MEDFileUtilities::AutoFid fid(OpenMEDFileForRead(fileName));
+  return New(fid);
 }
 
-void MEDFileMeshes::write(med_idt fid) const
+void MEDFileMeshes::writeLL(med_idt fid) const
 {
-  checkCoherency();
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
+  checkConsistencyLight();
+  for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
     {
       (*it)->copyOptionsFrom(*this);
-      (*it)->write(fid);
+      (*it)->writeLL(fid);
     }
 }
 
-void MEDFileMeshes::write(const std::string& fileName, int mode) const
-{
-  med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode);
-  MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod);
-  std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\""; 
-  MEDFileUtilities::CheckMEDCode(fid,fid,oss.str());
-  checkCoherency();
-  write(fid);
-}
+//  MEDFileMeshes::writ checkConsistencyLight();
 
 int MEDFileMeshes::getNumberOfMeshes() const
 {
-  return _meshes.size();
+  return (int)_meshes.size();
 }
 
 MEDFileMeshesIterator *MEDFileMeshes::iterator()
@@ -6591,7 +7603,7 @@ std::vector<std::string> MEDFileMeshes::getMeshesNames() const
 {
   std::vector<std::string> ret(_meshes.size());
   int i=0;
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
+  for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
     {
       const MEDFileMeshMultiTS *f=(*it);
       if(f)
@@ -6606,21 +7618,11 @@ std::vector<std::string> MEDFileMeshes::getMeshesNames() const
     }
   return ret;
 }
-/*const MEDFileJoints* MEDFileMeshes::getJoints() const
-{
-  const MEDFileJoints *ret=_joints;
-  if(!ret)
-  {
-    std::ostringstream oss; oss << "MEDFileMeshes::getJoints : joints is not defined !";
-    throw INTERP_KERNEL::Exception(oss.str().c_str());
-  }
-  return ret;
-}*/
 
 bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab)
 {
   bool ret=false;
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
+  for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
     {
       MEDFileMeshMultiTS *cur(*it);
       if(cur)
@@ -6629,6 +7631,16 @@ bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::st
   return ret;
 }
 
+void MEDFileMeshes::cartesianizeMe()
+{
+  for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
+    {
+      MEDFileMeshMultiTS *cur(*it);
+      if(cur)
+        cur->cartesianizeMe();
+    }
+}
+
 void MEDFileMeshes::resize(int newSize)
 {
   _meshes.resize(newSize);
@@ -6664,49 +7676,49 @@ void MEDFileMeshes::destroyMeshAtPos(int i)
   _meshes.erase(_meshes.begin()+i);
 }
 
-void MEDFileMeshes::loadFromFile(const std::string& fileName)
+void MEDFileMeshes::loadFromFile(med_idt fid)
 {
-  std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName);
+  std::vector<std::string> ms(MEDLoaderNS::getMeshNamesFid(fid));
   int i=0;
   _meshes.resize(ms.size());
   for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++)
-    _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it));
+    _meshes[i]=MEDFileMeshMultiTS::New(fid,(*it));
 }
 
 MEDFileMeshes::MEDFileMeshes()
 {
 }
 
-MEDFileMeshes::MEDFileMeshes(const std::string& fileName)
+MEDFileMeshes::MEDFileMeshes(med_idt fid)
 try
 {
-    loadFromFile(fileName);
+    loadFromFile(fid);
 }
 catch(INTERP_KERNEL::Exception& /*e*/)
 {
 }
 
-MEDFileMeshes *MEDFileMeshes::deepCpy() const
+MEDFileMeshes *MEDFileMeshes::deepCopy() const
 {
-  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> > meshes(_meshes.size());
+  std::vector< MCAuto<MEDFileMeshMultiTS> > meshes(_meshes.size());
   std::size_t i=0;
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
+  for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
     if((const MEDFileMeshMultiTS *)*it)
-      meshes[i]=(*it)->deepCpy();
-  MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> ret=MEDFileMeshes::New();
+      meshes[i]=(*it)->deepCopy();
+  MCAuto<MEDFileMeshes> ret(MEDFileMeshes::New());
   ret->_meshes=meshes;
   return ret.retn();
 }
 
 std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const
 {
-  return _meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS>));
+  return _meshes.capacity()*(sizeof(MCAuto<MEDFileMeshMultiTS>));
 }
 
 std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const
 {
   std::vector<const BigMemoryObject *> ret;
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
+  for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
     ret.push_back((const MEDFileMeshMultiTS *)*it);
   return ret;
 }
@@ -6728,12 +7740,12 @@ void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const
     oss << "  - #" << i << " \"" << mns[i] << "\"\n";
 }
 
-void MEDFileMeshes::checkCoherency() const
+void MEDFileMeshes::checkConsistencyLight() const
 {
-  static const char MSG[]="MEDFileMeshes::checkCoherency : mesh at rank ";
+  static const char MSG[]="MEDFileMeshes::checkConsistencyLight : mesh at rank ";
   int i=0;
   std::set<std::string> s;
-  for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
+  for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++)
     {
       const MEDFileMeshMultiTS *elt=(*it);
       if(!elt)
@@ -6751,6 +7763,22 @@ void MEDFileMeshes::checkCoherency() const
     }
 }
 
+bool MEDFileMeshes::presenceOfStructureElements() const
+{
+  for(std::vector< MCAuto<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++)
+    if((*it).isNotNull())
+      if((*it)->presenceOfStructureElements())
+        return true;
+  return false;
+}
+
+void MEDFileMeshes::killStructureElements()
+{
+  for(std::vector< MCAuto<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++)
+    if((*it).isNotNull())
+      (*it)->killStructureElements();
+}
+
 MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0)
 {
   if(ms)
@@ -6777,3 +7805,36 @@ MEDFileMesh *MEDFileMeshesIterator::nextt()
   else
     return 0;
 }
+
+INTERP_KERNEL::NormalizedCellType MEDFileMesh::ConvertFromMEDFileGeoType(med_geometry_type geoType)
+{
+  med_geometry_type *pos(std::find(typmai,typmai+MED_N_CELL_FIXED_GEO,geoType));
+  if(pos==typmai+MED_N_CELL_FIXED_GEO)
+    {
+      if(geoType==MED_NO_GEOTYPE)
+        return INTERP_KERNEL::NORM_ERROR;
+      std::ostringstream oss; oss << "MEDFileMesh::ConvertFromMEDFileGeoType : no entry with " << geoType << " !"; 
+      throw INTERP_KERNEL::Exception(oss.str());
+    }
+  return typmai2[std::distance(typmai,pos)];
+}
+
+TypeOfField MEDFileMesh::ConvertFromMEDFileEntity(med_entity_type etype)
+{
+  switch(etype)
+    {
+    case MED_NODE:
+      return ON_NODES;
+    case MED_CELL:
+      return ON_CELLS;
+    case MED_NODE_ELEMENT:
+      return ON_GAUSS_NE;
+    default:
+      {
+        std::ostringstream oss; oss << "MEDFileMesh::ConvertFromMEDFileEntity : not recognized entity " << etype << " !";
+        throw INTERP_KERNEL::Exception(oss.str());
+      }
+    }
+}
+
+