Salome HOME
1) Add CMake files to the dist rules (make dist)
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingUMesh.cxx
index 379f326ae82149b0d43bab8cca1ef9f07c0731bf..d8f87ad56216febabd1b67931b1a43b818c7b675 100644 (file)
-//  Copyright (C) 2007-2008  CEA/DEN, EDF R&D
+// Copyright (C) 2007-2012  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
-//  License as published by the Free Software Foundation; either
-//  version 2.1 of the License.
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
 //
-//  This library is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-//  Lesser General Public License for more details.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
 //
-//  You should have received a copy of the GNU Lesser General Public
-//  License along with this library; if not, write to the Free Software
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 //
-//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+// Author : Anthony Geay (CEA/DEN)
+
 #include "MEDCouplingUMesh.hxx"
+#include "MEDCouplingMemArray.txx"
+#include "MEDCouplingFieldDouble.hxx"
 #include "CellModel.hxx"
+#include "VolSurfUser.txx"
+#include "InterpolationUtils.hxx"
+#include "PointLocatorAlgos.txx"
+#include "BBTree.txx"
+#include "DirectedBoundingBox.hxx"
+#include "InterpKernelMeshQuality.hxx"
+#include "InterpKernelCellSimplify.hxx"
+#include "InterpKernelGeo2DEdgeArcCircle.hxx"
+#include "MEDCouplingAutoRefCountObjectPtr.hxx"
+#include "InterpKernelAutoPtr.hxx"
+#include "InterpKernelGeo2DNode.hxx"
+#include "InterpKernelGeo2DEdgeLin.hxx"
+#include "InterpKernelGeo2DEdgeArcCircle.hxx"
+#include "InterpKernelGeo2DQuadraticPolygon.hxx"
 
 #include <sstream>
+#include <fstream>
+#include <numeric>
+#include <cstring>
+#include <limits>
+#include <list>
 
 using namespace ParaMEDMEM;
 
+const char MEDCouplingUMesh::PART_OF_NAME[]="PartOf_";
+
+double MEDCouplingUMesh::EPS_FOR_POLYH_ORIENTATION=1.e-14;
+
+const INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::MEDMEM_ORDER[N_MEDMEM_ORDER] = { INTERP_KERNEL::NORM_POINT1, INTERP_KERNEL::NORM_SEG2, INTERP_KERNEL::NORM_SEG3, INTERP_KERNEL::NORM_SEG4, INTERP_KERNEL::NORM_POLYL, INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_TRI6, INTERP_KERNEL::NORM_TRI7, INTERP_KERNEL::NORM_QUAD8, INTERP_KERNEL::NORM_QUAD9, INTERP_KERNEL::NORM_POLYGON, INTERP_KERNEL::NORM_QPOLYG, INTERP_KERNEL::NORM_TETRA4, INTERP_KERNEL::NORM_PYRA5, INTERP_KERNEL::NORM_PENTA6, INTERP_KERNEL::NORM_HEXA8, INTERP_KERNEL::NORM_HEXGP12, INTERP_KERNEL::NORM_TETRA10, INTERP_KERNEL::NORM_PYRA13, INTERP_KERNEL::NORM_PENTA15, INTERP_KERNEL::NORM_HEXA20, INTERP_KERNEL::NORM_HEXA27, INTERP_KERNEL::NORM_POLYHED };
+
 MEDCouplingUMesh *MEDCouplingUMesh::New()
 {
- return new MEDCouplingUMesh;
 return new MEDCouplingUMesh;
 }
 
-void MEDCouplingUMesh::updateTime()
+MEDCouplingUMesh *MEDCouplingUMesh::New(const char *meshName, int meshDim)
 {
- if(_nodal_connec)
-  {
-   updateTimeWith(*_nodal_connec);
-  }
- if(_nodal_connec_index)
-  {
-   updateTimeWith(*_nodal_connec_index);
-  }
- if(_coords)
-  {
-   updateTimeWith(*_coords);
-  }
+  MEDCouplingUMesh *ret=new MEDCouplingUMesh;
+  ret->setName(meshName);
+  ret->setMeshDimension(meshDim);
+  return ret;
+}
+
+MEDCouplingMesh *MEDCouplingUMesh::deepCpy() const
+{
+  return clone(true);
+}
+
+MEDCouplingUMesh *MEDCouplingUMesh::clone(bool recDeepCpy) const
+{
+  return new MEDCouplingUMesh(*this,recDeepCpy);
 }
 
-MEDCouplingUMesh::MEDCouplingUMesh():_iterator(-1),_mesh_dim(-1),
-                                     _nodal_connec(0),_nodal_connec_index(0),_coords(0)
+void MEDCouplingUMesh::updateTime() const
 {
+  MEDCouplingPointSet::updateTime();
+  if(_nodal_connec)
+    {
+      updateTimeWith(*_nodal_connec);
+    }
+  if(_nodal_connec_index)
+    {
+      updateTimeWith(*_nodal_connec_index);
+    }
 }
 
+MEDCouplingUMesh::MEDCouplingUMesh():_iterator(-1),_mesh_dim(-2),
+                                     _nodal_connec(0),_nodal_connec_index(0)
+{
+}
+
+/*!
+ * This method checks that this is correctly designed. For example le coordinates are set, nodal connectivity.
+ * When this method returns without throwing any exception, 'this' is expected to be writable, exchangeable and to be 
+ * available for most of algorithm. When a mesh has been constructed from scratch it is a good habits to call this method to check
+ * that all is in order in 'this'.
+ */
 void MEDCouplingUMesh::checkCoherency() const throw(INTERP_KERNEL::Exception)
 {
for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator iter=_types.begin();iter!=_types.end();iter++)
-  {
-   if(INTERP_KERNEL::CellModel::getCellModel(*iter).getDimension()!=_mesh_dim)
 if(_mesh_dim<-1)
+    throw INTERP_KERNEL::Exception("No mesh dimension specified !");
+  for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator iter=_types.begin();iter!=_types.end();iter++)
     {
-     std::ostringstream message;
-     message << "Mesh invalid because dimension is " << _mesh_dim << " and there is presence of cell(s) with type " << (*iter);
-     throw INTERP_KERNEL::Exception(message.str().c_str());
+      if((int)INTERP_KERNEL::CellModel::GetCellModel(*iter).getDimension()!=_mesh_dim)
+        {
+          std::ostringstream message;
+          message << "Mesh invalid because dimension is " << _mesh_dim << " and there is presence of cell(s) with type " << (*iter);
+          throw INTERP_KERNEL::Exception(message.str().c_str());
+        }
+    }
+  if(_nodal_connec)
+    {
+      if(_nodal_connec->getNumberOfComponents()!=1)
+        throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !");
+      if(_nodal_connec->getInfoOnComponent(0)!="")
+        throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !");
+    }
+  if(_nodal_connec_index)
+    {
+      if(_nodal_connec_index->getNumberOfComponents()!=1)
+        throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !");
+      if(_nodal_connec_index->getInfoOnComponent(0)!="")
+        throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !");
+    }
+  if(_iterator!=-1)
+    {
+      throw INTERP_KERNEL::Exception("It appears that finishInsertingCells method has not been invoked after a insertNextCell session !");
+    }
+}
+
+/*!
+ * This method performs deeper checking in 'this' than MEDCouplingUMesh::checkCoherency does.
+ * So this method is more time-consuming. This method checks that nodal connectivity points to valid node ids.
+ * No geometrical aspects are checked here. These aspects are done in MEDCouplingUMesh::checkCoherency2.
+ */
+void MEDCouplingUMesh::checkCoherency1(double eps) const throw(INTERP_KERNEL::Exception)
+{
+  checkCoherency();
+  if(_mesh_dim==-1)
+    return ;
+  int meshDim=getMeshDimension();
+  int nbOfNodes=getNumberOfNodes();
+  int nbOfCells=getNumberOfCells();
+  const int *ptr=_nodal_connec->getConstPointer();
+  const int *ptrI=_nodal_connec_index->getConstPointer();
+  for(int i=0;i<nbOfCells;i++)
+    {
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)ptr[ptrI[i]]);
+      if((int)cm.getDimension()!=meshDim)
+        {
+          std::ostringstream oss;
+          oss << "MEDCouplingUMesh::checkCoherency1 : cell << #" << i<< " with type Type " << cm.getRepr() << " in 'this' whereas meshdim == " << meshDim << " !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+      int nbOfNodesInCell=ptrI[i+1]-ptrI[i]-1;
+      if(!cm.isDynamic())
+        if(nbOfNodesInCell!=(int)cm.getNumberOfNodes())
+          {
+            std::ostringstream oss;
+            oss << "MEDCouplingUMesh::checkCoherency1 : cell #" << i << " with static Type '" << cm.getRepr() << "' has " <<  cm.getNumberOfNodes();
+            oss << " nodes whereas in connectivity there is " << nbOfNodesInCell << " nodes ! Looks very bad !";
+            throw INTERP_KERNEL::Exception(oss.str().c_str());
+          }
+      for(const int *w=ptr+ptrI[i]+1;w!=ptr+ptrI[i+1];w++)
+        {
+          int nodeId=*w;
+          if(nodeId>=0)
+            {
+              if(nodeId>=nbOfNodes)
+                {
+                  std::ostringstream oss; oss << "Cell #" << i << " is consituted of node #" << nodeId << " whereas there are only " << nbOfNodes << " nodes !";
+                  throw INTERP_KERNEL::Exception(oss.str().c_str());
+                }
+            }
+          else if(nodeId<-1)
+            {
+              std::ostringstream oss; oss << "Cell #" << i << " is consituted of node #" << nodeId << " in connectivity ! sounds bad !";
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }
+          else
+            {
+              if((INTERP_KERNEL::NormalizedCellType)(ptr[ptrI[i]])!=INTERP_KERNEL::NORM_POLYHED)
+                {
+                  std::ostringstream oss; oss << "Cell #" << i << " is consituted of node #-1 in connectivity ! sounds bad !";
+                  throw INTERP_KERNEL::Exception(oss.str().c_str());
+                }
+            }
+        }
     }
-  }
 }
 
-void MEDCouplingUMesh::setMeshDimension(unsigned meshDim)
+void MEDCouplingUMesh::checkCoherency2(double eps) const throw(INTERP_KERNEL::Exception)
 {
- _mesh_dim=meshDim;
- declareAsNew();
+  checkCoherency1(eps);
+}
+
+void MEDCouplingUMesh::setMeshDimension(int meshDim)
+{
+  if(meshDim<-1)
+    throw INTERP_KERNEL::Exception("Invalid meshDim specified ! Must be greater or equal to -1 !");
+  _mesh_dim=meshDim;
+  declareAsNew();
 }
 
 void MEDCouplingUMesh::allocateCells(int nbOfCells)
 {
- if(_nodal_connec_index)
-  {
-   _nodal_connec_index->decrRef();
-  }
- if(_nodal_connec)
-  {
-   _nodal_connec->decrRef();
-  }
 if(_nodal_connec_index)
+    {
+      _nodal_connec_index->decrRef();
+    }
 if(_nodal_connec)
+    {
+      _nodal_connec->decrRef();
+    }
 
- _nodal_connec_index=DataArrayInt::New();
- _nodal_connec_index->alloc(nbOfCells+1,1);
- int *pt=_nodal_connec_index->getPointer();
- pt[0]=0;
- _nodal_connec=DataArrayInt::New();
- _nodal_connec->alloc(2*nbOfCells,1);
- _iterator=0;
- _types.clear();
- declareAsNew();
 _nodal_connec_index=DataArrayInt::New();
 _nodal_connec_index->alloc(nbOfCells+1,1);
 int *pt=_nodal_connec_index->getPointer();
 pt[0]=0;
 _nodal_connec=DataArrayInt::New();
 _nodal_connec->alloc(2*nbOfCells,1);
 _iterator=0;
 _types.clear();
 declareAsNew();
 }
 
-void MEDCouplingUMesh::setCoords(DataArrayDouble *coords)
+/*!
+ * Appends a cell in connectivity array.
+ * @param type type of cell to add.
+ * @param size number of nodes constituting this cell.
+ * @param nodalConnOfCell the connectivity of the cell to add.
+ */
+void MEDCouplingUMesh::insertNextCell(INTERP_KERNEL::NormalizedCellType type, int size, const int *nodalConnOfCell) throw(INTERP_KERNEL::Exception)
 {
- if( coords != _coords )
-  {
-   if (_coords)
-  _coords->decrRef();
-      _coords=coords;
-      if(_coords)
-  _coords->incrRef();
-      declareAsNew();
+  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
+  if(_nodal_connec_index==0)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::insertNextCell : nodal connectivity not set ! invoke allocateCells before calling insertNextCell !");
+  if((int)cm.getDimension()==_mesh_dim)
+    {
+      int nbOfElems=_nodal_connec_index->getNbOfElems()-1;
+      if(_iterator>=nbOfElems)
+        throw INTERP_KERNEL::Exception("MEDCouplingUMesh::insertNextCell : allocation of cells was wide enough ! Call insertNextCell with higher value or call finishInsertingCells !");
+      int *pt=_nodal_connec_index->getPointer();
+      int idx=pt[_iterator];
+      
+      _nodal_connec->writeOnPlace(idx,type,nodalConnOfCell,size);
+      _types.insert(type);
+      pt[++_iterator]=idx+size+1;
+    }
+  else
+    {
+      std::ostringstream oss; oss << "MEDCouplingUMesh::insertNextCell : cell type " << cm.getRepr() << " has a dimension " << cm.getDimension();
+      oss << " whereas Mesh Dimension of current UMesh instance is set to " << _mesh_dim << " ! Please invoke \"setMeshDimension\" method before or invoke ";
+      oss << "\"MEDCouplingUMesh::New\" static method with 2 parameters name and meshDimension !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
 }
 
-void MEDCouplingUMesh::insertNextCell(INTERP_KERNEL::NormalizedCellType type, int size, const int *nodalConnOfCell)
+/*!
+ * Method to be called to cloture the insertion of cells using this->insertNextCell.
+ */
+void MEDCouplingUMesh::finishInsertingCells()
 {
int *pt=_nodal_connec_index->getPointer();
- int idx=pt[_iterator];
 const int *pt=_nodal_connec_index->getConstPointer();
 int idx=pt[_iterator];
 
- _nodal_connec->writeOnPlace(idx,type,nodalConnOfCell,size);
- _types.insert(type);
- pt[++_iterator]=idx+size+1;
+  _nodal_connec->reAlloc(idx);
+  _nodal_connec_index->reAlloc(_iterator+1);
+  _iterator=-1;
+  _nodal_connec->declareAsNew();
+  _nodal_connec_index->declareAsNew();
+  updateTime();
 }
 
-void MEDCouplingUMesh::finishInsertingCells()
+/*!
+ * Entry point for iteration over cells of this. Warning the returned cell iterator should be deallocated.
+ * Useful for python users.
+ */
+MEDCouplingUMeshCellIterator *MEDCouplingUMesh::cellIterator()
 {
int *pt=_nodal_connec_index->getPointer();
- int idx=pt[_iterator];
 return new MEDCouplingUMeshCellIterator(this);
+}
 
- _nodal_connec->reAlloc(idx);
- _nodal_connec_index->reAlloc(_iterator+1);
- _iterator=-1;
+/*!
+ * Entry point for iteration over cells groups geo types per geotypes. Warning the returned cell iterator should be deallocated.
+ * If 'this' is not so that that cells are grouped by geo types this method will throw an exception.
+ * In this case MEDCouplingUMesh::sortCellsInMEDFileFrmt or MEDCouplingUMesh::rearrange2ConsecutiveCellTypes methods for example can be called before invoking this method.
+ * Useful for python users.
+ */
+MEDCouplingUMeshCellByTypeEntry *MEDCouplingUMesh::cellsByType() throw(INTERP_KERNEL::Exception)
+{
+  if(!checkConsecutiveCellTypes())
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::cellsByType : this mesh is not sorted by type !");
+  return new MEDCouplingUMeshCellByTypeEntry(this);
 }
 
-INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::getTypeOfCell(int cellId) const
+std::set<INTERP_KERNEL::NormalizedCellType> MEDCouplingUMesh::getAllGeoTypes() const
 {
- int *ptI=_nodal_connec_index->getPointer();
- int *pt=_nodal_connec->getPointer();
- return (INTERP_KERNEL::NormalizedCellType) pt[ptI[cellId]];
+  return _types;
 }
 
-int MEDCouplingUMesh::getNumberOfNodesInCell(int cellId) const
+/*!
+ * This method is a method that compares 'this' and 'other'.
+ * This method compares \b all attributes, even names and component names.
+ */
+bool MEDCouplingUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const throw(INTERP_KERNEL::Exception)
+{
+  if(!other)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::isEqualIfNotWhy : input other pointer is null !");
+  std::ostringstream oss; oss.precision(15);
+  const MEDCouplingUMesh *otherC=dynamic_cast<const MEDCouplingUMesh *>(other);
+  if(!otherC)
+    {
+      reason="mesh given in input is not castable in MEDCouplingUMesh !";
+      return false;
+    }
+  if(!MEDCouplingPointSet::isEqualIfNotWhy(other,prec,reason))
+    return false;
+  if(_mesh_dim!=otherC->_mesh_dim)
+    {
+      oss << "umesh dimension mismatch : this mesh dimension=" << _mesh_dim << " other mesh dimension=" <<  otherC->_mesh_dim;
+      reason=oss.str();
+      return false;
+    }
+  if(_types!=otherC->_types)
+    {
+      oss << "umesh geometric type mismatch :\nThis geometric types are :";
+      for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator iter=_types.begin();iter!=_types.end();iter++)
+        { const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*iter); oss << cm.getRepr() << ", "; }
+      oss << "\nOther geometric types are :";
+      for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator iter=otherC->_types.begin();iter!=otherC->_types.end();iter++)
+        { const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*iter); oss << cm.getRepr() << ", "; }
+      reason=oss.str();
+      return false;
+    }
+  if(_nodal_connec!=0 || otherC->_nodal_connec!=0)
+    if(_nodal_connec==0 || otherC->_nodal_connec==0)
+      {
+        reason="Only one UMesh between the two this and other has its nodal connectivity DataArrayInt defined !";
+        return false;
+      }
+  if(_nodal_connec!=otherC->_nodal_connec)
+    if(!_nodal_connec->isEqualIfNotWhy(*otherC->_nodal_connec,reason))
+      {
+        reason.insert(0,"Nodal connectivity DataArrayInt differ : ");
+        return false;
+      }
+  if(_nodal_connec_index!=0 || otherC->_nodal_connec_index!=0)
+    if(_nodal_connec_index==0 || otherC->_nodal_connec_index==0)
+      {
+        reason="Only one UMesh between the two this and other has its nodal connectivity index DataArrayInt defined !";
+        return false;
+      }
+  if(_nodal_connec_index!=otherC->_nodal_connec_index)
+    if(!_nodal_connec_index->isEqualIfNotWhy(*otherC->_nodal_connec_index,reason))
+      {
+        reason.insert(0,"Nodal connectivity index DataArrayInt differ : ");
+        return false;
+      }
+  return true;
+}
+
+bool MEDCouplingUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const
 {
- int *ptI=_nodal_connec_index->getPointer();
- return ptI[cellId+1]-ptI[cellId]-1;
+  const MEDCouplingUMesh *otherC=dynamic_cast<const MEDCouplingUMesh *>(other);
+  if(!otherC)
+    return false;
+  if(!MEDCouplingPointSet::isEqualWithoutConsideringStr(other,prec))
+    return false;
+  if(_mesh_dim!=otherC->_mesh_dim)
+    return false;
+  if(_types!=otherC->_types)
+    return false;
+  if(_nodal_connec!=0 || otherC->_nodal_connec!=0)
+    if(_nodal_connec==0 || otherC->_nodal_connec==0)
+      return false;
+  if(_nodal_connec!=otherC->_nodal_connec)
+    if(!_nodal_connec->isEqualWithoutConsideringStr(*otherC->_nodal_connec))
+      return false;
+  if(_nodal_connec_index!=0 || otherC->_nodal_connec_index!=0)
+    if(_nodal_connec_index==0 || otherC->_nodal_connec_index==0)
+      return false;
+  if(_nodal_connec_index!=otherC->_nodal_connec_index)
+    if(!_nodal_connec_index->isEqualWithoutConsideringStr(*otherC->_nodal_connec_index))
+      return false;
+  return true;
 }
 
-void MEDCouplingUMesh::setConnectivity(DataArrayInt *conn, DataArrayInt *connIndex, bool isComputingTypes)
+/*!
+ * This method looks if 'this' and 'other' are geometrically equivalent that is to say if each cell in 'other' correspond to one cell and only one
+ * in 'this' is found regarding 'prec' parameter and 'cellCompPol' parameter.
+ * 
+ * In case of success cellCor and nodeCor are informed both. 
+ * @param cellCompPol values are described in MEDCouplingUMesh::zipConnectivityTraducer method.
+ * @param cellCor output array giving the correspondance of cells from 'other' to 'this'.
+ * @param nodeCor output array giving the correspondance of nodes from 'other' to 'this'.
+ */
+void MEDCouplingUMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
+                                            DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const throw(INTERP_KERNEL::Exception)
 {
- if(_nodal_connec!=conn)
-  {
-   if(_nodal_connec)
-     _nodal_connec->decrRef();
-      _nodal_connec=conn;
-      if(_nodal_connec)
-        _nodal_connec->incrRef();
+  const MEDCouplingUMesh *otherC=dynamic_cast<const MEDCouplingUMesh *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("checkDeepEquivalWith : Two meshes are not not unstructured !");
+  MEDCouplingMesh::checkFastEquivalWith(other,prec);
+  if(_types!=otherC->_types)
+    throw INTERP_KERNEL::Exception("checkDeepEquivalWith : Types are not equal !");
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MergeUMeshes(this,otherC);
+  bool areNodesMerged;
+  int newNbOfNodes;
+  int oldNbOfNodes=getNumberOfNodes();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=m->buildPermArrayForMergeNode(prec,oldNbOfNodes,areNodesMerged,newNbOfNodes);
+  //mergeNodes
+  if(!areNodesMerged)
+    throw INTERP_KERNEL::Exception("checkDeepEquivalWith : Nodes are incompatible ! ");
+  const int *pt=std::find_if(da->getConstPointer()+oldNbOfNodes,da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater<int>(),oldNbOfNodes-1));
+  if(pt!=da->getConstPointer()+da->getNbOfElems())
+    throw INTERP_KERNEL::Exception("checkDeepEquivalWith : some nodes in other are not in this !");
+  m->renumberNodes(da->getConstPointer(),newNbOfNodes);
+  //
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodeCor2=da->substr(oldNbOfNodes);
+  da=m->mergeNodes(prec,areNodesMerged,newNbOfNodes);
+  
+  //
+  da=m->zipConnectivityTraducer(cellCompPol);
+  int maxId=*std::max_element(da->getConstPointer(),da->getConstPointer()+getNumberOfCells());
+  pt=std::find_if(da->getConstPointer()+getNumberOfCells(),da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater<int>(),maxId));
+  if(pt!=da->getConstPointer()+da->getNbOfElems())
+    throw INTERP_KERNEL::Exception("checkDeepEquivalWith : some cells in other are not in this !");
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellCor2=DataArrayInt::New();
+  cellCor2->alloc(otherC->getNumberOfCells(),1);
+  std::copy(da->getConstPointer()+getNumberOfCells(),da->getConstPointer()+da->getNbOfElems(),cellCor2->getPointer());
+  bool nident=nodeCor2->isIdentity();
+  bool cident=cellCor2->isIdentity();
+  if(!nident) { nodeCor=nodeCor2; nodeCor2->incrRef(); } else nodeCor=0;
+  if(!cident) { cellCor=cellCor2; cellCor2->incrRef(); } else cellCor=0;
+}
+
+/*!
+ * This method looks if 'this' and 'other' are geometrically equivalent that is to say if each cell in 'other' correspond to one cell and only one
+ * in 'this' is found regarding 'prec' parameter and 'cellCompPol' parameter. The difference with MEDCouplingUMesh::checkDeepEquivalWith method is that
+ * coordinates of 'this' and 'other' are expected to be the same. If not an exception will be thrown.
+ * This method is close to MEDCouplingUMesh::areCellsIncludedIn except that this method throws exception !
+ * 
+ * In case of success cellCor are informed both. 
+ * @param cellCompPol values are described in MEDCouplingUMesh::zipConnectivityTraducer method.
+ * @param cellCor output array giving the correspondance of cells from 'other' to 'this'.
+ */
+void MEDCouplingUMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec,
+                                                       DataArrayInt *&cellCor) const throw(INTERP_KERNEL::Exception)
+{
+  const MEDCouplingUMesh *otherC=dynamic_cast<const MEDCouplingUMesh *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : Two meshes are not not unstructured !");
+  MEDCouplingMesh::checkFastEquivalWith(other,prec);
+  if(_types!=otherC->_types)
+    throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : Types are not equal !");
+  if(_coords!=otherC->_coords)
+    throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : meshes do not share the same coordinates ! Use tryToShareSameCoordinates or call checkDeepEquivalWith !");
+  std::vector<const MEDCouplingUMesh *> ms(2);
+  ms[0]=this;
+  ms[1]=otherC;
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MergeUMeshesOnSameCoords(ms);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=m->zipConnectivityTraducer(cellCompPol);
+  int maxId=*std::max_element(da->getConstPointer(),da->getConstPointer()+getNumberOfCells());
+  const int *pt=std::find_if(da->getConstPointer()+getNumberOfCells(),da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater<int>(),maxId));
+  if(pt!=da->getConstPointer()+da->getNbOfElems())
+    {
+      throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : some cells in other are not in this !");
     }
-  if(_nodal_connec_index!=connIndex)
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellCor2=DataArrayInt::New();
+  cellCor2->alloc(otherC->getNumberOfCells(),1);
+  std::copy(da->getConstPointer()+getNumberOfCells(),da->getConstPointer()+da->getNbOfElems(),cellCor2->getPointer());
+  if(!cellCor2->isIdentity()) { cellCor=cellCor2; cellCor2->incrRef(); } else cellCor=0;
+}
+
+/*!
+ * This method checks fastly that 'this' and 'other' are equal. 
+ */
+void MEDCouplingUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception)
+{
+  const MEDCouplingUMesh *otherC=dynamic_cast<const MEDCouplingUMesh *>(other);
+  if(!otherC)
+    throw INTERP_KERNEL::Exception("checkFastEquivalWith : Two meshes are not not unstructured !");
+  MEDCouplingPointSet::checkFastEquivalWith(other,prec);
+  int nbOfCells=getNumberOfCells();
+  if(nbOfCells<1)
+    return ;
+  bool status=true;
+  status&=areCellsFrom2MeshEqual(otherC,0,prec);
+  status&=areCellsFrom2MeshEqual(otherC,nbOfCells/2,prec);
+  status&=areCellsFrom2MeshEqual(otherC,nbOfCells-1,prec);
+  if(!status)
+    throw INTERP_KERNEL::Exception("checkFastEquivalWith : Two meshes are not equal because on 3 test cells some difference have been detected !");
+}
+
+/*!
+ * \b WARNING this method do the assumption that connectivity lies on the coordinates set.
+ * For speed reasons no check of this will be done.
+ */
+void MEDCouplingUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception)
+{
+  checkFullyDefined();
+  int nbOfNodes=getNumberOfNodes();
+  int *revNodalIndxPtr=new int[nbOfNodes+1];
+  revNodalIndx->useArray(revNodalIndxPtr,true,CPP_DEALLOC,nbOfNodes+1,1);
+  std::fill(revNodalIndxPtr,revNodalIndxPtr+nbOfNodes+1,0);
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connIndex=_nodal_connec_index->getConstPointer();
+  int nbOfCells=getNumberOfCells();
+  int nbOfEltsInRevNodal=0;
+  for(int eltId=0;eltId<nbOfCells;eltId++)
     {
-      if(_nodal_connec_index)
-        _nodal_connec_index->decrRef();
-      _nodal_connec_index=connIndex;
-      if(_nodal_connec_index)
-        _nodal_connec_index->incrRef();
+      const int *strtNdlConnOfCurCell=conn+connIndex[eltId]+1;
+      const int *endNdlConnOfCurCell=conn+connIndex[eltId+1];
+      for(const int *iter=strtNdlConnOfCurCell;iter!=endNdlConnOfCurCell;iter++)
+        if(*iter>=0)//for polyhedrons
+          {
+            nbOfEltsInRevNodal++;
+            revNodalIndxPtr[(*iter)+1]++;
+          }
     }
-  if(isComputingTypes)
+  std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>());
+  int *revNodalPtr=new int[nbOfEltsInRevNodal];
+  revNodal->useArray(revNodalPtr,true,CPP_DEALLOC,nbOfEltsInRevNodal,1);
+  std::fill(revNodalPtr,revNodalPtr+nbOfEltsInRevNodal,-1);
+  for(int eltId=0;eltId<nbOfCells;eltId++)
+    {
+      const int *strtNdlConnOfCurCell=conn+connIndex[eltId]+1;
+      const int *endNdlConnOfCurCell=conn+connIndex[eltId+1];
+      for(const int *iter=strtNdlConnOfCurCell;iter!=endNdlConnOfCurCell;iter++)
+        if(*iter>=0)//for polyhedrons
+          *std::find_if(revNodalPtr+revNodalIndxPtr[*iter],revNodalPtr+revNodalIndxPtr[*iter+1],std::bind2nd(std::equal_to<int>(),-1))=eltId;
+    }
+}
+
+/// @cond INTERNAL
+
+int MEDCouplingFastNbrer(int id, unsigned nb, const INTERP_KERNEL::CellModel& cm, bool compute, const int *conn1, const int *conn2)
+{
+  return id;
+}
+
+int MEDCouplingOrientationSensitiveNbrer(int id, unsigned nb, const INTERP_KERNEL::CellModel& cm, bool compute, const int *conn1, const int *conn2)
+{
+  if(!compute)
+    return id+1;
+  else
+    {
+      if(cm.getOrientationStatus(nb,conn1,conn2))
+        return id+1;
+      else
+        return -(id+1);
+    }
+}
+
+/// @endcond
+
+/*!
+ * \b WARNING this method do the assumption that connectivity lies on the coordinates set.
+ * For speed reasons no check of this will be done.
+ * Given 'this' with spacedim equal to s and meshdim equal to p, this method returns a new allocated mesh
+ * lying on the same coordinates than 'this' and having a meshdim equal to p-1.
+ * The algorithm to compute this p-1 mesh is the following :
+ * For each cell in 'this' it splits into p-1 elements.
+ *   If this p-1 element does not already exists it is appended to the returned mesh
+ *   If this p-1 element already exists, it is not appended.
+ * This method returns or 4 arrays plus the returned mesh.
+ * 'desc' and 'descIndx' are the descending connectivity. These 2 arrays tell for each cell in 'this', to wich p-1 dimension cell in returned mesh it refers.
+ * For a cell with a cellid c in 'this' it is constituted of cells in [desc+descIndx[c],desc+descIndex[c+1])
+ *
+ * Reversely 'revDesc' and 'revDescIndx' are the reverse descending connectivity. These 2 arrays tell for each cell in returned mesh, to wich cell in 'this' it refers.
+ * For a cell with a cellid d in returned p-1 mesh it is shared by the following cells in 'this' [revDesc+revDescIndx[d],revDesc+revDescIndx[d+1])
+ *
+ * \warning This method returns a mesh whose geometric type order in are \b not sorted.
+ * In view of the MED file writing, a renumbering of cells in returned mesh (using MEDCouplingUMesh::sortCellsInMEDFileFrmt) should be necessary.
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception)
+{
+  return buildDescendingConnectivityGen(desc,descIndx,revDesc,revDescIndx,MEDCouplingFastNbrer);
+}
+
+/*!
+ * WARNING this method do the assumption that connectivity lies on the coordinates set.
+ * For speed reasons no check of this will be done.
+ * This method differs from MEDCouplingUMesh::buildDescendingConnectivity method in that 'desc' is in different format.
+ * This method is more precise because it returns in descending connectivity giving the direction. If value is positive the n-1 dim element is taken in the same direction,
+ * if it is in the opposite direction it is retrieved negative. So the problem is for elemt #0 in C convention. That's why this method is the only one that retrieves 
+ * an array in relative "FORTRAN" mode.
+ *
+ * \warning This method returns a mesh whose geometric type order in are \b not sorted.
+ * In view of the MED file writing, a renumbering of cells in returned mesh (using MEDCouplingUMesh::sortCellsInMEDFileFrmt) should be necessary.
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivity2(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception)
+{
+  return buildDescendingConnectivityGen(desc,descIndx,revDesc,revDescIndx,MEDCouplingOrientationSensitiveNbrer);
+}
+
+/*!
+ * \b WARNING this method do the assumption that connectivity lies on the coordinates set.
+ * For speed reasons no check of this will be done. This method calls MEDCouplingUMesh::buildDescendingConnectivity to compute the result.
+ * This method lists cell by cell in \b this which are its neighbors. To compute the result only connectivities are considered.
+ * The a cell with id 'cellId' its neighbors are neighbors[neighborsIndx[cellId]:neighborsIndx[cellId+1]].
+ *
+ * \param [out] neighbors is an array storing all the neighbors of all cells in \b this. This array is newly allocated and should be dealt by the caller. \b neighborsIndx 2nd output
+ *                        parameter allows to select the right part in this array. The number of tuples is equal to the last values in \b neighborsIndx.
+ * \param [out] neighborsIndx is an array of size this->getNumberOfCells()+1 newly allocated and should be dealt by the caller. This arrays allow to use the first output parameter \b neighbors.
+ */
+void MEDCouplingUMesh::computeNeighborsOfCells(DataArrayInt *&neighbors, DataArrayInt *&neighborsIndx) const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descIndx=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDesc=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDescIndx=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> meshDM1=buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx);
+  meshDM1=0;
+  ComputeNeighborsOfCellsAdv(desc,descIndx,revDesc,revDescIndx,neighbors,neighborsIndx);
+}
+
+/*!
+ * This method is called by MEDCouplingUMesh::computeNeighborsOfCells. This methods performs the algorithm of MEDCouplingUMesh::computeNeighborsOfCells.
+ * This method is useful for users that want to reduce along a criterion the set of neighbours cell. This is typically the case to extract a set a neighbours,
+ * excluding a set of meshdim-1 cells in input descending connectivity.
+ * Typically \b desc, \b descIndx, \b revDesc and \b revDescIndx input params are the result of MEDCouplingUMesh::buildDescendingConnectivity.
+ * This method lists cell by cell in \b this which are its neighbors. To compute the result only connectivities are considered.
+ * The a cell with id 'cellId' its neighbors are neighbors[neighborsIndx[cellId]:neighborsIndx[cellId+1]].
+ *
+ * \param [in] desc descending connectivity array.
+ * \param [in] descIndx descending connectivity index array used to walk through \b desc.
+ * \param [in] revDesc reverse descending connectivity array.
+ * \param [in] revDescIndx reverse descending connectivity index array used to walk through \b revDesc.
+ * \param [out] neighbors is an array storing all the neighbors of all cells in \b this. This array is newly allocated and should be dealt by the caller. \b neighborsIndx 2nd output
+ *                        parameter allows to select the right part in this array. The number of tuples is equal to the last values in \b neighborsIndx.
+ * \param [out] neighborsIndx is an array of size this->getNumberOfCells()+1 newly allocated and should be dealt by the caller. This arrays allow to use the first output parameter \b neighbors.
+ */
+void MEDCouplingUMesh::ComputeNeighborsOfCellsAdv(const DataArrayInt *desc, const DataArrayInt *descIndx, const DataArrayInt *revDesc, const DataArrayInt *revDescIndx,
+                                                  DataArrayInt *&neighbors, DataArrayInt *&neighborsIndx) throw(INTERP_KERNEL::Exception)
+{
+  if(!desc || !descIndx || !revDesc || !revDescIndx)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ComputeNeighborsOfCellsAdv some input array is empty !");
+  const int *descPtr=desc->getConstPointer();
+  const int *descIPtr=descIndx->getConstPointer();
+  const int *revDescPtr=revDesc->getConstPointer();
+  const int *revDescIPtr=revDescIndx->getConstPointer();
+  //
+  int nbCells=descIndx->getNumberOfTuples()-1;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> out0=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> out1=DataArrayInt::New(); out1->alloc(nbCells+1,1);
+  int *out1Ptr=out1->getPointer();
+  *out1Ptr++=0;
+  std::vector<int> out0v;
+  out0v.reserve(desc->getNumberOfTuples());
+  for(int i=0;i<nbCells;i++,descIPtr++,out1Ptr++)
+    {
+      for(const int *w1=descPtr+descIPtr[0];w1!=descPtr+descIPtr[1];w1++)
+        {
+          std::set<int> s(revDescPtr+revDescIPtr[*w1],revDescPtr+revDescIPtr[(*w1)+1]);
+          s.erase(i);
+          out0v.insert(out0v.end(),s.begin(),s.end());
+        }
+      *out1Ptr=out0v.size();
+    }
+  out0->alloc((int)out0v.size(),1);
+  std::copy(out0v.begin(),out0v.end(),out0->getPointer());
+  neighbors=out0; out0->incrRef();
+  neighborsIndx=out1; out1->incrRef();
+}
+
+/// @cond INTERNAL
+
+/*!
+ * \b WARNING this method do the assumption that connectivity lies on the coordinates set.
+ * For speed reasons no check of this will be done.
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivityGen(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx, DimM1DescNbrer nbrer) const throw(INTERP_KERNEL::Exception)
+{
+  checkConnectivityFullyDefined();
+  int nbOfCells=getNumberOfCells();
+  int nbOfNodes=getNumberOfNodes();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connIndex=_nodal_connec_index->getConstPointer();
+  std::vector< std::vector<int> > descMeshConnB(nbOfCells);
+  std::vector< std::vector<int> > revDescMeshConnB;
+  std::vector< std::vector<int> > revNodalB(nbOfNodes);
+  std::vector<int> meshDM1Conn;
+  std::vector<int> meshDM1ConnIndex(1); meshDM1ConnIndex[0]=0;
+  std::vector<int> meshDM1Type;
+  for(int eltId=0;eltId<nbOfCells;eltId++)
+    {
+      int pos=connIndex[eltId];
+      int posP1=connIndex[eltId+1];
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[pos]);
+      unsigned nbOfSons=cm.getNumberOfSons2(conn+pos+1,posP1-pos-1);
+      int *tmp=new int[posP1-pos];
+      for(unsigned i=0;i<nbOfSons;i++)
+        {
+          INTERP_KERNEL::NormalizedCellType cmsId;
+          unsigned nbOfNodesSon=cm.fillSonCellNodalConnectivity2(i,conn+pos+1,posP1-pos-1,tmp,cmsId);
+          const INTERP_KERNEL::CellModel& cms=INTERP_KERNEL::CellModel::GetCellModel(cmsId);
+          std::set<int> shareableCells(revNodalB[tmp[0]].begin(),revNodalB[tmp[0]].end());
+          for(unsigned j=1;j<nbOfNodesSon && !shareableCells.empty();j++)
+            {
+              std::set<int> tmp2(revNodalB[tmp[j]].begin(),revNodalB[tmp[j]].end());
+              std::set<int> tmp3;
+              std::set_intersection(tmp2.begin(),tmp2.end(),shareableCells.begin(),shareableCells.end(),inserter(tmp3,tmp3.begin()));
+              shareableCells=tmp3;
+            }
+          std::list<int> shareableCellsL(shareableCells.begin(),shareableCells.end());
+          std::set<int> ref(tmp,tmp+nbOfNodesSon);
+          for(std::list<int>::iterator iter=shareableCellsL.begin();iter!=shareableCellsL.end();)
+            {
+              if(cms.isCompatibleWith((INTERP_KERNEL::NormalizedCellType)meshDM1Type[*iter]))
+                {
+                  std::set<int> ref2(meshDM1Conn.begin()+meshDM1ConnIndex[*iter],meshDM1Conn.begin()+meshDM1ConnIndex[(*iter)+1]);
+                  if(ref==ref2)
+                    break;
+                  else
+                    iter=shareableCellsL.erase(iter);
+                }
+              else
+                iter=shareableCellsL.erase(iter);
+            }
+          if(shareableCellsL.empty())
+            {
+              meshDM1Conn.insert(meshDM1Conn.end(),tmp,tmp+nbOfNodesSon);
+              meshDM1ConnIndex.push_back(meshDM1ConnIndex.back()+nbOfNodesSon);
+              int cellDM1Id=(int)meshDM1Type.size();
+              meshDM1Type.push_back((int)cmsId);
+              for(unsigned k=0;k<nbOfNodesSon;k++)
+                revNodalB[tmp[k]].push_back(cellDM1Id);
+              revDescMeshConnB.resize(cellDM1Id+1);
+              revDescMeshConnB.back().push_back(eltId);
+              descMeshConnB[eltId].push_back(nbrer(cellDM1Id,0,cms,false,0,0));
+            }
+          else
+            {
+              int DM1cellId=shareableCellsL.front();
+              revDescMeshConnB[DM1cellId].push_back(eltId);
+              descMeshConnB[eltId].push_back(nbrer(DM1cellId,nbOfNodesSon,cms,true,tmp,&meshDM1Conn[meshDM1ConnIndex[DM1cellId]]));
+            }
+        }
+      delete [] tmp;
+    }
+  revNodalB.clear();
+  //
+  std::string name="Mesh constituent of "; name+=getName();
+  MEDCouplingUMesh *ret=MEDCouplingUMesh::New(name.c_str(),getMeshDimension()-1);
+  ret->setCoords(getCoords());
+  int nbOfCellsInConstituent=(int)meshDM1Type.size();
+  ret->allocateCells(nbOfCellsInConstituent);
+  revDescIndx->alloc(nbOfCellsInConstituent+1,1);
+  int *tmp3=revDescIndx->getPointer(); tmp3[0]=0;
+  for(int ii=0;ii<nbOfCellsInConstituent;ii++)
+    {
+      ret->insertNextCell((INTERP_KERNEL::NormalizedCellType)meshDM1Type[ii],meshDM1ConnIndex[ii+1]-meshDM1ConnIndex[ii],&meshDM1Conn[meshDM1ConnIndex[ii]]);
+      tmp3[ii+1]=tmp3[ii]+((int)revDescMeshConnB[ii].size());
+    }
+  ret->finishInsertingCells();
+  revDesc->alloc(tmp3[nbOfCellsInConstituent],1);
+  tmp3=revDesc->getPointer();
+  for(std::vector< std::vector<int> >::const_iterator iter2=revDescMeshConnB.begin();iter2!=revDescMeshConnB.end();iter2++)
+    tmp3=std::copy((*iter2).begin(),(*iter2).end(),tmp3);
+  meshDM1Type.clear(); meshDM1ConnIndex.clear(); meshDM1Conn.clear();
+  descIndx->alloc(nbOfCells+1,1);
+  tmp3=descIndx->getPointer(); tmp3[0]=0;
+  for(int jj=0;jj<nbOfCells;jj++)
+    tmp3[jj+1]=tmp3[jj]+((int)descMeshConnB[jj].size());
+  desc->alloc(tmp3[nbOfCells],1);
+  tmp3=desc->getPointer();
+  for(std::vector< std::vector<int> >::const_iterator iter3=descMeshConnB.begin();iter3!=descMeshConnB.end();iter3++)
+    tmp3=std::copy((*iter3).begin(),(*iter3).end(),tmp3);
+  //
+  return ret;
+}
+
+struct MEDCouplingAccVisit
+{
+  MEDCouplingAccVisit():_new_nb_of_nodes(0) { }
+  int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; }
+  int _new_nb_of_nodes;
+};
+
+/// @endcond
+
+
+/*!
+ * This method convert cell with ids in ['cellIdsToConvertBg','cellIdsToConvertEnd') into 'this' into dynamic types without changing geometry.
+ * That is to say if 'this' is a 2D, mesh after the invocation of this method it will contain only polygons.
+ * If 'this' is a 3D mesh after the invocation of this method it will contain only polyhedra.
+ * If mesh dimension is not in [2,3] an exception is thrown.
+ * Of course pay attention that the resulting mesh is slower than previous one.
+ * If in ['cellIdsToConvertBg','cellIdsToConvertEnd') there is a cell id not in [0,'this->getNumberOfCells()') an exception will be thrown.
+ * In this case if meshDim==2 the mesh is still valid and only cells treated before throw will be converted into polygon.
+ * If mesh==3, after throw the mesh is \b unconsistent !
+ * This method is above all designed to test more extensively algorithms able to deal with polygons/polyhedra.
+ * 
+ * \warning This method modifies can modify significantly the geometric type order in \a this.
+ * In view of the MED file writing, a renumbering of cells in \a this (using MEDCouplingUMesh::sortCellsInMEDFileFrmt) should be necessary.
+ */
+void MEDCouplingUMesh::convertToPolyTypes(const int *cellIdsToConvertBg, const int *cellIdsToConvertEnd)
+{
+  checkFullyDefined();
+  int dim=getMeshDimension();
+  if(dim<2 || dim>3)
+    throw INTERP_KERNEL::Exception("Invalid mesh dimension : must be 2 or 3 !");
+  int nbOfCells=getNumberOfCells();
+  if(dim==2)
+    {
+      const int *connIndex=_nodal_connec_index->getConstPointer();
+      int *conn=_nodal_connec->getPointer();
+      for(const int *iter=cellIdsToConvertBg;iter!=cellIdsToConvertEnd;iter++)
+        {
+          if(*iter>=0 && *iter<nbOfCells)
+            {
+              const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[connIndex[*iter]]);
+              if(!cm.isDynamic())
+                conn[connIndex[*iter]]=INTERP_KERNEL::NORM_POLYGON;
+              else
+                conn[connIndex[*iter]]=INTERP_KERNEL::NORM_QPOLYG;
+            }
+          else
+            {
+              std::ostringstream oss; oss << "MEDCouplingUMesh::convertToPolyTypes : On rank #" << std::distance(cellIdsToConvertBg,iter) << " value is " << *iter << " which is not";
+              oss << " in range [0," << nbOfCells << ") !";
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }
+        }
+    }
+  else
+    {
+      int *connIndex=_nodal_connec_index->getPointer();
+      int connIndexLgth=_nodal_connec_index->getNbOfElems();
+      const int *connOld=_nodal_connec->getConstPointer();
+      int connOldLgth=_nodal_connec->getNbOfElems();
+      std::vector<int> connNew(connOld,connOld+connOldLgth);
+      for(const int *iter=cellIdsToConvertBg;iter!=cellIdsToConvertEnd;iter++)
+        {
+          if(*iter>=0 && *iter<nbOfCells)
+            {
+              int pos=connIndex[*iter];
+              int posP1=connIndex[(*iter)+1];
+              int lgthOld=posP1-pos-1;
+              const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)connNew[pos]);
+              connNew[pos]=INTERP_KERNEL::NORM_POLYHED;
+              unsigned nbOfFaces=cm.getNumberOfSons2(&connNew[pos+1],lgthOld);
+              int *tmp=new int[nbOfFaces*lgthOld];
+              int *work=tmp;
+              for(int j=0;j<(int)nbOfFaces;j++)
+                {
+                  INTERP_KERNEL::NormalizedCellType type;
+                  unsigned offset=cm.fillSonCellNodalConnectivity2(j,&connNew[pos+1],lgthOld,work,type);
+                  work+=offset;
+                  *work++=-1;
+                }
+              std::size_t newLgth=std::distance(tmp,work)-1;
+              std::size_t delta=newLgth-lgthOld;
+              std::transform(connIndex+(*iter)+1,connIndex+connIndexLgth,connIndex+(*iter)+1,std::bind2nd(std::plus<int>(),delta));
+              connNew.insert(connNew.begin()+posP1,tmp+lgthOld,tmp+newLgth);
+              std::copy(tmp,tmp+lgthOld,connNew.begin()+pos+1);
+              delete [] tmp;
+            }
+          else
+            {
+              std::ostringstream oss; oss << "MEDCouplingUMesh::convertToPolyTypes : On rank #" << std::distance(cellIdsToConvertBg,iter) << " value is " << *iter << " which is not";
+              oss << " in range [0," << nbOfCells << ") !";
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }
+        }
+      _nodal_connec->alloc((int)connNew.size(),1);
+      int *newConnPtr=_nodal_connec->getPointer();
+      std::copy(connNew.begin(),connNew.end(),newConnPtr);
+    }
+  computeTypes();
+}
+
+/*!
+ * This method converts all cells into poly type if possible.
+ * This method is purely for userfriendliness.
+ * As this method can be costly in Memory, no optimization is done to avoid construction of useless vector.
+ */
+void MEDCouplingUMesh::convertAllToPoly()
+{
+  int nbOfCells=getNumberOfCells();
+  std::vector<int> cellIds(nbOfCells);
+  for(int i=0;i<nbOfCells;i++)
+    cellIds[i]=i;
+  convertToPolyTypes(&cellIds[0],&cellIds[0]+cellIds.size());
+}
+
+/*!
+ * This method expects that 'this' has a spacedim equal to 3 and a mesh dimension equal to 3 too, if not an exception will be thrown.
+ * This method work only on cells with type NORM_POLYHED, all other cells with different type, are remains unchanged.
+ * For such polyhedra, they are expected to have only 1 face (containing 2 faces in opposition), having 2*n number of nodes (n nodes on
+ * each 2 faces hidden in the single face of polyhedron).
+ * The first face is expected to be right oriented because all faces of this polyhedron will be deduced.
+ * When called 'this' is an invalid mesh on MED sense. This method will correct that for polyhedra.
+ * In case of presence of polyhedron that has not the extruded aspect (2 faces with the same number of nodes) an exception is thrown and 'this'
+ * remains unchanged.
+ * This method is usefull only for users that wants to build extruded unstructured mesh.
+ * This method is a convenient one that avoids boring polyhedra setting during insertNextCell process.
+ * In case of success, 'this' has be corrected contains the same number of cells and is valid in MED sense.
+ */
+void MEDCouplingUMesh::convertExtrudedPolyhedra() throw(INTERP_KERNEL::Exception)
+{
+  checkFullyDefined();
+  if(getMeshDimension()!=3 || getSpaceDimension()!=3)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertExtrudedPolyhedra works on umeshes with meshdim equal to 3 and spaceDim equal to 3 too!");
+  int nbOfCells=getNumberOfCells();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newCi=DataArrayInt::New();
+  newCi->alloc(nbOfCells+1,1);
+  int *newci=newCi->getPointer();
+  const int *ci=_nodal_connec_index->getConstPointer();
+  const int *c=_nodal_connec->getConstPointer();
+  newci[0]=0;
+  for(int i=0;i<nbOfCells;i++)
+    {
+      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)c[ci[i]];
+      if(type==INTERP_KERNEL::NORM_POLYHED)
+        {
+          if(std::count(c+ci[i]+1,c+ci[i+1],-1)!=0)
+            {
+              std::ostringstream oss; oss << "MEDCouplingUMesh::convertExtrudedPolyhedra : cell # " << i << " is a polhedron BUT it has NOT exactly 1 face !";
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }
+          std::size_t n2=std::distance(c+ci[i]+1,c+ci[i+1]);
+          if(n2%2!=0)
+            {
+              std::ostringstream oss; oss << "MEDCouplingUMesh::convertExtrudedPolyhedra : cell # " << i << " is a polhedron with 1 face but there is a mismatch of number of nodes in face should be even !";
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }
+          int n1=(int)(n2/2);
+          newci[i+1]=7*n1+2+newci[i];//6*n1 (nodal length) + n1+2 (number of faces) - 1 (number of '-1' separator is equal to number of faces -1) + 1 (for cell type)
+        }
+      else
+        newci[i+1]=(ci[i+1]-ci[i])+newci[i];
+    }
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newC=DataArrayInt::New();
+  newC->alloc(newci[nbOfCells],1);
+  int *newc=newC->getPointer();
+  for(int i=0;i<nbOfCells;i++)
+    {
+      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)c[ci[i]];
+      if(type==INTERP_KERNEL::NORM_POLYHED)
+        {
+          std::size_t n1=std::distance(c+ci[i]+1,c+ci[i+1])/2;
+          newc=std::copy(c+ci[i],c+ci[i]+n1+1,newc);
+          *newc++=-1;
+          for(std::size_t j=0;j<n1;j++)
+            {
+              newc[j]=c[ci[i]+1+n1+(n1-j)%n1];
+              newc[n1+5*j]=-1;
+              newc[n1+5*j+1]=c[ci[i]+1+j];
+              newc[n1+5*j+2]=c[ci[i]+1+(j+1)%n1];
+              newc[n1+5*j+3]=c[ci[i]+1+(j+1)%n1+n1];
+              newc[n1+5*j+4]=c[ci[i]+1+j+n1];
+            }
+          newc+=n1*6;
+        }
+      else
+        newc=std::copy(c+ci[i],c+ci[i+1],newc);
+    }
+  _nodal_connec_index->decrRef(); _nodal_connec_index=newCi;
+  _nodal_connec->decrRef(); _nodal_connec=newC;
+  newC->incrRef(); newCi->incrRef();
+}
+
+/*!
+ * This method is the opposite of ParaMEDMEM::MEDCouplingUMesh::convertToPolyTypes method.
+ * The aim is to take all polygons or polyhedrons cell and to try to traduce them into classical cells.
+ *
+ *  \return If true at least one cell has been unpolyzed.
+            \n If false has been returned the nodal connectivity of \a this has **not** been altered and \a this has remains unchanged.
+ *
+ * \warning This method modifies can modify significantly the geometric type order in \a this.
+ * In view of the MED file writing, a renumbering of cells in \a this (using MEDCouplingUMesh::sortCellsInMEDFileFrmt) should be necessary.
+ */
+bool MEDCouplingUMesh::unPolyze()
+{
+  checkFullyDefined();
+  int mdim=getMeshDimension();
+  if(mdim<0)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::unPolyze works on umeshes with meshdim equals to 0, 1 2 or 3 !");
+  if(mdim<=1)
+    return false;
+  int nbOfCells=getNumberOfCells();
+  if(nbOfCells<1)
+    return false;
+  int initMeshLgth=getMeshLength();
+  int *conn=_nodal_connec->getPointer();
+  int *index=_nodal_connec_index->getPointer();
+  int posOfCurCell=0;
+  int newPos=0;
+  int lgthOfCurCell;
+  bool ret=false;
+  for(int i=0;i<nbOfCells;i++)
+    {
+      lgthOfCurCell=index[i+1]-posOfCurCell;
+      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[posOfCurCell];
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
+      INTERP_KERNEL::NormalizedCellType newType=INTERP_KERNEL::NORM_ERROR;
+      int newLgth;
+      if(cm.isDynamic())
+        {
+          switch(cm.getDimension())
+            {
+            case 2:
+              {
+                INTERP_KERNEL::AutoPtr<int> tmp=new int[lgthOfCurCell-1];
+                std::copy(conn+posOfCurCell+1,conn+posOfCurCell+lgthOfCurCell,(int *)tmp);
+                newType=INTERP_KERNEL::CellSimplify::tryToUnPoly2D(cm.isQuadratic(),tmp,lgthOfCurCell-1,conn+newPos+1,newLgth);
+                break;
+              }
+            case 3:
+              {
+                int nbOfFaces,lgthOfPolyhConn;
+                INTERP_KERNEL::AutoPtr<int> zipFullReprOfPolyh=INTERP_KERNEL::CellSimplify::getFullPolyh3DCell(type,conn+posOfCurCell+1,lgthOfCurCell-1,nbOfFaces,lgthOfPolyhConn);
+                newType=INTERP_KERNEL::CellSimplify::tryToUnPoly3D(zipFullReprOfPolyh,nbOfFaces,lgthOfPolyhConn,conn+newPos+1,newLgth);
+                break;
+              }
+            case 1:
+              {
+                newType=(lgthOfCurCell==3)?INTERP_KERNEL::NORM_SEG2:INTERP_KERNEL::NORM_POLYL;
+                break;
+              }
+            }
+          ret=ret || (newType!=type);
+          conn[newPos]=newType;
+          newPos+=newLgth+1;
+          posOfCurCell=index[i+1];
+          index[i+1]=newPos;
+        }
+      else
+        {
+          std::copy(conn+posOfCurCell,conn+posOfCurCell+lgthOfCurCell,conn+newPos);
+          newPos+=lgthOfCurCell;
+          posOfCurCell+=lgthOfCurCell;
+          index[i+1]=newPos;
+        }
+    }
+  if(newPos!=initMeshLgth)
+    _nodal_connec->reAlloc(newPos);
+  if(ret)
     computeTypes();
+  return ret;
 }
 
-MEDCouplingUMesh::~MEDCouplingUMesh()
+/*!
+ * This method expects that spaceDimension is equal to 3 and meshDimension equal to 3.
+ * This method performs operation only on polyhedrons in \b this. If no polyhedrons exists in \b this, \b this remains unchanged.
+ * This method allows to merge if any coplanar 3DSurf cells that may appear in some polyhedrons cells. 
+ *
+ * \param [in] eps is a relative precision that allows to establish if some 3D plane are coplanar or not. This epsilon is used to recenter around origin to have maximal 
+ *             precision.
+ */
+void MEDCouplingUMesh::simplifyPolyhedra(double eps) throw(INTERP_KERNEL::Exception)
+{
+  checkFullyDefined();
+  if(getMeshDimension()!=3 || getSpaceDimension()!=3)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplifyPolyhedra : works on meshdimension 3 and spaceDimension 3 !");
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=getCoords()->deepCpy();
+  coords->recenterForMaxPrecision(eps);
+  const double *coordsPtr=coords->getConstPointer();
+  //
+  int nbOfCells=getNumberOfCells();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *index=_nodal_connec_index->getConstPointer();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connINew=DataArrayInt::New();
+  connINew->alloc(nbOfCells+1,1);
+  int *connINewPtr=connINew->getPointer(); *connINewPtr++=0;
+  std::vector<int> connNew;
+  bool changed=false;
+  for(int i=0;i<nbOfCells;i++,connINewPtr++)
+    {
+      if(conn[index[i]]==(int)INTERP_KERNEL::NORM_POLYHED)
+        {
+          SimplifyPolyhedronCell(eps,coords,conn+index[i],conn+index[i+1],connNew);
+          changed=true;
+        }
+      else
+        connNew.insert(connNew.end(),conn+index[i],conn+index[i+1]);
+      *connINewPtr=(int)connNew.size();
+    }
+  if(changed)
+    {
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connNew2=DataArrayInt::New();
+      connNew2->alloc((int)connNew.size(),1);
+      std::copy(connNew.begin(),connNew.end(),connNew2->getPointer());
+      setConnectivity(connNew2,connINew,false);
+    }
+}
+
+/*!
+ * This method returns all node ids used in \b this. The data array returned has to be dealt by the caller.
+ * The returned node ids are sortes ascendingly. This method is closed to MEDCouplingUMesh::getNodeIdsInUse except
+ * the format of returned DataArrayInt instance.
+ * 
+ * @return a newly allocated DataArrayInt sorted ascendingly of fetched node ids.
+ * \sa MEDCouplingUMesh::getNodeIdsInUse
+ */
+DataArrayInt *MEDCouplingUMesh::computeFetchedNodeIds() const throw(INTERP_KERNEL::Exception)
 {
- if(_nodal_connec)
-   _nodal_connec->decrRef();
- if(_nodal_connec_index)
-   _nodal_connec_index->decrRef();
- if(_coords)
-   _coords->decrRef();
+  checkConnectivityFullyDefined();
+  std::set<int> retS;
+  int nbOfCells=getNumberOfCells();
+  const int *connIndex=_nodal_connec_index->getConstPointer();
+  const int *conn=_nodal_connec->getConstPointer();
+  for(int i=0;i<nbOfCells;i++)
+    for(int j=connIndex[i]+1;j<connIndex[i+1];j++)
+      if(conn[j]>=0)
+        retS.insert(conn[j]);
+  DataArrayInt *ret=DataArrayInt::New();
+  ret->alloc((int)retS.size(),1);
+  std::copy(retS.begin(),retS.end(),ret->getPointer());
+  return ret;
 }
 
-void MEDCouplingUMesh::computeTypes()
+/*!
+ * Array returned is the correspondance in \b old \b to \b new format (that's why 'nbrOfNodesInUse' is returned too).
+ * The returned array is newly created and should be dealt by the caller.
+ * To retrieve the new to old format the user can use DataArrayInt::invertArrayO2N2N2O method.
+ * The size of returned array is the number of nodes of 'this'.
+ * -1 values in returned array means that the corresponding node never appear in any nodal connectivity of cells constituting 'this'.
+ * @param [out] nbrOfNodesInUse out parameter that specifies how many of nodes in 'this' is really used in nodal connectivity.
+ * @return a newly allocated DataArrayInt that tells for each nodeid in \b this if it is unused (-1) or used (the corresponding new id)
+ */
+DataArrayInt *MEDCouplingUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception)
 {
-  if(_nodal_connec && _nodal_connec_index)
+  nbrOfNodesInUse=-1;
+  int nbOfNodes=getNumberOfNodes();
+  DataArrayInt *ret=DataArrayInt::New();
+  ret->alloc(nbOfNodes,1);
+  int *traducer=ret->getPointer();
+  std::fill(traducer,traducer+nbOfNodes,-1);
+  int nbOfCells=getNumberOfCells();
+  const int *connIndex=_nodal_connec_index->getConstPointer();
+  const int *conn=_nodal_connec->getConstPointer();
+  for(int i=0;i<nbOfCells;i++)
+    for(int j=connIndex[i]+1;j<connIndex[i+1];j++)
+      if(conn[j]>=0)
+        traducer[conn[j]]=1;
+  nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1);
+  std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit());
+  return ret;
+}
+
+/*!
+ * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component.
+ * For each cell in \b this the number of nodes constituting cell is computed.
+ * Excepted for poyhedrons, the result can be deduced by performing a deltaShiftIndex on the nodal connectivity index in \b this minus 1.
+ * For polyhedrons, the face separation (-1) are excluded from the couting.
+ * 
+ * \return a newly allocated array
+ */
+DataArrayInt *MEDCouplingUMesh::computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception)
+{
+  checkConnectivityFullyDefined();
+  int nbOfCells=getNumberOfCells();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
+  ret->alloc(nbOfCells,1);
+  int *retPtr=ret->getPointer();
+  const int *conn=getNodalConnectivity()->getConstPointer();
+  const int *connI=getNodalConnectivityIndex()->getConstPointer();
+  for(int i=0;i<nbOfCells;i++,retPtr++)
     {
-      _types.clear();
-      const int *conn=_nodal_connec->getPointer();
-      const int *connIndex=_nodal_connec_index->getPointer();
-      int nbOfElem=_nodal_connec_index->getNbOfElems()-1;
-      for(const int *pt=connIndex;pt!=connIndex+nbOfElem;pt++)
-        _types.insert((INTERP_KERNEL::NormalizedCellType)conn[*pt]);
+      if(conn[connI[i]]!=(int)INTERP_KERNEL::NORM_POLYHED)
+        *retPtr=connI[i+1]-connI[i]-1;
+      else
+        *retPtr=connI[i+1]-connI[i]-1-std::count(conn+connI[i]+1,conn+connI[i+1],-1);
     }
+  ret->incrRef(); return ret;
 }
 
-bool MEDCouplingUMesh::isStructured() const
+/*!
+ * 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.
+ * The maximum value stored in returned array is the number of nodes of '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.
+ */
+DataArrayInt *MEDCouplingUMesh::zipCoordsTraducer() throw(INTERP_KERNEL::Exception)
 {
-  return false;
+  int newNbOfNodes=-1;
+  DataArrayInt *traducer=getNodeIdsInUse(newNbOfNodes);
+  renumberNodes(traducer->getConstPointer(),newNbOfNodes);
+  return traducer;
 }
 
-int MEDCouplingUMesh::getNumberOfCells() const
-{ 
- if(_nodal_connec_index)
-   if(_iterator==-1)
-     return _nodal_connec_index->getNumberOfTuples()-1;
-   else
-     return _iterator;
- else
-   throw INTERP_KERNEL::Exception("Unable to get number of cells because no coordinates specified !");
+/*!
+ * This method stands if 'cell1' and 'cell2' are equals regarding 'compType' policy.
+ * The semantic of 'compType' is specified in MEDCouplingUMesh::zipConnectivityTraducer method.
+ */
+int MEDCouplingUMesh::areCellsEqual(int cell1, int cell2, int compType) const
+{
+  switch(compType)
+    {
+    case 0:
+      return areCellsEqual0(cell1,cell2);
+    case 1:
+      return areCellsEqual1(cell1,cell2);
+    case 2:
+      return areCellsEqual2(cell1,cell2);
+    case 7:
+      return areCellsEqual7(cell1,cell2);
+    }
+  throw INTERP_KERNEL::Exception("Unknown comparison asked ! Must be in 0,1 or 2.");
 }
 
-int MEDCouplingUMesh::getNumberOfNodes() const
+/*!
+ * This method is the last step of the MEDCouplingUMesh::zipConnectivityTraducer with policy 0.
+ */
+int MEDCouplingUMesh::areCellsEqual0(int cell1, int cell2) const
 {
- if(_coords)
-   return _coords->getNumberOfTuples();
- else
-   throw INTERP_KERNEL::Exception("Unable to get number of nodes because no coordinates specified !");
+  const int *conn=getNodalConnectivity()->getConstPointer();
+  const int *connI=getNodalConnectivityIndex()->getConstPointer();
+  if(connI[cell1+1]-connI[cell1]==connI[cell2+1]-connI[cell2])
+    return std::equal(conn+connI[cell1]+1,conn+connI[cell1+1],conn+connI[cell2]+1)?1:0;
+  return 0;
 }
 
-int MEDCouplingUMesh::getSpaceDimension() const
+/*!
+ * This method is the last step of the MEDCouplingUMesh::zipConnectivityTraducer with policy 1.
+ */
+int MEDCouplingUMesh::areCellsEqual1(int cell1, int cell2) const
 {
- if(_coords)
-   return _coords->getNumberOfComponents();
- else
-   throw INTERP_KERNEL::Exception("Unable to get space dimension because no coordinates specified !");
+  const int *conn=getNodalConnectivity()->getConstPointer();
+  const int *connI=getNodalConnectivityIndex()->getConstPointer();
+  int sz=connI[cell1+1]-connI[cell1];
+  if(sz==connI[cell2+1]-connI[cell2])
+    {
+      if(conn[connI[cell1]]==conn[connI[cell2]])
+        {
+          const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[connI[cell1]]);
+          unsigned dim=cm.getDimension();
+          if(dim!=3)
+            {
+              if(dim!=1)
+                {
+                  int sz1=2*(sz-1);
+                  int *tmp=new int[sz1];
+                  int *work=std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],tmp);
+                  std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],work);
+                  work=std::search(tmp,tmp+sz1,conn+connI[cell2]+1,conn+connI[cell2+1]);
+                  delete [] tmp;
+                  return work!=tmp+sz1?1:0;
+                }
+              else
+                return std::equal(conn+connI[cell1]+1,conn+connI[cell1+1],conn+connI[cell2]+1)?1:0;//case of SEG2 and SEG3
+            }
+          else
+            throw INTERP_KERNEL::Exception("MEDCouplingUMesh::areCellsEqual1 : not implemented yet for meshdim == 3 !");
+        }
+    }
+  return 0;
 }
 
-int MEDCouplingUMesh::getMeshLength() const
+/*!
+ * This method is the last step of the MEDCouplingUMesh::zipConnectivityTraducer with policy 2.
+ */
+int MEDCouplingUMesh::areCellsEqual2(int cell1, int cell2) const
 {
-  return _nodal_connec->getNbOfElems();
+  const int *conn=getNodalConnectivity()->getConstPointer();
+  const int *connI=getNodalConnectivityIndex()->getConstPointer();
+  if(connI[cell1+1]-connI[cell1]==connI[cell2+1]-connI[cell2])
+    {
+      if(conn[connI[cell1]]==conn[connI[cell2]])
+        {
+          std::set<int> s1(conn+connI[cell1]+1,conn+connI[cell1+1]);
+          std::set<int> s2(conn+connI[cell2]+1,conn+connI[cell2+1]);
+          return s1==s2?1:0;
+        }
+    }
+  return 0;
+}
+
+/*!
+ * This method is the last step of the MEDCouplingUMesh::zipConnectivityTraducer with policy 7.
+ */
+int MEDCouplingUMesh::areCellsEqual7(int cell1, int cell2) const
+{
+  const int *conn=getNodalConnectivity()->getConstPointer();
+  const int *connI=getNodalConnectivityIndex()->getConstPointer();
+  int sz=connI[cell1+1]-connI[cell1];
+  if(sz==connI[cell2+1]-connI[cell2])
+    {
+      if(conn[connI[cell1]]==conn[connI[cell2]])
+        {
+          const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[connI[cell1]]);
+          unsigned dim=cm.getDimension();
+          if(dim!=3)
+            {
+              if(dim!=1)
+                {
+                  int sz1=2*(sz-1);
+                  int *tmp=new int[sz1];
+                  int *work=std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],tmp);
+                  std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],work);
+                  work=std::search(tmp,tmp+sz1,conn+connI[cell2]+1,conn+connI[cell2+1]);
+                  if(work!=tmp+sz1)
+                    {
+                      delete [] tmp;
+                      return 1;
+                    }
+                  else
+                    {
+                      std::reverse_iterator<int *> it1(tmp+sz1);
+                      std::reverse_iterator<int *> it2(tmp);
+                      if(std::search(it1,it2,conn+connI[cell2]+1,conn+connI[cell2+1])!=it2)
+                        {
+                          delete [] tmp;
+                          return 2;
+                        }
+                      else
+                        {
+                          delete [] tmp;
+                          return 0;
+                        }
+                    }
+                  
+                  return work!=tmp+sz1?1:0;
+                }
+              else
+                {//case of SEG2 and SEG3
+                  if(std::equal(conn+connI[cell1]+1,conn+connI[cell1+1],conn+connI[cell2]+1))
+                    return 1;
+                  if(!cm.isQuadratic())
+                    {
+                      std::reverse_iterator<const int *> it1(conn+connI[cell1+1]);
+                      std::reverse_iterator<const int *> it2(conn+connI[cell1]+1);
+                      if(std::equal(it1,it2,conn+connI[cell2]+1))
+                        return 2;
+                      return 0;
+                    }
+                  else
+                    {
+                      if(conn[connI[cell1]+1]==conn[connI[cell2]+2] && conn[connI[cell1]+2]==conn[connI[cell2]+1] && conn[connI[cell1]+3]==conn[connI[cell2]+3])
+                        return 2;
+                      return 0;
+                    }
+                }
+            }
+          else
+            throw INTERP_KERNEL::Exception("MEDCouplingUMesh::areCellsEqual7 : not implemented yet for meshdim == 3 !");
+        }
+    }
+  return 0;
+}
+
+
+/*!
+ * This method compares 2 cells coming from two unstructured meshes : 'this' and 'other'.
+ * This method compares 2 cells having the same id 'cellId' in 'this' and 'other'.
+ */
+bool MEDCouplingUMesh::areCellsFrom2MeshEqual(const MEDCouplingUMesh *other, int cellId, double prec) const
+{
+  if(getTypeOfCell(cellId)!=other->getTypeOfCell(cellId))
+    return false;
+  std::vector<int> c1,c2;
+  getNodeIdsOfCell(cellId,c1);
+  other->getNodeIdsOfCell(cellId,c2);
+  std::size_t sz=c1.size();
+  if(sz!=c2.size())
+    return false;
+  for(std::size_t i=0;i<sz;i++)
+    {
+      std::vector<double> n1,n2;
+      getCoordinatesOfNode(c1[0],n1);
+      other->getCoordinatesOfNode(c2[0],n2);
+      std::transform(n1.begin(),n1.end(),n2.begin(),n1.begin(),std::minus<double>());
+      std::transform(n1.begin(),n1.end(),n1.begin(),std::ptr_fun<double,double>(fabs));
+      if(*std::max_element(n1.begin(),n1.end())>prec)
+        return false;
+    }
+  return true;
+}
+
+/*!
+ * This method find in candidate pool defined by 'candidates' the cells equal following the polycy 'compType'.
+ * If any true is returned and the results will be put at the end of 'result' output parameter. If not false is returned
+ * and result remains unchanged.
+ * The semantic of 'compType' is specified in MEDCouplingUMesh::zipConnectivityTraducer method.
+ * If in 'candidates' pool -1 value is considered as an empty value.
+ * WARNING this method returns only ONE set of result !
+ */
+bool MEDCouplingUMesh::areCellsEqualInPool(const std::vector<int>& candidates, int compType, std::vector<int>& result) const
+{
+  std::set<int> cand(candidates.begin(),candidates.end());
+  cand.erase(-1);
+  if(cand.size()<=1)
+    return false;
+  bool ret=false;
+  std::set<int>::const_iterator iter=cand.begin();
+  int start=(*iter++);
+  for(;iter!=cand.end();iter++)
+    {
+      int status=areCellsEqual(start,*iter,compType);
+      if(status!=0)
+        {
+          if(!ret)
+            {
+              result.push_back(start);
+              ret=true;
+            }
+          if(status==1)
+            result.push_back(*iter);
+          else
+            result.push_back(status==2?(*iter+1):-(*iter+1));
+        }
+    }
+  return ret;
+}
+
+/*!
+ * This method common cells base regarding 'compType' comparison policy described in ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer for details.
+ * This method returns 2 values 'res' and 'resI'.
+ * If 'res' and 'resI' are not empty before calling this method they will be cleared before set.
+ * The format of 'res' and 'resI' is as explained here.
+ * resI.size()-1 is the number of set of cells equal.
+ * The nth set is [res.begin()+resI[n];res.begin()+resI[n+1]) with 0<=n<resI.size()-1 
+ */
+template<int SPACEDIM>
+void MEDCouplingUMesh::findCommonCellsBase(int compType, std::vector<int>& res, std::vector<int>& resI) const
+{
+  res.clear(); resI.clear();
+  resI.push_back(0);
+  std::vector<double> bbox;
+  int nbOfCells=getNumberOfCells();
+  getBoundingBoxForBBTree(bbox);
+  double bb[2*SPACEDIM];
+  double eps=getCaracteristicDimension();
+  eps*=1.e-12;
+  BBTree<SPACEDIM,int> myTree(&bbox[0],0,0,nbOfCells,-eps);
+  const int *conn=getNodalConnectivity()->getConstPointer();
+  const int *connI=getNodalConnectivityIndex()->getConstPointer();
+  const double *coords=getCoords()->getConstPointer();
+  std::vector<bool> isFetched(nbOfCells);
+  for(int k=0;k<nbOfCells;k++)
+    {
+      if(!isFetched[k])
+        {
+          for(int j=0;j<SPACEDIM;j++)
+            { bb[2*j]=std::numeric_limits<double>::max(); bb[2*j+1]=-std::numeric_limits<double>::max(); }
+          for(const int *pt=conn+connI[k]+1;pt!=conn+connI[k+1];pt++)
+            if(*pt>-1)
+              {
+                for(int j=0;j<SPACEDIM;j++)
+                  {
+                    bb[2*j]=std::min(bb[2*j],coords[SPACEDIM*(*pt)+j]);
+                    bb[2*j+1]=std::max(bb[2*j+1],coords[SPACEDIM*(*pt)+j]);
+                  }
+              }
+          std::vector<int> candidates1;
+          myTree.getIntersectingElems(bb,candidates1);
+          std::vector<int> candidates;
+          for(std::vector<int>::const_iterator iter=candidates1.begin();iter!=candidates1.end();iter++)
+            if(!isFetched[*iter])
+              candidates.push_back(*iter);
+          if(areCellsEqualInPool(candidates,compType,res))
+            {
+              int pos=resI.back();
+              resI.push_back((int)res.size());
+              for(std::vector<int>::const_iterator it=res.begin()+pos;it!=res.end();it++)
+                isFetched[*it]=true;
+            }
+          isFetched[k]=true;
+        }
+    }
+}
+
+/*!
+ * This method could potentially modify 'this'. This method merges cells if there are cells equal in 'this'. The comparison is specified by 'compType'.
+ * This method keeps the coordiantes of 'this'.
+ *
+ * @param compType input specifying the technique used to compare cells each other.
+ *   - 0 : exactly. A cell is detected to be the same if and only if the connectivity is exactly the same without permutation and types same too. This is the strongest policy.
+ *   - 1 : permutation same orientation. cell1 and cell2 are considered equal if the connectivity of cell2 can be deduced by those of cell1 by direct permutation (with exactly the same orientation)
+ * and their type equal. For 1D mesh the policy 1 is equivalent to 0.
+ *   - 2 : nodal. cell1 and cell2 are equal if and only if cell1 and cell2 have same type and have the same nodes constituting connectivity. This is the laziest policy. This policy
+ * can be used for users not sensitive to orientation of cell
+ * @return the correspondance array old to new.
+ * 
+ * \warning This method modifies can modify significantly the geometric type order in \a this.
+ * In view of the MED file writing, a renumbering of cells in \a this (using MEDCouplingUMesh::sortCellsInMEDFileFrmt) should be necessary.
+ */
+DataArrayInt *MEDCouplingUMesh::zipConnectivityTraducer(int compType) throw(INTERP_KERNEL::Exception)
+{
+  int spaceDim=getSpaceDimension();
+  int nbOfCells=getNumberOfCells();
+  std::vector<int> commonCells;
+  std::vector<int> commonCellsI;
+  switch(spaceDim)
+    {
+    case 3:
+      {
+        findCommonCellsBase<3>(compType,commonCells,commonCellsI);
+        break;
+      }
+    case 2:
+      {
+        findCommonCellsBase<2>(compType,commonCells,commonCellsI);
+        break;
+      }
+    case 1:
+      {
+        findCommonCellsBase<1>(compType,commonCells,commonCellsI);
+        break;
+      }
+    default:
+      throw INTERP_KERNEL::Exception("Invalid spaceDimension : must be 1, 2 or 3.");
+    }
+  DataArrayInt *ret=DataArrayInt::New();
+  ret->alloc(nbOfCells,1);
+  int *retPtr=ret->getPointer();
+  std::fill(retPtr,retPtr+nbOfCells,0);
+  const std::size_t nbOfTupleSmCells=commonCellsI.size()-1;
+  int id=-1;
+  std::vector<int> cellsToKeep;
+  for(std::size_t i=0;i<nbOfTupleSmCells;i++)
+    {
+      for(std::vector<int>::const_iterator it=commonCells.begin()+commonCellsI[i];it!=commonCells.begin()+commonCellsI[i+1];it++)
+        retPtr[*it]=id;
+      id--;
+    }
+  id=0;
+  std::map<int,int> m;
+  for(int i=0;i<nbOfCells;i++)
+    {
+      int val=retPtr[i];
+      if(val==0)
+        {
+          retPtr[i]=id++;
+          cellsToKeep.push_back(i);
+        }
+      else
+        {
+          std::map<int,int>::const_iterator iter=m.find(val);
+          if(iter==m.end())
+            {
+              m[val]=id;
+              retPtr[i]=id++;
+              cellsToKeep.push_back(i);
+            }
+          else
+            retPtr[i]=(*iter).second;
+        }
+    }
+  MEDCouplingUMesh *self=(MEDCouplingUMesh *)buildPartOfMySelf(&cellsToKeep[0],&cellsToKeep[0]+cellsToKeep.size(),true);
+  setConnectivity(self->getNodalConnectivity(),self->getNodalConnectivityIndex(),true);
+  self->decrRef();
+  return ret;
+}
+
+/*!
+ * This method makes the assumption that 'this' and 'other' share the same coords. If not an exception will be thrown !
+ * This method tries to determine if 'other' is fully included in 'this'. To compute that, this method works with connectivity as MEDCouplingUMesh::zipConnectivityTraducer method does. 
+ * This method is close to MEDCouplingUMesh::checkDeepEquivalOnSameNodesWith or MEDCouplingMesh::checkGeoEquivalWith with policy 20,21,or 22.
+ * The main difference is that this method is not expected to throw exception.
+ * This method has two outputs :
+ *
+ * @param compType is the comparison type. The possible values of this parameter are described in ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer method
+ * @param arr is an output parameter that returns a \b newly created instance. This array is of size 'other->getNumberOfCells()'.
+ * @return If 'other' is fully included in 'this 'true is returned. If not false is returned.
+ */
+bool MEDCouplingUMesh::areCellsIncludedIn(const MEDCouplingUMesh *other, int compType, DataArrayInt *& arr) const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MergeUMeshesOnSameCoords(this,other);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=mesh->zipConnectivityTraducer(compType);
+  int nbOfCells=getNumberOfCells();
+  arr=o2n->substr(nbOfCells);
+  arr->setName(other->getName());
+  int tmp;
+  if(other->getNumberOfCells()==0)
+    return true;
+  return arr->getMaxValue(tmp)<nbOfCells;
+}
+
+/*!
+ * This method makes the assumption that 'this' and 'other' share the same coords. If not an exception will be thrown !
+ * This method tries to determine if \b other is fully included in \b this.
+ * The main difference is that this method is not expected to throw exception.
+ * This method has two outputs :
+ *
+ * @param arr is an output parameter that returns a \b newly created instance. This array is of size 'other->getNumberOfCells()'.
+ * @return If 'other' is fully included in 'this 'true is returned. If not false is returned.
+ */
+bool MEDCouplingUMesh::areCellsIncludedIn2(const MEDCouplingUMesh *other, DataArrayInt *& arr) const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MergeUMeshesOnSameCoords(this,other);
+  int spaceDim=mesh->getSpaceDimension();
+  std::vector<int> commonCells;
+  std::vector<int> commonCellsI;
+  switch(spaceDim)
+    {
+    case 3:
+      {
+        findCommonCellsBase<3>(7,commonCells,commonCellsI);
+        break;
+      }
+    case 2:
+      {
+        findCommonCellsBase<2>(7,commonCells,commonCellsI);
+        break;
+      }
+    case 1:
+      {
+        findCommonCellsBase<1>(7,commonCells,commonCellsI);
+        break;
+      }
+    default:
+      throw INTERP_KERNEL::Exception("Invalid spaceDimension : must be 1, 2 or 3.");
+    }
+  int thisNbCells=getNumberOfCells();
+  int otherNbCells=other->getNumberOfCells();
+  int nbOfCells=mesh->getNumberOfCells();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr2=DataArrayInt::New();
+  arr2->alloc(otherNbCells,1);
+  arr2->fillWithZero();
+  int *arr2Ptr=arr2->getPointer();
+  int nbOfCommon=(int)commonCellsI.size()-1;
+  for(int i=0;i<nbOfCommon;i++)
+    {
+      int start=commonCells[commonCellsI[i]];
+      if(start<thisNbCells)
+        {
+          for(int j=commonCellsI[i]+1;j!=commonCellsI[i+1];j++)
+            {
+              int sig=commonCells[j]>0?1:-1;
+              int val=std::abs(commonCells[j])-1;
+              if(val>=thisNbCells)
+                arr2Ptr[val-thisNbCells]=sig*(start+1);
+            }
+        }
+    }
+  arr2->setName(other->getName());
+  if(arr2->presenceOfValue(0))
+    return false;
+  arr=arr2;
+  arr2->incrRef();
+  return true;
+}
+
+/*!
+ * @param areNodesMerged if at least two nodes have been merged.
+ * @return old to new node correspondance.
+ */
+DataArrayInt *MEDCouplingUMesh::mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes)
+{
+  DataArrayInt *ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes);
+  if(areNodesMerged)
+    renumberNodes(ret->getConstPointer(),newNbOfNodes);
+  return ret;
+}
+
+/*!
+ * Idem ParaMEDMEM::MEDCouplingUMesh::mergeNodes method except that the merged nodes are meld into the barycenter of them.
+ */
+DataArrayInt *MEDCouplingUMesh::mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes)
+{
+  DataArrayInt *ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes);
+  if(areNodesMerged)
+    renumberNodes2(ret->getConstPointer(),newNbOfNodes);
+  return ret;
+}
+
+/*!
+ * This method tries to use 'other' coords and use it for 'this'. If no exception was thrown after the call of this method :
+ * this->_coords==other->_coords. If an exception is thrown 'this' remains unchanged.
+ * Contrary to MEDCouplingUMesh::tryToShareSameCoords method this method makes a deeper analyze of coordinates (and so more expensive) than simple equality.
+ * Two nodes one in 'this' and other in 'other' are considered equal if the distance between the two is lower than epsilon.
+ */
+void MEDCouplingUMesh::tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception)
+{
+  const DataArrayDouble *coords=other.getCoords();
+  if(!coords)
+    throw INTERP_KERNEL::Exception("tryToShareSameCoordsPermute : No coords specified in other !");
+  if(!_coords)
+    throw INTERP_KERNEL::Exception("tryToShareSameCoordsPermute : No coords specified in this whereas there is any in other !");
+  int otherNbOfNodes=other.getNumberOfNodes();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=MergeNodesArray(&other,this);
+  _coords->incrRef();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> oldCoords=_coords;
+  setCoords(newCoords);
+  bool areNodesMerged;
+  int newNbOfNodes;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=buildPermArrayForMergeNode(epsilon,otherNbOfNodes,areNodesMerged,newNbOfNodes);
+  if(!areNodesMerged)
+    {
+      setCoords(oldCoords);
+      throw INTERP_KERNEL::Exception("tryToShareSameCoordsPermute fails : no nodes are mergeable with specified given epsilon !");
+    }
+  int maxId=*std::max_element(da->getConstPointer(),da->getConstPointer()+otherNbOfNodes);
+  const int *pt=std::find_if(da->getConstPointer()+otherNbOfNodes,da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater<int>(),maxId));
+  if(pt!=da->getConstPointer()+da->getNbOfElems())
+    {
+      setCoords(oldCoords);
+      throw INTERP_KERNEL::Exception("tryToShareSameCoordsPermute fails : some nodes in this are not in other !");
+    }
+  setCoords(oldCoords);
+  renumberNodesInConn(da->getConstPointer()+otherNbOfNodes);
+  setCoords(coords);
+}
+
+/*!
+ * Build a sub part of \b this lying or not on the same coordinates than \b this (regarding value of \b keepCoords).
+ * By default coordinates are kept. This method is close to MEDCouplingUMesh::buildPartOfMySelf except that here input
+ * cellIds is not given explicitely but by a range python like.
+ * 
+ * \param keepCoords that specifies if you want or not to keep coords as this or zip it (see ParaMEDMEM::MEDCouplingUMesh::zipCoords). If true zipCoords is \b NOT called, if false, zipCoords is called.
+ * \return a newly allocated
+ * 
+ * \warning This method modifies can generate an unstructured mesh whose cells are not sorted by geometric type order.
+ * In view of the MED file writing, a renumbering of cells of returned unstructured mesh (using MEDCouplingUMesh::sortCellsInMEDFileFrmt) should be necessary.
+ */
+MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelf2(int start, int end, int step, bool keepCoords) const throw(INTERP_KERNEL::Exception)
+{
+  if(getMeshDimension()!=-1)
+    {
+      MEDCouplingUMesh *ret=buildPartOfMySelfKeepCoords2(start,end,step);
+      if(!keepCoords)
+        ret->zipCoords();
+      return ret;
+    }
+  else
+    {
+      int newNbOfCells=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::buildPartOfMySelf2 for -1 dimension mesh ");
+      if(newNbOfCells!=1)
+        throw INTERP_KERNEL::Exception("-1D mesh has only one cell !");
+      if(start!=0)
+        throw INTERP_KERNEL::Exception("-1D mesh has only one cell : 0 !");
+      incrRef();
+      return const_cast<MEDCouplingUMesh *>(this);
+    }
+}
+
+/*!
+ * build a sub part of \b this. This sub part is defined by the cell ids contained in the array in [begin,end).
+ * @param begin begin of array containing the cell ids to keep.
+ * @param end end of array of cell ids to keep. \b WARNING end param is \b not included ! Idem STL standard definitions.
+ * @param keepCoords that specifies if you want or not to keep coords as this or zip it (see ParaMEDMEM::MEDCouplingUMesh::zipCoords). If true zipCoords is \b NOT called, if false, zipCoords is called.
+ * 
+ * \warning This method modifies can generate an unstructured mesh whose cells are not sorted by geometric type order.
+ * In view of the MED file writing, a renumbering of cells of returned unstructured mesh (using MEDCouplingUMesh::sortCellsInMEDFileFrmt) should be necessary.
+ */
+MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelf(const int *begin, const int *end, bool keepCoords) const
+{
+  if(getMeshDimension()!=-1)
+    {
+      MEDCouplingUMesh *ret=buildPartOfMySelfKeepCoords(begin,end);
+      if(!keepCoords)
+        ret->zipCoords();
+      return ret;
+    }
+  else
+    {
+      if(end-begin!=1)
+        throw INTERP_KERNEL::Exception("-1D mesh has only one cell !");
+      if(begin[0]!=0)
+        throw INTERP_KERNEL::Exception("-1D mesh has only one cell : 0 !");
+      incrRef();
+      return const_cast<MEDCouplingUMesh *>(this);
+    }
+}
+
+/*!
+ * This method operates only on nodal connectivity on \b this. Coordinates of \b this is completely ignored here.
+ *
+ * This method allows to partially modify some cells in \b this (whose list is specified by [\b cellIdsBg, \b cellIdsEnd) ) with cells coming in \b otherOnSameCoordsThanThis.
+ * Size of [\b cellIdsBg, \b cellIdsEnd) ) must be equal to the number of cells of otherOnSameCoordsThanThis.
+ * The number of cells of \b this will remain the same with this method.
+ *
+ * \param [in] begin begin of cell ids (included) of cells in this to assign
+ * \param [in] end end of cell ids (excluded) of cells in this to assign
+ * \param [in] otherOnSameCoordsThanThis an another mesh with same meshdimension than \b this with exactly the same number of cells than cell ids list in [\b cellIdsBg, \b cellIdsEnd).
+ *             Coordinate pointer of \b this and those of \b otherOnSameCoordsThanThis must be the same
+ */
+void MEDCouplingUMesh::setPartOfMySelf(const int *cellIdsBg, const int *cellIdsEnd, const MEDCouplingUMesh& otherOnSameCoordsThanThis) throw(INTERP_KERNEL::Exception)
+{
+  checkConnectivityFullyDefined();
+  otherOnSameCoordsThanThis.checkConnectivityFullyDefined();
+  if(getCoords()!=otherOnSameCoordsThanThis.getCoords())
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::setPartOfMySelf : coordinates pointer are not the same ! Invoke setCoords or call tryToShareSameCoords method !");
+  if(getMeshDimension()!=otherOnSameCoordsThanThis.getMeshDimension())
+    {
+      std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf : Mismatch of meshdimensions ! this is equal to " << getMeshDimension();
+      oss << ", whereas other mesh dimension is set equal to " << otherOnSameCoordsThanThis.getMeshDimension() << " !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  int nbOfCellsToModify=(int)std::distance(cellIdsBg,cellIdsEnd);
+  if(nbOfCellsToModify!=otherOnSameCoordsThanThis.getNumberOfCells())
+    {
+      std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf : cells ids length (" <<  nbOfCellsToModify << ") do not match the number of cells of other mesh (" << otherOnSameCoordsThanThis.getNumberOfCells() << ") !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  int nbOfCells=getNumberOfCells();
+  bool easyAssign=true;
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  const int *connOther=otherOnSameCoordsThanThis._nodal_connec->getConstPointer();
+  const int *connIOther=otherOnSameCoordsThanThis._nodal_connec_index->getConstPointer();
+  for(const int *it=cellIdsBg;it!=cellIdsEnd && easyAssign;it++,connIOther++)
+    {
+      if(*it>=0 && *it<nbOfCells)
+        {
+          easyAssign=(connIOther[1]-connIOther[0])==(connI[*it+1]-connI[*it]);
+        }
+      else
+        {
+          std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf : On pos #" << std::distance(cellIdsBg,it) << " id is equal to " << *it << " which is not in [0," << nbOfCells << ") !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  if(easyAssign)
+    {
+      MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx(cellIdsBg,cellIdsEnd,_nodal_connec,_nodal_connec_index,otherOnSameCoordsThanThis._nodal_connec,otherOnSameCoordsThanThis._nodal_connec_index);
+      computeTypes();
+    }
+  else
+    {
+      DataArrayInt *arrOut=0,*arrIOut=0;
+      MEDCouplingUMesh::SetPartOfIndexedArrays(cellIdsBg,cellIdsEnd,_nodal_connec,_nodal_connec_index,otherOnSameCoordsThanThis._nodal_connec,otherOnSameCoordsThanThis._nodal_connec_index,
+                                               arrOut,arrIOut);
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arrOutAuto(arrOut),arrIOutAuto(arrIOut);
+      setConnectivity(arrOut,arrIOut,true);
+    }
+}
+
+void MEDCouplingUMesh::setPartOfMySelf2(int start, int end, int step, const MEDCouplingUMesh& otherOnSameCoordsThanThis) throw(INTERP_KERNEL::Exception)
+{
+  checkConnectivityFullyDefined();
+  otherOnSameCoordsThanThis.checkConnectivityFullyDefined();
+  if(getCoords()!=otherOnSameCoordsThanThis.getCoords())
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::setPartOfMySelf2 : coordinates pointer are not the same ! Invoke setCoords or call tryToShareSameCoords method !");
+  if(getMeshDimension()!=otherOnSameCoordsThanThis.getMeshDimension())
+    {
+      std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf2 : Mismatch of meshdimensions ! this is equal to " << getMeshDimension();
+      oss << ", whereas other mesh dimension is set equal to " << otherOnSameCoordsThanThis.getMeshDimension() << " !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  int nbOfCellsToModify=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::setPartOfMySelf2 : ");
+  if(nbOfCellsToModify!=otherOnSameCoordsThanThis.getNumberOfCells())
+    {
+      std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf2 : cells ids length (" <<  nbOfCellsToModify << ") do not match the number of cells of other mesh (" << otherOnSameCoordsThanThis.getNumberOfCells() << ") !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  int nbOfCells=getNumberOfCells();
+  bool easyAssign=true;
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  const int *connOther=otherOnSameCoordsThanThis._nodal_connec->getConstPointer();
+  const int *connIOther=otherOnSameCoordsThanThis._nodal_connec_index->getConstPointer();
+  int it=start;
+  for(int i=0;i<nbOfCellsToModify && easyAssign;i++,it+=step,connIOther++)
+    {
+      if(it>=0 && it<nbOfCells)
+        {
+          easyAssign=(connIOther[1]-connIOther[0])==(connI[it+1]-connI[it]);
+        }
+      else
+        {
+          std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf2 : On pos #" << i << " id is equal to " << it << " which is not in [0," << nbOfCells << ") !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  if(easyAssign)
+    {
+      MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2(start,end,step,_nodal_connec,_nodal_connec_index,otherOnSameCoordsThanThis._nodal_connec,otherOnSameCoordsThanThis._nodal_connec_index);
+      computeTypes();
+    }
+  else
+    {
+      DataArrayInt *arrOut=0,*arrIOut=0;
+      MEDCouplingUMesh::SetPartOfIndexedArrays2(start,end,step,_nodal_connec,_nodal_connec_index,otherOnSameCoordsThanThis._nodal_connec,otherOnSameCoordsThanThis._nodal_connec_index,
+                                                arrOut,arrIOut);
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arrOutAuto(arrOut),arrIOutAuto(arrIOut);
+      setConnectivity(arrOut,arrIOut,true);
+    }
+}                      
+
+DataArrayInt *MEDCouplingUMesh::getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const
+{
+  std::vector<int> cellIdsKept;
+  fillCellIdsToKeepFromNodeIds(partBg,partEnd,true,cellIdsKept);
+  DataArrayInt *ret=DataArrayInt::New();
+  ret->alloc((int)cellIdsKept.size(),1);
+  std::copy(cellIdsKept.begin(),cellIdsKept.end(),ret->getPointer());
+  return ret;
+}
+
+/*!
+ * Keeps from 'this' only cells which constituing point id are in the ids specified by ['begin','end').
+ * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter.
+ * Parameter 'fullyIn' specifies if a cell that has part of its nodes in ids array is kept or not.
+ * If 'fullyIn' is true only cells whose ids are \b fully contained in ['begin','end') tab will be kept.
+ *
+ * @param begin input start of array of node ids.
+ * @param end input end of array of node ids.
+ * @param fullyIn input that specifies if all node ids must be in ['begin','end') array to consider cell to be in.
+ * @param cellIdsKept in/out array where all candidate cell ids are put at the end.
+ */
+void MEDCouplingUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, std::vector<int>& cellIdsKept) const
+{
+  std::set<int> fastFinder(begin,end);
+  int nbOfCells=getNumberOfCells();
+  const int *conn=getNodalConnectivity()->getConstPointer();
+  const int *connIndex=getNodalConnectivityIndex()->getConstPointer();
+  for(int i=0;i<nbOfCells;i++)
+    {
+      std::set<int> connOfCell(conn+connIndex[i]+1,conn+connIndex[i+1]);
+      connOfCell.erase(-1);//polyhedron separator
+      int refLgth=(int)connOfCell.size();
+      std::set<int> locMerge;
+      std::insert_iterator< std::set<int> > it(locMerge,locMerge.begin());
+      std::set_intersection(connOfCell.begin(),connOfCell.end(),fastFinder.begin(),fastFinder.end(),it);
+      if(((int)locMerge.size()==refLgth && fullyIn) || (locMerge.size()!=0 && !fullyIn))
+        cellIdsKept.push_back(i);
+    }
+}
+
+/*!
+ * This method is very close too MEDCouplingUMesh::buildPartOfMySelfNode. The difference is that it returns directly ids.
+ */
+DataArrayInt *MEDCouplingUMesh::getCellIdsLyingOnNodes(const int *begin, const int *end, bool fullyIn) const
+{
+  std::vector<int> cellIdsKept;
+  fillCellIdsToKeepFromNodeIds(begin,end,fullyIn,cellIdsKept);
+  DataArrayInt *ret=DataArrayInt::New();
+  ret->alloc((int)cellIdsKept.size(),1);
+  std::copy(cellIdsKept.begin(),cellIdsKept.end(),ret->getPointer());
+  ret->setName(getName());
+  return ret;
+}
+
+/*!
+ * Keeps from 'this' only cells which constituing point id are in the ids specified by ['begin','end').
+ * The return newly allocated mesh will share the same coordinates as 'this'.
+ * Parameter 'fullyIn' specifies if a cell that has part of its nodes in ids array is kept or not.
+ * If 'fullyIn' is true only cells whose ids are \b fully contained in ['begin','end') tab will be kept.
+ */
+MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const
+{
+  std::vector<int> cellIdsKept;
+  fillCellIdsToKeepFromNodeIds(begin,end,fullyIn,cellIdsKept);
+  return buildPartOfMySelf(&cellIdsKept[0],&cellIdsKept[0]+cellIdsKept.size(),true);
+}
+
+/*!
+ * Contrary to MEDCouplingUMesh::buildPartOfMySelfNode method this method builds a mesh with a meshDimension equal to
+ * this->getMeshDimension()-1. The return newly allocated mesh will share the same coordinates as 'this'.
+ * Parameter 'fullyIn' specifies if a face that has part of its nodes in ids array is kept or not.
+ * If 'fullyIn' is true only faces whose ids are \b fully contained in ['begin','end') tab will be kept.
+ */
+MEDCouplingPointSet *MEDCouplingUMesh::buildFacePartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const
+{
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc,descIndx,revDesc,revDescIndx;
+  desc=DataArrayInt::New(); descIndx=DataArrayInt::New(); revDesc=DataArrayInt::New(); revDescIndx=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> subMesh=buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx);
+  desc=0; descIndx=0; revDesc=0; revDescIndx=0;
+  return subMesh->buildPartOfMySelfNode(begin,end,fullyIn);
+}
+
+/*!
+ * This method returns a mesh with meshDim=this->getMeshDimension()-1.
+ * This returned mesh contains cells that are linked with one and only one cell of this.
+ * @param keepCoords specifies if ParaMEDMEM::MEDCouplingUMesh::zipCoords is called on returned mesh before being returned. If true zipCoords is \b NOT called, if false, zipCoords is called.
+ * @return mesh with ref counter equal to 1.
+ */
+MEDCouplingPointSet *MEDCouplingUMesh::buildBoundaryMesh(bool keepCoords) const
+{
+  DataArrayInt *desc=DataArrayInt::New();
+  DataArrayInt *descIndx=DataArrayInt::New();
+  DataArrayInt *revDesc=DataArrayInt::New();
+  DataArrayInt *revDescIndx=DataArrayInt::New();
+  //
+  MEDCouplingUMesh *meshDM1=buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx);
+  revDesc->decrRef();
+  desc->decrRef();
+  descIndx->decrRef();
+  int nbOfCells=meshDM1->getNumberOfCells();
+  const int *revDescIndxC=revDescIndx->getConstPointer();
+  std::vector<int> boundaryCells;
+  for(int i=0;i<nbOfCells;i++)
+    if(revDescIndxC[i+1]-revDescIndxC[i]==1)
+      boundaryCells.push_back(i);
+  revDescIndx->decrRef();
+  MEDCouplingPointSet *ret=meshDM1->buildPartOfMySelf(&boundaryCells[0],&boundaryCells[0]+boundaryCells.size(),keepCoords);
+  meshDM1->decrRef();
+  return ret;
+}
+
+/*!
+ * This method returns a newly created DataArrayInt instance containing ids of cells located in boundary.
+ * A cell is detected to be on boundary if it contains one or more than one face having only one father.
+ * This method makes the assumption that 'this' is fully defined (coords,connectivity). If not an exception will be thrown. 
+ */
+DataArrayInt *MEDCouplingUMesh::findCellIdsOnBoundary() const throw(INTERP_KERNEL::Exception)
+{
+  checkFullyDefined();
+  DataArrayInt *desc=DataArrayInt::New();
+  DataArrayInt *descIndx=DataArrayInt::New();
+  DataArrayInt *revDesc=DataArrayInt::New();
+  DataArrayInt *revDescIndx=DataArrayInt::New();
+  //
+  MEDCouplingUMesh *meshDM1=buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx);
+  meshDM1->decrRef();
+  desc->decrRef();
+  descIndx->decrRef();
+  //
+  DataArrayInt *tmp=revDescIndx->deltaShiftIndex();
+  DataArrayInt *faceIds=tmp->getIdsEqual(1);
+  tmp->decrRef();
+  int nbOfFaces=faceIds->getNumberOfTuples();
+  const int *faces=faceIds->getConstPointer();
+  std::set<int> ret;
+  for(const int *w=faces;w!=faces+nbOfFaces;w++)
+    ret.insert(revDesc->getIJ(revDescIndx->getIJ(*w,0),0));
+  faceIds->decrRef();
+  //
+  revDescIndx->decrRef();
+  revDesc->decrRef();
+  //
+  DataArrayInt *ret2=DataArrayInt::New();
+  ret2->alloc((int)ret.size(),1);
+  std::copy(ret.begin(),ret.end(),ret2->getPointer());
+  ret2->setName("BoundaryCells");
+  return ret2;
+}
+
+/*!
+ * This method find in \b this cells ids that lie on mesh \b otherDimM1OnSameCoords.
+ * \b this and \b otherDimM1OnSameCoords have to lie on the same coordinate array pointer. The coherency of that coords array with connectivity
+ * of \b this and \b otherDimM1OnSameCoords is not important here because this method works only on connectivity.
+ * this->getMeshDimension() - 1 must be equal to otherDimM1OnSameCoords.getMeshDimension()
+ *
+ * s0 is the cells ids set in \b this lying on at least one node in fetched nodes in \b otherDimM1OnSameCoords.
+ * This method method returns cells ids set s = s1 + s2 where :
+ * 
+ *  - s1 are cells ids in \b this whose dim-1 constituent equals a cell in \b otherDimM1OnSameCoords.
+ *  - s2 are cells ids in \b s0 - \b s1 whose at least two neighbors are in s1.
+ *
+ * \throw if \b otherDimM1OnSameCoords is not part of constituent of \b this, or if coordinate pointer of \b this and \b otherDimM1OnSameCoords
+ *        are not same, or if this->getMeshDimension()-1!=otherDimM1OnSameCoords.getMeshDimension()
+ *
+ * \param [out] cellIdsRk0 a newly allocated array containing cells ids in \b this containg s0 in above algorithm.
+ * \param [out] cellIdsRk1 a newly allocated array containing cells ids of s1+s2 \b into \b cellIdsRk0 subset. To get absolute ids of s1+s2 simply invoke
+ *              cellIdsRk1->transformWithIndArr(cellIdsRk0->begin(),cellIdsRk0->end());
+ */
+void MEDCouplingUMesh::findCellIdsLyingOn(const MEDCouplingUMesh& otherDimM1OnSameCoords, DataArrayInt *&cellIdsRk0, DataArrayInt *&cellIdsRk1) const throw(INTERP_KERNEL::Exception)
+{
+  if(getCoords()!=otherDimM1OnSameCoords.getCoords())
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findCellIdsLyingOn : coordinates pointer are not the same ! Use tryToShareSameCoords method !");
+  checkConnectivityFullyDefined();
+  otherDimM1OnSameCoords.checkConnectivityFullyDefined();
+  if(getMeshDimension()-1!=otherDimM1OnSameCoords.getMeshDimension())
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findCellIdsLyingOn : invalid mesh dimension of input mesh regarding meshdimesion of this !");
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fetchedNodeIds1=otherDimM1OnSameCoords.computeFetchedNodeIds();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> s0arr=getCellIdsLyingOnNodes(fetchedNodeIds1->begin(),fetchedNodeIds1->end(),false);
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisPart=static_cast<MEDCouplingUMesh *>(buildPartOfMySelf(s0arr->begin(),s0arr->end(),true));
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descThisPart=DataArrayInt::New(),descIThisPart=DataArrayInt::New(),revDescThisPart=DataArrayInt::New(),revDescIThisPart=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisPartConsti=thisPart->buildDescendingConnectivity(descThisPart,descIThisPart,revDescThisPart,revDescIThisPart);
+  const int *revDescThisPartPtr=revDescThisPart->getConstPointer(),*revDescIThisPartPtr=revDescIThisPart->getConstPointer();
+  DataArrayInt *idsOtherInConsti=0;
+  bool b=thisPartConsti->areCellsIncludedIn(&otherDimM1OnSameCoords,2,idsOtherInConsti);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idsOtherInConstiAuto(idsOtherInConsti);
+  if(!b)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findCellIdsLyingOn : the given mdim-1 mesh in other is not a constituent of this !");
+  std::set<int> s1;
+  for(const int *idOther=idsOtherInConsti->begin();idOther!=idsOtherInConsti->end();idOther++)
+    s1.insert(revDescThisPartPtr+revDescIThisPartPtr[*idOther],revDescThisPartPtr+revDescIThisPartPtr[*idOther+1]);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> s1arr_renum1=DataArrayInt::New(); s1arr_renum1->alloc((int)s1.size(),1); std::copy(s1.begin(),s1.end(),s1arr_renum1->getPointer());
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> s1Comparr_renum1=s1arr_renum1->buildComplement(s0arr->getNumberOfTuples());
+  DataArrayInt *neighThisPart=0,*neighIThisPart=0;
+  ComputeNeighborsOfCellsAdv(descThisPart,descIThisPart,revDescThisPart,revDescIThisPart,neighThisPart,neighIThisPart);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> neighThisPartAuto(neighThisPart),neighIThisPartAuto(neighIThisPart);
+  ExtractFromIndexedArrays(s1Comparr_renum1->begin(),s1Comparr_renum1->end(),neighThisPart,neighIThisPart,neighThisPart,neighIThisPart);// reuse of neighThisPart and neighIThisPart
+  neighThisPartAuto=neighThisPart; neighIThisPartAuto=neighIThisPart;
+  RemoveIdsFromIndexedArrays(s1Comparr_renum1->begin(),s1Comparr_renum1->end(),neighThisPart,neighIThisPart);
+  neighThisPartAuto=0;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> s2_tmp=neighIThisPart->deltaShiftIndex();
+  const int li[2]={0,1};
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> s2_renum2=s2_tmp->getIdsNotEqualList(li,li+2);
+  s2_renum2->transformWithIndArr(s1Comparr_renum1->begin(),s1Comparr_renum1->end());//s2_renum2==s2_renum1
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> s_renum1=DataArrayInt::Aggregate(s2_renum2,s1arr_renum1,0);
+  s_renum1->sort();
+  //
+  s0arr->incrRef(); cellIdsRk0=s0arr;
+  s_renum1->incrRef(); cellIdsRk1=s_renum1;
+}
+
+/*!
+ * This method computes the skin of \b this. That is to say the consituting meshdim-1 mesh is built and only the boundary subpart is
+ * returned. This subpart of meshdim-1 mesh is built using meshdim-1 cells in it shared only one cell in \b this.
+ * 
+ * \return a newly allocated mesh lying on the same coordinates than \b this. The caller has to deal with returned mesh.
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::computeSkin() const throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descIndx=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDesc=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDescIndx=DataArrayInt::New();
+  //
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> meshDM1=buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx);
+  revDesc=0; desc=0; descIndx=0;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDescIndx2=revDescIndx->deltaShiftIndex();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part=revDescIndx2->getIdsEqual(1);
+  return static_cast<MEDCouplingUMesh *>(meshDM1->buildPartOfMySelf(part->begin(),part->end(),true));
+}
+
+/*!
+ * This methods returns set of nodes in a newly allocated array that the caller has to deal with.
+ * The returned nodes ids are those lying on the boundary of \b this.
+ */
+DataArrayInt *MEDCouplingUMesh::findBoundaryNodes() const
+{
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> skin=computeSkin();
+  return skin->computeFetchedNodeIds();
+}
+
+MEDCouplingUMesh *MEDCouplingUMesh::buildUnstructured() const throw(INTERP_KERNEL::Exception)
+{
+  incrRef();
+  return const_cast<MEDCouplingUMesh *>(this);
+}
+
+/*
+ * This method renumber 'this' using 'newNodeNumbers' array of size this->getNumberOfNodes.
+ * newNbOfNodes specifies the *std::max_element(newNodeNumbers,newNodeNumbers+this->getNumberOfNodes())
+ * This value is asked because often known by the caller of this method.
+ * This method, contrary to MEDCouplingMesh::renumberCells does NOT conserve the number of nodes before and after.
+ *
+ * @param newNodeNumbers array specifying the new numbering in old2New convention.
+ * @param newNbOfNodes the new number of nodes.
+ */
+void MEDCouplingUMesh::renumberNodes(const int *newNodeNumbers, int newNbOfNodes)
+{
+  MEDCouplingPointSet::renumberNodes(newNodeNumbers,newNbOfNodes);
+  renumberNodesInConn(newNodeNumbers);
+}
+
+/*
+ * This method renumber 'this' using 'newNodeNumbers' array of size this->getNumberOfNodes.
+ * newNbOfNodes specifies the *std::max_element(newNodeNumbers,newNodeNumbers+this->getNumberOfNodes())
+ * This value is asked because often known by the caller of this method.
+ * This method, contrary to MEDCouplingMesh::renumberCells does NOT conserve the number of nodes before and after.
+ * The difference with ParaMEDMEM::MEDCouplingUMesh::renumberNodes method is in the fact that the barycenter of merged nodes is computed here.
+ *
+ * @param newNodeNumbers array specifying the new numbering.
+ * @param newNbOfNodes the new number of nodes.
+ *
+ */
+void MEDCouplingUMesh::renumberNodes2(const int *newNodeNumbers, int newNbOfNodes)
+{
+  MEDCouplingPointSet::renumberNodes2(newNodeNumbers,newNbOfNodes);
+  renumberNodesInConn(newNodeNumbers);
+}
+
+/*!
+ * This method expects that \b this and \b otherDimM1OnSameCoords share the same coordinates array.
+ * otherDimM1OnSameCoords->getMeshDimension() is expected to be equal to this->getMeshDimension()-1.
+ * This method searches for nodes needed to be duplicated. These nodes are nodes fetched by \b otherDimM1OnSameCoords which are not part of the boundary of \b otherDimM1OnSameCoords.
+ * If a node is in the boundary of \b this \b and in the boundary of \b otherDimM1OnSameCoords this node is considerd as needed to be duplicated.
+ * When the set of node ids \b nodeIdsToDuplicate is computed, cell ids in \b this is searched so that their connectivity includes at least 1 node in \b nodeIdsToDuplicate.
+ *
+ * \param [in] otherDimM1OnSameCoords a mesh lying on the same coords than \b this and with a mesh dimension equal to those of \b this minus 1. WARNING this input
+ *             parameter is altered during the call.
+ * \param [out] nodeIdsToDuplicate node ids needed to be duplicated following the algorithm explain above.
+ * \param [out] cellIdsNeededToBeRenum cell ids in \b this in which the renumber of nodes should be performed.
+ * \param [out] cellIdsNotModified cell ids int \b this that lies on \b otherDimM1OnSameCoords mesh whose connectivity do \b not need to be modified as it is the case for \b cellIdsNeededToBeRenum.
+ *
+ * \warning This method modifies param \b otherDimM1OnSameCoords (for speed reasons).
+ */
+void MEDCouplingUMesh::findNodesToDuplicate(const MEDCouplingUMesh& otherDimM1OnSameCoords, DataArrayInt *& nodeIdsToDuplicate,
+                                            DataArrayInt *& cellIdsNeededToBeRenum, DataArrayInt *& cellIdsNotModified) const throw(INTERP_KERNEL::Exception)
+{
+  checkFullyDefined();
+  otherDimM1OnSameCoords.checkFullyDefined();
+  if(getCoords()!=otherDimM1OnSameCoords.getCoords())
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findNodesToDuplicate : meshes do not share the same coords array !");
+  if(otherDimM1OnSameCoords.getMeshDimension()!=getMeshDimension()-1)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findNodesToDuplicate : the mesh given in other parameter must have this->getMeshDimension()-1 !");
+  DataArrayInt *cellIdsRk0=0,*cellIdsRk1=0;
+  findCellIdsLyingOn(otherDimM1OnSameCoords,cellIdsRk0,cellIdsRk1);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsRk0Auto(cellIdsRk0),cellIdsRk1Auto(cellIdsRk1);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> s0=cellIdsRk1->buildComplement(cellIdsRk0->getNumberOfTuples());
+  s0->transformWithIndArr(cellIdsRk0Auto->begin(),cellIdsRk0Auto->end());
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Part=static_cast<MEDCouplingUMesh *>(buildPartOfMySelf(s0->begin(),s0->end(),true));
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> s1=m0Part->computeFetchedNodeIds();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> s2=otherDimM1OnSameCoords.computeFetchedNodeIds();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> s3=s2->buildSubstraction(s1);
+  cellIdsRk1->transformWithIndArr(cellIdsRk0Auto->begin(),cellIdsRk0Auto->end());
+  //
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Part2=static_cast<MEDCouplingUMesh *>(buildPartOfMySelf(cellIdsRk1->begin(),cellIdsRk1->end(),true));
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc00=DataArrayInt::New(),descI00=DataArrayInt::New(),revDesc00=DataArrayInt::New(),revDescI00=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m01=m0Part2->buildDescendingConnectivity(desc00,descI00,revDesc00,revDescI00);
+  DataArrayInt *idsTmp=0;
+  bool b=m01->areCellsIncludedIn(&otherDimM1OnSameCoords,2,idsTmp);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids(idsTmp);
+  if(!b)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findNodesToDuplicate : the given mdim-1 mesh in other is not a constituent of this !");
+  MEDCouplingUMesh::RemoveIdsFromIndexedArrays(ids->begin(),ids->end(),desc00,descI00);
+  DataArrayInt *tmp0=0,*tmp1=0;
+  ComputeNeighborsOfCellsAdv(desc00,descI00,revDesc00,revDescI00,tmp0,tmp1);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> neigh00(tmp0);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> neighI00(tmp1);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn0_torenum=MEDCouplingUMesh::ComputeSpreadZoneGradually(neigh00,neighI00);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn1_torenum=cellsToModifyConn0_torenum->buildComplement(neighI00->getNumberOfTuples()-1);
+  cellsToModifyConn0_torenum->transformWithIndArr(cellIdsRk1->begin(),cellIdsRk1->end());
+  cellsToModifyConn1_torenum->transformWithIndArr(cellIdsRk1->begin(),cellIdsRk1->end());
+  //
+  cellIdsNeededToBeRenum=cellsToModifyConn0_torenum; cellsToModifyConn0_torenum->incrRef();
+  cellIdsNotModified=cellsToModifyConn1_torenum; cellsToModifyConn1_torenum->incrRef();
+  nodeIdsToDuplicate=s3; s3->incrRef();
+}
+
+/*!
+ * This method operates a modification of the connectivity and coords in \b this.
+ * Every time that a node id in [\b nodeIdsToDuplicateBg, \b nodeIdsToDuplicateEnd) will append in nodal connectivity of \b this 
+ * its ids will be modified to id this->getNumberOfNodes()+std::distance(nodeIdsToDuplicateBg,std::find(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd,id)).
+ * More explicitely the renumber array in nodes is not explicitely given in old2new to avoid to build a big array of renumbering whereas typically few node ids needs to be
+ * renumbered. The node id nodeIdsToDuplicateBg[0] will have id this->getNumberOfNodes()+0, node id nodeIdsToDuplicateBg[1] will have id this->getNumberOfNodes()+1,
+ * node id nodeIdsToDuplicateBg[2] will have id this->getNumberOfNodes()+2...
+ * 
+ * As a consequence nodal connectivity array length will remain unchanged by this method, and nodal connectivity index array will remain unchanged by this method.
+ * 
+ * \param [in] nodeIdsToDuplicateBg begin of node ids (included) to be duplicated in connectivity only
+ * \param [in] nodeIdsToDuplicateEnd end of node ids (excluded) to be duplicated in connectivity only
+ */
+void MEDCouplingUMesh::duplicateNodes(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd) throw(INTERP_KERNEL::Exception)
+{
+  int nbOfNodes=getNumberOfNodes();
+  duplicateNodesInCoords(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd);
+  duplicateNodesInConn(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd,nbOfNodes);
+}
+
+/*!
+ * This method renumbers nodes \b in \b connectivity \b only \b without \b any \b reference \b to \b coords.
+ * This method performs no check on the fact that new coordinate ids are valid. \b Use \b it \b with \b care !
+ * This method is an generalization of \ref ParaMEDMEM::MEDCouplingUMesh::shiftNodeNumbersInConn "shiftNodeNumbersInConn method".
+ * @param [in] newNodeNumbers in old2New convention
+ */
+void MEDCouplingUMesh::renumberNodesInConn(const int *newNodeNumbersO2N)
+{
+  checkConnectivityFullyDefined();
+  int *conn=getNodalConnectivity()->getPointer();
+  const int *connIndex=getNodalConnectivityIndex()->getConstPointer();
+  int nbOfCells=getNumberOfCells();
+  for(int i=0;i<nbOfCells;i++)
+    for(int iconn=connIndex[i]+1;iconn!=connIndex[i+1];iconn++)
+      {
+        int& node=conn[iconn];
+        if(node>=0)//avoid polyhedron separator
+          {
+            node=newNodeNumbersO2N[node];
+          }
+      }
+  _nodal_connec->declareAsNew();
+  updateTime();
+}
+
+/*!
+ * This method renumbers nodes \b in \b connectivity \b only \b without \b any \b reference \b to \b coords.
+ * This method performs no check on the fact that new coordinate ids are valid. \b Use \b it \b with \b care !
+ * This method is an specialization of \ref ParaMEDMEM::MEDCouplingUMesh::renumberNodesInConn "renumberNodesInConn method".
+ * 
+ * @param [in] delta specifies the shift size applied to nodeId in nodal connectivity in \b this.
+ */
+void MEDCouplingUMesh::shiftNodeNumbersInConn(int delta) throw(INTERP_KERNEL::Exception)
+{
+  checkConnectivityFullyDefined();
+  int *conn=getNodalConnectivity()->getPointer();
+  const int *connIndex=getNodalConnectivityIndex()->getConstPointer();
+  int nbOfCells=getNumberOfCells();
+  for(int i=0;i<nbOfCells;i++)
+    for(int iconn=connIndex[i]+1;iconn!=connIndex[i+1];iconn++)
+      {
+        int& node=conn[iconn];
+        if(node>=0)//avoid polyhedron separator
+          {
+            node+=delta;
+          }
+      }
+  _nodal_connec->declareAsNew();
+  updateTime();
+}
+
+/*!
+ * This method operates a modification of the connectivity in \b this.
+ * Coordinates are \b NOT considered here and will remain unchanged by this method. this->_coords can ever been null for the needs of this method.
+ * Every time that a node id in [\b nodeIdsToDuplicateBg, \b nodeIdsToDuplicateEnd) will append in nodal connectivity of \b this 
+ * its ids will be modified to id offset+std::distance(nodeIdsToDuplicateBg,std::find(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd,id)).
+ * More explicitely the renumber array in nodes is not explicitely given in old2new to avoid to build a big array of renumbering whereas typically few node ids needs to be
+ * renumbered. The node id nodeIdsToDuplicateBg[0] will have id offset+0, node id nodeIdsToDuplicateBg[1] will have id offset+1,
+ * node id nodeIdsToDuplicateBg[2] will have id offset+2...
+ * 
+ * As a consequence nodal connectivity array length will remain unchanged by this method, and nodal connectivity index array will remain unchanged by this method.
+ * As an another consequense after the call of this method \b this can be transiently non cohrent.
+ * 
+ * \param [in] nodeIdsToDuplicateBg begin of node ids (included) to be duplicated in connectivity only
+ * \param [in] nodeIdsToDuplicateEnd end of node ids (excluded) to be duplicated in connectivity only
+ * \param [in] offset the offset applied to all node ids in connectivity that are in [nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd). 
+ */
+void MEDCouplingUMesh::duplicateNodesInConn(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd, int offset) throw(INTERP_KERNEL::Exception)
+{
+  checkConnectivityFullyDefined();
+  std::map<int,int> m;
+  int val=offset;
+  for(const int *work=nodeIdsToDuplicateBg;work!=nodeIdsToDuplicateEnd;work++,val++)
+    m[*work]=val;
+  int *conn=getNodalConnectivity()->getPointer();
+  const int *connIndex=getNodalConnectivityIndex()->getConstPointer();
+  int nbOfCells=getNumberOfCells();
+  for(int i=0;i<nbOfCells;i++)
+    for(int iconn=connIndex[i]+1;iconn!=connIndex[i+1];iconn++)
+      {
+        int& node=conn[iconn];
+        if(node>=0)//avoid polyhedron separator
+          {
+            std::map<int,int>::iterator it=m.find(node);
+            if(it!=m.end())
+              node=(*it).second;
+          }
+      }
+  updateTime();
+}
+
+/*!
+ * This method renumbers cells of 'this' using the array specified by [old2NewBg;old2NewBg+getNumberOfCells())
+ *
+ * Contrary to MEDCouplingPointSet::renumberNodes, this method makes a permutation without any fuse of cell.
+ * After the call of this method the number of cells remains the same as before.
+ *
+ * If 'check' equals true the method will check that any elements in [old2NewBg;old2NewEnd) is unique ; if not
+ * an INTERP_KERNEL::Exception will be thrown. When 'check' equals true [old2NewBg;old2NewEnd) is not expected to
+ * be strictly in [0;this->getNumberOfCells()).
+ *
+ * If 'check' equals false the method will not check the content of [old2NewBg;old2NewEnd).
+ * To avoid any throw of SIGSEGV when 'check' equals false, the elements in [old2NewBg;old2NewEnd) should be unique and
+ * should be contained in[0;this->getNumberOfCells()).
+ * 
+ * \param [in] old2NewBg is expected to be a dynamically allocated pointer of size at least equal to this->getNumberOfCells()
+ */
+void MEDCouplingUMesh::renumberCells(const int *old2NewBg, bool check) throw(INTERP_KERNEL::Exception)
+{
+  checkConnectivityFullyDefined();
+  int nbCells=getNumberOfCells();
+  const int *array=old2NewBg;
+  if(check)
+    array=DataArrayInt::CheckAndPreparePermutation(old2NewBg,old2NewBg+nbCells);
+  //
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
+  newConn->alloc(_nodal_connec->getNumberOfTuples(),_nodal_connec->getNumberOfComponents());
+  newConn->copyStringInfoFrom(*_nodal_connec);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
+  newConnI->alloc(_nodal_connec_index->getNumberOfTuples(),_nodal_connec_index->getNumberOfComponents());
+  newConnI->copyStringInfoFrom(*_nodal_connec_index);
+  //
+  int *newC=newConn->getPointer();
+  int *newCI=newConnI->getPointer();
+  int loc=0;
+  newCI[0]=loc;
+  for(int i=0;i<nbCells;i++)
+    {
+      std::size_t pos=std::distance(array,std::find(array,array+nbCells,i));
+      int nbOfElts=connI[pos+1]-connI[pos];
+      newC=std::copy(conn+connI[pos],conn+connI[pos+1],newC);
+      loc+=nbOfElts;
+      newCI[i+1]=loc;
+    }
+  //
+  setConnectivity(newConn,newConnI);
+  if(check)
+    delete [] const_cast<int *>(array);
+}
+
+/*!
+ * Given a boundary box 'bbox' returns elements 'elems' contained in this 'bbox'.
+ * Warning 'elems' is incremented during the call so if elems is not empty before call returned elements will be
+ * added in 'elems' parameter.
+ */
+void MEDCouplingUMesh::getCellsInBoundingBox(const double *bbox, double eps, std::vector<int>& elems) const
+{
+  if(getMeshDimension()==-1)
+    {
+      elems.push_back(0);
+      return;
+    }
+  int dim=getSpaceDimension();
+  double* elem_bb=new double[2*dim];
+  const int* conn      = getNodalConnectivity()->getConstPointer();
+  const int* conn_index= getNodalConnectivityIndex()->getConstPointer();
+  const double* coords = getCoords()->getConstPointer();
+  int nbOfCells=getNumberOfCells();
+  for ( int ielem=0; ielem<nbOfCells;ielem++ )
+    {
+      for (int i=0; i<dim; i++)
+        {
+          elem_bb[i*2]=std::numeric_limits<double>::max();
+          elem_bb[i*2+1]=-std::numeric_limits<double>::max();
+        }
+
+      for (int inode=conn_index[ielem]+1; inode<conn_index[ielem+1]; inode++)//+1 due to offset of cell type.
+        {
+          int node= conn[inode];
+          if(node>=0)//avoid polyhedron separator
+            {
+              for (int idim=0; idim<dim; idim++)
+                {
+                  if ( coords[node*dim+idim] < elem_bb[idim*2] )
+                    {
+                      elem_bb[idim*2] = coords[node*dim+idim] ;
+                    }
+                  if ( coords[node*dim+idim] > elem_bb[idim*2+1] )
+                    {
+                      elem_bb[idim*2+1] = coords[node*dim+idim] ;
+                    }
+                }
+            }
+        }
+      if (intersectsBoundingBox(elem_bb, bbox, dim, eps))
+        {
+          elems.push_back(ielem);
+        }
+    }
+  delete [] elem_bb;
+}
+
+/*!
+ * Given a boundary box 'bbox' returns elements 'elems' contained in this 'bbox' or touching 'bbox' (within 'eps' distance).
+ * Warning 'elems' is incremented during the call so if elems is not empty before call returned elements will be
+ * added in 'elems' parameter.
+ */
+void MEDCouplingUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps, std::vector<int>& elems)
+{
+  if(getMeshDimension()==-1)
+    {
+      elems.push_back(0);
+      return;
+    }
+  int dim=getSpaceDimension();
+  double* elem_bb=new double[2*dim];
+  const int* conn      = getNodalConnectivity()->getConstPointer();
+  const int* conn_index= getNodalConnectivityIndex()->getConstPointer();
+  const double* coords = getCoords()->getConstPointer();
+  int nbOfCells=getNumberOfCells();
+  for ( int ielem=0; ielem<nbOfCells;ielem++ )
+    {
+      for (int i=0; i<dim; i++)
+        {
+          elem_bb[i*2]=std::numeric_limits<double>::max();
+          elem_bb[i*2+1]=-std::numeric_limits<double>::max();
+        }
+
+      for (int inode=conn_index[ielem]+1; inode<conn_index[ielem+1]; inode++)//+1 due to offset of cell type.
+        {
+          int node= conn[inode];
+          if(node>=0)//avoid polyhedron separator
+            {
+              for (int idim=0; idim<dim; idim++)
+                {
+                  if ( coords[node*dim+idim] < elem_bb[idim*2] )
+                    {
+                      elem_bb[idim*2] = coords[node*dim+idim] ;
+                    }
+                  if ( coords[node*dim+idim] > elem_bb[idim*2+1] )
+                    {
+                      elem_bb[idim*2+1] = coords[node*dim+idim] ;
+                    }
+                }
+            }
+        }
+      if (intersectsBoundingBox(bbox, elem_bb, dim, eps))
+        {
+          elems.push_back(ielem);
+        }
+    }
+  delete [] elem_bb;
+}
+
+/*!
+ * Returns the cell type of cell with id 'cellId'.
+ */
+INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::getTypeOfCell(int cellId) const
+{
+  const int *ptI=_nodal_connec_index->getConstPointer();
+  const int *pt=_nodal_connec->getConstPointer();
+  return (INTERP_KERNEL::NormalizedCellType) pt[ptI[cellId]];
+}
+
+/*!
+ * This method returns a newly allocated array containing cell ids (ascendingly sorted) whose geometric type are equal to type.
+ * This method throws an INTERP_KERNEL::Exception if meshdimension of \b this is not equal to those of \b type.
+ * The coordinates array is not considered here.
+ *
+ * \param [in] type the geometric type
+ * \return the 
+ */
+DataArrayInt *MEDCouplingUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception)
+{
+  
+  std::vector<int> v;
+  checkConnectivityFullyDefined();
+  int nbCells=getNumberOfCells();
+  int mdim=getMeshDimension();
+  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
+  if(mdim!=(int)cm.getDimension())
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::giveCellsWithType : Mismatch between mesh dimension and dimension of the cell !");
+  const int *ptI=_nodal_connec_index->getConstPointer();
+  const int *pt=_nodal_connec->getConstPointer();
+  for(int i=0;i<nbCells;i++)
+    {
+      if((INTERP_KERNEL::NormalizedCellType)pt[ptI[i]]==type)
+        v.push_back(i);
+    }
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc((int)v.size(),1);
+  std::copy(v.begin(),v.end(),ret->getPointer());
+  ret->incrRef();
+  return ret;
+}
+
+/*!
+ * Returns nb of cells having the geometric type 'type'.
+ */
+int MEDCouplingUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const
+{
+  const int *ptI=_nodal_connec_index->getConstPointer();
+  const int *pt=_nodal_connec->getConstPointer();
+  int nbOfCells=getNumberOfCells();
+  int ret=0;
+  for(int i=0;i<nbOfCells;i++)
+    if((INTERP_KERNEL::NormalizedCellType) pt[ptI[i]]==type)
+      ret++;
+  return ret;
+}
+
+/*!
+ * Appends the nodal connectivity in 'conn' of cell with id 'cellId'.
+ * All elements added in conn can be used by MEDCouplingUMesh::getCoordinatesOfNode method.
+ * That is to say -1 separator is omitted in returned conn.
+ */
+void MEDCouplingUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const
+{
+  const int *ptI=_nodal_connec_index->getConstPointer();
+  const int *pt=_nodal_connec->getConstPointer();
+  for(const int *w=pt+ptI[cellId]+1;w!=pt+ptI[cellId+1];w++)
+    if(*w>=0)
+      conn.push_back(*w);
+}
+
+std::string MEDCouplingUMesh::simpleRepr() const
+{
+  static const char msg0[]="No coordinates specified !";
+  std::ostringstream ret;
+  ret << "Unstructured mesh with name : \"" << getName() << "\"\n";
+  ret << "Description of mesh : \"" << getDescription() << "\"\n";
+  int tmpp1,tmpp2;
+  double tt=getTime(tmpp1,tmpp2);
+  ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n";
+  ret << "Iteration : " << tmpp1  << " Order : " << tmpp2 << "\n";
+  ret << "Mesh dimension : " << _mesh_dim << "\nSpace dimension : ";
+  if(_coords!=0)
+    {
+      const int spaceDim=getSpaceDimension();
+      ret << spaceDim << "\nInfo attached on space dimension : ";
+      for(int i=0;i<spaceDim;i++)
+        ret << "\"" << _coords->getInfoOnComponent(i) << "\" ";
+      ret << "\n";
+    }
+  else
+    ret << msg0 << "\n";
+  ret << "Number of nodes : ";
+  if(_coords!=0)
+    ret << getNumberOfNodes() << "\n";
+  else
+    ret << msg0 << "\n";
+  ret << "Number of cells : ";
+  if(_nodal_connec!=0 && _nodal_connec_index!=0)
+    ret << getNumberOfCells() << "\n";
+  else
+    ret << "No connectivity specified !" << "\n";
+  ret << "Cell types present : ";
+  for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator iter=_types.begin();iter!=_types.end();iter++)
+    {
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*iter);
+      ret << cm.getRepr() << " ";
+    }
+  ret << "\n";
+  return ret.str();
+}
+
+std::string MEDCouplingUMesh::advancedRepr() const
+{
+  std::ostringstream ret;
+  ret << simpleRepr();
+  ret << "\nCoordinates array : \n___________________\n\n";
+  if(_coords)
+    _coords->reprWithoutNameStream(ret);
+  else
+    ret << "No array set !\n";
+  ret << "\n\nConnectivity arrays : \n_____________________\n\n";
+  reprConnectivityOfThisLL(ret);
+  return ret.str();
+}
+
+std::string MEDCouplingUMesh::reprConnectivityOfThis() const
+{
+  std::ostringstream ret;
+  reprConnectivityOfThisLL(ret);
+  return ret.str();
+}
+
+/*!
+ * This method builds a newly allocated instance (with the same name than 'this') that the caller has the responsability to deal with.
+ * This method returns an instance with all arrays allocated (connectivity, connectivity index, coordinates)
+ * but with length of these arrays set to 0. It allows to define an "empty" mesh (with nor cells nor nodes but compliant with
+ * some algos).
+ * 
+ * This method expects that 'this' has a mesh dimension set and higher or equal to 0. If not an exception will be thrown.
+ * This method analyzes the 3 arrays of 'this'. For each the following behaviour is done : if the array is null a newly one is created
+ * with number of tuples set to 0, if not the array is taken as this in the returned instance.
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception)
+{
+  int mdim=getMeshDimension();
+  if(mdim<0)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSetInstanceFromThis : invalid mesh dimension ! Should be >= 0 !");
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),mdim);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1,tmp2;
+  bool needToCpyCT=true;
+  if(!_nodal_connec)
+    {
+      tmp1=DataArrayInt::New(); tmp1->alloc(0,1);
+      needToCpyCT=false;
+    }
+  else
+    {
+      tmp1=_nodal_connec;
+      tmp1->incrRef();
+    }
+  if(!_nodal_connec_index)
+    {
+      tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0);
+      needToCpyCT=false;
+    }
+  else
+    {
+      tmp2=_nodal_connec_index;
+      tmp2->incrRef();
+    }
+  ret->setConnectivity(tmp1,tmp2,false);
+  if(needToCpyCT)
+    ret->_types=_types;
+  if(!_coords)
+    {
+      MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim);
+      ret->setCoords(coords);
+    }
+  else
+    ret->setCoords(_coords);
+  ret->incrRef();
+  return ret;
+}
+
+void MEDCouplingUMesh::reprConnectivityOfThisLL(std::ostringstream& stream) const
+{
+  if(_nodal_connec!=0 && _nodal_connec_index!=0)
+    {
+      int nbOfCells=getNumberOfCells();
+      const int *c=_nodal_connec->getConstPointer();
+      const int *ci=_nodal_connec_index->getConstPointer();
+      for(int i=0;i<nbOfCells;i++)
+        {
+          const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)c[ci[i]]);
+          stream << "Cell #" << i << " " << cm.getRepr() << " : ";
+          std::copy(c+ci[i]+1,c+ci[i+1],std::ostream_iterator<int>(stream," "));
+          stream << "\n";
+        }
+    }
+  else
+    stream << "Connectivity not defined !\n";
+}
+
+int MEDCouplingUMesh::getNumberOfNodesInCell(int cellId) const
+{
+  const int *ptI=_nodal_connec_index->getConstPointer();
+  const int *pt=_nodal_connec->getConstPointer();
+  if(pt[ptI[cellId]]!=INTERP_KERNEL::NORM_POLYHED)
+    return ptI[cellId+1]-ptI[cellId]-1;
+  else
+    return (int)std::count_if(pt+ptI[cellId]+1,pt+ptI[cellId+1],std::bind2nd(std::not_equal_to<int>(),-1));
+}
+
+/*!
+ * This method is equivalent to MEDCouplingUMesh::getAllTypes excecpt that it returns only types of submesh which cell ids are in [begin,end).
+ * This method avoids to compute explicitely submesh to get its types.
+ */
+std::set<INTERP_KERNEL::NormalizedCellType> MEDCouplingUMesh::getTypesOfPart(const int *begin, const int *end) const throw(INTERP_KERNEL::Exception)
+{
+  checkFullyDefined();
+  std::set<INTERP_KERNEL::NormalizedCellType> ret;
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connIndex=_nodal_connec_index->getConstPointer();
+  for(const int *w=begin;w!=end;w++)
+    ret.insert((INTERP_KERNEL::NormalizedCellType)conn[connIndex[*w]]);
+  return ret;
+}
+
+/*!
+ * Method reserved for advanced users having prepared their connectivity before.
+ * Arrays 'conn' and 'connIndex' will be aggregated without any copy and their counter will be incremented.
+ */
+void MEDCouplingUMesh::setConnectivity(DataArrayInt *conn, DataArrayInt *connIndex, bool isComputingTypes)
+{
+  DataArrayInt::SetArrayIn(conn,_nodal_connec);
+  DataArrayInt::SetArrayIn(connIndex,_nodal_connec_index);
+  if(isComputingTypes)
+    computeTypes();
+  declareAsNew();
+}
+
+/*!
+ * Copy constructor. If 'deepCpy' is false 'this' is a shallow copy of other.
+ * If 'deeCpy' is true all arrays (coordinates and connectivities) are deeply copied.
+ */
+MEDCouplingUMesh::MEDCouplingUMesh(const MEDCouplingUMesh& other, bool deepCopy):MEDCouplingPointSet(other,deepCopy),_iterator(-1),_mesh_dim(other._mesh_dim),
+                                                                                 _nodal_connec(0),_nodal_connec_index(0),
+                                                                                _types(other._types)
+{
+  if(other._nodal_connec)
+    _nodal_connec=other._nodal_connec->performCpy(deepCopy);
+  if(other._nodal_connec_index)
+    _nodal_connec_index=other._nodal_connec_index->performCpy(deepCopy);
+}
+
+MEDCouplingUMesh::~MEDCouplingUMesh()
+{
+  if(_nodal_connec)
+    _nodal_connec->decrRef();
+  if(_nodal_connec_index)
+    _nodal_connec_index->decrRef();
+}
+
+/*!
+ * This method recomputes all cell types of 'this'.
+ */
+void MEDCouplingUMesh::computeTypes()
+{
+  if(_nodal_connec && _nodal_connec_index)
+    {
+      _types.clear();
+      const int *conn=_nodal_connec->getConstPointer();
+      const int *connIndex=_nodal_connec_index->getConstPointer();
+      int nbOfElem=_nodal_connec_index->getNbOfElems()-1;
+      for(const int *pt=connIndex;pt!=connIndex+nbOfElem;pt++)
+        _types.insert((INTERP_KERNEL::NormalizedCellType)conn[*pt]);
+    }
+}
+
+/*!
+ * This method checks that all arrays are set. If yes nothing done if no an exception is thrown.
+ */
+void MEDCouplingUMesh::checkFullyDefined() const throw(INTERP_KERNEL::Exception)
+{
+  if(!_nodal_connec_index || !_nodal_connec || !_coords)
+    throw INTERP_KERNEL::Exception("Reverse nodal connectivity computation requires full connectivity and coordinates set in unstructured mesh.");
+}
+
+/*!
+ * This method checks that all connectivity arrays are set. If yes nothing done if no an exception is thrown.
+ */
+void MEDCouplingUMesh::checkConnectivityFullyDefined() const throw(INTERP_KERNEL::Exception)
+{
+  if(!_nodal_connec_index || !_nodal_connec)
+    throw INTERP_KERNEL::Exception("Reverse nodal connectivity computation requires full connectivity set in unstructured mesh.");
+}
+
+int MEDCouplingUMesh::getNumberOfCells() const
+{ 
+  if(_nodal_connec_index)
+    if(_iterator==-1)
+      return _nodal_connec_index->getNumberOfTuples()-1;
+    else
+      return _iterator;
+  else
+    if(_mesh_dim==-1)
+      return 1;
+    else
+      throw INTERP_KERNEL::Exception("Unable to get number of cells because no connectivity specified !");
+}
+
+int MEDCouplingUMesh::getMeshDimension() const
+{
+  if(_mesh_dim<-1)
+    throw INTERP_KERNEL::Exception("No mesh dimension specified !");
+  return _mesh_dim;
+}
+
+/*!
+ * This method is for test reason. Normally the integer returned is not useable by user.
+ */
+int MEDCouplingUMesh::getMeshLength() const
+{
+  return _nodal_connec->getNbOfElems();
+}
+
+/*!
+ * First step of serialization process. Used by ParaMEDMEM and MEDCouplingCorba to transfert data between process.
+ */
+void MEDCouplingUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const
+{
+  MEDCouplingPointSet::getTinySerializationInformation(tinyInfoD,tinyInfo,littleStrings);
+  tinyInfo.push_back(getMeshDimension());
+  tinyInfo.push_back(getNumberOfCells());
+  if(_nodal_connec)
+    tinyInfo.push_back(getMeshLength());
+  else
+    tinyInfo.push_back(-1);
+}
+
+/*!
+ * First step of unserialization process.
+ */
+bool MEDCouplingUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const
+{
+  return tinyInfo[6]<=0;
+}
+
+/*!
+ * Second step of serialization process.
+ * @param tinyInfo must be equal to the result given by getTinySerializationInformation method.
+ */
+void MEDCouplingUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const
+{
+  MEDCouplingPointSet::resizeForUnserialization(tinyInfo,a1,a2,littleStrings);
+  if(tinyInfo[5]!=-1)
+    a1->alloc(tinyInfo[7]+tinyInfo[6]+1,1);
+}
+
+/*!
+ * Third and final step of serialization process.
+ */
+void MEDCouplingUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const
+{
+  MEDCouplingPointSet::serialize(a1,a2);
+  if(getMeshDimension()>-1)
+    {
+      a1=DataArrayInt::New();
+      a1->alloc(getMeshLength()+getNumberOfCells()+1,1);
+      int *ptA1=a1->getPointer();
+      const int *conn=getNodalConnectivity()->getConstPointer();
+      const int *index=getNodalConnectivityIndex()->getConstPointer();
+      ptA1=std::copy(index,index+getNumberOfCells()+1,ptA1);
+      std::copy(conn,conn+getMeshLength(),ptA1);
+    }
+  else
+    a1=0;
+}
+
+/*!
+ * Second and final unserialization process.
+ * @param tinyInfo must be equal to the result given by getTinySerializationInformation method.
+ */
+void MEDCouplingUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector<std::string>& littleStrings)
+{
+  MEDCouplingPointSet::unserialization(tinyInfoD,tinyInfo,a1,a2,littleStrings);
+  setMeshDimension(tinyInfo[5]);
+  if(tinyInfo[7]!=-1)
+    {
+      // Connectivity
+      const int *recvBuffer=a1->getConstPointer();
+      DataArrayInt* myConnecIndex=DataArrayInt::New();
+      myConnecIndex->alloc(tinyInfo[6]+1,1);
+      std::copy(recvBuffer,recvBuffer+tinyInfo[6]+1,myConnecIndex->getPointer());
+      DataArrayInt* myConnec=DataArrayInt::New();
+      myConnec->alloc(tinyInfo[7],1);
+      std::copy(recvBuffer+tinyInfo[6]+1,recvBuffer+tinyInfo[6]+1+tinyInfo[7],myConnec->getPointer());
+      setConnectivity(myConnec, myConnecIndex) ;
+      myConnec->decrRef();
+      myConnecIndex->decrRef();
+    }
+}
+
+/*!
+ * This is the low algorithm of MEDCouplingUMesh::buildPartOfMySelf2.
+ * CellIds are given using range specified by a start an end and step.
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const
+{
+  checkFullyDefined();
+  int ncell=getNumberOfCells();
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
+  ret->_mesh_dim=_mesh_dim;
+  ret->setCoords(_coords);
+  int newNbOfCells=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::buildPartOfMySelfKeepCoords2 : ");
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New(); newConnI->alloc(newNbOfCells+1,1);
+  int *newConnIPtr=newConnI->getPointer(); *newConnIPtr=0;
+  int work=start;
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connIndex=_nodal_connec_index->getConstPointer();
+  for(int i=0;i<newNbOfCells;i++,newConnIPtr++,work+=step)
+    {
+      if(work>=0 && work<ncell)
+        {
+          newConnIPtr[1]=newConnIPtr[0]+connIndex[work+1]-connIndex[work];
+        }
+      else
+        {
+          std::ostringstream oss; oss << "MEDCouplingUMesh::buildPartOfMySelfKeepCoords2 : On pos #" << i << " input cell id =" << work << " should be in [0," << ncell << ") !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(newConnIPtr[0],1);
+  int *newConnPtr=newConn->getPointer();
+  std::set<INTERP_KERNEL::NormalizedCellType> types;
+  work=start;
+  for(int i=0;i<newNbOfCells;i++,newConnIPtr++,work+=step)
+    {
+      types.insert((INTERP_KERNEL::NormalizedCellType)conn[connIndex[work]]);
+      newConnPtr=std::copy(conn+connIndex[work],conn+connIndex[work+1],newConnPtr);
+    }
+  ret->setConnectivity(newConn,newConnI,false);
+  ret->_types=types;
+  ret->copyTinyInfoFrom(this);
+  std::string name(getName());
+  std::size_t sz=strlen(PART_OF_NAME);
+  if(name.length()>=sz)
+    name=name.substr(0,sz);
+  if(name!=PART_OF_NAME)
+    {
+      std::ostringstream stream; stream << PART_OF_NAME << getName();
+      ret->setName(stream.str().c_str());
+    }
+  else
+    ret->setName(getName());
+  ret->incrRef();
+  return ret;
+}
+
+/*!
+ * This is the low algorithm of MEDCouplingUMesh::buildPartOfMySelf.
+ * Keeps from 'this' only cells which constituing point id are in the ids specified by ['begin','end').
+ * The return newly allocated mesh will share the same coordinates as 'this'.
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const
+{
+  checkFullyDefined();
+  int ncell=getNumberOfCells();
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New();
+  ret->_mesh_dim=_mesh_dim;
+  ret->setCoords(_coords);
+  std::size_t nbOfElemsRet=std::distance(begin,end);
+  int *connIndexRet=new int[nbOfElemsRet+1];
+  connIndexRet[0]=0;
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connIndex=_nodal_connec_index->getConstPointer();
+  int newNbring=0;
+  for(const int *work=begin;work!=end;work++,newNbring++)
+    {
+      if(*work>=0 && *work<ncell)
+        connIndexRet[newNbring+1]=connIndexRet[newNbring]+connIndex[*work+1]-connIndex[*work];
+      else
+        {
+          delete [] connIndexRet;
+          std::ostringstream oss; oss << "MEDCouplingUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  int *connRet=new int[connIndexRet[nbOfElemsRet]];
+  int *connRetWork=connRet;
+  std::set<INTERP_KERNEL::NormalizedCellType> types;
+  for(const int *work=begin;work!=end;work++)
+    {
+      types.insert((INTERP_KERNEL::NormalizedCellType)conn[connIndex[*work]]);
+      connRetWork=std::copy(conn+connIndex[*work],conn+connIndex[*work+1],connRetWork);
+    }
+  DataArrayInt *connRetArr=DataArrayInt::New();
+  connRetArr->useArray(connRet,true,CPP_DEALLOC,connIndexRet[nbOfElemsRet],1);
+  DataArrayInt *connIndexRetArr=DataArrayInt::New();
+  connIndexRetArr->useArray(connIndexRet,true,CPP_DEALLOC,(int)nbOfElemsRet+1,1);
+  ret->setConnectivity(connRetArr,connIndexRetArr,false);
+  ret->_types=types;
+  connRetArr->decrRef();
+  connIndexRetArr->decrRef();
+  ret->copyTinyInfoFrom(this);
+  std::string name(getName());
+  std::size_t sz=strlen(PART_OF_NAME);
+  if(name.length()>=sz)
+    name=name.substr(0,sz);
+  if(name!=PART_OF_NAME)
+    {
+      std::ostringstream stream; stream << PART_OF_NAME << getName();
+      ret->setName(stream.str().c_str());
+    }
+  else
+    ret->setName(getName());
+  ret->incrRef();
+  return ret;
+}
+
+/*!
+ * brief returns the volumes of the cells underlying the field \a field
+ *
+ * For 2D geometries, the returned field contains the areas.
+ * For 3D geometries, the returned field contains the volumes.
+ *
+ * param field field on which cells the volumes are required
+ * return field containing the volumes, area or length depending the meshdimension.
+ */
+MEDCouplingFieldDouble *MEDCouplingUMesh::getMeasureField(bool isAbs) const
+{
+  std::string name="MeasureOfMesh_";
+  name+=getName();
+  int nbelem=getNumberOfCells();
+  MEDCouplingFieldDouble *field=MEDCouplingFieldDouble::New(ON_CELLS);
+  field->setName(name.c_str());
+  DataArrayDouble* array=DataArrayDouble::New();
+  array->alloc(nbelem,1);
+  double *area_vol=array->getPointer();
+  field->setArray(array) ;
+  array->decrRef();
+  field->setMesh(const_cast<MEDCouplingUMesh *>(this));
+  if(getMeshDimension()!=-1)
+    {
+      int ipt;
+      INTERP_KERNEL::NormalizedCellType type;
+      int dim_space=getSpaceDimension();
+      const double *coords=getCoords()->getConstPointer();
+      const int *connec=getNodalConnectivity()->getConstPointer();
+      const int *connec_index=getNodalConnectivityIndex()->getConstPointer();
+      for(int iel=0;iel<nbelem;iel++)
+        {
+          ipt=connec_index[iel];
+          type=(INTERP_KERNEL::NormalizedCellType)connec[ipt];
+          area_vol[iel]=INTERP_KERNEL::computeVolSurfOfCell2<int,INTERP_KERNEL::ALL_C_MODE>(type,connec+ipt+1,connec_index[iel+1]-ipt-1,coords,dim_space);
+        }
+      if(isAbs)
+        std::transform(area_vol,area_vol+nbelem,area_vol,std::ptr_fun<double,double>(fabs));
+    }
+  else
+    {
+      area_vol[0]=std::numeric_limits<double>::max();
+    }
+  return field;
+}
+
+/*!
+ * This method is equivalent to MEDCouplingUMesh::getMeasureField except that only part defined by [begin,end) is returned !
+ * This method avoids to build explicitely part of this to perform the work.
+ */
+DataArrayDouble *MEDCouplingUMesh::getPartMeasureField(bool isAbs, const int *begin, const int *end) const
+{
+  std::string name="PartMeasureOfMesh_";
+  name+=getName();
+  int nbelem=(int)std::distance(begin,end);
+  DataArrayDouble* array=DataArrayDouble::New();
+  array->setName(name.c_str());
+  array->alloc(nbelem,1);
+  double *area_vol=array->getPointer();
+  if(getMeshDimension()!=-1)
+    {
+      int ipt;
+      INTERP_KERNEL::NormalizedCellType type;
+      int dim_space=getSpaceDimension();
+      const double *coords=getCoords()->getConstPointer();
+      const int *connec=getNodalConnectivity()->getConstPointer();
+      const int *connec_index=getNodalConnectivityIndex()->getConstPointer();
+      for(const int *iel=begin;iel!=end;iel++)
+        {
+          ipt=connec_index[*iel];
+          type=(INTERP_KERNEL::NormalizedCellType)connec[ipt];
+          *area_vol++=INTERP_KERNEL::computeVolSurfOfCell2<int,INTERP_KERNEL::ALL_C_MODE>(type,connec+ipt+1,connec_index[*iel+1]-ipt-1,coords,dim_space);
+        }
+      if(isAbs)
+        std::transform(array->getPointer(),area_vol,array->getPointer(),std::ptr_fun<double,double>(fabs));
+    }
+  else
+    {
+      area_vol[0]=std::numeric_limits<double>::max();
+    }
+  return array;
+}
+
+/*!
+ * This methods returns a field on nodes and no time. This method is usefull to check "P1*" conservative interpolators.
+ * This field returns the getMeasureField of the dualMesh in P1 sens of 'this'.
+ */
+MEDCouplingFieldDouble *MEDCouplingUMesh::getMeasureFieldOnNode(bool isAbs) const
+{
+  MEDCouplingFieldDouble *tmp=getMeasureField(isAbs);
+  std::string name="MeasureOnNodeOfMesh_";
+  name+=getName();
+  int nbNodes=getNumberOfNodes();
+  MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_NODES);
+  double cst=1./((double)getMeshDimension()+1.);
+  DataArrayDouble* array=DataArrayDouble::New();
+  array->alloc(nbNodes,1);
+  double *valsToFill=array->getPointer();
+  std::fill(valsToFill,valsToFill+nbNodes,0.);
+  const double *values=tmp->getArray()->getConstPointer();
+  DataArrayInt *da=DataArrayInt::New();
+  DataArrayInt *daInd=DataArrayInt::New();
+  getReverseNodalConnectivity(da,daInd);
+  const int *daPtr=da->getConstPointer();
+  const int *daIPtr=daInd->getConstPointer();
+  for(int i=0;i<nbNodes;i++)
+    for(const int *cell=daPtr+daIPtr[i];cell!=daPtr+daIPtr[i+1];cell++)
+      valsToFill[i]+=cst*values[*cell];
+  ret->setMesh(this);
+  da->decrRef();
+  daInd->decrRef();
+  ret->setArray(array);
+  array->decrRef();
+  tmp->decrRef();
+  return ret;
+}
+
+/*!
+ * This methods returns a vector field on cells that represents the orthogonal vector normalized of each 2D cell of this.
+ * This method is only callable on mesh with meshdim == 2 and spacedim==2 or 3.
+ */
+MEDCouplingFieldDouble *MEDCouplingUMesh::buildOrthogonalField() const
+{
+  if((getMeshDimension()!=2) && (getMeshDimension()!=1 || getSpaceDimension()!=2))
+    throw INTERP_KERNEL::Exception("Expected a umesh with ( meshDim == 2 spaceDim == 2 or 3 ) or ( meshDim == 1 spaceDim == 2 ) !");
+  MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  DataArrayDouble *array=DataArrayDouble::New();
+  int nbOfCells=getNumberOfCells();
+  int nbComp=getMeshDimension()+1;
+  array->alloc(nbOfCells,nbComp);
+  double *vals=array->getPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  const int *conn=_nodal_connec->getConstPointer();
+  const double *coords=_coords->getConstPointer();
+  if(getMeshDimension()==2)
+    {
+      if(getSpaceDimension()==3)
+        {
+          DataArrayDouble *loc=getBarycenterAndOwner();
+          const double *locPtr=loc->getConstPointer();
+          for(int i=0;i<nbOfCells;i++,vals+=3)
+            {
+              int offset=connI[i];
+              INTERP_KERNEL::crossprod<3>(locPtr+3*i,coords+3*conn[offset+1],coords+3*conn[offset+2],vals);
+              double n=INTERP_KERNEL::norm<3>(vals);
+              std::transform(vals,vals+3,vals,std::bind2nd(std::multiplies<double>(),1./n));
+            }
+          loc->decrRef();
+        }
+      else
+        {
+          for(int i=0;i<nbOfCells;i++)
+            { vals[3*i]=0.; vals[3*i+1]=0.; vals[3*i+2]=1.; }
+        }
+    }
+  else//meshdimension==1
+    {
+      double tmp[2];
+      for(int i=0;i<nbOfCells;i++)
+        {
+          int offset=connI[i];
+          std::transform(coords+2*conn[offset+2],coords+2*conn[offset+2]+2,coords+2*conn[offset+1],tmp,std::minus<double>());
+          double n=INTERP_KERNEL::norm<2>(tmp);
+          std::transform(tmp,tmp+2,tmp,std::bind2nd(std::multiplies<double>(),1./n));
+          *vals++=-tmp[1];
+          *vals++=tmp[0];
+        }
+    }
+  ret->setArray(array);
+  array->decrRef();
+  ret->setMesh(this);
+  return ret;
+}
+
+/*!
+ * This method is equivalent to MEDCouplingUMesh::buildOrthogonalField except that only part defined by [begin,end) is returned !
+ * This method avoids to build explicitely part of this to perform the work.
+ */
+MEDCouplingFieldDouble *MEDCouplingUMesh::buildPartOrthogonalField(const int *begin, const int *end) const
+{
+  if((getMeshDimension()!=2) && (getMeshDimension()!=1 || getSpaceDimension()!=2))
+    throw INTERP_KERNEL::Exception("Expected a umesh with ( meshDim == 2 spaceDim == 2 or 3 ) or ( meshDim == 1 spaceDim == 2 ) !");
+  MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  DataArrayDouble *array=DataArrayDouble::New();
+  std::size_t nbelems=std::distance(begin,end);
+  int nbComp=getMeshDimension()+1;
+  array->alloc((int)nbelems,nbComp);
+  double *vals=array->getPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  const int *conn=_nodal_connec->getConstPointer();
+  const double *coords=_coords->getConstPointer();
+  if(getMeshDimension()==2)
+    {
+      if(getSpaceDimension()==3)
+        {
+          DataArrayDouble *loc=getPartBarycenterAndOwner(begin,end);
+          const double *locPtr=loc->getConstPointer();
+          for(const int *i=begin;i!=end;i++,vals+=3,locPtr+=3)
+            {
+              int offset=connI[*i];
+              INTERP_KERNEL::crossprod<3>(locPtr,coords+3*conn[offset+1],coords+3*conn[offset+2],vals);
+              double n=INTERP_KERNEL::norm<3>(vals);
+              std::transform(vals,vals+3,vals,std::bind2nd(std::multiplies<double>(),1./n));
+            }
+          loc->decrRef();
+        }
+      else
+        {
+          for(std::size_t i=0;i<nbelems;i++)
+            { vals[3*i]=0.; vals[3*i+1]=0.; vals[3*i+2]=1.; }
+        }
+    }
+  else//meshdimension==1
+    {
+      double tmp[2];
+      for(const int *i=begin;i!=end;i++)
+        {
+          int offset=connI[*i];
+          std::transform(coords+2*conn[offset+2],coords+2*conn[offset+2]+2,coords+2*conn[offset+1],tmp,std::minus<double>());
+          double n=INTERP_KERNEL::norm<2>(tmp);
+          std::transform(tmp,tmp+2,tmp,std::bind2nd(std::multiplies<double>(),1./n));
+          *vals++=-tmp[1];
+          *vals++=tmp[0];
+        }
+    }
+  ret->setArray(array);
+  array->decrRef();
+  ret->setMesh(this);
+  return ret;
+}
+
+/*!
+ * This methods returns a vector newly created field on cells that represents the direction vector of each 1D cell of this.
+ * This method is only callable on mesh with meshdim == 1 containing only SEG2.
+ */
+MEDCouplingFieldDouble *MEDCouplingUMesh::buildDirectionVectorField() const
+{
+   if(getMeshDimension()!=1)
+    throw INTERP_KERNEL::Exception("Expected a umesh with meshDim == 1 for buildDirectionVectorField !");
+   if(_types.size()!=1 || *(_types.begin())!=INTERP_KERNEL::NORM_SEG2)
+     throw INTERP_KERNEL::Exception("Expected a umesh with only NORM_SEG2 type of elements for buildDirectionVectorField !");
+   MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+   DataArrayDouble *array=DataArrayDouble::New();
+   int nbOfCells=getNumberOfCells();
+   int spaceDim=getSpaceDimension();
+   array->alloc(nbOfCells,spaceDim);
+   double *pt=array->getPointer();
+   const double *coo=getCoords()->getConstPointer();
+   std::vector<int> conn;
+   conn.reserve(2);
+   for(int i=0;i<nbOfCells;i++)
+     {
+       conn.resize(0);
+       getNodeIdsOfCell(i,conn);
+       pt=std::transform(coo+conn[1]*spaceDim,coo+(conn[1]+1)*spaceDim,coo+conn[0]*spaceDim,pt,std::minus<double>());
+     }
+   ret->setArray(array);
+   array->decrRef();
+   ret->setMesh(this);
+   return ret;   
+}
+
+/*!
+ * This method expects that 'this' is fully defined and has a spaceDim==3 and a meshDim==3. If it is not the case an exception will be thrown.
+ * This method returns 2 objects : 
+ * - a newly created mesh instance containing the result of the slice lying on different coords than 'this' and with a meshdim == 2
+ * - a newly created dataarray having number of tuples equal to the number of cells in returned mesh that tells for each 2D cell in returned
+ *   mesh the 3D cell id is 'this' it comes from.
+ * This method works only for linear meshes (non quadratic).
+ * If plane crosses within 'eps' a face in 'this' shared by more than 1 cell, 2 output faces will be generated. The 2 faces having the same geometry than intersecting
+ * face. Only 'cellIds' parameter can distinguish the 2.
+ * @param origin is the origin of the plane. It should be an array of length 3.
+ * @param vec is the direction vector of the plane. It should be an array of length 3. Norm of 'vec' should be > 1e-6.
+ * @param eps is the precision. It is used by called method MEDCouplingUMesh::getCellIdsCrossingPlane for the first 3D cell selection (in absolute). 'eps' is
+ * also used to state if new points should be created or already existing points are reused. 'eps' is also used to tells if plane overlaps a face, edge or nodes (in absolute).
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::buildSlice3D(const double *origin, const double *vec, double eps, DataArrayInt *&cellIds) const throw(INTERP_KERNEL::Exception)
+{
+  checkFullyDefined();
+  if(getMeshDimension()!=3 || getSpaceDimension()!=3)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3D works on umeshes with meshdim equal to 3 and spaceDim equal to 3 too!");
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> candidates=getCellIdsCrossingPlane(origin,vec,eps);
+  if(candidates->empty())
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3D : No 3D cells in this intercepts the specified plane considering bounding boxes !");
+  std::vector<int> nodes;
+  std::vector<int> cellIds2D,cellIds1D;
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> subMesh=static_cast<MEDCouplingUMesh*>(buildPartOfMySelf(candidates->begin(),candidates->end(),false));
+  subMesh->findNodesOnPlane(origin,vec,eps,nodes);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc1=DataArrayInt::New(),desc2=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descIndx1=DataArrayInt::New(),descIndx2=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDesc1=DataArrayInt::New(),revDesc2=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDescIndx1=DataArrayInt::New(),revDescIndx2=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mDesc2=subMesh->buildDescendingConnectivity(desc2,descIndx2,revDesc2,revDescIndx2);//meshDim==2 spaceDim==3
+  revDesc2=0; revDescIndx2=0;
+  mDesc2->fillCellIdsToKeepFromNodeIds(&nodes[0],&nodes[0]+nodes.size(),true,cellIds2D);
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mDesc1=mDesc2->buildDescendingConnectivity(desc1,descIndx1,revDesc1,revDescIndx1);//meshDim==1 spaceDim==3
+  revDesc1=0; revDescIndx1=0;
+  mDesc1->fillCellIdsToKeepFromNodeIds(&nodes[0],&nodes[0]+nodes.size(),true,cellIds1D);
+  //
+  std::vector<int> cut3DCurve(mDesc1->getNumberOfCells(),-2);
+  for(std::vector<int>::const_iterator it=cellIds1D.begin();it!=cellIds1D.end();it++)
+    cut3DCurve[*it]=-1;
+  mDesc1->split3DCurveWithPlane(origin,vec,eps,cut3DCurve);
+  std::vector< std::pair<int,int> > cut3DSurf(mDesc2->getNumberOfCells());
+  AssemblyForSplitFrom3DCurve(cut3DCurve,nodes,mDesc2->getNodalConnectivity()->getConstPointer(),mDesc2->getNodalConnectivityIndex()->getConstPointer(),
+                              mDesc1->getNodalConnectivity()->getConstPointer(),mDesc1->getNodalConnectivityIndex()->getConstPointer(),
+                              desc1->getConstPointer(),descIndx1->getConstPointer(),cut3DSurf);
+  std::vector<int> conn,connI,cellIds2;
+  connI.push_back(0);
+  subMesh->assemblyForSplitFrom3DSurf(cut3DSurf,desc2->getConstPointer(),descIndx2->getConstPointer(),conn,connI,cellIds2);
+  if(cellIds2.empty())
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3D : No 3D cells in this intercepts the specified plane !");
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New("Slice3D",2);
+  ret->setCoords(mDesc1->getCoords());
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New();
+  c->alloc((int)conn.size(),1); std::copy(conn.begin(),conn.end(),c->getPointer());
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::New();
+  cI->alloc((int)connI.size(),1); std::copy(connI.begin(),connI.end(),cI->getPointer());
+  ret->setConnectivity(c,cI,true);
+  cellIds=candidates->selectByTupleId(&cellIds2[0],&cellIds2[0]+cellIds2.size());
+  ret->incrRef();
+  return ret;
+}
+
+/*!
+ * This method expects that 'this' is fully defined and has a spaceDim==3 and a meshDim==2. If it is not the case an exception will be thrown.
+ * This method returns 2 objects : 
+ * - a newly created mesh instance containing the result of the slice lying on different coords than 'this' and with a meshdim == 1
+ * - a newly created dataarray having number of tuples equal to the number of cells in returned mesh that tells for each 2D cell in returned
+ *   mesh the 3DSurf cell id is 'this' it comes from.
+ * This method works only for linear meshes (non quadratic).
+ * If plane crosses within 'eps' a face in 'this' shared by more than 1 cell, 2 output faces will be generated. The 2 faces having the same geometry than intersecting
+ * face. Only 'cellIds' parameter can distinguish the 2.
+ * @param origin is the origin of the plane. It should be an array of length 3.
+ * @param vec is the direction vector of the plane. It should be an array of length 3. Norm of 'vec' should be > 1e-6.
+ * @param eps is the precision. It is used by called method MEDCouplingUMesh::getCellIdsCrossingPlane for the first 3DSurf cell selection (in absolute). 'eps' is
+ * also used to state if new points should be created or already existing points are reused. 'eps' is also used to tells if plane overlaps a face, edge or nodes (in absolute).
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::buildSlice3DSurf(const double *origin, const double *vec, double eps, DataArrayInt *&cellIds) const throw(INTERP_KERNEL::Exception)
+{
+  checkFullyDefined();
+  if(getMeshDimension()!=2 || getSpaceDimension()!=3)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3D works on umeshes with meshdim equal to 2 and spaceDim equal to 3 !");
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> candidates=getCellIdsCrossingPlane(origin,vec,eps);
+  if(candidates->empty())
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3D : No 3D cells in this intercepts the specified plane considering bounding boxes !");
+  std::vector<int> nodes;
+  std::vector<int> cellIds1D;
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> subMesh=static_cast<MEDCouplingUMesh*>(buildPartOfMySelf(candidates->begin(),candidates->end(),false));
+  subMesh->findNodesOnPlane(origin,vec,eps,nodes);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc1=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descIndx1=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDesc1=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDescIndx1=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mDesc1=subMesh->buildDescendingConnectivity(desc1,descIndx1,revDesc1,revDescIndx1);//meshDim==1 spaceDim==3
+  mDesc1->fillCellIdsToKeepFromNodeIds(&nodes[0],&nodes[0]+nodes.size(),true,cellIds1D);
+  //
+  std::vector<int> cut3DCurve(mDesc1->getNumberOfCells(),-2);
+  for(std::vector<int>::const_iterator it=cellIds1D.begin();it!=cellIds1D.end();it++)
+    cut3DCurve[*it]=-1;
+  mDesc1->split3DCurveWithPlane(origin,vec,eps,cut3DCurve);
+  int ncellsSub=subMesh->getNumberOfCells();
+  std::vector< std::pair<int,int> > cut3DSurf(ncellsSub);
+  AssemblyForSplitFrom3DCurve(cut3DCurve,nodes,subMesh->getNodalConnectivity()->getConstPointer(),subMesh->getNodalConnectivityIndex()->getConstPointer(),
+                              mDesc1->getNodalConnectivity()->getConstPointer(),mDesc1->getNodalConnectivityIndex()->getConstPointer(),
+                              desc1->getConstPointer(),descIndx1->getConstPointer(),cut3DSurf);
+  std::vector<int> conn,connI,cellIds2; connI.push_back(0);
+  const int *nodal=subMesh->getNodalConnectivity()->getConstPointer();
+  const int *nodalI=subMesh->getNodalConnectivityIndex()->getConstPointer();
+  for(int i=0;i<ncellsSub;i++)
+    {
+      if(cut3DSurf[i].first!=-1 && cut3DSurf[i].second!=-1)
+        {
+          if(cut3DSurf[i].first!=-2)
+            {
+              conn.push_back((int)INTERP_KERNEL::NORM_SEG2); conn.push_back(cut3DSurf[i].first); conn.push_back(cut3DSurf[i].second);
+              connI.push_back((int)conn.size());
+              cellIds2.push_back(i);
+            }
+          else
+            {
+              int cellId3DSurf=cut3DSurf[i].second;
+              int offset=nodalI[cellId3DSurf]+1;
+              int nbOfEdges=nodalI[cellId3DSurf+1]-offset;
+              for(int j=0;j<nbOfEdges;j++)
+                {
+                  conn.push_back((int)INTERP_KERNEL::NORM_SEG2); conn.push_back(nodal[offset+j]); conn.push_back(nodal[offset+(j+1)%nbOfEdges]);
+                  connI.push_back((int)conn.size());
+                  cellIds2.push_back(cellId3DSurf);
+                }
+            }
+        }
+    }
+  if(cellIds2.empty())
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3DSurf : No 3DSurf cells in this intercepts the specified plane !");
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New("Slice3DSurf",1);
+  ret->setCoords(mDesc1->getCoords());
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New();
+  c->alloc((int)conn.size(),1); std::copy(conn.begin(),conn.end(),c->getPointer());
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::New();
+  cI->alloc((int)connI.size(),1); std::copy(connI.begin(),connI.end(),cI->getPointer());
+  ret->setConnectivity(c,cI,true);
+  cellIds=candidates->selectByTupleId(&cellIds2[0],&cellIds2[0]+cellIds2.size());
+  ret->incrRef();
+  return ret;
+}
+
+/*!
+ * This method expects that 'this' is fully defined and has a spaceDim==3. If it is not the case an exception will be thrown.
+ * This method returns a newly created dataarray containing cellsids in 'this' that potentially crosses the plane specified by 'origin' and 'vec'.
+ * @param origin is the origin of the plane. It should be an array of length 3.
+ * @param vec is the direction vector of the plane. It should be an array of length 3. Norm of 'vec' should be > 1e-6.
+ */
+DataArrayInt *MEDCouplingUMesh::getCellIdsCrossingPlane(const double *origin, const double *vec, double eps) const throw(INTERP_KERNEL::Exception)
+{
+  checkFullyDefined();
+  if(getSpaceDimension()!=3)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3D works on umeshes with spaceDim equal to 3 !");
+  double normm=sqrt(vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]);
+  if(normm<1e-6)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getCellIdsCrossingPlane : parameter 'vec' should have a norm2 greater than 1e-6 !");
+  double vec2[3];
+  vec2[0]=vec[1]; vec2[1]=-vec[0]; vec2[2]=0.;//vec2 is the result of cross product of vec with (0,0,1)
+  double angle=acos(vec[2]/normm);
+  std::vector<int> cellIds;
+  double bbox[6];
+  if(angle>eps)
+    {
+      MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coo=_coords->deepCpy();
+      MEDCouplingPointSet::Rotate3DAlg(origin,vec2,angle,coo->getNumberOfTuples(),coo->getPointer());
+      MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mw=clone(false);//false -> shallow copy
+      mw->setCoords(coo);
+      mw->getBoundingBox(bbox);
+      bbox[4]=origin[2]-eps; bbox[5]=origin[2]+eps;
+      mw->getCellsInBoundingBox(bbox,eps,cellIds);
+    }
+  else
+    {
+      getBoundingBox(bbox);
+      bbox[4]=origin[2]-eps; bbox[5]=origin[2]+eps;
+      getCellsInBoundingBox(bbox,eps,cellIds);
+    }
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
+  ret->alloc((int)cellIds.size(),1);
+  std::copy(cellIds.begin(),cellIds.end(),ret->getPointer());
+  ret->incrRef();
+  return ret;
+}
+
+/*!
+ * This method checks that 'this' is a contiguous mesh. The user is expected to call this method on a mesh with meshdim==1.
+ * If not an exception will thrown. If this is an empty mesh with no cell an exception will be thrown too.
+ * No consideration of coordinate is done by this method.
+ * A 1D mesh is said contiguous if : a cell i with nodal connectivity (k,p) the cell i+1 the nodal connectivity should be (p,m)
+ * If not false is returned. In case that false is returned a call to ParaMEDMEM::MEDCouplingUMesh::mergeNodes could be usefull.
+ */
+bool MEDCouplingUMesh::isContiguous1D() const throw(INTERP_KERNEL::Exception)
+{
+  if(getMeshDimension()!=1)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::isContiguous1D : this method has a sense only for 1D mesh !");
+  int nbCells=getNumberOfCells();
+  if(nbCells<1)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::isContiguous1D : this method has a sense for non empty mesh !");
+  const int *connI=_nodal_connec_index->getConstPointer();
+  const int *conn=_nodal_connec->getConstPointer();
+  int ref=conn[connI[0]+2];
+  for(int i=1;i<nbCells;i++)
+    {
+      if(conn[connI[i]+1]!=ref)
+        return false;
+      ref=conn[connI[i]+2];
+    }
+  return true;
+}
+
+/*!
+ * This method is only callable on mesh with meshdim == 1 containing only SEG2 and spaceDim==3.
+ * This method projects this on the 3D line defined by (pt,v). This methods first checks that all SEG2 are along v vector.
+ * @param pt reference point of the line
+ * @param v normalized director vector of the line
+ * @param eps max precision before throwing an exception
+ * @param res output of size this->getNumberOfCells
+ */
+void MEDCouplingUMesh::project1D(const double *pt, const double *v, double eps, double *res) const
+{
+  if(getMeshDimension()!=1)
+    throw INTERP_KERNEL::Exception("Expected a umesh with meshDim == 1 for project1D !");
+   if(_types.size()!=1 || *(_types.begin())!=INTERP_KERNEL::NORM_SEG2)
+     throw INTERP_KERNEL::Exception("Expected a umesh with only NORM_SEG2 type of elements for project1D !");
+   if(getSpaceDimension()!=3)
+     throw INTERP_KERNEL::Exception("Expected a umesh with spaceDim==3 for project1D !");
+   MEDCouplingFieldDouble *f=buildDirectionVectorField();
+   const double *fPtr=f->getArray()->getConstPointer();
+   double tmp[3];
+   for(int i=0;i<getNumberOfCells();i++)
+     {
+       const double *tmp1=fPtr+3*i;
+       tmp[0]=tmp1[1]*v[2]-tmp1[2]*v[1];
+       tmp[1]=tmp1[2]*v[0]-tmp1[0]*v[2];
+       tmp[2]=tmp1[0]*v[1]-tmp1[1]*v[0];
+       double n1=INTERP_KERNEL::norm<3>(tmp);
+       n1/=INTERP_KERNEL::norm<3>(tmp1);
+       if(n1>eps)
+         {
+           f->decrRef();
+           throw INTERP_KERNEL::Exception("UMesh::Projection 1D failed !");
+         }
+     }
+   const double *coo=getCoords()->getConstPointer();
+   for(int i=0;i<getNumberOfNodes();i++)
+     {
+       std::transform(coo+i*3,coo+i*3+3,pt,tmp,std::minus<double>());
+       std::transform(tmp,tmp+3,v,tmp,std::multiplies<double>());
+       res[i]=std::accumulate(tmp,tmp+3,0.);
+     }
+   f->decrRef();
+}
+
+/*!
+ * Returns a cell if any that contains the point located on 'pos' with precison eps.
+ * If 'pos' is outside 'this' -1 is returned. If several cells contain this point the cell with the smallest id is returned.
+ * \b Warning this method is good if the caller intends to evaluate only one point. But if more than one point is requested on 'this'
+ * it is better to use MEDCouplingUMesh::getCellsContainingPoints method because in this case, the acceleration structure will be computed only once.
+ */
+int MEDCouplingUMesh::getCellContainingPoint(const double *pos, double eps) const
+{
+  std::vector<int> elts;
+  getCellsContainingPoint(pos,eps,elts);
+  if(elts.empty())
+    return -1;
+  return elts.front();
+}
+
+/*!
+ * Returns all cellIds in 'elts' of point 'pos' with eps accuracy.
+ * \b Warning this method is good if the caller intends to evaluate only one point. But if more than one point is requested on 'this'
+ * it is better to use MEDCouplingUMesh::getCellsContainingPoints method because in this case, the acceleration structure will be computed only once.
+ */
+void MEDCouplingUMesh::getCellsContainingPoint(const double *pos, double eps, std::vector<int>& elts) const
+{
+  std::vector<int> eltsIndex;
+  getCellsContainingPoints(pos,1,eps,elts,eltsIndex);
+}
+
+/// @cond INTERNAL
+
+namespace ParaMEDMEM
+{
+  template<const int SPACEDIMM>
+  class DummyClsMCUG
+  {
+  public:
+    static const int MY_SPACEDIM=SPACEDIMM;
+    static const int MY_MESHDIM=8;
+    typedef int MyConnType;
+    static const INTERP_KERNEL::NumberingPolicy My_numPol=INTERP_KERNEL::ALL_C_MODE;
+    // begin
+    // useless, but for windows compilation ...
+    const double* getCoordinatesPtr() const { return 0; }
+    const int* getConnectivityPtr() const { return 0; }
+    const int* getConnectivityIndexPtr() const { return 0; }
+    INTERP_KERNEL::NormalizedCellType getTypeOfElement(int) const { return (INTERP_KERNEL::NormalizedCellType)0; }
+    // end
+  };
+
+  INTERP_KERNEL::Edge *MEDCouplingUMeshBuildQPFromEdge(INTERP_KERNEL::NormalizedCellType typ, std::map<int, std::pair<INTERP_KERNEL::Node *,bool> >& mapp2, const int *bg)
+  {
+    INTERP_KERNEL::Edge *ret=0;
+    switch(typ)
+      {
+      case INTERP_KERNEL::NORM_SEG2:
+        {
+          ret=new INTERP_KERNEL::EdgeLin(mapp2[bg[0]].first,mapp2[bg[1]].first);
+          break;
+        }
+      case INTERP_KERNEL::NORM_SEG3:
+        {
+          INTERP_KERNEL::EdgeLin *e1=new INTERP_KERNEL::EdgeLin(mapp2[bg[0]].first,mapp2[bg[2]].first);
+          INTERP_KERNEL::EdgeLin *e2=new INTERP_KERNEL::EdgeLin(mapp2[bg[2]].first,mapp2[bg[1]].first);
+          INTERP_KERNEL::SegSegIntersector inters(*e1,*e2);
+          bool colinearity=inters.areColinears();
+          delete e1; delete e2;
+          if(colinearity)
+            ret=new INTERP_KERNEL::EdgeLin(mapp2[bg[0]].first,mapp2[bg[1]].first);
+          else
+            ret=new INTERP_KERNEL::EdgeArcCircle(mapp2[bg[0]].first,mapp2[bg[2]].first,mapp2[bg[1]].first);
+          mapp2[bg[2]].second=false;
+          break;
+        }
+      default:
+        throw INTERP_KERNEL::Exception("MEDCouplingUMeshBuildQPFromEdge : Expecting a mesh with spaceDim==2 and meshDim==1 !");
+      }
+    return ret;
+  }
+
+  /*!
+   * This method creates a sub mesh in Geometric2D DS. The sub mesh is composed be the sub set of cells in 'candidates' and the global mesh 'mDesc'.
+   * The input meth 'mDesc' must be so that mDim==1 et spaceDim==3.
+   * 'mapp' contains a mapping between local numbering in submesh and the global node numbering in 'mDesc'.
+   */
+  INTERP_KERNEL::QuadraticPolygon *MEDCouplingUMeshBuildQPFromMesh(const MEDCouplingUMesh *mDesc, const std::vector<int>& candidates, std::map<INTERP_KERNEL::Node *,int>& mapp) throw(INTERP_KERNEL::Exception)
+  {
+    mapp.clear();
+    std::map<int, std::pair<INTERP_KERNEL::Node *,bool> > mapp2;//bool is for a flag specifying if node is boundary (true) or only a middle for SEG3.
+    const double *coo=mDesc->getCoords()->getConstPointer();
+    const int *c=mDesc->getNodalConnectivity()->getConstPointer();
+    const int *cI=mDesc->getNodalConnectivityIndex()->getConstPointer();
+    std::set<int> s;
+    for(std::vector<int>::const_iterator it=candidates.begin();it!=candidates.end();it++)
+      s.insert(c+cI[*it]+1,c+cI[(*it)+1]);
+    for(std::set<int>::const_iterator it2=s.begin();it2!=s.end();it2++)
+      {
+        INTERP_KERNEL::Node *n=new INTERP_KERNEL::Node(coo[2*(*it2)],coo[2*(*it2)+1]);
+        mapp2[*it2]=std::pair<INTERP_KERNEL::Node *,bool>(n,true);
+      }
+    INTERP_KERNEL::QuadraticPolygon *ret=new INTERP_KERNEL::QuadraticPolygon;
+    for(std::vector<int>::const_iterator it=candidates.begin();it!=candidates.end();it++)
+      {
+        INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)c[cI[*it]];
+        ret->pushBack(MEDCouplingUMeshBuildQPFromEdge(typ,mapp2,c+cI[*it]+1));
+      }
+    for(std::map<int, std::pair<INTERP_KERNEL::Node *,bool> >::const_iterator it2=mapp2.begin();it2!=mapp2.end();it2++)
+      {
+        if((*it2).second.second)
+          mapp[(*it2).second.first]=(*it2).first;
+        ((*it2).second.first)->decrRef();
+      }
+    return ret;
+  }
+
+  INTERP_KERNEL::Node *MEDCouplingUMeshBuildQPNode(int nodeId, const double *coo1, int offset1, const double *coo2, int offset2, const std::vector<double>& addCoo)
+  {
+    if(nodeId>=offset2)
+      {
+        int locId=nodeId-offset2;
+        return new INTERP_KERNEL::Node(addCoo[2*locId],addCoo[2*locId+1]);
+      }
+    if(nodeId>=offset1)
+      {
+        int locId=nodeId-offset1;
+        return new INTERP_KERNEL::Node(coo2[2*locId],coo2[2*locId+1]);
+      }
+    return new INTERP_KERNEL::Node(coo1[2*nodeId],coo1[2*nodeId+1]);
+  }
+
+  void MEDCouplingUMeshBuildQPFromMesh3(const double *coo1, int offset1, const double *coo2, int offset2, const std::vector<double>& addCoo,
+                                        const int *desc1Bg, const int *desc1End, const std::vector<std::vector<int> >& intesctEdges1,
+                                        /*output*/std::map<INTERP_KERNEL::Node *,int>& mapp, std::map<int,INTERP_KERNEL::Node *>& mappRev)
+  {
+    for(const int *desc1=desc1Bg;desc1!=desc1End;desc1++)
+      {
+        int eltId1=abs(*desc1)-1;
+        for(std::vector<int>::const_iterator it1=intesctEdges1[eltId1].begin();it1!=intesctEdges1[eltId1].end();it1++)
+          {
+            std::map<int,INTERP_KERNEL::Node *>::const_iterator it=mappRev.find(*it1);
+            if(it==mappRev.end())
+              {
+                INTERP_KERNEL::Node *node=MEDCouplingUMeshBuildQPNode(*it1,coo1,offset1,coo2,offset2,addCoo);
+                mapp[node]=*it1;
+                mappRev[*it1]=node;
+              }
+          }
+      }
+  }
+}
+
+/// @endcond
+
+template<int SPACEDIM>
+void MEDCouplingUMesh::getCellsContainingPointsAlg(const double *coords, const double *pos, int nbOfPoints,
+                                                   double eps, std::vector<int>& elts, std::vector<int>& eltsIndex) const
+{
+  std::vector<double> bbox;
+  eltsIndex.resize(nbOfPoints+1);
+  eltsIndex[0]=0;
+  elts.clear();
+  getBoundingBoxForBBTree(bbox);
+  int nbOfCells=getNumberOfCells();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  double bb[2*SPACEDIM];
+  BBTree<SPACEDIM,int> myTree(&bbox[0],0,0,nbOfCells,-eps);
+  for(int i=0;i<nbOfPoints;i++)
+    {
+      eltsIndex[i+1]=eltsIndex[i];
+      for(int j=0;j<SPACEDIM;j++)
+        {
+          bb[2*j]=pos[SPACEDIM*i+j];
+          bb[2*j+1]=pos[SPACEDIM*i+j];
+        }
+      std::vector<int> candidates;
+      myTree.getIntersectingElems(bb,candidates);
+      for(std::vector<int>::const_iterator iter=candidates.begin();iter!=candidates.end();iter++)
+        {
+          int sz=connI[(*iter)+1]-connI[*iter]-1;
+          if(INTERP_KERNEL::PointLocatorAlgos<DummyClsMCUG<SPACEDIM> >::isElementContainsPoint(pos+i*SPACEDIM,
+                                                                                               (INTERP_KERNEL::NormalizedCellType)conn[connI[*iter]],
+                                                                                               coords,conn+connI[*iter]+1,sz,eps))
+            {
+              eltsIndex[i+1]++;
+              elts.push_back(*iter);
+            }
+        }
+    }
+}
+
+/*!
+ * This method is an extension of MEDCouplingUMesh::getCellContainingPoint and MEDCouplingUMesh::getCellsContainingPoint.
+ * This method performs 'nbOfPoints' time the getCellsContainingPoint request. This method is recommended rather than the 2 others
+ * in case of multi points searching.
+ * This method returns 2 arrays 'elts' and 'eltsIndex'. 'eltsIndex' is of size 'nbOfPoints+1' and 'elts' is of size 'eltsIndex[nbOfPoints-1]'.
+ * For point j in [0,nbOfPoints), (eltsIndex[j+1]-eltsIndex[j]) cells contain this point. These cells are : [elts.begin()+eltsIndex[j],elts.begin():eltsIndex[j+1]).
+ * 
+ * \param pos input parameter that points to an array of size 'getSpaceDim()*nbOfPoints' points stored in full interlace mode : X0,Y0,Z0,X1,Y1,Z1...
+ */
+void MEDCouplingUMesh::getCellsContainingPoints(const double *pos, int nbOfPoints, double eps,
+                                                std::vector<int>& elts, std::vector<int>& eltsIndex) const
+{
+  int spaceDim=getSpaceDimension();
+  int mDim=getMeshDimension();
+  if(spaceDim==3)
+    {
+      if(mDim==3)
+        {
+          const double *coords=_coords->getConstPointer();
+          getCellsContainingPointsAlg<3>(coords,pos,nbOfPoints,eps,elts,eltsIndex);
+        }
+      /*else if(mDim==2)
+        {
+          
+        }*/
+      else
+        throw INTERP_KERNEL::Exception("For spaceDim==3 only meshDim==3 implemented for getelementscontainingpoints !");
+    }
+  else if(spaceDim==2)
+    {
+      if(mDim==2)
+        {
+          const double *coords=_coords->getConstPointer();
+          getCellsContainingPointsAlg<2>(coords,pos,nbOfPoints,eps,elts,eltsIndex);
+        }
+      else
+        throw INTERP_KERNEL::Exception("For spaceDim==2 only meshDim==2 implemented for getelementscontainingpoints !");
+    }
+  else if(spaceDim==1)
+    {
+      if(mDim==1)
+        {
+          const double *coords=_coords->getConstPointer();
+          getCellsContainingPointsAlg<1>(coords,pos,nbOfPoints,eps,elts,eltsIndex);
+        }
+      else
+        throw INTERP_KERNEL::Exception("For spaceDim==1 only meshDim==1 implemented for getelementscontainingpoints !");
+    }
+  else
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getCellsContainingPoints : not managed for mdim not in [1,2,3] !");
+}
+
+/*!
+ * This method is only available for a mesh with meshDim==2 and spaceDim==2||spaceDim==3.
+ * This method returns a vector 'cells' where all detected butterfly cells have been added to cells.
+ * A 2D cell is considered to be butterfly if it exists at least one pair of distinct edges of it that intersect each other
+ * anywhere excepted their extremities. An INTERP_KERNEL::NORM_NORI3 could \b not be butterfly.
+ */
+void MEDCouplingUMesh::checkButterflyCells(std::vector<int>& cells, double eps) const
+{
+  const char msg[]="Butterfly detection work only for 2D cells with spaceDim==2 or 3!";
+  if(getMeshDimension()!=2)
+    throw INTERP_KERNEL::Exception(msg);
+  int spaceDim=getSpaceDimension();
+  if(spaceDim!=2 && spaceDim!=3)
+    throw INTERP_KERNEL::Exception(msg);
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  int nbOfCells=getNumberOfCells();
+  std::vector<double> cell2DinS2;
+  for(int i=0;i<nbOfCells;i++)
+    {
+      int offset=connI[i];
+      int nbOfNodesForCell=connI[i+1]-offset-1;
+      if(nbOfNodesForCell<=3)
+        continue;
+      bool isQuad=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[offset]).isQuadratic();
+      project2DCellOnXY(conn+offset+1,conn+connI[i+1],cell2DinS2);
+      if(isButterfly2DCell(cell2DinS2,isQuad,eps))
+        cells.push_back(i);
+      cell2DinS2.clear();
+    }
+}
+
+/*!
+ * This method is typically requested to unbutterfly 2D linear cells in \b this.
+ *
+ * This method expects that space dimension is equal to 2 and mesh dimension is equal to 2 too. If it is not the case an INTERP_KERNEL::Exception will be thrown.
+ * This method works only for linear 2D cells. If there is any of non linear cells (INTERP_KERNEL::NORM_QUAD8 for example) an INTERP_KERNEL::Exception will be thrown too.
+ * 
+ * For each 2D linear cell in \b this, this method builds the convex envelop (or the convex hull) of the current cell.
+ * This convex envelop is computed using Jarvis march algorithm.
+ * The coordinates and the number of cells of \b this remain unchanged on invocation of this method.
+ * Only connectivity of some cells could be modified if those cells were not representing a convex envelop. If a cell already equals its convex envelop (regardless orientation)
+ * its connectivity will remain unchanged. If the computation leads to a modification of nodal connectivity of a cell its geometric type will be modified to INTERP_KERNEL::NORM_POLYGON.
+ *
+ * @return a newly allocated array containing cellIds that have been modified if any. If no cells have been impacted by this method NULL is returned.
+ */
+DataArrayInt *MEDCouplingUMesh::convexEnvelop2D() throw(INTERP_KERNEL::Exception)
+{
+  if(getMeshDimension()!=2 || getSpaceDimension()!=2)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convexEnvelop2D  works only for meshDim=2 and spaceDim=2 !");
+  checkFullyDefined();
+  const double *coords=getCoords()->getConstPointer();
+  int nbOfCells=getNumberOfCells();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodalConnecIndexOut=DataArrayInt::New();
+  nodalConnecIndexOut->alloc(nbOfCells+1,1);
+  std::vector<int> nodalConnecOut;
+  int *workIndexOut=nodalConnecIndexOut->getPointer();
+  *workIndexOut=0;
+  const int *nodalConnecIn=_nodal_connec->getConstPointer();
+  const int *nodalConnecIndexIn=_nodal_connec_index->getConstPointer();
+  std::set<INTERP_KERNEL::NormalizedCellType> types;
+  std::vector<int> isChanged;
+  for(int i=0;i<nbOfCells;i++,workIndexOut++)
+    {
+      std::size_t pos=nodalConnecOut.size();
+      if(BuildConvexEnvelopOf2DCellJarvis(coords,nodalConnecIn+nodalConnecIndexIn[i],nodalConnecIn+nodalConnecIndexIn[i+1],nodalConnecOut))
+        isChanged.push_back(i);
+      types.insert((INTERP_KERNEL::NormalizedCellType)nodalConnecOut[pos]);
+      workIndexOut[1]=(int)nodalConnecOut.size();
+    }
+  if(isChanged.empty())
+    return 0;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodalConnecOut2=DataArrayInt::New();
+  nodalConnecOut2->alloc((int)nodalConnecOut.size(),1);
+  std::copy(nodalConnecOut.begin(),nodalConnecOut.end(),nodalConnecOut2->getPointer());
+  setConnectivity(nodalConnecOut2,nodalConnecIndexOut,false);
+  _types=types;
+  DataArrayInt *ret=DataArrayInt::New(); ret->alloc((int)isChanged.size(),1);
+  std::copy(isChanged.begin(),isChanged.end(),ret->getPointer());
+  return ret;
+}
+
+/*!
+ * This method is expected to be applied on a mesh with spaceDim==3 and meshDim==3. If not an exception will be thrown.
+ * This method analyzes only linear extruded 3D cells (NORM_HEXA8,NORM_PENTA6,NORM_HEXGP12...)
+ * If some extruded cells does not fulfill the MED norm for extruded cells (first face of 3D cell should be oriented to the exterior of the 3D cell).
+ * Some viewers are very careful of that (SMESH), but ParaVis ignore that.
+ */
+void MEDCouplingUMesh::findAndCorrectBadOriented3DExtrudedCells(std::vector<int>& cells) throw(INTERP_KERNEL::Exception)
+{
+  const char msg[]="check3DCellsWellOriented detection works only for 3D cells !";
+  if(getMeshDimension()!=3)
+    throw INTERP_KERNEL::Exception(msg);
+  int spaceDim=getSpaceDimension();
+  if(spaceDim!=3)
+    throw INTERP_KERNEL::Exception(msg);
+  //
+  int nbOfCells=getNumberOfCells();
+  int *conn=_nodal_connec->getPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  const double *coo=getCoords()->getConstPointer();
+  double vec0[3],vec1[3];
+  for(int i=0;i<nbOfCells;i++)
+    {
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]);
+      if(cm.isExtruded() && !cm.isDynamic() && !cm.isQuadratic())
+        {
+          INTERP_KERNEL::AutoPtr<int> tmp=new int[connI[i+1]-connI[i]-1];
+          int nbOfNodes=cm.fillSonCellNodalConnectivity(0,conn+connI[i]+1,tmp);
+          INTERP_KERNEL::areaVectorOfPolygon<int,INTERP_KERNEL::ALL_C_MODE>(tmp,nbOfNodes,coo,vec0);
+          const double *pt0=coo+3*conn[connI[i]+1];
+          const double *pt1=coo+3*conn[connI[i]+nbOfNodes+1];
+          vec1[0]=pt0[0]-pt1[0]; vec1[1]=pt0[1]-pt1[1]; vec1[2]=pt0[2]-pt1[2];
+          double dot=vec0[0]*vec1[0]+vec0[1]*vec1[1]+vec0[2]*vec1[2];
+          if(dot<0)
+            {
+              cells.push_back(i);
+              std::copy(conn+connI[i]+1,conn+connI[i+1],(int *)tmp);
+              for(int j=1;j<nbOfNodes;j++)
+                {
+                  conn[connI[i]+1+j]=tmp[nbOfNodes-j];
+                  conn[connI[i]+1+j+nbOfNodes]=tmp[nbOfNodes+nbOfNodes-j];
+                }
+            }
+        }
+    }
+}
+
+/*!
+ * This method is \b NOT const because it can modify 'this'.
+ * 'this' is expected to be an unstructured mesh with meshDim==2 and spaceDim==3. If not an exception will be thrown.
+ * @param mesh1D is an unstructured mesh with MeshDim==1 and spaceDim==3. If not an exception will be thrown.
+ * @param policy specifies the type of extrusion chosen. \b 0 for translation (most simple),
+ * \b 1 for translation and rotation around point of 'mesh1D'.
+ * @return an unstructured mesh with meshDim==3 and spaceDim==3. The returned mesh has the same coords than 'this'.  
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::buildExtrudedMesh(const MEDCouplingUMesh *mesh1D, int policy)
+{
+  checkFullyDefined();
+  mesh1D->checkFullyDefined();
+  if(!mesh1D->isContiguous1D())
+    throw INTERP_KERNEL::Exception("buildExtrudedMesh : 1D mesh passed in parameter is not contiguous !");
+  if(getSpaceDimension()!=mesh1D->getSpaceDimension())
+    throw INTERP_KERNEL::Exception("Invalid call to buildExtrudedMesh this and mesh1D must have same dimension !");
+  if((getMeshDimension()!=2 || getSpaceDimension()!=3) && (getMeshDimension()!=1 || getSpaceDimension()!=2))
+    throw INTERP_KERNEL::Exception("Invalid 'this' for buildExtrudedMesh method : must be (meshDim==2 and spaceDim==3) or (meshDim==1 and spaceDim==2) !");
+  if(mesh1D->getMeshDimension()!=1)
+    throw INTERP_KERNEL::Exception("Invalid 'mesh1D' for buildExtrudedMesh method : must be meshDim==1 !");
+  bool isQuad=false;
+  if(isPresenceOfQuadratic())
+    {
+      if(mesh1D->isFullyQuadratic())
+        isQuad=true;
+      else
+        throw INTERP_KERNEL::Exception("Invalid 2D mesh and 1D mesh because 2D mesh has quadratic cells and 1D is not fully quadratic !");
+    }
+  zipCoords();
+  int oldNbOfNodes=getNumberOfNodes();
+  DataArrayDouble *newCoords=0;
+  switch(policy)
+    {
+    case 0:
+      {
+        newCoords=fillExtCoordsUsingTranslation(mesh1D,isQuad);
+        break;
+      }
+    case 1:
+      {
+        newCoords=fillExtCoordsUsingTranslAndAutoRotation(mesh1D,isQuad);
+        break;
+      }
+    default:
+      throw INTERP_KERNEL::Exception("Not implemented extrusion policy : must be in (0) !");
+    }
+  setCoords(newCoords);
+  newCoords->decrRef();
+  MEDCouplingUMesh *ret=buildExtrudedMeshFromThisLowLev(oldNbOfNodes,isQuad);
+  updateTime();
+  return ret;
+}
+
+/*!
+ * This method works on a 3D curve linear mesh that is to say (meshDim==1 and spaceDim==3).
+ * If it is not the case an exception will be thrown.
+ * This method is non const because the coordinate of 'this' can be appended with some new points issued from
+ * intersection of plane defined by ('origin','vec').
+ * This method has one in/out parameter : 'cut3DCurve'.
+ * Param 'cut3DCurve' is expected to be of size 'this->getNumberOfCells()'. For each i in [0,'this->getNumberOfCells()')
+ * if cut3DCurve[i]==-2, it means that for cell #i in 'this' nothing has been detected previously.
+ * if cut3DCurve[i]==-1, it means that cell#i has been already detected to be fully part of plane defined by ('origin','vec').
+ * This method will throw an exception if 'this' contains a non linear segment.
+ */
+void MEDCouplingUMesh::split3DCurveWithPlane(const double *origin, const double *vec, double eps, std::vector<int>& cut3DCurve) throw(INTERP_KERNEL::Exception)
+{
+  checkFullyDefined();
+  if(getMeshDimension()!=1 || getSpaceDimension()!=3)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split3DCurveWithPlane works on umeshes with meshdim equal to 1 and spaceDim equal to 3 !");
+  int ncells=getNumberOfCells();
+  int nnodes=getNumberOfNodes();
+  double vec2[3],vec3[3],vec4[3];
+  double normm=sqrt(vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]);
+  if(normm<1e-6)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split3DCurveWithPlane : parameter 'vec' should have a norm2 greater than 1e-6 !");
+  vec2[0]=vec[0]/normm; vec2[1]=vec[1]/normm; vec2[2]=vec[2]/normm;
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  const double *coo=_coords->getConstPointer();
+  std::vector<double> addCoo;
+  for(int i=0;i<ncells;i++)
+    {
+      if(conn[connI[i]]==(int)INTERP_KERNEL::NORM_SEG2)
+        {
+          if(cut3DCurve[i]==-2)
+            {
+              int st=conn[connI[i]+1],endd=conn[connI[i]+2];
+              vec3[0]=coo[3*endd]-coo[3*st]; vec3[1]=coo[3*endd+1]-coo[3*st+1]; vec3[2]=coo[3*endd+2]-coo[3*st+2];
+              double normm2=sqrt(vec3[0]*vec3[0]+vec3[1]*vec3[1]+vec3[2]*vec3[2]);
+              double colin=std::abs((vec3[0]*vec2[0]+vec3[1]*vec2[1]+vec3[2]*vec2[2])/normm2);
+              if(colin>eps)//if colin<=eps -> current SEG2 is colinear to the input plane
+                {
+                  const double *st2=coo+3*st;
+                  vec4[0]=st2[0]-origin[0]; vec4[1]=st2[1]-origin[1]; vec4[2]=st2[2]-origin[2];
+                  double pos=-(vec4[0]*vec2[0]+vec4[1]*vec2[1]+vec4[2]*vec2[2])/((vec3[0]*vec2[0]+vec3[1]*vec2[1]+vec3[2]*vec2[2]));
+                  if(pos>eps && pos<1-eps)
+                    {
+                      int nNode=((int)addCoo.size())/3;
+                      vec4[0]=st2[0]+pos*vec3[0]; vec4[1]=st2[1]+pos*vec3[1]; vec4[2]=st2[2]+pos*vec3[2];
+                      addCoo.insert(addCoo.end(),vec4,vec4+3);
+                      cut3DCurve[i]=nnodes+nNode;
+                    }
+                }
+            }
+        }
+      else
+        throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split3DCurveWithPlane : this method is only available for linear cell (NORM_SEG2) !");
+    }
+  if(!addCoo.empty())
+    {
+      int newNbOfNodes=nnodes+((int)addCoo.size())/3;
+      MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coo2=DataArrayDouble::New();
+      coo2->alloc(newNbOfNodes,3);
+      double *tmp=coo2->getPointer();
+      tmp=std::copy(_coords->begin(),_coords->end(),tmp);
+      std::copy(addCoo.begin(),addCoo.end(),tmp);
+      DataArrayDouble::SetArrayIn(coo2,_coords);
+    }
+}
+
+/*!
+ * This method incarnates the policy 0 for MEDCouplingUMesh::buildExtrudedMesh method.
+ * @param mesh1D is the input 1D mesh used for translation computation.
+ * @return newCoords new coords filled by this method. 
+ */
+DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslation(const MEDCouplingUMesh *mesh1D, bool isQuad) const
+{
+  int oldNbOfNodes=getNumberOfNodes();
+  int nbOf1DCells=mesh1D->getNumberOfCells();
+  int spaceDim=getSpaceDimension();
+  DataArrayDouble *ret=DataArrayDouble::New();
+  std::vector<bool> isQuads;
+  int nbOfLevsInVec=isQuad?2*nbOf1DCells+1:nbOf1DCells+1;
+  ret->alloc(oldNbOfNodes*nbOfLevsInVec,spaceDim);
+  double *retPtr=ret->getPointer();
+  const double *coords=getCoords()->getConstPointer();
+  double *work=std::copy(coords,coords+spaceDim*oldNbOfNodes,retPtr);
+  std::vector<int> v;
+  std::vector<double> c;
+  double vec[3];
+  v.reserve(3);
+  c.reserve(6);
+  for(int i=0;i<nbOf1DCells;i++)
+    {
+      v.resize(0);
+      mesh1D->getNodeIdsOfCell(i,v);
+      c.resize(0);
+      mesh1D->getCoordinatesOfNode(v[isQuad?2:1],c);
+      mesh1D->getCoordinatesOfNode(v[0],c);
+      std::transform(c.begin(),c.begin()+spaceDim,c.begin()+spaceDim,vec,std::minus<double>());
+      for(int j=0;j<oldNbOfNodes;j++)
+        work=std::transform(vec,vec+spaceDim,retPtr+spaceDim*(i*oldNbOfNodes+j),work,std::plus<double>());
+      if(isQuad)
+        {
+          c.resize(0);
+          mesh1D->getCoordinatesOfNode(v[1],c);
+          mesh1D->getCoordinatesOfNode(v[0],c);
+          std::transform(c.begin(),c.begin()+spaceDim,c.begin()+spaceDim,vec,std::minus<double>());
+          for(int j=0;j<oldNbOfNodes;j++)
+            work=std::transform(vec,vec+spaceDim,retPtr+spaceDim*(i*oldNbOfNodes+j),work,std::plus<double>());
+        }
+    }
+  ret->copyStringInfoFrom(*getCoords());
+  return ret;
+}
+
+/*!
+ * This method incarnates the policy 1 for MEDCouplingUMesh::buildExtrudedMesh method.
+ * @param mesh1D is the input 1D mesh used for translation and automatic rotation computation.
+ * @return newCoords new coords filled by this method. 
+ */
+DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation(const MEDCouplingUMesh *mesh1D, bool isQuad) const throw(INTERP_KERNEL::Exception)
+{
+  if(mesh1D->getSpaceDimension()==2)
+    return fillExtCoordsUsingTranslAndAutoRotation2D(mesh1D,isQuad);
+  if(mesh1D->getSpaceDimension()==3)
+    return fillExtCoordsUsingTranslAndAutoRotation3D(mesh1D,isQuad);
+  throw INTERP_KERNEL::Exception("Not implemented rotation and translation alg. for spacedim other than 2 and 3 !");
+}
+
+/*!
+ * This method incarnates the policy 1 for MEDCouplingUMesh::buildExtrudedMesh method.
+ * @param mesh1D is the input 1D mesh used for translation and automatic rotation computation.
+ * @return newCoords new coords filled by this method. 
+ */
+DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation2D(const MEDCouplingUMesh *mesh1D, bool isQuad) const throw(INTERP_KERNEL::Exception)
+{
+  if(isQuad)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation2D : not implemented for quadratic cells !");
+  int oldNbOfNodes=getNumberOfNodes();
+  int nbOf1DCells=mesh1D->getNumberOfCells();
+  if(nbOf1DCells<2)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation2D : impossible to detect any angle of rotation ! Change extrusion policy 1->0 !");
+  DataArrayDouble *ret=DataArrayDouble::New();
+  int nbOfLevsInVec=nbOf1DCells+1;
+  ret->alloc(oldNbOfNodes*nbOfLevsInVec,2);
+  double *retPtr=ret->getPointer();
+  retPtr=std::copy(getCoords()->getConstPointer(),getCoords()->getConstPointer()+getCoords()->getNbOfElems(),retPtr);
+  MEDCouplingUMesh *tmp=MEDCouplingUMesh::New();
+  DataArrayDouble *tmp2=getCoords()->deepCpy();
+  tmp->setCoords(tmp2);
+  tmp2->decrRef();
+  const double *coo1D=mesh1D->getCoords()->getConstPointer();
+  const int *conn1D=mesh1D->getNodalConnectivity()->getConstPointer();
+  const int *connI1D=mesh1D->getNodalConnectivityIndex()->getConstPointer();
+  for(int i=1;i<nbOfLevsInVec;i++)
+    {
+      const double *begin=coo1D+2*conn1D[connI1D[i-1]+1];
+      const double *end=coo1D+2*conn1D[connI1D[i-1]+2];
+      const double *third=i+1<nbOfLevsInVec?coo1D+2*conn1D[connI1D[i]+2]:coo1D+2*conn1D[connI1D[i-2]+1];
+      const double vec[2]={end[0]-begin[0],end[1]-begin[1]};
+      tmp->translate(vec);
+      double tmp3[2],radius,alpha,alpha0;
+      const double *p0=i+1<nbOfLevsInVec?begin:third;
+      const double *p1=i+1<nbOfLevsInVec?end:begin;
+      const double *p2=i+1<nbOfLevsInVec?third:end;
+      INTERP_KERNEL::EdgeArcCircle::GetArcOfCirclePassingThru(p0,p1,p2,tmp3,radius,alpha,alpha0);
+      double cosangle=i+1<nbOfLevsInVec?(p0[0]-tmp3[0])*(p1[0]-tmp3[0])+(p0[1]-tmp3[1])*(p1[1]-tmp3[1]):(p2[0]-tmp3[0])*(p1[0]-tmp3[0])+(p2[1]-tmp3[1])*(p1[1]-tmp3[1]);
+      double angle=acos(cosangle/(radius*radius));
+      tmp->rotate(end,0,angle);
+      retPtr=std::copy(tmp2->getConstPointer(),tmp2->getConstPointer()+tmp2->getNbOfElems(),retPtr);
+    }
+  tmp->decrRef();
+  return ret;
+}
+
+/*!
+ * This method incarnates the policy 1 for MEDCouplingUMesh::buildExtrudedMesh method.
+ * @param mesh1D is the input 1D mesh used for translation and automatic rotation computation.
+ * @return newCoords new coords filled by this method. 
+ */
+DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation3D(const MEDCouplingUMesh *mesh1D, bool isQuad) const throw(INTERP_KERNEL::Exception)
+{
+  if(isQuad)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation3D : not implemented for quadratic cells !");
+  int oldNbOfNodes=getNumberOfNodes();
+  int nbOf1DCells=mesh1D->getNumberOfCells();
+  if(nbOf1DCells<2)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation3D : impossible to detect any angle of rotation ! Change extrusion policy 1->0 !");
+  DataArrayDouble *ret=DataArrayDouble::New();
+  int nbOfLevsInVec=nbOf1DCells+1;
+  ret->alloc(oldNbOfNodes*nbOfLevsInVec,3);
+  double *retPtr=ret->getPointer();
+  retPtr=std::copy(getCoords()->getConstPointer(),getCoords()->getConstPointer()+getCoords()->getNbOfElems(),retPtr);
+  MEDCouplingUMesh *tmp=MEDCouplingUMesh::New();
+  DataArrayDouble *tmp2=getCoords()->deepCpy();
+  tmp->setCoords(tmp2);
+  tmp2->decrRef();
+  const double *coo1D=mesh1D->getCoords()->getConstPointer();
+  const int *conn1D=mesh1D->getNodalConnectivity()->getConstPointer();
+  const int *connI1D=mesh1D->getNodalConnectivityIndex()->getConstPointer();
+  for(int i=1;i<nbOfLevsInVec;i++)
+    {
+      const double *begin=coo1D+3*conn1D[connI1D[i-1]+1];
+      const double *end=coo1D+3*conn1D[connI1D[i-1]+2];
+      const double *third=i+1<nbOfLevsInVec?coo1D+3*conn1D[connI1D[i]+2]:coo1D+3*conn1D[connI1D[i-2]+1];
+      const double vec[3]={end[0]-begin[0],end[1]-begin[1],end[2]-begin[2]};
+      tmp->translate(vec);
+      double tmp3[2],radius,alpha,alpha0;
+      const double *p0=i+1<nbOfLevsInVec?begin:third;
+      const double *p1=i+1<nbOfLevsInVec?end:begin;
+      const double *p2=i+1<nbOfLevsInVec?third:end;
+      double vecPlane[3]={
+        (p1[1]-p0[1])*(p2[2]-p1[2])-(p1[2]-p0[2])*(p2[1]-p1[1]),
+        (p1[2]-p0[2])*(p2[0]-p1[0])-(p1[0]-p0[0])*(p2[2]-p1[2]),
+        (p1[0]-p0[0])*(p2[1]-p1[1])-(p1[1]-p0[1])*(p2[0]-p1[0]),
+      };
+      double norm=sqrt(vecPlane[0]*vecPlane[0]+vecPlane[1]*vecPlane[1]+vecPlane[2]*vecPlane[2]);
+      if(norm>1.e-7)
+        {
+          vecPlane[0]/=norm; vecPlane[1]/=norm; vecPlane[2]/=norm;
+          double norm2=sqrt(vecPlane[0]*vecPlane[0]+vecPlane[1]*vecPlane[1]);
+          double vec2[2]={vecPlane[1]/norm2,-vecPlane[0]/norm2};
+          double s2=norm2;
+          double c2=cos(asin(s2));
+          double m[3][3]={
+            {vec2[0]*vec2[0]*(1-c2)+c2, vec2[0]*vec2[1]*(1-c2), vec2[1]*s2},
+            {vec2[0]*vec2[1]*(1-c2), vec2[1]*vec2[1]*(1-c2)+c2, -vec2[0]*s2},
+            {-vec2[1]*s2, vec2[0]*s2, c2}
+          };
+          double p0r[3]={m[0][0]*p0[0]+m[0][1]*p0[1]+m[0][2]*p0[2], m[1][0]*p0[0]+m[1][1]*p0[1]+m[1][2]*p0[2], m[2][0]*p0[0]+m[2][1]*p0[1]+m[2][2]*p0[2]};
+          double p1r[3]={m[0][0]*p1[0]+m[0][1]*p1[1]+m[0][2]*p1[2], m[1][0]*p1[0]+m[1][1]*p1[1]+m[1][2]*p1[2], m[2][0]*p1[0]+m[2][1]*p1[1]+m[2][2]*p1[2]};
+          double p2r[3]={m[0][0]*p2[0]+m[0][1]*p2[1]+m[0][2]*p2[2], m[1][0]*p2[0]+m[1][1]*p2[1]+m[1][2]*p2[2], m[2][0]*p2[0]+m[2][1]*p2[1]+m[2][2]*p2[2]};
+          INTERP_KERNEL::EdgeArcCircle::GetArcOfCirclePassingThru(p0r,p1r,p2r,tmp3,radius,alpha,alpha0);
+          double cosangle=i+1<nbOfLevsInVec?(p0r[0]-tmp3[0])*(p1r[0]-tmp3[0])+(p0r[1]-tmp3[1])*(p1r[1]-tmp3[1]):(p2r[0]-tmp3[0])*(p1r[0]-tmp3[0])+(p2r[1]-tmp3[1])*(p1r[1]-tmp3[1]);
+          double angle=acos(cosangle/(radius*radius));
+          tmp->rotate(end,vecPlane,angle);
+          
+        }
+      retPtr=std::copy(tmp2->getConstPointer(),tmp2->getConstPointer()+tmp2->getNbOfElems(),retPtr);
+    }
+  tmp->decrRef();
+  return ret;
+}
+
+/*!
+ * This method is private because not easy to use for end user. This method is const contrary to
+ * MEDCouplingUMesh::buildExtrudedMesh method because this->_coords are expected to contain
+ * the coords sorted slice by slice.
+ * @param isQuad specifies presence of quadratic cells.
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::buildExtrudedMeshFromThisLowLev(int nbOfNodesOf1Lev, bool isQuad) const
+{
+  int nbOf1DCells=getNumberOfNodes()/nbOfNodesOf1Lev-1;
+  int nbOf2DCells=getNumberOfCells();
+  int nbOf3DCells=nbOf2DCells*nbOf1DCells;
+  MEDCouplingUMesh *ret=MEDCouplingUMesh::New("Extruded",getMeshDimension()+1);
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  DataArrayInt *newConn=DataArrayInt::New();
+  DataArrayInt *newConnI=DataArrayInt::New();
+  newConnI->alloc(nbOf3DCells+1,1);
+  int *newConnIPtr=newConnI->getPointer();
+  *newConnIPtr++=0;
+  std::vector<int> newc;
+  for(int j=0;j<nbOf2DCells;j++)
+    {
+      AppendExtrudedCell(conn+connI[j],conn+connI[j+1],nbOfNodesOf1Lev,isQuad,newc);
+      *newConnIPtr++=(int)newc.size();
+    }
+  newConn->alloc((int)(newc.size())*nbOf1DCells,1);
+  int *newConnPtr=newConn->getPointer();
+  int deltaPerLev=isQuad?2*nbOfNodesOf1Lev:nbOfNodesOf1Lev;
+  newConnIPtr=newConnI->getPointer();
+  for(int iz=0;iz<nbOf1DCells;iz++)
+    {
+      if(iz!=0)
+        std::transform(newConnIPtr+1,newConnIPtr+1+nbOf2DCells,newConnIPtr+1+iz*nbOf2DCells,std::bind2nd(std::plus<int>(),newConnIPtr[iz*nbOf2DCells]));
+      for(std::vector<int>::const_iterator iter=newc.begin();iter!=newc.end();iter++,newConnPtr++)
+        {
+          int icell=(int)(iter-newc.begin());
+          if(std::find(newConnIPtr,newConnIPtr+nbOf2DCells,icell)==newConnIPtr+nbOf2DCells)
+            {
+              if(*iter!=-1)
+                *newConnPtr=(*iter)+iz*deltaPerLev;
+              else
+                *newConnPtr=-1;
+            }
+          else
+            *newConnPtr=(*iter);
+        }
+    }
+  ret->setConnectivity(newConn,newConnI,true);
+  newConn->decrRef();
+  newConnI->decrRef();
+  ret->setCoords(getCoords());
+  return ret;
+}
+
+/*!
+ * This method returns if 'this' is constituted by only quadratic cells.
+ */
+bool MEDCouplingUMesh::isFullyQuadratic() const
+{
+  checkFullyDefined();
+  bool ret=true;
+  int nbOfCells=getNumberOfCells();
+  for(int i=0;i<nbOfCells && ret;i++)
+    {
+      INTERP_KERNEL::NormalizedCellType type=getTypeOfCell(i);
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
+      ret=cm.isQuadratic();
+    }
+  return ret;
+}
+
+/*!
+ * This method returns if there is at least one quadratic cell.
+ */
+bool MEDCouplingUMesh::isPresenceOfQuadratic() const
+{
+  checkFullyDefined();
+  bool ret=false;
+  int nbOfCells=getNumberOfCells();
+  for(int i=0;i<nbOfCells && !ret;i++)
+    {
+      INTERP_KERNEL::NormalizedCellType type=getTypeOfCell(i);
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
+      ret=cm.isQuadratic();
+    }
+  return ret;
+}
+
+/*!
+ * This method convert quadratic cells to linear cells if any was found.
+ * If no such cells exists 'this' remains unchanged.
+ */
+void MEDCouplingUMesh::convertQuadraticCellsToLinear() throw(INTERP_KERNEL::Exception)
+{
+  checkFullyDefined();
+  int nbOfCells=getNumberOfCells();
+  int delta=0;
+  for(int i=0;i<nbOfCells;i++)
+    {
+      INTERP_KERNEL::NormalizedCellType type=getTypeOfCell(i);
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
+      if(cm.isQuadratic())
+        {
+          INTERP_KERNEL::NormalizedCellType typel=cm.getLinearType();
+          const INTERP_KERNEL::CellModel& cml=INTERP_KERNEL::CellModel::GetCellModel(typel);
+          delta+=cm.getNumberOfNodes()-cml.getNumberOfNodes();
+        }
+    }
+  if(delta==0)
+    return ;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
+  newConn->alloc(getMeshLength()-delta,1);
+  newConnI->alloc(nbOfCells+1,1);
+  const int *icptr=_nodal_connec->getConstPointer();
+  const int *iciptr=_nodal_connec_index->getConstPointer();
+  int *ocptr=newConn->getPointer();
+  int *ociptr=newConnI->getPointer();
+  *ociptr=0;
+  _types.clear();
+  for(int i=0;i<nbOfCells;i++,ociptr++)
+    {
+      INTERP_KERNEL::NormalizedCellType type=getTypeOfCell(i);
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type);
+      if(!cm.isQuadratic())
+        {
+          _types.insert(type);
+          ocptr=std::copy(icptr+iciptr[i],icptr+iciptr[i+1],ocptr);
+          ociptr[1]=ociptr[0]+iciptr[i+1]-iciptr[i];
+        }
+      else
+        {
+          INTERP_KERNEL::NormalizedCellType typel=cm.getLinearType();
+          _types.insert(typel);
+          const INTERP_KERNEL::CellModel& cml=INTERP_KERNEL::CellModel::GetCellModel(typel);
+          int newNbOfNodes=cml.getNumberOfNodes();
+          *ocptr++=(int)typel;
+          ocptr=std::copy(icptr+iciptr[i]+1,icptr+iciptr[i]+newNbOfNodes+1,ocptr);
+          ociptr[1]=ociptr[0]+newNbOfNodes+1;
+        }
+    }
+  setConnectivity(newConn,newConnI,false);
+}
+
+/*!
+ * This method tessallates 'this' so that the number of cells remains the same.
+ * This method works only for meshes with spaceDim equal to 2 and meshDim equal to 2.
+ * If no cells are quadratic in 'this' (INTERP_KERNEL::NORM_QUAD8, INTERP_KERNEL::NORM_TRI6, INTERP_KERNEL::NORM_QPOLYG ) this method will remain unchanged.
+ * 
+ * \b WARNING this method can lead to a uge amount of nodes if eps is very low.
+ * @param eps specifies the maximal angle (in radian) between 2 subedges of polylinized edge constituting the input polygon.
+ */
+void MEDCouplingUMesh::tessellate2D(double eps) throw(INTERP_KERNEL::Exception)
+{
+  checkFullyDefined();
+  if(getMeshDimension()!=2 || getSpaceDimension()!=2)  
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2D works on umeshes with meshdim equal to 2 and spaceDim equal to 2 too!");
+  double epsa=fabs(eps);
+  if(epsa<std::numeric_limits<double>::min())
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DCurve : epsilon is null ! Please specify a higher epsilon. If too tiny it can lead to a huge amount of nodes and memory !");
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc1=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descIndx1=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDesc1=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDescIndx1=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mDesc=buildDescendingConnectivity2(desc1,descIndx1,revDesc1,revDescIndx1);
+  revDesc1=0; revDescIndx1=0;
+  mDesc->tessellate2DCurve(eps);
+  subDivide2DMesh(mDesc->_nodal_connec->getConstPointer(),mDesc->_nodal_connec_index->getConstPointer(),desc1->getConstPointer(),descIndx1->getConstPointer());
+  setCoords(mDesc->getCoords());
+}
+
+/*!
+ * This method tessallates 'this' so that the number of cells remains the same.
+ * This method works only for meshes with spaceDim equal to 2 and meshDim equal to 1.
+ * If no cells are quadratic in 'this' (INTERP_KERNEL::NORM_QUAD8, INTERP_KERNEL::NORM_TRI6, INTERP_KERNEL::NORM_QPOLYG ) this method will remain unchanged.
+ * 
+ * \b WARNING this method can lead to a uge amount of nodes if eps is very low.
+ * @param eps specifies the maximal angle (in radian) between 2 subedges of polylinized edge constituting the input polygon.
+ */
+void MEDCouplingUMesh::tessellate2DCurve(double eps) throw(INTERP_KERNEL::Exception)
+{
+  checkFullyDefined();
+  if(getMeshDimension()!=1 || getSpaceDimension()!=2)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DCurve works on umeshes with meshdim equal to 1 and spaceDim equal to 2 too!");
+  double epsa=fabs(eps);
+  if(epsa<std::numeric_limits<double>::min())
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DCurve : epsilon is null ! Please specify a higher epsilon. If too tiny it can lead to a huge amount of nodes and memory !");
+  INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=1.e-10;
+  int nbCells=getNumberOfCells();
+  int nbNodes=getNumberOfNodes();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  const double *coords=_coords->getConstPointer();
+  std::vector<double> addCoo;
+  std::vector<int> newConn;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New();
+  newConnI->alloc(nbCells+1,1);
+  int *newConnIPtr=newConnI->getPointer();
+  *newConnIPtr=0;
+  int tmp1[3];
+  INTERP_KERNEL::Node *tmp2[3];
+  std::set<INTERP_KERNEL::NormalizedCellType> types;
+  for(int i=0;i<nbCells;i++,newConnIPtr++)
+    {
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]);
+      if(cm.isQuadratic())
+        {//assert(connI[i+1]-connI[i]-1==3)
+          tmp1[0]=conn[connI[i]+1+0]; tmp1[1]=conn[connI[i]+1+1]; tmp1[2]=conn[connI[i]+1+2];
+          tmp2[0]=new INTERP_KERNEL::Node(coords[2*tmp1[0]],coords[2*tmp1[0]+1]);
+          tmp2[1]=new INTERP_KERNEL::Node(coords[2*tmp1[1]],coords[2*tmp1[1]+1]);
+          tmp2[2]=new INTERP_KERNEL::Node(coords[2*tmp1[2]],coords[2*tmp1[2]+1]);
+          INTERP_KERNEL::EdgeArcCircle *eac=INTERP_KERNEL::EdgeArcCircle::BuildFromNodes(tmp2[0],tmp2[2],tmp2[1]);
+          if(eac)
+            {
+              eac->tesselate(tmp1,nbNodes,epsa,newConn,addCoo);
+              types.insert((INTERP_KERNEL::NormalizedCellType)newConn[newConnIPtr[0]]);
+              delete eac;
+              newConnIPtr[1]=(int)newConn.size();
+            }
+          else
+            {
+              types.insert(INTERP_KERNEL::NORM_SEG2);
+              newConn.push_back(INTERP_KERNEL::NORM_SEG2);
+              newConn.insert(newConn.end(),conn+connI[i]+1,conn+connI[i]+3);
+              newConnIPtr[1]=newConnIPtr[0]+3;
+            }
+        }
+      else
+        {
+          types.insert((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]);
+          newConn.insert(newConn.end(),conn+connI[i],conn+connI[i+1]);
+          newConnIPtr[1]=newConnIPtr[0]+3;
+        }
+    }
+  if(addCoo.empty() && ((int)newConn.size())==_nodal_connec->getNumberOfTuples())//nothing happens during tasselation : no update needed
+    return ;
+  _types=types;
+  DataArrayInt::SetArrayIn(newConnI,_nodal_connec_index);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnArr=DataArrayInt::New();
+  newConnArr->alloc((int)newConn.size(),1);
+  std::copy(newConn.begin(),newConn.end(),newConnArr->getPointer());
+  DataArrayInt::SetArrayIn(newConnArr,_nodal_connec);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=DataArrayDouble::New();
+  newCoords->alloc(nbNodes+((int)addCoo.size())/2,2);
+  double *work=std::copy(_coords->begin(),_coords->end(),newCoords->getPointer());
+  std::copy(addCoo.begin(),addCoo.end(),work);
+  DataArrayDouble::SetArrayIn(newCoords,_coords);
+  updateTime();
+}
+
+/*!
+ * This methods modify this by converting each cells into simplex cell, that is too say triangle for meshdim==2 or tetra for meshdim==3.
+ * This cut into simplex is performed following the parameter 'policy'. This method so typically increases the number of cells of this.
+ * This method returns new2old array that specifies a each cell of 'this' after the call what was its id it comes.
+ * 
+ * The semantic of 'policy' parameter :
+ * - 1 only QUAD4. For QUAD4 the cut is done along 0-2 diagonal for QUAD4
+ * - 2 only QUAD4. For QUAD4 the cut is done along 1-3 diagonal for QUAD4
+ */
+DataArrayInt *MEDCouplingUMesh::simplexize(int policy) throw(INTERP_KERNEL::Exception)
+{
+  switch(policy)
+    {
+    case 0:
+      return simplexizePol0();
+    case 1:
+      return simplexizePol1();
+    default:
+      throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexize : unrecognized policy ! Must be 0 or 1 !");
+    }
+}
+
+bool MEDCouplingUMesh::areOnlySimplexCells() const throw(INTERP_KERNEL::Exception)
+{
+  checkFullyDefined();
+  if(getMeshDimension()<1)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::areOnlySimplexCells : only available with meshes having a meshdim >= 1 !");
+  int nbCells=getNumberOfCells();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  for(int i=0;i<nbCells;i++)
+    {
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]);
+      if(!cm.isSimplex())
+        return false;
+    }
+  return true;
+}
+
+/*!
+ * This method implements policy 0 of virtual method ParaMEDMEM::MEDCouplingUMesh::simplexize.
+ */
+DataArrayInt *MEDCouplingUMesh::simplexizePol0() throw(INTERP_KERNEL::Exception)
+{
+  if(getMeshDimension()!=2)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePol0 : this policy is only available for mesh with meshdim == 2 !");
+  int nbOfCells=getNumberOfCells();
+  DataArrayInt *ret=DataArrayInt::New();
+  int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD4);
+  ret->alloc(nbOfCells+nbOfCutCells,1);
+  if(nbOfCutCells==0)
+    {
+      ret->iota(0);
+      return ret;
+    }
+  int *retPt=ret->getPointer();
+  DataArrayInt *newConn=DataArrayInt::New();
+  DataArrayInt *newConnI=DataArrayInt::New();
+  newConnI->alloc(nbOfCells+nbOfCutCells+1,1);
+  newConn->alloc(getMeshLength()+3*nbOfCutCells,1);
+  int *pt=newConn->getPointer();
+  int *ptI=newConnI->getPointer();
+  ptI[0]=0;
+  const int *oldc=_nodal_connec->getConstPointer();
+  const int *ci=_nodal_connec_index->getConstPointer();
+  for(int i=0;i<nbOfCells;i++,ci++)
+    {
+      if((INTERP_KERNEL::NormalizedCellType)oldc[ci[0]]==INTERP_KERNEL::NORM_QUAD4)
+        {
+          const int tmp[8]={(int)INTERP_KERNEL::NORM_TRI3,oldc[ci[0]+1],oldc[ci[0]+2],oldc[ci[0]+3],
+                            (int)INTERP_KERNEL::NORM_TRI3,oldc[ci[0]+1],oldc[ci[0]+3],oldc[ci[0]+4]};
+          pt=std::copy(tmp,tmp+8,pt);
+          ptI[1]=ptI[0]+4;
+          ptI[2]=ptI[0]+8;
+          *retPt++=i;
+          *retPt++=i;
+          ptI+=2;
+        }
+      else
+        {
+          pt=std::copy(oldc+ci[0],oldc+ci[1],pt);
+          ptI[1]=ptI[0]+ci[1]-ci[0];
+          ptI++;
+          *retPt++=i;
+        }
+    }
+  _nodal_connec->decrRef();
+  _nodal_connec=newConn;
+  _nodal_connec_index->decrRef();
+  _nodal_connec_index=newConnI;
+  computeTypes();
+  updateTime();
+  return ret;
+}
+
+/*!
+ * This method implements policy 1 of virtual method ParaMEDMEM::MEDCouplingUMesh::simplexize.
+ */
+DataArrayInt *MEDCouplingUMesh::simplexizePol1() throw(INTERP_KERNEL::Exception)
+{
+  if(getMeshDimension()!=2)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePol0 : this policy is only available for mesh with meshdim == 2 !");
+  int nbOfCells=getNumberOfCells();
+  DataArrayInt *ret=DataArrayInt::New();
+  int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD4);
+  ret->alloc(nbOfCells+nbOfCutCells,1);
+  if(nbOfCutCells==0)
+    {
+      ret->iota(0);
+      return ret;
+    }
+  int *retPt=ret->getPointer();
+  DataArrayInt *newConn=DataArrayInt::New();
+  DataArrayInt *newConnI=DataArrayInt::New();
+  newConnI->alloc(nbOfCells+nbOfCutCells+1,1);
+  newConn->alloc(getMeshLength()+3*nbOfCutCells,1);
+  int *pt=newConn->getPointer();
+  int *ptI=newConnI->getPointer();
+  ptI[0]=0;
+  const int *oldc=_nodal_connec->getConstPointer();
+  const int *ci=_nodal_connec_index->getConstPointer();
+  for(int i=0;i<nbOfCells;i++,ci++)
+    {
+      if((INTERP_KERNEL::NormalizedCellType)oldc[ci[0]]==INTERP_KERNEL::NORM_QUAD4)
+        {
+          const int tmp[8]={(int)INTERP_KERNEL::NORM_TRI3,oldc[ci[0]+1],oldc[ci[0]+2],oldc[ci[0]+4],
+                            (int)INTERP_KERNEL::NORM_TRI3,oldc[ci[0]+2],oldc[ci[0]+3],oldc[ci[0]+4]};
+          pt=std::copy(tmp,tmp+8,pt);
+          ptI[1]=ptI[0]+4;
+          ptI[2]=ptI[0]+8;
+          *retPt++=i;
+          *retPt++=i;
+          ptI+=2;
+        }
+      else
+        {
+          pt=std::copy(oldc+ci[0],oldc+ci[1],pt);
+          ptI[1]=ptI[0]+ci[1]-ci[0];
+          ptI++;
+          *retPt++=i;
+        }
+    }
+  _nodal_connec->decrRef();
+  _nodal_connec=newConn;
+  _nodal_connec_index->decrRef();
+  _nodal_connec_index=newConnI;
+  computeTypes();
+  updateTime();
+  return ret;
+}
+
+/*!
+ * This private method is used to subdivide edges of a mesh with meshdim==2. If 'this' has no a meshdim equal to 2 an exception will be thrown.
+ * This method completly ignore coordinates.
+ * @param nodeSubdived is the nodal connectivity of subdivision of edges
+ * @param nodeIndxSubdived is the nodal connectivity index of subdivision of edges
+ * @param desc is descending connectivity in format specified in MEDCouplingUMesh::buildDescendingConnectivity2
+ * @param descIndex is descending connectivity index in format specified in MEDCouplingUMesh::buildDescendingConnectivity2
+ */
+void MEDCouplingUMesh::subDivide2DMesh(const int *nodeSubdived, const int *nodeIndxSubdived, const int *desc, const int *descIndex) throw(INTERP_KERNEL::Exception)
+{
+  checkFullyDefined();
+  if(getMeshDimension()!=2)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::subDivide2DMesh : works only on umesh with meshdim==2 !");
+  int nbOfCells=getNumberOfCells();
+  int *connI=_nodal_connec_index->getPointer();
+  int newConnLgth=0;
+  for(int i=0;i<nbOfCells;i++,connI++)
+    {
+      int offset=descIndex[i];
+      int nbOfEdges=descIndex[i+1]-offset;
+      //
+      bool ddirect=desc[offset+nbOfEdges-1]>0;
+      int eedgeId=std::abs(desc[offset+nbOfEdges-1])-1;
+      int ref=ddirect?nodeSubdived[nodeIndxSubdived[eedgeId+1]-1]:nodeSubdived[nodeIndxSubdived[eedgeId]+1];
+      for(int j=0;j<nbOfEdges;j++)
+        {
+          bool direct=desc[offset+j]>0;
+          int edgeId=std::abs(desc[offset+j])-1;
+          if(!INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)nodeSubdived[nodeIndxSubdived[edgeId]]).isQuadratic())
+            {
+              int id1=nodeSubdived[nodeIndxSubdived[edgeId]+1];
+              int id2=nodeSubdived[nodeIndxSubdived[edgeId+1]-1];
+              int ref2=direct?id1:id2;
+              if(ref==ref2)
+                {
+                  int nbOfSubNodes=nodeIndxSubdived[edgeId+1]-nodeIndxSubdived[edgeId]-1;
+                  newConnLgth+=nbOfSubNodes-1;
+                  ref=direct?id2:id1;
+                }
+              else
+                {
+                  std::ostringstream oss; oss << "MEDCouplingUMesh::subDivide2DMesh : On polygon #" << i << " edgeid #" << j << " subedges mismatch : end subedge k!=start subedge k+1 !";
+                  throw INTERP_KERNEL::Exception(oss.str().c_str());
+                }
+            }
+          else
+            {
+              throw INTERP_KERNEL::Exception("MEDCouplingUMesh::subDivide2DMesh : this method only subdivides into linear edges !");
+            }
+        }
+      newConnLgth++;//+1 is for cell type
+      connI[1]=newConnLgth;
+    }
+  //
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New();
+  newConn->alloc(newConnLgth,1);
+  int *work=newConn->getPointer();
+  for(int i=0;i<nbOfCells;i++)
+    {
+      *work++=INTERP_KERNEL::NORM_POLYGON;
+      int offset=descIndex[i];
+      int nbOfEdges=descIndex[i+1]-offset;
+      for(int j=0;j<nbOfEdges;j++)
+        {
+          bool direct=desc[offset+j]>0;
+          int edgeId=std::abs(desc[offset+j])-1;
+          if(direct)
+            work=std::copy(nodeSubdived+nodeIndxSubdived[edgeId]+1,nodeSubdived+nodeIndxSubdived[edgeId+1]-1,work);
+          else
+            {
+              int nbOfSubNodes=nodeIndxSubdived[edgeId+1]-nodeIndxSubdived[edgeId]-1;
+              std::reverse_iterator<const int *> it(nodeSubdived+nodeIndxSubdived[edgeId+1]);
+              work=std::copy(it,it+nbOfSubNodes-1,work);
+            }
+        }
+    }
+  DataArrayInt::SetArrayIn(newConn,_nodal_connec);
+  _types.clear();
+  if(nbOfCells>0)
+    _types.insert(INTERP_KERNEL::NORM_POLYGON);
+}
+
+/*!
+ * This method converts all degenerated cells to simpler cells. For example a NORM_QUAD4 cell consituted from 2 same node id in its
+ * nodal connectivity will be transform to a NORM_TRI3 cell.
+ * This method works \b only \b on \b linear cells.
+ * This method works on nodes ids, that is to say a call to ParaMEDMEM::MEDCouplingUMesh::mergeNodes
+ * method could be usefull before calling this method in case of presence of several pair of nodes located on same position.
+ * This method throws an exception if 'this' is not fully defined (connectivity).
+ * This method throws an exception too if a "too" degenerated cell is detected. For example a NORM_TRI3 with 3 times the same node id.
+ */
+void MEDCouplingUMesh::convertDegeneratedCells() throw(INTERP_KERNEL::Exception)
+{
+  checkFullyDefined();
+  if(getMeshDimension()<=1)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertDegeneratedCells works on umeshes with meshdim equals to 2 or 3 !");
+  int nbOfCells=getNumberOfCells();
+  if(nbOfCells<1)
+    return ;
+  int initMeshLgth=getMeshLength();
+  int *conn=_nodal_connec->getPointer();
+  int *index=_nodal_connec_index->getPointer();
+  int posOfCurCell=0;
+  int newPos=0;
+  int lgthOfCurCell;
+  for(int i=0;i<nbOfCells;i++)
+    {
+      lgthOfCurCell=index[i+1]-posOfCurCell;
+      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[posOfCurCell];
+      int newLgth;
+      INTERP_KERNEL::NormalizedCellType newType=INTERP_KERNEL::CellSimplify::simplifyDegeneratedCell(type,conn+posOfCurCell+1,lgthOfCurCell-1,
+                                                                                                     conn+newPos+1,newLgth);
+      conn[newPos]=newType;
+      newPos+=newLgth+1;
+      posOfCurCell=index[i+1];
+      index[i+1]=newPos;
+    }
+  if(newPos!=initMeshLgth)
+    _nodal_connec->reAlloc(newPos);
+  computeTypes();
+}
+
+/*!
+ * This method checks that all or only polygons (depending 'polyOnly' parameter) 2D cells are correctly oriented relative to 'vec' vector.
+ * The 'vec' vector has to have a non nul norm.
+ * If not 'cells' parameter will be appended with cellIds of incorrect cells.
+ * @throw when 'this' is not a mesh with meshdim==2 and spacedim==3
+ */
+void MEDCouplingUMesh::are2DCellsNotCorrectlyOriented(const double *vec, bool polyOnly, std::vector<int>& cells) const throw(INTERP_KERNEL::Exception)
+{
+  if(getMeshDimension()!=2 || getSpaceDimension()!=3)
+    throw INTERP_KERNEL::Exception("Invalid mesh to apply are2DCellsNotCorrectlyOriented on it : must be meshDim==2 and spaceDim==3 !");
+  int nbOfCells=getNumberOfCells();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  const double *coordsPtr=_coords->getConstPointer();
+  for(int i=0;i<nbOfCells;i++)
+    {
+      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[connI[i]];
+      if(!polyOnly || (type==INTERP_KERNEL::NORM_POLYGON || type==INTERP_KERNEL::NORM_QPOLYG))
+        {
+          bool isQuadratic=INTERP_KERNEL::CellModel::GetCellModel(type).isQuadratic();
+          if(!IsPolygonWellOriented(isQuadratic,vec,conn+connI[i]+1,conn+connI[i+1],coordsPtr))
+            cells.push_back(i);
+        }
+    }
+}
+
+/*!
+ * This method orient correctly (if needed) all or only polygons (depending 'polyOnly' parameter)  2D cells are correctly oriented relative to 'vec' vector.
+ * The 'vec' vector has to have a non nul norm.
+ * @throw when 'this' is not a mesh with meshdim==2 and spacedim==3
+ */
+void MEDCouplingUMesh::orientCorrectly2DCells(const double *vec, bool polyOnly) throw(INTERP_KERNEL::Exception)
+{
+  if(getMeshDimension()!=2 || getSpaceDimension()!=3)
+    throw INTERP_KERNEL::Exception("Invalid mesh to apply orientCorrectly2DCells on it : must be meshDim==2 and spaceDim==3 !");
+  int nbOfCells=getNumberOfCells();
+  int *conn=_nodal_connec->getPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  const double *coordsPtr=_coords->getConstPointer();
+  bool isModified=false;
+  for(int i=0;i<nbOfCells;i++)
+    {
+      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[connI[i]];
+      if(!polyOnly || (type==INTERP_KERNEL::NORM_POLYGON || type==INTERP_KERNEL::NORM_QPOLYG))
+        {
+          bool isQuadratic=INTERP_KERNEL::CellModel::GetCellModel(type).isQuadratic();
+          if(!IsPolygonWellOriented(isQuadratic,vec,conn+connI[i]+1,conn+connI[i+1],coordsPtr))
+            {
+              isModified=true;
+              std::vector<int> tmp(connI[i+1]-connI[i]-2);
+              std::copy(conn+connI[i]+2,conn+connI[i+1],tmp.rbegin());
+              std::copy(tmp.begin(),tmp.end(),conn+connI[i]+2);
+            }
+        }
+    }
+  if(isModified)
+    _nodal_connec->declareAsNew();
+  updateTime();
+}
+
+/*!
+ * This method checks that all polyhedrons cells have correctly oriented faces.
+ * If not, 'cells' parameter will be appended with cellIds of incorrect cells.
+ * @throw when 'this' is not a mesh with meshdim==3 and spacedim==3
+ */
+void MEDCouplingUMesh::arePolyhedronsNotCorrectlyOriented(std::vector<int>& cells) const throw(INTERP_KERNEL::Exception)
+{
+  if(getMeshDimension()!=3 || getSpaceDimension()!=3)
+    throw INTERP_KERNEL::Exception("Invalid mesh to apply arePolyhedronsNotCorrectlyOriented on it : must be meshDim==3 and spaceDim==3 !");
+  int nbOfCells=getNumberOfCells();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  const double *coordsPtr=_coords->getConstPointer();
+  for(int i=0;i<nbOfCells;i++)
+    {
+      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[connI[i]];
+      if(type==INTERP_KERNEL::NORM_POLYHED)
+        {
+          if(!IsPolyhedronWellOriented(conn+connI[i]+1,conn+connI[i+1],coordsPtr))
+            cells.push_back(i);
+        }
+    }
+}
+
+/*!
+ * This method tries to orient correctly polhedrons cells.
+ * @throw when 'this' is not a mesh with meshdim==3 and spacedim==3. An exception is also thrown when the attempt of reparation fails.
+ */
+void MEDCouplingUMesh::orientCorrectlyPolyhedrons() throw(INTERP_KERNEL::Exception)
+{
+  if(getMeshDimension()!=3 || getSpaceDimension()!=3)
+    throw INTERP_KERNEL::Exception("Invalid mesh to apply orientCorrectlyPolyhedrons on it : must be meshDim==3 and spaceDim==3 !");
+  int nbOfCells=getNumberOfCells();
+  int *conn=_nodal_connec->getPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  const double *coordsPtr=_coords->getConstPointer();
+  bool isModified=false;
+  for(int i=0;i<nbOfCells;i++)
+    {
+      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[connI[i]];
+      if(type==INTERP_KERNEL::NORM_POLYHED)
+        if(!IsPolyhedronWellOriented(conn+connI[i]+1,conn+connI[i+1],coordsPtr))
+          {
+            TryToCorrectPolyhedronOrientation(conn+connI[i]+1,conn+connI[i+1],coordsPtr);
+            isModified=true;
+          }
+    }
+  if(isModified)
+    _nodal_connec->declareAsNew();
+  updateTime();
+}
+
+/*!
+ * This method has a sense for meshes with spaceDim==3 and meshDim==2.
+ * If it is not the case an exception will be thrown.
+ * This method is fast because the first cell of 'this' is used to compute the plane.
+ * @param vec output of size at least 3 used to store the normal vector (with norm equal to Area ) of searched plane.
+ * @param pos output of size at least 3 used to store a point owned of searched plane.
+ */
+void MEDCouplingUMesh::getFastAveragePlaneOfThis(double *vec, double *pos) const throw(INTERP_KERNEL::Exception)
+{
+  if(getMeshDimension()!=2 || getSpaceDimension()!=3)
+    throw INTERP_KERNEL::Exception("Invalid mesh to apply getFastAveragePlaneOfThis on it : must be meshDim==2 and spaceDim==3 !");
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  const double *coordsPtr=_coords->getConstPointer();
+  INTERP_KERNEL::areaVectorOfPolygon<int,INTERP_KERNEL::ALL_C_MODE>(conn+1,connI[1]-connI[0]-1,coordsPtr,vec);
+  std::copy(coordsPtr+3*conn[1],coordsPtr+3*conn[1]+3,pos);
+}
+
+/*!
+ * The returned newly created field has to be managed by the caller.
+ * This method returns a field on cell with no time lying on 'this'. The meshdimension and spacedimension of this are expected to be both in [2,3]. If not an exception will be thrown.
+ * This method for the moment only deals with NORM_TRI3, NORM_QUAD4 and NORM_TETRA4 geometric types.
+ * If a cell has an another type an exception will be thrown.
+ */
+MEDCouplingFieldDouble *MEDCouplingUMesh::getEdgeRatioField() const throw(INTERP_KERNEL::Exception)
+{
+  checkCoherency();
+  int spaceDim=getSpaceDimension();
+  int meshDim=getMeshDimension();
+  if(spaceDim!=2 && spaceDim!=3)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getEdgeRatioField : SpaceDimension must be equal to 2 or 3 !");
+  if(meshDim!=2 && meshDim!=3)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getEdgeRatioField : MeshDimension must be equal to 2 or 3 !");
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  ret->setMesh(this);
+  int nbOfCells=getNumberOfCells();
+  DataArrayDouble *arr=DataArrayDouble::New();
+  arr->alloc(nbOfCells,1);
+  double *pt=arr->getPointer();
+  ret->setArray(arr);//In case of throw to avoid mem leaks arr will be used after decrRef.
+  arr->decrRef();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  const double *coo=_coords->getConstPointer();
+  double tmp[12];
+  for(int i=0;i<nbOfCells;i++,pt++)
+    {
+      INTERP_KERNEL::NormalizedCellType t=(INTERP_KERNEL::NormalizedCellType)*conn;
+      switch(t)
+        {
+          case INTERP_KERNEL::NORM_TRI3:
+            {
+              FillInCompact3DMode(spaceDim,3,conn+1,coo,tmp);
+              *pt=INTERP_KERNEL::triEdgeRatio(tmp);
+              break;
+            }
+          case INTERP_KERNEL::NORM_QUAD4:
+            {
+              FillInCompact3DMode(spaceDim,4,conn+1,coo,tmp);
+              *pt=INTERP_KERNEL::quadEdgeRatio(tmp);
+              break;
+            }
+          case INTERP_KERNEL::NORM_TETRA4:
+            {
+              FillInCompact3DMode(spaceDim,4,conn+1,coo,tmp);
+              *pt=INTERP_KERNEL::tetraEdgeRatio(tmp);
+              break;
+            }
+        default:
+          throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getEdgeRatioField : A cell with not manged type (NORM_TRI3, NORM_QUAD4 and NORM_TETRA4) has been detected !");
+        }
+      conn+=connI[i+1]-connI[i];
+    }
+  ret->setName("EdgeRatio");
+  ret->incrRef();
+  return ret;
+}
+
+/*!
+ * The returned newly created field has to be managed by the caller.
+ * This method returns a field on cell with no time lying on 'this'. The meshdimension and spacedimension of this are expected to be both in [2,3]. If not an exception will be thrown.
+ * This method for the moment only deals with NORM_TRI3, NORM_QUAD4 and NORM_TETRA4 geometric types.
+ * If a cell has an another type an exception will be thrown.
+ */
+MEDCouplingFieldDouble *MEDCouplingUMesh::getAspectRatioField() const throw(INTERP_KERNEL::Exception)
+{
+  checkCoherency();
+  int spaceDim=getSpaceDimension();
+  int meshDim=getMeshDimension();
+  if(spaceDim!=2 && spaceDim!=3)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getAspectRatioField : SpaceDimension must be equal to 2 or 3 !");
+  if(meshDim!=2 && meshDim!=3)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getAspectRatioField : MeshDimension must be equal to 2 or 3 !");
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  ret->setMesh(this);
+  int nbOfCells=getNumberOfCells();
+  DataArrayDouble *arr=DataArrayDouble::New();
+  arr->alloc(nbOfCells,1);
+  double *pt=arr->getPointer();
+  ret->setArray(arr);//In case of throw to avoid mem leaks arr will be used after decrRef.
+  arr->decrRef();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  const double *coo=_coords->getConstPointer();
+  double tmp[12];
+  for(int i=0;i<nbOfCells;i++,pt++)
+    {
+      INTERP_KERNEL::NormalizedCellType t=(INTERP_KERNEL::NormalizedCellType)*conn;
+      switch(t)
+        {
+          case INTERP_KERNEL::NORM_TRI3:
+            {
+              FillInCompact3DMode(spaceDim,3,conn+1,coo,tmp);
+              *pt=INTERP_KERNEL::triAspectRatio(tmp);
+              break;
+            }
+          case INTERP_KERNEL::NORM_QUAD4:
+            {
+              FillInCompact3DMode(spaceDim,4,conn+1,coo,tmp);
+              *pt=INTERP_KERNEL::quadAspectRatio(tmp);
+              break;
+            }
+          case INTERP_KERNEL::NORM_TETRA4:
+            {
+              FillInCompact3DMode(spaceDim,4,conn+1,coo,tmp);
+              *pt=INTERP_KERNEL::tetraAspectRatio(tmp);
+              break;
+            }
+        default:
+          throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getAspectRatioField : A cell with not manged type (NORM_TRI3, NORM_QUAD4 and NORM_TETRA4) has been detected !");
+        }
+      conn+=connI[i+1]-connI[i];
+    }
+  ret->setName("AspectRatio");
+  ret->incrRef();
+  return ret;
+}
+
+/*!
+ * The returned newly created field has to be managed by the caller.
+ * This method returns a field on cell with no time lying on 'this'. The meshdimension must be equal to 2 and the spacedimension must be equal to 3. If not an exception will be thrown.
+ * This method for the moment only deals with NORM_QUAD4 geometric type.
+ * If a cell has an another type an exception will be thrown.
+ */
+MEDCouplingFieldDouble *MEDCouplingUMesh::getWarpField() const throw(INTERP_KERNEL::Exception)
+{
+  checkCoherency();
+  int spaceDim=getSpaceDimension();
+  int meshDim=getMeshDimension();
+  if(spaceDim!=3)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getWarpField : SpaceDimension must be equal to 3 !");
+  if(meshDim!=2)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getWarpField : MeshDimension must be equal to 2 !");
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  ret->setMesh(this);
+  int nbOfCells=getNumberOfCells();
+  DataArrayDouble *arr=DataArrayDouble::New();
+  arr->alloc(nbOfCells,1);
+  double *pt=arr->getPointer();
+  ret->setArray(arr);//In case of throw to avoid mem leaks arr will be used after decrRef.
+  arr->decrRef();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  const double *coo=_coords->getConstPointer();
+  double tmp[12];
+  for(int i=0;i<nbOfCells;i++,pt++)
+    {
+      INTERP_KERNEL::NormalizedCellType t=(INTERP_KERNEL::NormalizedCellType)*conn;
+      switch(t)
+        {
+          case INTERP_KERNEL::NORM_QUAD4:
+            {
+              FillInCompact3DMode(3,4,conn+1,coo,tmp);
+              *pt=INTERP_KERNEL::quadWarp(tmp);
+              break;
+            }
+        default:
+          throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getWarpField : A cell with not manged type (NORM_QUAD4) has been detected !");
+        }
+      conn+=connI[i+1]-connI[i];
+    }
+  ret->setName("Warp");
+  ret->incrRef();
+  return ret;
+}
+
+/*!
+ * The returned newly created field has to be managed by the caller.
+ * This method returns a field on cell with no time lying on 'this'. The meshdimension must be equal to 2 and the spacedimension must be equal to 3. If not an exception will be thrown.
+ * This method for the moment only deals with NORM_QUAD4 geometric type.
+ * If a cell has an another type an exception will be thrown.
+ */
+MEDCouplingFieldDouble *MEDCouplingUMesh::getSkewField() const throw(INTERP_KERNEL::Exception)
+{
+  checkCoherency();
+  int spaceDim=getSpaceDimension();
+  int meshDim=getMeshDimension();
+  if(spaceDim!=3)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getSkewField : SpaceDimension must be equal to 3 !");
+  if(meshDim!=2)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getSkewField : MeshDimension must be equal to 2 !");
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME);
+  ret->setMesh(this);
+  int nbOfCells=getNumberOfCells();
+  DataArrayDouble *arr=DataArrayDouble::New();
+  arr->alloc(nbOfCells,1);
+  double *pt=arr->getPointer();
+  ret->setArray(arr);//In case of throw to avoid mem leaks arr will be used after decrRef.
+  arr->decrRef();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  const double *coo=_coords->getConstPointer();
+  double tmp[12];
+  for(int i=0;i<nbOfCells;i++,pt++)
+    {
+      INTERP_KERNEL::NormalizedCellType t=(INTERP_KERNEL::NormalizedCellType)*conn;
+      switch(t)
+        {
+          case INTERP_KERNEL::NORM_QUAD4:
+            {
+              FillInCompact3DMode(3,4,conn+1,coo,tmp);
+              *pt=INTERP_KERNEL::quadSkew(tmp);
+              break;
+            }
+        default:
+          throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getSkewField : A cell with not manged type (NORM_QUAD4) has been detected !");
+        }
+      conn+=connI[i+1]-connI[i];
+    }
+  ret->setName("Skew");
+  ret->incrRef();
+  return ret;
+}
+
+/*!
+ * This method aggregate the bbox of each cell and put it into bbox parameter.
+ * @param bbox out parameter of size 2*spacedim*nbOfcells.
+ */
+void MEDCouplingUMesh::getBoundingBoxForBBTree(std::vector<double>& bbox) const
+{
+  int spaceDim=getSpaceDimension();
+  int nbOfCells=getNumberOfCells();
+  bbox.resize(2*nbOfCells*spaceDim);
+  for(int i=0;i<nbOfCells*spaceDim;i++)
+    {
+      bbox[2*i]=std::numeric_limits<double>::max();
+      bbox[2*i+1]=-std::numeric_limits<double>::max();
+    }
+  const double *coordsPtr=_coords->getConstPointer();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  for(int i=0;i<nbOfCells;i++)
+    {
+      int offset=connI[i]+1;
+      int nbOfNodesForCell=connI[i+1]-offset;
+      for(int j=0;j<nbOfNodesForCell;j++)
+        {
+          int nodeId=conn[offset+j];
+          if(nodeId>=0)
+            for(int k=0;k<spaceDim;k++)
+              {
+                bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]);
+                bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]);
+              }
+        }
+    }
+}
+
+/// @cond INTERNAL
+
+namespace ParaMEDMEMImpl
+{
+  class ConnReader
+  {
+  public:
+    ConnReader(const int *c, int val):_conn(c),_val(val) { }
+    bool operator() (const int& pos) { return _conn[pos]!=_val; }
+  private:
+    const int *_conn;
+    int _val;
+  };
+
+  class ConnReader2
+  {
+  public:
+    ConnReader2(const int *c, int val):_conn(c),_val(val) { }
+    bool operator() (const int& pos) { return _conn[pos]==_val; }
+  private:
+    const int *_conn;
+    int _val;
+  };
+}
+
+/// @endcond
+
+/*!
+ * This method expects that 'this' is sorted by types. If not an exception will be thrown.
+ * This method returns in the same format as code (see MEDCouplingUMesh::checkTypeConsistencyAndContig or MEDCouplingUMesh::splitProfilePerType) how
+ * 'this' is composed in cell types.
+ * The returned array is of size 3*n where n is the number of different types present in 'this'. 
+ * For every k in [0,n] ret[3*k+2]==0 because it has no sense here. 
+ * This parameter is kept only for compatibility with other methode listed above.
+ */
+std::vector<int> MEDCouplingUMesh::getDistributionOfTypes() const throw(INTERP_KERNEL::Exception)
+{
+  checkConnectivityFullyDefined();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  const int *work=connI;
+  int nbOfCells=getNumberOfCells();
+  std::size_t n=getAllTypes().size();
+  std::vector<int> ret(3*n,0); //ret[3*k+2]==0 because it has no sense here
+  std::set<INTERP_KERNEL::NormalizedCellType> types;
+  for(std::size_t i=0;work!=connI+nbOfCells;i++)
+    {
+      INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)conn[*work];
+      if(types.find(typ)!=types.end())
+        {
+          std::ostringstream oss; oss << "MEDCouplingUMesh::getDistributionOfTypes : Type " << INTERP_KERNEL::CellModel::GetCellModel(typ).getRepr();
+          oss << " is not contiguous !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+      types.insert(typ);
+      ret[3*i]=typ;
+      const int *work2=std::find_if(work+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,typ));
+      ret[3*i+1]=(int)std::distance(work,work2);
+      work=work2;
+    }
+  return ret;
+}
+
+/*!
+ * This method is used to check that this has contiguous cell type in same order than described in 'code'.
+ * only for types cell, type node is not managed.
+ * Format of 'code' is the following. 'code' should be of size 3*n and non empty. If not an exception is thrown.
+ * foreach k in [0,n) on 3*k pos represent the geometric type and 3*k+1 number of elements of type 3*k.
+ * 3*k+2 refers if different from -1 the pos in 'idsPerType' to get the corresponding array.
+ * If 2 or more same geometric type is in 'code' and exception is thrown too.
+ *
+ * This method firstly checks
+ * If it exists k so that 3*k geometric type is not in geometric types of this an exception will be thrown.
+ * If it exists k so that 3*k geometric type exists but the number of consecutive cell types does not match,
+ * an exception is thrown too.
+ * 
+ * If all geometric types in 'code' are exactly those in 'this' null pointer is returned.
+ * If it exists a geometric type in 'this' \b not in 'code' \b no exception is thrown 
+ * and a DataArrayInt instance is returned that the user has the responsability to deallocate.
+ */
+DataArrayInt *MEDCouplingUMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
+{
+  if(code.empty())
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : code is empty, should not !");
+  std::size_t sz=code.size();
+  std::size_t n=sz/3;
+  if(sz%3!=0)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : code size is NOT %3 !");
+  std::vector<INTERP_KERNEL::NormalizedCellType> types;
+  int nb=0;
+  for(std::size_t i=0;i<n;i++)
+    if(std::find(types.begin(),types.end(),(INTERP_KERNEL::NormalizedCellType)code[3*i])==types.end())
+      {
+        types.push_back((INTERP_KERNEL::NormalizedCellType)code[3*i]);
+        nb+=code[3*i+1];
+        if(_types.find((INTERP_KERNEL::NormalizedCellType)code[3*i])==_types.end())
+          throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : expected geo types not in this !");
+      }
+  if(types.size()!=n)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : code contains duplication of types in unstructured mesh !");
+  if(idsPerType.empty())
+    {
+      if(!checkConsecutiveCellTypesAndOrder(&types[0],&types[0]+types.size()))
+        throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : non contiguous type !");
+      if(types.size()==_types.size())
+        return 0;
+    }
+  DataArrayInt *ret=DataArrayInt::New();
+  ret->alloc(nb,1);
+  int *retPtr=ret->getPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  const int *conn=_nodal_connec->getConstPointer();
+  int nbOfCells=getNumberOfCells();
+  const int *i=connI;
+  int kk=0;
+  for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator it=types.begin();it!=types.end();it++,kk++)
+    {
+      i=std::find_if(i,connI+nbOfCells,ParaMEDMEMImpl::ConnReader2(conn,(int)(*it)));
+      int offset=(int)std::distance(connI,i);
+      if(code[3*kk+2]==-1)
+        {
+          const int *j=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)(*it)));
+          std::size_t pos2=std::distance(i,j);
+          for(std::size_t k=0;k<pos2;k++)
+            *retPtr++=(int)k+offset;
+          i=j;
+        }
+      else
+        {
+          retPtr=std::transform(idsPerType[code[3*kk+2]]->getConstPointer(),idsPerType[code[3*kk+2]]->getConstPointer()+idsPerType[code[3*kk+2]]->getNbOfElems(),
+                                retPtr,std::bind2nd(std::plus<int>(),offset));
+        }
+    }
+  return ret;
+}
+
+/*!
+ * This method makes the hypothesis that 'this' is sorted by type. If not an exception will be thrown.
+ * This method is the opposite of MEDCouplingUMesh::checkTypeConsistencyAndContig method. Given a list of cells in 'profile' it returns a list of profiles sorted by geo type.
+ * This method has 1 input 'profile' and 2 outputs 'code' and 'idsPerType'.
+ * @throw if 'profile' has not exactly one component. It throws too, if 'profile' contains some values not in [0,getNumberOfCells()) or if 'this' is not fully defined
+ */
+void MEDCouplingUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const throw(INTERP_KERNEL::Exception)
+{
+  if(profile->getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::splitProfilePerType : input profile should have exactly one component !");
+  checkConnectivityFullyDefined();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  int nbOfCells=getNumberOfCells();
+  std::vector<INTERP_KERNEL::NormalizedCellType> types;
+  std::vector<int> typeRangeVals(1);
+  for(const int *i=connI;i!=connI+nbOfCells;)
+    {
+      INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i];
+      if(std::find(types.begin(),types.end(),curType)!=types.end())
+        {
+          throw INTERP_KERNEL::Exception("MEDCouplingUMesh::splitProfilePerType : current mesh is not sorted by type !");
+        }
+      types.push_back(curType);
+      i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType));
+      typeRangeVals.push_back((int)std::distance(connI,i));
+    }
+  //
+  DataArrayInt *castArr=0,*rankInsideCast=0,*castsPresent=0;
+  profile->splitByValueRange(&typeRangeVals[0],&typeRangeVals[0]+typeRangeVals.size(),castArr,rankInsideCast,castsPresent);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp0=castArr;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1=rankInsideCast;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp2=castsPresent;
+  //
+  int nbOfCastsFinal=castsPresent->getNumberOfTuples();
+  code.resize(3*nbOfCastsFinal);
+  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsInPflPerType2;
+  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerType2;
+  for(int i=0;i<nbOfCastsFinal;i++)
+    {
+      int castId=castsPresent->getIJ(i,0);
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp3=castArr->getIdsEqual(castId);
+      idsInPflPerType2.push_back(tmp3);
+      code[3*i]=(int)types[castId];
+      code[3*i+1]=tmp3->getNumberOfTuples();
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp4=rankInsideCast->selectByTupleId(tmp3->getConstPointer(),tmp3->getConstPointer()+tmp3->getNumberOfTuples());
+      if(tmp4->getNumberOfTuples()!=typeRangeVals[castId+1]-typeRangeVals[castId] || !tmp4->isIdentity())
+        {
+          tmp4->copyStringInfoFrom(*profile);
+          idsPerType2.push_back(tmp4);
+          code[3*i+2]=(int)idsPerType2.size()-1;
+        }
+      else
+        {
+          code[3*i+2]=-1;
+        }
+    }
+  std::size_t sz2=idsInPflPerType2.size();
+  idsInPflPerType.resize(sz2);
+  for(std::size_t i=0;i<sz2;i++)
+    {
+      DataArrayInt *locDa=idsInPflPerType2[i];
+      locDa->incrRef();
+      idsInPflPerType[i]=locDa;
+    }
+  std::size_t sz=idsPerType2.size();
+  idsPerType.resize(sz);
+  for(std::size_t i=0;i<sz;i++)
+    {
+      DataArrayInt *locDa=idsPerType2[i];
+      locDa->incrRef();
+      idsPerType[i]=locDa;
+    }
+}
+
+/*!
+ * This method is here too emulate the MEDMEM behaviour on BDC (buildDescendingConnectivity). Hoping this method becomes deprecated very soon.
+ * This method make the assumption that 'this' and 'nM1LevMesh' mesh lyies on same coords (same pointer) as MED and MEDMEM does.
+ * The following equality should be verified 'nM1LevMesh->getMeshDimension()==this->getMeshDimension()-1'
+ * This method returns 5+2 elements. 'desc', 'descIndx', 'revDesc', 'revDescIndx' and 'meshnM1' behaves exactly as ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity except the content as described after. The returned array specifies the n-1 mesh reordered by type as MEDMEM does. 'nM1LevMeshIds' contains the ids in returned 'meshnM1'. Finally 'meshnM1Old2New' contains numbering old2new that is to say the cell #k in coarse 'nM1LevMesh' will have the number ret[k] in returned mesh 'nM1LevMesh' MEDMEM reordered.
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::emulateMEDMEMBDC(const MEDCouplingUMesh *nM1LevMesh, DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *&revDesc, DataArrayInt *&revDescIndx, DataArrayInt *& nM1LevMeshIds, DataArrayInt *&meshnM1Old2New) const throw(INTERP_KERNEL::Exception)
+{
+  checkFullyDefined();
+  nM1LevMesh->checkFullyDefined();
+  if(getMeshDimension()-1!=nM1LevMesh->getMeshDimension())
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::emulateMEDMEMBDC : The mesh passed as first argument should have a meshDim equal to this->getMeshDimension()-1 !" );
+  if(_coords!=nM1LevMesh->getCoords())
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::emulateMEDMEMBDC : 'this' and mesh in first argument should share the same coords : Use tryToShareSameCoords method !");
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp0=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret1=buildDescendingConnectivity(desc,descIndx,tmp0,tmp1);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=ret1->sortCellsInMEDFileFrmt();
+  desc->transformWithIndArr(ret0->getConstPointer(),ret0->getConstPointer()+ret0->getNbOfElems());
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp=MEDCouplingUMesh::New();
+  tmp->setConnectivity(tmp0,tmp1);
+  tmp->renumberCells(ret0->getConstPointer(),false);
+  revDesc=tmp->getNodalConnectivity();
+  revDescIndx=tmp->getNodalConnectivityIndex();
+  DataArrayInt *ret=0;
+  if(!ret1->areCellsIncludedIn(nM1LevMesh,2,ret))
+    {
+      int tmp2;
+      ret->getMaxValue(tmp2);
+      ret->decrRef();
+      std::ostringstream oss; oss << "MEDCouplingUMesh::emulateMEDMEMBDC : input N-1 mesh present a cell not in descending mesh ... Id of cell is " << tmp2 << " !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  nM1LevMeshIds=ret;
+  //
+  revDesc->incrRef();
+  revDescIndx->incrRef();
+  ret1->incrRef();
+  ret0->incrRef();
+  meshnM1Old2New=ret0;
+  return ret1;
+}
+
+/*!
+ * This method sorts cell in this so that cells are sorted by cell type specified by MEDMEM and so for MED file.
+ * It avoids to deal with renum in MEDLoader so it is usefull for MED file R/W with multi types.
+ * This method returns a newly allocated array old2New.
+ * This method expects that connectivity of this is set. If not an exception will be thrown. Coordinates are not taken into account.
+ */
+DataArrayInt *MEDCouplingUMesh::sortCellsInMEDFileFrmt() throw(INTERP_KERNEL::Exception)
+{
+  checkConnectivityFullyDefined();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=getRenumArrForConsecutiveCellTypesSpec(MEDMEM_ORDER,MEDMEM_ORDER+N_MEDMEM_ORDER);
+  renumberCells(ret->getConstPointer(),false);
+  ret->incrRef();
+  return ret;
+}
+
+/*!
+ * This methods checks that cells are sorted by their types.
+ * This method makes asumption (no check) that connectivity is correctly set before calling.
+ */
+bool MEDCouplingUMesh::checkConsecutiveCellTypes() const
+{
+  checkFullyDefined();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  int nbOfCells=getNumberOfCells();
+  std::set<INTERP_KERNEL::NormalizedCellType> types;
+  for(const int *i=connI;i!=connI+nbOfCells;)
+    {
+      INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i];
+      if(types.find(curType)!=types.end())
+        return false;
+      types.insert(curType);
+      i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType));
+    }
+  return true;
+}
+
+/*!
+ * This method performs the same job as checkConsecutiveCellTypes except that the order of types sequence is analyzed to check
+ * that the order is specified in array defined by [orderBg,orderEnd). 
+ */
+bool MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const
+{
+  checkFullyDefined();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  int nbOfCells=getNumberOfCells();
+  int lastPos=-1;
+  for(const int *i=connI;i!=connI+nbOfCells;)
+    {
+      INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i];
+      int pos=(int)std::distance(orderBg,std::find(orderBg,orderEnd,curType));
+      if(pos<=lastPos)
+        return false;
+      lastPos=pos;
+      i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType));
+    }
+  return true;
+}
+
+/*!
+ * This method returns 2 newly allocated DataArrayInt instances. The first is an array of size 'this->getNumberOfCells()' with one component,
+ * that tells for each cell the pos of its type in the array on type given in input parameter. The 2nd output parameter is an array with the same
+ * number of tuples than input type array and with one component. This 2nd output array gives type by type the number of occurence of type in 'this'.
+ */
+DataArrayInt *MEDCouplingUMesh::getLevArrPerCellTypes(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd, DataArrayInt *&nbPerType) const throw(INTERP_KERNEL::Exception)
+{
+  checkConnectivityFullyDefined();
+  int nbOfCells=getNumberOfCells();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmpa=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmpb=DataArrayInt::New();
+  tmpa->alloc(nbOfCells,1);
+  tmpb->alloc((int)std::distance(orderBg,orderEnd),1);
+  tmpb->fillWithZero();
+  int *tmp=tmpa->getPointer();
+  int *tmp2=tmpb->getPointer();
+  for(const int *i=connI;i!=connI+nbOfCells;i++)
+    {
+      const INTERP_KERNEL::NormalizedCellType *where=std::find(orderBg,orderEnd,(INTERP_KERNEL::NormalizedCellType)conn[*i]);
+      if(where!=orderEnd)
+        {
+          int pos=(int)std::distance(orderBg,where);
+          tmp2[pos]++;
+          tmp[std::distance(connI,i)]=pos;
+        }
+      else
+        {
+          const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[*i]);
+          std::ostringstream oss; oss << "MEDCouplingUMesh::getLevArrPerCellTypes : Cell #" << std::distance(connI,i);
+          oss << " has a type " << cm.getRepr() << " not in input array of type !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  nbPerType=tmpb;
+  tmpa->incrRef();
+  tmpb->incrRef();
+  return tmpa;
+}
+
+/*!
+ * This method is similar to method MEDCouplingUMesh::rearrange2ConsecutiveCellTypes except that the type order is specfied by [orderBg,orderEnd) (as MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder method) and that this method is \b const and performs \b NO permutation in 'this'.
+ * This method returns an array of size getNumberOfCells() that gives a renumber array old2New that can be used as input of MEDCouplingMesh::renumberCells.
+ * The mesh after this call to MEDCouplingMesh::renumberCells will pass the test of MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder with the same inputs.
+ * The returned array minimizes the permutations that is to say the order of cells inside same geometric type remains the same.
+ */
+DataArrayInt *MEDCouplingUMesh::getRenumArrForConsecutiveCellTypesSpec(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const throw(INTERP_KERNEL::Exception)
+{
+  DataArrayInt *nbPerType=0;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmpa=getLevArrPerCellTypes(orderBg,orderEnd,nbPerType);
+  nbPerType->decrRef();
+  return tmpa->buildPermArrPerLevel();
+}
+
+/*!
+ * This method reorganize the cells of 'this' so that the cells with same geometric types are put together.
+ * The number of cells remains unchanged after the call of this method.
+ * This method tries to minimizes the number of needed permutations. So, this method behaves not exactly as
+ * MEDCouplingUMesh::sortCellsInMEDFileFrmt.
+ *
+ * @return the array giving the correspondance old to new.
+ */
+DataArrayInt *MEDCouplingUMesh::rearrange2ConsecutiveCellTypes()
+{
+  checkFullyDefined();
+  computeTypes();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  int nbOfCells=getNumberOfCells();
+  std::vector<INTERP_KERNEL::NormalizedCellType> types;
+  for(const int *i=connI;i!=connI+nbOfCells && (types.size()!=_types.size());)
+    if(std::find(types.begin(),types.end(),(INTERP_KERNEL::NormalizedCellType)conn[*i])==types.end())
+      {
+        INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i];
+        types.push_back(curType);
+        for(i++;i!=connI+nbOfCells && (INTERP_KERNEL::NormalizedCellType)conn[*i]==curType;i++);
+      }
+  DataArrayInt *ret=DataArrayInt::New();
+  ret->alloc(nbOfCells,1);
+  int *retPtr=ret->getPointer();
+  std::fill(retPtr,retPtr+nbOfCells,-1);
+  int newCellId=0;
+  for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator iter=types.begin();iter!=types.end();iter++)
+    {
+      for(const int *i=connI;i!=connI+nbOfCells;i++)
+        if((INTERP_KERNEL::NormalizedCellType)conn[*i]==(*iter))
+          retPtr[std::distance(connI,i)]=newCellId++;
+    }
+  renumberCells(retPtr,false);
+  return ret;
+}
+
+/*!
+ * This method splits 'this' into as mush as untructured meshes that consecutive set of same type cells.
+ * So this method has typically a sense if MEDCouplingUMesh::checkConsecutiveCellTypes has a sense.
+ * This method makes asumption that connectivity is correctly set before calling.
+ */
+std::vector<MEDCouplingUMesh *> MEDCouplingUMesh::splitByType() const
+{
+  checkFullyDefined();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  int nbOfCells=getNumberOfCells();
+  std::vector<MEDCouplingUMesh *> ret;
+  for(const int *i=connI;i!=connI+nbOfCells;)
+    {
+      INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i];
+      int beginCellId=(int)std::distance(connI,i);
+      i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType));
+      int endCellId=(int)std::distance(connI,i);
+      int sz=endCellId-beginCellId;
+      int *cells=new int[sz];
+      for(int j=0;j<sz;j++)
+        cells[j]=beginCellId+j;
+      MEDCouplingUMesh *m=(MEDCouplingUMesh *)buildPartOfMySelf(cells,cells+sz,true);
+      delete [] cells;
+      ret.push_back(m);
+    }
+  return ret;
+}
+
+/*!
+ * This method takes in input a vector of MEDCouplingUMesh instances lying on the same coordinates with same mesh dimensions.
+ * Each mesh in \b ms must be sorted by type with the same order (typically using MEDCouplingUMesh::sortCellsInMEDFileFrmt).
+ * This method is particulary useful for MED file interaction. It allows to aggregate several meshes and keeping the type sorting
+ * and the track of the permutation by chunk of same geotype cells to retrieve it. The traditional formats old2new and new2old
+ * are not used here to avoid the build of big permutation array.
+ *
+ * \param [in] ms meshes with same mesh dimension lying on the same coords and sorted by type following de the same geometric type order than
+ *                those specified in MEDCouplingUMesh::sortCellsInMEDFileFrmt method.
+ * \param [out] szOfCellGrpOfSameType is a newly allocated DataArrayInt instance whose number of tuples is equal to the number of chunks of same geotype
+ *              in all meshes in \b ms. The accumulation of all values of this array is equal to the number of cells of returned mesh.
+ * \param [out] idInMsOfCellGrpOfSameType is a newly allocated DataArrayInt instance having the same size than \b szOfCellGrpOfSameType. This
+ *              output array gives for each chunck of same type the corresponding mesh id in \b ms.
+ * \return A newly allocated unstructured mesh that is the result of the aggregation on same coords of all meshes in \b ms. This returned mesh
+ *         is sorted by type following the geo cell types order of MEDCouplingUMesh::sortCellsInMEDFileFrmt method.
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(const std::vector<const MEDCouplingUMesh *>& ms,
+                                                                            DataArrayInt *&szOfCellGrpOfSameType,
+                                                                            DataArrayInt *&idInMsOfCellGrpOfSameType) throw(INTERP_KERNEL::Exception)
+{
+  std::vector<const MEDCouplingUMesh *> ms2;
+  for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++)
+    if(*it)
+      {
+        (*it)->checkConnectivityFullyDefined();
+        ms2.push_back(*it);
+      }
+  if(ms2.empty())
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords : input vector is empty !");
+  const DataArrayDouble *refCoo=ms2[0]->getCoords();
+  int meshDim=ms2[0]->getMeshDimension();
+  std::vector<const MEDCouplingUMesh *> m1ssm;
+  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > m1ssmAuto;
+  //
+  std::vector<const MEDCouplingUMesh *> m1ssmSingle;
+  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > m1ssmSingleAuto;
+  int fake=0,rk=0;
+  std::vector<int> ret1Data;
+  std::vector<int> ret2Data;
+  for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms2.begin();it!=ms2.end();it++,rk++)
+    {
+      if(meshDim!=(*it)->getMeshDimension())
+        throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords : meshdims mismatch !");
+      if(refCoo!=(*it)->getCoords())
+        throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords : meshes are not shared by a single coordinates coords !");
+      std::vector<MEDCouplingUMesh *> sp=(*it)->splitByType();
+      std::copy(sp.begin(),sp.end(),std::back_insert_iterator< std::vector<const MEDCouplingUMesh *> >(m1ssm));
+      std::copy(sp.begin(),sp.end(),std::back_insert_iterator< std::vector<MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > >(m1ssmAuto));
+      for(std::vector<MEDCouplingUMesh *>::const_iterator it2=sp.begin();it2!=sp.end();it2++)
+        {
+          MEDCouplingUMesh *singleCell=static_cast<MEDCouplingUMesh *>((*it2)->buildPartOfMySelf(&fake,&fake+1,true));
+          m1ssmSingleAuto.push_back(singleCell);
+          m1ssmSingle.push_back(singleCell);
+          ret1Data.push_back((*it2)->getNumberOfCells()); ret2Data.push_back(rk);
+        }
+    }
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc((int)m1ssmSingle.size(),1); std::copy(ret1Data.begin(),ret1Data.end(),ret1->getPointer());
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)m1ssmSingle.size(),1); std::copy(ret2Data.begin(),ret2Data.end(),ret2->getPointer());
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1ssmSingle2=MEDCouplingUMesh::MergeUMeshesOnSameCoords(m1ssmSingle);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renum=m1ssmSingle2->sortCellsInMEDFileFrmt();
+  std::vector<const MEDCouplingUMesh *> m1ssmfinal(m1ssm.size());
+  for(std::size_t i=0;i<m1ssm.size();i++)
+    m1ssmfinal[renum->getIJ(i,0)]=m1ssm[i];
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret0=MEDCouplingUMesh::MergeUMeshesOnSameCoords(m1ssmfinal);
+  szOfCellGrpOfSameType=ret1->renumber(renum->getConstPointer());
+  idInMsOfCellGrpOfSameType=ret2->renumber(renum->getConstPointer());
+  ret0->incrRef();
+  return ret0;
+}
+
+/*!
+ * This method returns a newly created DataArrayInt instance.
+ * This method retrieves cell ids in [begin,end) that have the type 'type'.
+ */
+DataArrayInt *MEDCouplingUMesh::keepCellIdsByType(INTERP_KERNEL::NormalizedCellType type, const int *begin, const int *end) const throw(INTERP_KERNEL::Exception)
+{
+  checkFullyDefined();
+  std::vector<int> r;
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connIndex=_nodal_connec_index->getConstPointer();
+  for(const int *w=begin;w!=end;w++)
+    if((INTERP_KERNEL::NormalizedCellType)conn[connIndex[*w]]==type)
+      r.push_back(*w);
+  DataArrayInt *ret=DataArrayInt::New();
+  ret->alloc((int)r.size(),1);
+  std::copy(r.begin(),r.end(),ret->getPointer());
+  return ret;
+}
+
+/*!
+ * This method makes the assumption that da->getNumberOfTuples()<this->getNumberOfCells(). This method makes the assumption that ids contained in 'da'
+ * are in [0:getNumberOfCells())
+ */
+DataArrayInt *MEDCouplingUMesh::convertCellArrayPerGeoType(const DataArrayInt *da) const throw(INTERP_KERNEL::Exception)
+{
+  checkFullyDefined();
+  const int *conn=_nodal_connec->getConstPointer();
+  const int *connI=_nodal_connec_index->getConstPointer();
+  int nbOfCells=getNumberOfCells();
+  std::set<INTERP_KERNEL::NormalizedCellType> types=getAllTypes();
+  int *tmp=new int[nbOfCells];
+  for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator iter=types.begin();iter!=types.end();iter++)
+    {
+      int j=0;
+      for(const int *i=connI;i!=connI+nbOfCells;i++)
+        if((INTERP_KERNEL::NormalizedCellType)conn[*i]==(*iter))
+          tmp[std::distance(connI,i)]=j++;
+    }
+  DataArrayInt *ret=DataArrayInt::New();
+  ret->alloc(da->getNumberOfTuples(),da->getNumberOfComponents());
+  ret->copyStringInfoFrom(*da);
+  int *retPtr=ret->getPointer();
+  const int *daPtr=da->getConstPointer();
+  int nbOfElems=da->getNbOfElems();
+  for(int k=0;k<nbOfElems;k++)
+    retPtr[k]=tmp[daPtr[k]];
+  delete [] tmp;
+  return ret;
+}
+
+/*!
+ * This method reduced number of cells of this by keeping cells whose type is different from 'type' and if type=='type'
+ * cells whose ids is in 'idsPerGeoType' array.
+ * This method conserves coords and name of mesh.
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::keepSpecifiedCells(INTERP_KERNEL::NormalizedCellType type, const int *idsPerGeoTypeBg, const int *idsPerGeoTypeEnd) const
+{
+  std::vector<int> idsTokeep;
+  int nbOfCells=getNumberOfCells();
+  int j=0;
+  for(int i=0;i<nbOfCells;i++)
+    if(getTypeOfCell(i)!=type)
+      idsTokeep.push_back(i);
+    else
+      {
+        if(std::find(idsPerGeoTypeBg,idsPerGeoTypeEnd,j)!=idsPerGeoTypeEnd)
+          idsTokeep.push_back(i);
+        j++;
+      }
+  MEDCouplingPointSet *ret=buildPartOfMySelf(&idsTokeep[0],&idsTokeep[0]+idsTokeep.size(),true);
+  MEDCouplingUMesh *ret2=dynamic_cast<MEDCouplingUMesh *>(ret);
+  if(!ret2)
+    {
+      ret->decrRef();
+      return 0;
+    }
+  ret2->copyTinyInfoFrom(this);
+  return ret2;
+}
+
+/*!
+ * This method returns a vector of size 'this->getNumberOfCells()'.
+ * This method retrieves for each cell in 'this' if it is linear (false) or quadratic(true).
+ */
+std::vector<bool> MEDCouplingUMesh::getQuadraticStatus() const throw(INTERP_KERNEL::Exception)
+{
+  int ncell=getNumberOfCells();
+  std::vector<bool> ret(ncell);
+  const int *cI=getNodalConnectivityIndex()->getConstPointer();
+  const int *c=getNodalConnectivity()->getConstPointer();
+  for(int i=0;i<ncell;i++)
+    {
+      INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)c[cI[i]];
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ);
+      ret[i]=cm.isQuadratic();
+    }
+  return ret;
+}
+
+/*!
+ * Returns a newly created mesh (with ref count ==1) that contains merge of 'this' and 'other'.
+ */
+MEDCouplingMesh *MEDCouplingUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const
+{
+  if(other->getType()!=UNSTRUCTURED)
+    throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh each other !");
+  const MEDCouplingUMesh *otherC=static_cast<const MEDCouplingUMesh *>(other);
+  return MergeUMeshes(this,otherC);
+}
+
+/*!
+ * Returns an array with this->getNumberOfCells() tuples and this->getSpaceDimension() dimension.
+ * The false barycenter is computed that is to say barycenter of a cell is computed using average on each
+ * components of coordinates of the cell.
+ */
+DataArrayDouble *MEDCouplingUMesh::getBarycenterAndOwner() const
+{
+  DataArrayDouble *ret=DataArrayDouble::New();
+  int spaceDim=getSpaceDimension();
+  int nbOfCells=getNumberOfCells();
+  ret->alloc(nbOfCells,spaceDim);
+  ret->copyStringInfoFrom(*getCoords());
+  double *ptToFill=ret->getPointer();
+  double *tmp=new double[spaceDim];
+  const int *nodal=_nodal_connec->getConstPointer();
+  const int *nodalI=_nodal_connec_index->getConstPointer();
+  const double *coor=_coords->getConstPointer();
+  for(int i=0;i<nbOfCells;i++)
+    {
+      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)nodal[nodalI[i]];
+      INTERP_KERNEL::computeBarycenter2<int,INTERP_KERNEL::ALL_C_MODE>(type,nodal+nodalI[i]+1,nodalI[i+1]-nodalI[i]-1,coor,spaceDim,ptToFill);
+      ptToFill+=spaceDim;
+    }
+  delete [] tmp;
+  return ret;
+}
+
+/*!
+ * This method is similar to MEDCouplingUMesh::getBarycenterAndOwner except that it works on subPart of 'this' without
+ * building explicitely it. The input part is defined by an array [begin,end). All ids contained in this array should be less than this->getNumberOfCells().
+ * No check of that will be done !
+ */
+DataArrayDouble *MEDCouplingUMesh::getPartBarycenterAndOwner(const int *begin, const int *end) const
+{
+  DataArrayDouble *ret=DataArrayDouble::New();
+  int spaceDim=getSpaceDimension();
+  int nbOfTuple=(int)std::distance(begin,end);
+  ret->alloc(nbOfTuple,spaceDim);
+  double *ptToFill=ret->getPointer();
+  double *tmp=new double[spaceDim];
+  const int *nodal=_nodal_connec->getConstPointer();
+  const int *nodalI=_nodal_connec_index->getConstPointer();
+  const double *coor=_coords->getConstPointer();
+  for(const int *w=begin;w!=end;w++)
+    {
+      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)nodal[nodalI[*w]];
+      INTERP_KERNEL::computeBarycenter2<int,INTERP_KERNEL::ALL_C_MODE>(type,nodal+nodalI[*w]+1,nodalI[*w+1]-nodalI[*w]-1,coor,spaceDim,ptToFill);
+      ptToFill+=spaceDim;
+    }
+  delete [] tmp;
+  return ret;
+}
+
+/*!
+ * This method expects as input a DataArrayDouble non nul instance 'da' that should be allocated. If not an exception is thrown.
+ * 
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::Build0DMeshFromCoords(DataArrayDouble *da) throw(INTERP_KERNEL::Exception)
+{
+  if(!da)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Build0DMeshFromCoords : instance of DataArrayDouble must be not null !");
+  da->checkAllocated();
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(da->getName().c_str(),0);
+  ret->setCoords(da);
+  int nbOfTuples=da->getNumberOfTuples();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::New();
+  c->alloc(2*nbOfTuples,1);
+  cI->alloc(nbOfTuples+1,1);
+  int *cp=c->getPointer();
+  int *cip=cI->getPointer();
+  *cip++=0;
+  for(int i=0;i<nbOfTuples;i++)
+    {
+      *cp++=INTERP_KERNEL::NORM_POINT1;
+      *cp++=i;
+      *cip++=2*(i+1);
+    }
+  ret->setConnectivity(c,cI,true);
+  ret->incrRef();
+  return ret;
+}
+
+/*!
+ * Returns a newly created mesh (with ref count ==1) that contains merge of 'mesh1' and 'other'.
+ * The coords of 'mesh2' are added at the end of coords of 'mesh1'.
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) throw(INTERP_KERNEL::Exception)
+{
+  std::vector<const MEDCouplingUMesh *> tmp(2);
+  tmp[0]=const_cast<MEDCouplingUMesh *>(mesh1); tmp[1]=const_cast<MEDCouplingUMesh *>(mesh2);
+  return MergeUMeshes(tmp);
+}
+
+/*!
+ * This method returns in case of success a mesh constitued from union of all meshes in 'a'.
+ * There should be \b no presence of null pointer into 'a'. If any an INTERP_KERNEL::Exception will be thrown.
+ * The returned mesh will contain aggregation of nodes in 'a' (in the same order) and aggregation of
+ * cells in meshes in 'a' (in the same order too).
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshes(std::vector<const MEDCouplingUMesh *>& a) throw(INTERP_KERNEL::Exception)
+{
+  std::size_t sz=a.size();
+  if(sz==0)
+    return MergeUMeshesLL(a);
+  for(std::size_t ii=0;ii<sz;ii++)
+    if(!a[ii])
+      {
+        std::ostringstream oss; oss << "MEDCouplingUMesh::MergeUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !";
+        throw INTERP_KERNEL::Exception(oss.str().c_str());
+      }
+  std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > bb(sz);
+  std::vector< const MEDCouplingUMesh * > aa(sz);
+  int spaceDim=-3;
+  for(std::size_t i=0;i<sz && spaceDim==-3;i++)
+    {
+      const MEDCouplingUMesh *cur=a[i];
+      const DataArrayDouble *coo=cur->getCoords();
+      if(coo)
+        spaceDim=coo->getNumberOfComponents();
+    }
+  if(spaceDim==-3)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::MergeUMeshes : no spaceDim specified ! unable to perform merge !");
+  for(std::size_t i=0;i<sz;i++)
+    {
+      bb[i]=a[i]->buildSetInstanceFromThis(spaceDim);
+      aa[i]=bb[i];
+    }
+  return MergeUMeshesLL(aa);
+}
+
+/// @cond INTERNAL
+
+MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshesLL(std::vector<const MEDCouplingUMesh *>& a) throw(INTERP_KERNEL::Exception)
+{
+  if(a.empty())
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::MergeUMeshes : input array must be NON EMPTY !");
+  std::vector<const MEDCouplingUMesh *>::const_iterator it=a.begin();
+  int meshDim=(*it)->getMeshDimension();
+  int nbOfCells=(*it)->getNumberOfCells();
+  int meshLgth=(*it++)->getMeshLength();
+  for(;it!=a.end();it++)
+    {
+      if(meshDim!=(*it)->getMeshDimension())
+        throw INTERP_KERNEL::Exception("Mesh dimensions mismatches, MergeUMeshes impossible !");
+      nbOfCells+=(*it)->getNumberOfCells();
+      meshLgth+=(*it)->getMeshLength();
+    }
+  std::vector<const MEDCouplingPointSet *> aps(a.size());
+  std::copy(a.begin(),a.end(),aps.begin());
+  DataArrayDouble *pts=MergeNodesArray(aps);
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New("merge",meshDim);
+  ret->setCoords(pts);
+  pts->decrRef();
+  DataArrayInt *c=DataArrayInt::New();
+  c->alloc(meshLgth,1);
+  int *cPtr=c->getPointer();
+  DataArrayInt *cI=DataArrayInt::New();
+  cI->alloc(nbOfCells+1,1);
+  int *cIPtr=cI->getPointer();
+  *cIPtr++=0;
+  int offset=0;
+  int offset2=0;
+  for(it=a.begin();it!=a.end();it++)
+    {
+      int curNbOfCell=(*it)->getNumberOfCells();
+      const int *curCI=(*it)->_nodal_connec_index->getConstPointer();
+      const int *curC=(*it)->_nodal_connec->getConstPointer();
+      cIPtr=std::transform(curCI+1,curCI+curNbOfCell+1,cIPtr,std::bind2nd(std::plus<int>(),offset));
+      for(int j=0;j<curNbOfCell;j++)
+        {
+          const int *src=curC+curCI[j];
+          *cPtr++=*src++;
+          for(;src!=curC+curCI[j+1];src++,cPtr++)
+            {
+              if(*src!=-1)
+                *cPtr=*src+offset2;
+              else
+                *cPtr=-1;
+            }
+        }
+      offset+=curCI[curNbOfCell];
+      offset2+=(*it)->getNumberOfNodes();
+    }
+  //
+  ret->setConnectivity(c,cI,true);
+  c->decrRef();
+  cI->decrRef();
+  ret->incrRef();
+  return ret;
+}
+
+/// @endcond
+
+/*!
+ * Idem MergeUMeshes except that 'meshes' are expected to lyie on the same coords and 'meshes' have the same meshdim.
+ * 'meshes' must be a non empty vector.
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshesOnSameCoords(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) throw(INTERP_KERNEL::Exception)
+{
+  std::vector<const MEDCouplingUMesh *> tmp(2);
+  tmp[0]=mesh1; tmp[1]=mesh2;
+  return MergeUMeshesOnSameCoords(tmp);
+}
+
+/*!
+ * Idem MergeUMeshes except that 'meshes' are expected to lyie on the same coords and 'meshes' have the same meshdim.
+ * 'meshes' must be a non empty vector.
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshesOnSameCoords(const std::vector<const MEDCouplingUMesh *>& meshes)
+{
+  if(meshes.empty())
+    throw INTERP_KERNEL::Exception("meshes input parameter is expected to be non empty.");
+  for(std::size_t ii=0;ii<meshes.size();ii++)
+    if(!meshes[ii])
+      {
+        std::ostringstream oss; oss << "MEDCouplingUMesh::MergeUMeshesOnSameCoords : item #" << ii << " in input array of size "<< meshes.size() << " is empty !";
+        throw INTERP_KERNEL::Exception(oss.str().c_str());
+      }
+  const DataArrayDouble *coords=meshes.front()->getCoords();
+  int meshDim=meshes.front()->getMeshDimension();
+  std::vector<const MEDCouplingUMesh *>::const_iterator iter=meshes.begin();
+  int meshLgth=0;
+  int meshIndexLgth=0;
+  for(;iter!=meshes.end();iter++)
+    {
+      if(coords!=(*iter)->getCoords())
+        throw INTERP_KERNEL::Exception("meshes does not share the same coords ! Try using tryToShareSameCoords method !");
+      if(meshDim!=(*iter)->getMeshDimension())
+        throw INTERP_KERNEL::Exception("Mesh dimensions mismatches, FuseUMeshesOnSameCoords impossible !");
+      meshLgth+=(*iter)->getMeshLength();
+      meshIndexLgth+=(*iter)->getNumberOfCells();
+    }
+  DataArrayInt *nodal=DataArrayInt::New();
+  nodal->alloc(meshLgth,1);
+  int *nodalPtr=nodal->getPointer();
+  DataArrayInt *nodalIndex=DataArrayInt::New();
+  nodalIndex->alloc(meshIndexLgth+1,1);
+  int *nodalIndexPtr=nodalIndex->getPointer();
+  int offset=0;
+  for(iter=meshes.begin();iter!=meshes.end();iter++)
+    {
+      const int *nod=(*iter)->getNodalConnectivity()->getConstPointer();
+      const int *index=(*iter)->getNodalConnectivityIndex()->getConstPointer();
+      int nbOfCells=(*iter)->getNumberOfCells();
+      int meshLgth2=(*iter)->getMeshLength();
+      nodalPtr=std::copy(nod,nod+meshLgth2,nodalPtr);
+      if(iter!=meshes.begin())
+        nodalIndexPtr=std::transform(index+1,index+nbOfCells+1,nodalIndexPtr,std::bind2nd(std::plus<int>(),offset));
+      else
+        nodalIndexPtr=std::copy(index,index+nbOfCells+1,nodalIndexPtr);
+      offset+=meshLgth2;
+    }
+  MEDCouplingUMesh *ret=MEDCouplingUMesh::New();
+  ret->setName("merge");
+  ret->setMeshDimension(meshDim);
+  ret->setConnectivity(nodal,nodalIndex,true);
+  ret->setCoords(coords);
+  nodalIndex->decrRef();
+  nodal->decrRef();
+  return ret;
+}
+
+/*!
+ * This method fuses meshes 'meshes' and returns the fused mesh and the correspondances arrays for each mesh in 'meshes' in returned mesh.
+ * If a same cell is detected in several meshes in 'meshes', this cell will appear only once in returned mesh (see ParaMEDMEM::MEDCouplingUMesh::zipConnectivityTraducer for more details)
+ *
+ * @param meshes input non empty vector containing meshes having same coordiantes array and same mesh dimension.
+ * @param compType see MEDCouplingUMesh::zipConnectivityTraducer
+ * @param corr output vector with same size as 'meshes' parameter. corr[i] is the correspondance array of mesh meshes[i] in returned mesh.
+ *             The arrays contained in 'corr' parameter are returned with refcounter set to one.
+ *             To avoid memory leaks the caller have to deal with each instances of DataArrayInt contained in 'corr' parameter.
+ * @return The mesh lying on the same coordinates than those in meshes. All cells in 'meshes' are in returned mesh with 
+ * @exception if meshes is a empty vector or meshes are not lying on same coordinates or meshes not have the same dimension.
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::FuseUMeshesOnSameCoords(const std::vector<const MEDCouplingUMesh *>& meshes, int compType, std::vector<DataArrayInt *>& corr)
+{
+  //All checks are delegated to MergeUMeshesOnSameCoords
+  MEDCouplingUMesh *ret=MergeUMeshesOnSameCoords(meshes);
+  DataArrayInt *o2n=ret->zipConnectivityTraducer(compType);
+  corr.resize(meshes.size());
+  std::size_t nbOfMeshes=meshes.size();
+  int offset=0;
+  const int *o2nPtr=o2n->getConstPointer();
+  for(std::size_t i=0;i<nbOfMeshes;i++)
+    {
+      DataArrayInt *tmp=DataArrayInt::New();
+      int curNbOfCells=meshes[i]->getNumberOfCells();
+      tmp->alloc(curNbOfCells,1);
+      std::copy(o2nPtr+offset,o2nPtr+offset+curNbOfCells,tmp->getPointer());
+      offset+=curNbOfCells;
+      tmp->setName(meshes[i]->getName());
+      corr[i]=tmp;
+    }
+  o2n->decrRef();
+  return ret;
+}
+
+/*!
+ * This method takes in input meshes \b meshes containing no null reference. If any an INTERP_KERNEL::Exception will be thrown.
+ * \b meshes should have a good coherency (connectivity and coordinates well defined).
+ * All mesh in \b meshes must have the same space dimension. If not an INTERP_KERNEL:Exception will be thrown.
+ * But mesh in \b meshes \b can \b have \b different \b mesh \b dimension \b each \b other.
+ *
+ * This method performs nothing if size of \b meshes is in [0,1].
+ * This method is particulary usefull in MEDLoader context to build a \ref ParaMEDMEM::MEDFileUMesh "MEDFileUMesh" instance that expects that underlying
+ * coordinates DataArrayDouble instance.
+ *
+ * \param [in,out] meshes : vector containing no null instance of MEDCouplingUMesh that in case of success of this method will be modified.
+ */
+void MEDCouplingUMesh::PutUMeshesOnSameAggregatedCoords(const std::vector<MEDCouplingUMesh *>& meshes) throw(INTERP_KERNEL::Exception)
+{
+  std::size_t sz=meshes.size();
+  if(sz==0 || sz==1)
+    return;
+  std::vector< const DataArrayDouble * > coords(meshes.size());
+  std::vector< const DataArrayDouble * >::iterator it2=coords.begin();
+  for(std::vector<MEDCouplingUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,it2++)
+    {
+      if((*it))
+        {
+          (*it)->checkConnectivityFullyDefined();
+          const DataArrayDouble *coo=(*it)->getCoords();
+          if(coo)
+            *it2=coo;
+          else
+            {
+              std::ostringstream oss; oss << " MEDCouplingUMesh::PutUMeshesOnSameAggregatedCoords : Item #" << std::distance(meshes.begin(),it) << " inside the vector of length " << meshes.size();
+              oss << " has no coordinate array defined !";
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }
+        }
+      else
+        {
+          std::ostringstream oss; oss << " MEDCouplingUMesh::PutUMeshesOnSameAggregatedCoords : Item #" << std::distance(meshes.begin(),it) << " inside the vector of length " << meshes.size();
+          oss << " is null !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> res=DataArrayDouble::Aggregate(coords);
+  std::vector<MEDCouplingUMesh *>::const_iterator it=meshes.begin();
+  int offset=(*it)->getNumberOfNodes();
+  (*it++)->setCoords(res);
+  for(;it!=meshes.end();it++)
+    {
+      int oldNumberOfNodes=(*it)->getNumberOfNodes();
+      (*it)->setCoords(res);
+      (*it)->shiftNodeNumbersInConn(offset);
+      offset+=oldNumberOfNodes;
+    }
+}
+
+/*!
+ * This method takes in input meshes \b meshes containing no null reference. If any an INTERP_KERNEL::Exception will be thrown.
+ * \b meshes should have a good coherency (connectivity and coordinates well defined).
+ * All mesh in \b meshes must have the same space dimension. If not an INTERP_KERNEL:Exception will be thrown.
+ * But mesh in \b meshes \b can \b have \b different \b mesh \b dimension \b each \b other.
+ * If \b meshes share the same instance of DataArrayDouble as coordinates and that this instance is null, this method do nothing and no exception will be thrown.
+ *
+ * This method performs nothing if size of \b meshes is empty.
+ * This method is particulary usefull in MEDLoader context to perform a treatment of a MEDFileUMesh instance on different levels.
+ * coordinates DataArrayDouble instance.
+ *
+ * \param [in,out] meshes :vector containing no null instance of MEDCouplingUMesh sharing the same DataArrayDouble instance of coordinates, that in case of success of this method will be modified.
+ * \param [in] eps is the distance in absolute (that should be positive !), so that 2 or more points within a distance of eps will be merged into a single point.
+ */
+void MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords(const std::vector<MEDCouplingUMesh *>& meshes, double eps) throw(INTERP_KERNEL::Exception)
+{
+  if(meshes.empty())
+    return ;
+  std::set<const DataArrayDouble *> s;
+  for(std::vector<MEDCouplingUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++)
+    {
+      if(*it)
+        s.insert((*it)->getCoords());
+      else
+        {
+          std::ostringstream oss; oss << "MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords : In input vector of unstructured meshes of size " << meshes.size() << " the element #" << std::distance(meshes.begin(),it) << " is null !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  if(s.size()!=1)
+    {
+      std::ostringstream oss; oss << "MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords : In input vector of unstructured meshes of size " << meshes.size() << ", it appears that they do not share the same instance of DataArrayDouble for coordiantes ! tryToShareSameCoordsPermute method can help to reach that !";
+      throw INTERP_KERNEL::Exception(oss.str().c_str());
+    }
+  const DataArrayDouble *coo=*(s.begin());
+  if(!coo)
+    return;
+  //
+  DataArrayInt *comm,*commI;
+  coo->findCommonTuples(eps,-1,comm,commI);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1(comm),tmp2(commI);
+  int oldNbOfNodes=coo->getNumberOfTuples();
+  int newNbOfNodes;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(oldNbOfNodes,comm,commI,newNbOfNodes);
+  if(oldNbOfNodes==newNbOfNodes)
+    return ;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=coo->renumberAndReduce(o2n->getConstPointer(),newNbOfNodes);
+  for(std::vector<MEDCouplingUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++)
+    {
+      (*it)->renumberNodesInConn(o2n->getConstPointer());
+      (*it)->setCoords(newCoords);
+    } 
+}
+
+/*!
+ * This method takes in input a cell defined by its MEDcouplingUMesh connectivity [connBg,connEnd) and returns its extruded cell by inserting the result at the end of ret.
+ * @param nbOfNodesPerLev in parameter that specifies the number of nodes of one slice of global dataset
+ * @param isQuad specifies the policy of connectivity.
+ * @ret in/out parameter in which the result will be append
+ */
+void MEDCouplingUMesh::AppendExtrudedCell(const int *connBg, const int *connEnd, int nbOfNodesPerLev, bool isQuad, std::vector<int>& ret)
+{
+  INTERP_KERNEL::NormalizedCellType flatType=(INTERP_KERNEL::NormalizedCellType)connBg[0];
+  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(flatType);
+  ret.push_back(cm.getExtrudedType());
+  int deltaz=isQuad?2*nbOfNodesPerLev:nbOfNodesPerLev;
+  switch(flatType)
+    {
+    case INTERP_KERNEL::NORM_POINT1:
+      {
+        ret.push_back(connBg[1]);
+        ret.push_back(connBg[1]+nbOfNodesPerLev);
+        break;
+      }
+    case INTERP_KERNEL::NORM_SEG2:
+      {
+        int conn[4]={connBg[1],connBg[2],connBg[2]+deltaz,connBg[1]+deltaz};
+        ret.insert(ret.end(),conn,conn+4);
+        break;
+      }
+    case INTERP_KERNEL::NORM_SEG3:
+      {
+        int conn[8]={connBg[1],connBg[3],connBg[3]+deltaz,connBg[1]+deltaz,connBg[2],connBg[3]+nbOfNodesPerLev,connBg[2]+deltaz,connBg[1]+nbOfNodesPerLev};
+        ret.insert(ret.end(),conn,conn+8);
+        break;
+      }
+    case INTERP_KERNEL::NORM_QUAD4:
+      {
+        int conn[8]={connBg[1],connBg[2],connBg[3],connBg[4],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz,connBg[4]+deltaz};
+        ret.insert(ret.end(),conn,conn+8);
+        break;
+      }
+    case INTERP_KERNEL::NORM_TRI3:
+      {
+        int conn[6]={connBg[1],connBg[2],connBg[3],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz};
+        ret.insert(ret.end(),conn,conn+6);
+        break;
+      }
+    case INTERP_KERNEL::NORM_TRI6:
+      {
+        int conn[15]={connBg[1],connBg[2],connBg[3],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz,connBg[4],connBg[5],connBg[6],connBg[4]+deltaz,connBg[5]+deltaz,connBg[6]+deltaz,
+                      connBg[1]+nbOfNodesPerLev,connBg[2]+nbOfNodesPerLev,connBg[3]+nbOfNodesPerLev};
+        ret.insert(ret.end(),conn,conn+15);
+        break;
+      }
+    case INTERP_KERNEL::NORM_QUAD8:
+      {
+        int conn[20]={
+          connBg[1],connBg[2],connBg[3],connBg[4],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz,connBg[4]+deltaz,
+          connBg[5],connBg[6],connBg[7],connBg[8],connBg[5]+deltaz,connBg[6]+deltaz,connBg[7]+deltaz,connBg[8]+deltaz,
+          connBg[1]+nbOfNodesPerLev,connBg[2]+nbOfNodesPerLev,connBg[3]+nbOfNodesPerLev,connBg[4]+nbOfNodesPerLev
+        };
+        ret.insert(ret.end(),conn,conn+20);
+        break;
+      }
+    case INTERP_KERNEL::NORM_POLYGON:
+      {
+        std::back_insert_iterator< std::vector<int> > ii(ret);
+        std::copy(connBg+1,connEnd,ii);
+        *ii++=-1;
+        std::reverse_iterator<const int *> rConnBg(connEnd);
+        std::reverse_iterator<const int *> rConnEnd(connBg+1);
+        std::transform(rConnBg,rConnEnd,ii,std::bind2nd(std::plus<int>(),deltaz));
+        std::size_t nbOfRadFaces=std::distance(connBg+1,connEnd);
+        for(std::size_t i=0;i<nbOfRadFaces;i++)
+          {
+            *ii++=-1;
+            int conn[4]={connBg[(i+1)%nbOfRadFaces+1],connBg[i+1],connBg[i+1]+deltaz,connBg[(i+1)%nbOfRadFaces+1]+deltaz};
+            std::copy(conn,conn+4,ii);
+          }
+        break;
+      }
+    default:
+      throw INTERP_KERNEL::Exception("A flat type has been detected that has not its extruded representation !");
+    }
+}
+
+/*!
+ * This static operates only for coords in 3D. The polygon is specfied by its connectivity nodes in [begin,end).
+ */
+bool MEDCouplingUMesh::IsPolygonWellOriented(bool isQuadratic, const double *vec, const int *begin, const int *end, const double *coords)
+{
+  double v[3]={0.,0.,0.};
+  std::size_t sz=std::distance(begin,end);
+  if(isQuadratic)
+    sz/=2;
+  for(std::size_t i=0;i<sz;i++)
+    {
+      v[0]+=coords[3*begin[i]+1]*coords[3*begin[(i+1)%sz]+2]-coords[3*begin[i]+2]*coords[3*begin[(i+1)%sz]+1];
+      v[1]+=coords[3*begin[i]+2]*coords[3*begin[(i+1)%sz]]-coords[3*begin[i]]*coords[3*begin[(i+1)%sz]+2];
+      v[2]+=coords[3*begin[i]]*coords[3*begin[(i+1)%sz]+1]-coords[3*begin[i]+1]*coords[3*begin[(i+1)%sz]];
+    }
+  return vec[0]*v[0]+vec[1]*v[1]+vec[2]*v[2]>0.;
+}
+
+/*!
+ * The polyhedron is specfied by its connectivity nodes in [begin,end).
+ */
+bool MEDCouplingUMesh::IsPolyhedronWellOriented(const int *begin, const int *end, const double *coords)
+{
+  std::vector<std::pair<int,int> > edges;
+  std::size_t nbOfFaces=std::count(begin,end,-1)+1;
+  const int *bgFace=begin;
+  for(std::size_t i=0;i<nbOfFaces;i++)
+    {
+      const int *endFace=std::find(bgFace+1,end,-1);
+      std::size_t nbOfEdgesInFace=std::distance(bgFace,endFace);
+      for(std::size_t j=0;j<nbOfEdgesInFace;j++)
+        {
+          std::pair<int,int> p1(bgFace[j],bgFace[(j+1)%nbOfEdgesInFace]);
+          if(std::find(edges.begin(),edges.end(),p1)!=edges.end())
+            return false;
+          edges.push_back(p1);
+        }
+      bgFace=endFace+1;
+    }
+  return INTERP_KERNEL::calculateVolumeForPolyh2<int,INTERP_KERNEL::ALL_C_MODE>(begin,(int)std::distance(begin,end),coords)>-EPS_FOR_POLYH_ORIENTATION;
+}
+
+/*!
+ * This method performs a simplyfication of a single polyedron cell. To do that each face of cell whose connectivity is defined by [\b begin, \b end) 
+ * is compared with the others in order to find faces in the same plane (with approx of eps). If any, the cells are grouped together and projected to
+ * a 2D space.
+ *
+ * \param [in] eps is a relative precision that allows to establish if some 3D plane are coplanar or not.
+ * \param [in] coords the coordinates with nb of components exactly equal to 3
+ * \param [in] begin begin of the nodal connectivity (geometric type included) of a single polyhedron cell
+ * \param [in] end end of nodal connectivity of a single polyhedron cell (excluded)
+ * \param [out] the result is put at the end of the vector without any alteration of the data.
+ */
+void MEDCouplingUMesh::SimplifyPolyhedronCell(double eps, const DataArrayDouble *coords, const int *begin, const int *end, std::vector<int>& res) throw(INTERP_KERNEL::Exception)
+{
+  int nbFaces=std::count(begin+1,end,-1)+1;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> v=DataArrayDouble::New(); v->alloc(nbFaces,3);
+  double *vPtr=v->getPointer();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> p=DataArrayDouble::New(); p->alloc(nbFaces,1);
+  double *pPtr=p->getPointer();
+  const int *stFaceConn=begin+1;
+  for(int i=0;i<nbFaces;i++,vPtr+=3,pPtr++)
+    {
+      const int *endFaceConn=std::find(stFaceConn,end,-1);
+      ComputeVecAndPtOfFace(eps,coords->getConstPointer(),stFaceConn,endFaceConn,vPtr,pPtr);
+      stFaceConn=endFaceConn+1;
+    }
+  pPtr=p->getPointer(); vPtr=v->getPointer();
+  DataArrayInt *comm1=0,*commI1=0;
+  v->findCommonTuples(eps,-1,comm1,commI1);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> comm1Auto(comm1),commI1Auto(commI1);
+  const int *comm1Ptr=comm1->getConstPointer();
+  const int *commI1Ptr=commI1->getConstPointer();
+  int nbOfGrps1=commI1Auto->getNumberOfTuples()-1;
+  res.push_back((int)INTERP_KERNEL::NORM_POLYHED);
+  //
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mm=MEDCouplingUMesh::New("",3);
+  mm->setCoords(const_cast<DataArrayDouble *>(coords)); mm->allocateCells(1); mm->insertNextCell(INTERP_KERNEL::NORM_POLYHED,(int)std::distance(begin+1,end),begin+1);
+  mm->finishInsertingCells();
+  //
+  for(int i=0;i<nbOfGrps1;i++)
+    {
+      int vecId=comm1Ptr[commI1Ptr[i]];
+      MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmpgrp2=p->selectByTupleId(comm1Ptr+commI1Ptr[i],comm1Ptr+commI1Ptr[i+1]);
+      DataArrayInt *comm2=0,*commI2=0;
+      tmpgrp2->findCommonTuples(eps,-1,comm2,commI2);
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> comm2Auto(comm2),commI2Auto(commI2);
+      const int *comm2Ptr=comm2->getConstPointer();
+      const int *commI2Ptr=commI2->getConstPointer();
+      int nbOfGrps2=commI2Auto->getNumberOfTuples()-1;
+      for(int j=0;j<nbOfGrps2;j++)
+        {
+          if(commI2Ptr[j+1]-commI2Ptr[j]<=1)
+            {
+              res.insert(res.end(),begin,end);
+              res.push_back(-1);
+            }
+          else
+            {
+              int pointId=comm1Ptr[commI1Ptr[i]+comm2Ptr[commI2Ptr[j]]];
+              MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=comm2->selectByTupleId2(commI2Ptr[j],commI2Ptr[j+1],1);
+              ids2->transformWithIndArr(comm1Ptr+commI1Ptr[i],comm1Ptr+commI1Ptr[i+1]);
+              DataArrayInt *tmp0=DataArrayInt::New(),*tmp1=DataArrayInt::New(),*tmp2=DataArrayInt::New(),*tmp3=DataArrayInt::New();
+              MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mm2=mm->buildDescendingConnectivity(tmp0,tmp1,tmp2,tmp3); tmp0->decrRef(); tmp1->decrRef(); tmp2->decrRef(); tmp3->decrRef();
+              MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mm3=static_cast<MEDCouplingUMesh *>(mm2->buildPartOfMySelf(ids2->begin(),ids2->end(),true));
+              MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idsNodeTmp=mm3->zipCoordsTraducer();
+              MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idsNode=idsNodeTmp->invertArrayO2N2N2O(mm3->getNumberOfNodes());
+              const int *idsNodePtr=idsNode->getConstPointer();
+              double center[3]; center[0]=pPtr[pointId]*vPtr[3*vecId]; center[1]=pPtr[pointId]*vPtr[3*vecId+1]; center[2]=pPtr[pointId]*vPtr[3*vecId+2];
+              double vec[3]; vec[0]=vPtr[3*vecId+1]; vec[1]=-vPtr[3*vecId]; vec[2]=0.;
+              double norm=vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2];
+              if(std::abs(norm)>eps)
+                {
+                  double angle=INTERP_KERNEL::EdgeArcCircle::SafeAsin(norm);
+                  mm3->rotate(center,vec,angle);
+                }
+              mm3->changeSpaceDimension(2);
+              MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mm4=mm3->buildSpreadZonesWithPoly();
+              const int *conn4=mm4->getNodalConnectivity()->getConstPointer();
+              const int *connI4=mm4->getNodalConnectivityIndex()->getConstPointer();
+              int nbOfCells=mm4->getNumberOfCells();
+              for(int k=0;k<nbOfCells;k++)
+                {
+                  int l=0;
+                  for(const int *work=conn4+connI4[k]+1;work!=conn4+connI4[k+1];work++,l++)
+                    res.push_back(idsNodePtr[*work]);
+                  res.push_back(-1);
+                }
+            }
+        }
+    }
+  res.pop_back();
+}
+
+/*!
+ * This method computes the normalized vector of the plane and the pos of the point belonging to the plane and the line defined by the vector going
+ * through origin. The plane is defined by its nodal connectivity [\b begin, \b end).
+ * 
+ * \param [in] eps below that value the dot product of 2 vectors is considered as colinears
+ * \param [in] coords coordinates expected to have 3 components.
+ * \param [in] begin start of the nodal connectivity of the face.
+ * \param [in] end end of the nodal connectivity (excluded) of the face.
+ * \param [out] v the normalized vector of size 3
+ * \param [out] p the pos of plane
+ */
+void MEDCouplingUMesh::ComputeVecAndPtOfFace(double eps, const double *coords, const int *begin, const int *end, double *v, double *p) throw(INTERP_KERNEL::Exception)
+{
+  std::size_t nbPoints=std::distance(begin,end);
+  if(nbPoints<3)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ComputeVecAndPtOfFace : < of 3 points in face ! not able to find a plane on that face !");
+  double vec[3];
+  std::size_t j=0;
+  bool refFound=false;
+  for(;j<nbPoints-1 && !refFound;j++)
+    {
+      vec[0]=coords[3*begin[j+1]]-coords[3*begin[j]];
+      vec[1]=coords[3*begin[j+1]+1]-coords[3*begin[j]+1];
+      vec[2]=coords[3*begin[j+1]+2]-coords[3*begin[j]+2];
+      double norm=sqrt(vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]);
+      if(norm>eps)
+        {
+          refFound=true;
+          vec[0]/=norm; vec[1]/=norm; vec[2]/=norm;
+        }
+    }
+  for(std::size_t i=j;i<nbPoints-1;i++)
+    {
+      double curVec[3];
+      curVec[0]=coords[3*begin[i+1]]-coords[3*begin[i]];
+      curVec[1]=coords[3*begin[i+1]+1]-coords[3*begin[i]+1];
+      curVec[2]=coords[3*begin[i+1]+2]-coords[3*begin[i]+2];
+      double norm=sqrt(curVec[0]*curVec[0]+curVec[1]*curVec[1]+curVec[2]*curVec[2]);
+      if(norm<eps)
+        continue;
+      curVec[0]/=norm; curVec[1]/=norm; curVec[2]/=norm;
+      v[0]=vec[1]*curVec[2]-vec[2]*curVec[1]; v[1]=vec[2]*curVec[0]-vec[0]*curVec[2]; v[2]=vec[0]*curVec[1]-vec[1]*curVec[0];
+      norm=sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);
+      if(norm>eps)
+        {
+          v[0]/=norm; v[1]/=norm; v[2]/=norm;
+          *p=v[0]*coords[3*begin[i]]+v[1]*coords[3*begin[i]+1]+v[2]*coords[3*begin[i]+2];
+          return ;
+        }
+    }
+  throw INTERP_KERNEL::Exception("Not able to find a normal vector of that 3D face !");
+}
+
+/*!
+ * This method tries to obtain a well oriented polyhedron.
+ * If the algorithm fails, an exception will be thrown.
+ */
+void MEDCouplingUMesh::TryToCorrectPolyhedronOrientation(int *begin, int *end, const double *coords) throw(INTERP_KERNEL::Exception)
+{
+  std::vector<std::pair<int,int> > edges;
+  std::size_t nbOfFaces=std::count(begin,end,-1)+1;
+  int *bgFace=begin;
+  std::vector<bool> isPerm(nbOfFaces);
+  for(std::size_t i=0;i<nbOfFaces;i++)
+    {
+      int *endFace=std::find(bgFace+1,end,-1);
+      std::size_t nbOfEdgesInFace=std::distance(bgFace,endFace);
+      for(std::size_t l=0;l<nbOfEdgesInFace;l++)
+        {
+          std::pair<int,int> p1(bgFace[l],bgFace[(l+1)%nbOfEdgesInFace]);
+          edges.push_back(p1);
+        }
+      int *bgFace2=endFace+1;
+      for(std::size_t k=i+1;k<nbOfFaces;k++)
+        {
+          int *endFace2=std::find(bgFace2+1,end,-1);
+          std::size_t nbOfEdgesInFace2=std::distance(bgFace2,endFace2);
+          for(std::size_t j=0;j<nbOfEdgesInFace2;j++)
+            {
+              std::pair<int,int> p2(bgFace2[j],bgFace2[(j+1)%nbOfEdgesInFace2]);
+              if(std::find(edges.begin(),edges.end(),p2)!=edges.end())
+                {
+                  if(isPerm[k])
+                    throw INTERP_KERNEL::Exception("Fail to repare polyhedron ! Polyedron looks bad !");
+                  std::vector<int> tmp(nbOfEdgesInFace2-1);
+                  std::copy(bgFace2+1,endFace2,tmp.rbegin());
+                  std::copy(tmp.begin(),tmp.end(),bgFace2+1);
+                  isPerm[k]=true;
+                  continue;
+                }
+            }
+          bgFace2=endFace2+1;
+        }
+      bgFace=endFace+1;
+    }
+  if(INTERP_KERNEL::calculateVolumeForPolyh2<int,INTERP_KERNEL::ALL_C_MODE>(begin,(int)std::distance(begin,end),coords)<-EPS_FOR_POLYH_ORIENTATION)
+    {//not lucky ! The first face was not correctly oriented : reorient all faces...
+      bgFace=begin;
+      for(std::size_t i=0;i<nbOfFaces;i++)
+        {
+          int *endFace=std::find(bgFace+1,end,-1);
+          std::size_t nbOfEdgesInFace=std::distance(bgFace,endFace);
+          std::vector<int> tmp(nbOfEdgesInFace-1);
+          std::copy(bgFace+1,endFace,tmp.rbegin());
+          std::copy(tmp.begin(),tmp.end(),bgFace+1);
+          bgFace=endFace+1;
+        }
+    }
+}
+
+/*!
+ * This method makes the assumption spacedimension == meshdimension == 2.
+ * This method works only for linear cells.
+ * 
+ * \return a newly allocated array containing the connectivity of a polygon type enum included (NORM_POLYGON in pos#0)
+ */
+DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMesh() const throw(INTERP_KERNEL::Exception)
+{
+  if(getMeshDimension()!=2 || getSpaceDimension()!=2)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : meshdimension, spacedimension must be equal to 2 !");
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=computeSkin();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=m->zipCoordsTraducer();
+  int nbOfNodesExpected=m->getNumberOfNodes();
+  if(m->getNumberOfCells()!=nbOfNodesExpected)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : the mesh 2D in input appears to be not in a single part or a quadratic 2D mesh !");
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o=o2n->invertArrayO2N2N2O(m->getNumberOfNodes());
+  const int *n2oPtr=n2o->getConstPointer();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodal(DataArrayInt::New()),revNodalI(DataArrayInt::New());
+  m->getReverseNodalConnectivity(revNodal,revNodalI);
+  const int *revNodalPtr=revNodal->getConstPointer(),*revNodalIPtr=revNodalI->getConstPointer();
+  const int *nodalPtr=m->getNodalConnectivity()->getConstPointer();
+  const int *nodalIPtr=m->getNodalConnectivityIndex()->getConstPointer();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfNodesExpected+1,1);
+  int *work=ret->getPointer();  *work++=INTERP_KERNEL::NORM_POLYGON;
+  if(nbOfNodesExpected<1)
+    { ret->incrRef(); return ret; }
+  int prevCell=0;
+  int prevNode=nodalPtr[nodalIPtr[0]+1];
+  *work++=n2oPtr[prevNode];
+  for(int i=1;i<nbOfNodesExpected;i++)
+    {
+      if(nodalIPtr[prevCell+1]-nodalIPtr[prevCell]==3)
+        {
+          std::set<int> conn(nodalPtr+nodalIPtr[prevCell]+1,nodalPtr+nodalIPtr[prevCell]+3);
+          conn.erase(prevNode);
+          if(conn.size()==1)
+            {
+              int curNode=*(conn.begin());
+              *work++=n2oPtr[curNode];
+              std::set<int> shar(revNodalPtr+revNodalIPtr[curNode],revNodalPtr+revNodalIPtr[curNode+1]);
+              shar.erase(prevCell);
+              if(shar.size()==1)
+                {
+                  prevCell=*(shar.begin());
+                  prevNode=curNode;
+                }
+              else
+                throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : presence of unexpected 2 !");
+            }
+          else
+            throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : presence of unexpected 1 !");
+        }
+      else
+        throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : presence of unexpected cell !");
+    }
+  ret->incrRef(); return ret;
+}
+
+/*!
+ * This method makes the assumption spacedimension == meshdimension == 3.
+ * This method works only for linear cells.
+ * 
+ * \return a newly allocated array containing the connectivity of a polygon type enum included (NORM_POLYHED in pos#0)
+ */
+DataArrayInt *MEDCouplingUMesh::buildUnionOf3DMesh() const throw(INTERP_KERNEL::Exception)
+{
+  if(getMeshDimension()!=3 || getSpaceDimension()!=3)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf3DMesh : meshdimension, spacedimension must be equal to 2 !");
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=computeSkin();
+  const int *conn=m->getNodalConnectivity()->getConstPointer();
+  const int *connI=m->getNodalConnectivityIndex()->getConstPointer();
+  int nbOfCells=m->getNumberOfCells();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(m->getNodalConnectivity()->getNumberOfTuples(),1);
+  int *work=ret->getPointer();  *work++=INTERP_KERNEL::NORM_POLYHED;
+  if(nbOfCells<1)
+    { ret->incrRef(); return ret; }
+  work=std::copy(conn+connI[0]+1,conn+connI[1],work);
+  for(int i=1;i<nbOfCells;i++)
+    {
+      *work++=-1;
+      work=std::copy(conn+connI[i]+1,conn+connI[i+1],work);
+    }
+  ret->incrRef();
+  return ret;
+}
+
+/*!
+ * This method put in zip format into parameter 'zipFrmt' in full interlace mode.
+ * This format is often asked by INTERP_KERNEL algorithms to avoid many indirections into coordinates array.
+ */
+void MEDCouplingUMesh::FillInCompact3DMode(int spaceDim, int nbOfNodesInCell, const int *conn, const double *coo, double *zipFrmt) throw(INTERP_KERNEL::Exception)
+{
+  double *w=zipFrmt;
+  if(spaceDim==3)
+    for(int i=0;i<nbOfNodesInCell;i++)
+      w=std::copy(coo+3*conn[i],coo+3*conn[i]+3,w);
+  else if(spaceDim==2)
+    {
+      for(int i=0;i<nbOfNodesInCell;i++)
+        {
+          w=std::copy(coo+2*conn[i],coo+2*conn[i]+2,w);
+          *w++=0.;
+        }
+    }
+  else
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::FillInCompact3DMode : Invalid spaceDim specified : must be 2 or 3 !");
+}
+
+void MEDCouplingUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData) const throw(INTERP_KERNEL::Exception)
+{
+  int nbOfCells=getNumberOfCells();
+  if(nbOfCells<=0)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::writeVTK : the unstructured mesh has no cells !");
+  static const int PARAMEDMEM2VTKTYPETRADUCER[INTERP_KERNEL::NORM_MAXTYPE+1]={1,3,21,5,9,7,22,-1,23,-1,-1,-1,-1,-1,10,14,13,-1,12,-1,24,-1,16,27,-1,26,-1,-1,-1,-1,25,42,-1,4};
+  ofs << "  <" << getVTKDataSetType() << ">\n";
+  ofs << "    <Piece NumberOfPoints=\"" << getNumberOfNodes() << "\" NumberOfCells=\"" << nbOfCells << "\">\n";
+  ofs << "      <PointData>\n" << pointData << std::endl;
+  ofs << "      </PointData>\n";
+  ofs << "      <CellData>\n" << cellData << std::endl;
+  ofs << "      </CellData>\n";
+  ofs << "      <Points>\n";
+  if(getSpaceDimension()==3)
+    _coords->writeVTK(ofs,8,"Points");
+  else
+    {
+      MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coo=_coords->changeNbOfComponents(3,0.);
+      coo->writeVTK(ofs,8,"Points");
+    }
+  ofs << "      </Points>\n";
+  ofs << "      <Cells>\n";
+  const int *cPtr=_nodal_connec->getConstPointer();
+  const int *cIPtr=_nodal_connec_index->getConstPointer();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> faceoffsets=DataArrayInt::New(); faceoffsets->alloc(nbOfCells,1);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> types=DataArrayInt::New(); types->alloc(nbOfCells,1);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> offsets=DataArrayInt::New(); offsets->alloc(nbOfCells,1);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connectivity=DataArrayInt::New(); connectivity->alloc(_nodal_connec->getNumberOfTuples()-nbOfCells,1);
+  int *w1=faceoffsets->getPointer(),*w2=types->getPointer(),*w3=offsets->getPointer(),*w4=connectivity->getPointer();
+  int szFaceOffsets=0,szConn=0;
+  for(int i=0;i<nbOfCells;i++,w1++,w2++,*w3++)
+    {
+      *w2=cPtr[cIPtr[i]];
+      if((INTERP_KERNEL::NormalizedCellType)cPtr[cIPtr[i]]!=INTERP_KERNEL::NORM_POLYHED)
+        {
+          *w1=-1;
+          *w3=szConn+cIPtr[i+1]-cIPtr[i]-1; szConn+=cIPtr[i+1]-cIPtr[i]-1;
+          w4=std::copy(cPtr+cIPtr[i]+1,cPtr+cIPtr[i+1],w4);
+        }
+      else
+        {
+          int deltaFaceOffset=cIPtr[i+1]-cIPtr[i]+1;
+          *w1=szFaceOffsets+deltaFaceOffset; szFaceOffsets+=deltaFaceOffset;
+          std::set<int> c(cPtr+cIPtr[i]+1,cPtr+cIPtr[i+1]); c.erase(-1);
+          *w3=szConn+(int)c.size(); szConn+=(int)c.size();
+          w4=std::copy(c.begin(),c.end(),w4);
+        }
+    }
+  types->transformWithIndArr(PARAMEDMEM2VTKTYPETRADUCER,PARAMEDMEM2VTKTYPETRADUCER+INTERP_KERNEL::NORM_MAXTYPE);
+  types->writeVTK(ofs,8,"UInt8","types");
+  offsets->writeVTK(ofs,8,"Int32","offsets");
+  if(szFaceOffsets!=0)
+    {//presence of Polyhedra
+      connectivity->reAlloc(szConn);
+      faceoffsets->writeVTK(ofs,8,"Int32","faceoffsets");
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> faces=DataArrayInt::New(); faces->alloc(szFaceOffsets,1);
+      w1=faces->getPointer();
+      for(int i=0;i<nbOfCells;i++)
+        if((INTERP_KERNEL::NormalizedCellType)cPtr[cIPtr[i]]==INTERP_KERNEL::NORM_POLYHED)
+          {
+            int nbFaces=std::count(cPtr+cIPtr[i]+1,cPtr+cIPtr[i+1],-1)+1;
+            *w1++=nbFaces;
+            const int *w4=cPtr+cIPtr[i]+1,*w5=0;
+            for(int j=0;j<nbFaces;j++)
+              {
+                w5=std::find(w4,cPtr+cIPtr[i+1],-1);
+                *w1++=(int)std::distance(w4,w5);
+                w1=std::copy(w4,w5,w1);
+                w4=w5+1;
+              }
+          }
+      faces->writeVTK(ofs,8,"Int32","faces");
+    }
+  connectivity->writeVTK(ofs,8,"Int32","connectivity");
+  ofs << "      </Cells>\n";
+  ofs << "    </Piece>\n";
+  ofs << "  </" << getVTKDataSetType() << ">\n";
+}
+
+std::string MEDCouplingUMesh::getVTKDataSetType() const throw(INTERP_KERNEL::Exception)
+{
+  return std::string("UnstructuredGrid");
+}
+
+/// @cond INTERNAL
+
+MEDCouplingUMesh *MEDCouplingUMesh::Intersect2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps, DataArrayInt *&cellNb1, DataArrayInt *&cellNb2) throw(INTERP_KERNEL::Exception)
+{
+  m1->checkFullyDefined();
+  m2->checkFullyDefined();
+  if(m1->getMeshDimension()!=2 || m1->getSpaceDimension()!=2 || m2->getMeshDimension()!=2 || m2->getSpaceDimension()!=2)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Intersect2DMeshes works on umeshes m1 AND m2  with meshdim equal to 2 and spaceDim equal to 2 too!");
+  std::vector< std::vector<int> > intersectEdge1, colinear2, subDiv2;
+  MEDCouplingUMesh *m1Desc=0,*m2Desc=0;
+  DataArrayInt *desc1=0,*descIndx1=0,*revDesc1=0,*revDescIndx1=0,*desc2=0,*descIndx2=0,*revDesc2=0,*revDescIndx2=0;
+  std::vector<double> addCoo,addCoordsQuadratic;
+  INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps;
+  INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps;
+  IntersectDescending2DMeshes(m1,m2,eps,intersectEdge1,colinear2, subDiv2,m1Desc,desc1,descIndx1,revDesc1,revDescIndx1,
+                              m2Desc,desc2,descIndx2,revDesc2,revDescIndx2,addCoo);
+  revDesc1->decrRef(); revDescIndx1->decrRef(); revDesc2->decrRef(); revDescIndx2->decrRef();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dd1(desc1),dd2(descIndx1),dd3(desc2),dd4(descIndx2);
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> dd5(m1Desc),dd6(m2Desc);
+  std::vector< std::vector<int> > intersectEdge2;
+  BuildIntersectEdges(m1Desc,m2Desc,addCoo,subDiv2,intersectEdge2);
+  subDiv2.clear(); dd5=0; dd6=0;
+  std::vector<int> cr,crI;
+  std::vector<int> cNb1,cNb2;
+  BuildIntersecting2DCellsFromEdges(eps,m1,desc1->getConstPointer(),descIndx1->getConstPointer(),intersectEdge1,colinear2,m2,desc2->getConstPointer(),descIndx2->getConstPointer(),intersectEdge2,addCoo,
+                                    /* outputs -> */addCoordsQuadratic,cr,crI,cNb1,cNb2);
+  //
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> addCooDa=DataArrayDouble::New();
+  addCooDa->alloc((int)(addCoo.size())/2,2);
+  std::copy(addCoo.begin(),addCoo.end(),addCooDa->getPointer());
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> addCoordsQuadraticDa=DataArrayDouble::New();
+  addCoordsQuadraticDa->alloc((int)(addCoordsQuadratic.size())/2,2);
+  std::copy(addCoordsQuadratic.begin(),addCoordsQuadratic.end(),addCoordsQuadraticDa->getPointer());
+  std::vector<const DataArrayDouble *> coordss(4);
+  coordss[0]=m1->getCoords(); coordss[1]=m2->getCoords(); coordss[2]=addCooDa; coordss[3]=addCoordsQuadraticDa;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coo=DataArrayDouble::Aggregate(coordss);
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New("Intersect2D",2);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn=DataArrayInt::New(); conn->alloc((int)cr.size(),1); std::copy(cr.begin(),cr.end(),conn->getPointer());
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connI=DataArrayInt::New(); connI->alloc((int)crI.size(),1); std::copy(crI.begin(),crI.end(),connI->getPointer());
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c1=DataArrayInt::New(); c1->alloc((int)cNb1.size(),1); std::copy(cNb1.begin(),cNb1.end(),c1->getPointer()); cellNb1=c1;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c2=DataArrayInt::New(); c2->alloc((int)cNb2.size(),1); std::copy(cNb2.begin(),cNb2.end(),c2->getPointer()); cellNb2=c2;
+  ret->setConnectivity(conn,connI,true);
+  ret->setCoords(coo);
+  ret->incrRef(); c1->incrRef(); c2->incrRef();
+  return ret;
+}
+
+/// @endcond
+
+void MEDCouplingUMesh::BuildIntersecting2DCellsFromEdges(double eps, const MEDCouplingUMesh *m1, const int *desc1, const int *descIndx1,
+                                                         const std::vector<std::vector<int> >& intesctEdges1, const std::vector< std::vector<int> >& colinear2,
+                                                         const MEDCouplingUMesh *m2, const int *desc2, const int *descIndx2, const std::vector<std::vector<int> >& intesctEdges2,
+                                                         const std::vector<double>& addCoords,
+                                                         std::vector<double>& addCoordsQuadratic, std::vector<int>& cr, std::vector<int>& crI, std::vector<int>& cNb1, std::vector<int>& cNb2)
+{
+  static const int SPACEDIM=2;
+  std::vector<double> bbox1,bbox2;
+  const double *coo1=m1->getCoords()->getConstPointer();
+  const int *conn1=m1->getNodalConnectivity()->getConstPointer();
+  const int *connI1=m1->getNodalConnectivityIndex()->getConstPointer();
+  int offset1=m1->getNumberOfNodes();
+  const double *coo2=m2->getCoords()->getConstPointer();
+  const int *conn2=m2->getNodalConnectivity()->getConstPointer();
+  const int *connI2=m2->getNodalConnectivityIndex()->getConstPointer();
+  int offset2=offset1+m2->getNumberOfNodes();
+  int offset3=offset2+((int)addCoords.size())/2;
+  m1->getBoundingBoxForBBTree(bbox1);
+  m2->getBoundingBoxForBBTree(bbox2);
+  BBTree<SPACEDIM,int> myTree(&bbox2[0],0,0,m2->getNumberOfCells(),eps);
+  int ncell1=m1->getNumberOfCells();
+  crI.push_back(0);
+  for(int i=0;i<ncell1;i++)
+    {
+      std::vector<int> candidates2;
+      myTree.getIntersectingElems(&bbox1[i*2*SPACEDIM],candidates2);
+      std::map<INTERP_KERNEL::Node *,int> mapp;
+      std::map<int,INTERP_KERNEL::Node *> mappRev;
+      INTERP_KERNEL::QuadraticPolygon pol1;
+      INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)conn1[connI1[i]];
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ);
+      MEDCouplingUMeshBuildQPFromMesh3(coo1,offset1,coo2,offset2,addCoords,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,/* output */mapp,mappRev);
+      pol1.buildFromCrudeDataArray(mappRev,cm.isQuadratic(),conn1+connI1[i]+1,coo1,
+                                   desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1);
+      std::vector<int> crTmp,crITmp;
+      crITmp.push_back(crI.back());
+      for(std::vector<int>::const_iterator it2=candidates2.begin();it2!=candidates2.end();it2++)
+        {
+          INTERP_KERNEL::QuadraticPolygon pol2;
+          pol1.initLocations();
+          MEDCouplingUMeshBuildQPFromMesh3(coo1,offset1,coo2,offset2,addCoords,desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,/* output */mapp,mappRev);
+          INTERP_KERNEL::NormalizedCellType typ2=(INTERP_KERNEL::NormalizedCellType)conn2[connI2[*it2]];
+          const INTERP_KERNEL::CellModel& cm2=INTERP_KERNEL::CellModel::GetCellModel(typ2);
+          pol2.buildFromCrudeDataArray2(mappRev,cm2.isQuadratic(),conn2+connI2[*it2]+1,coo2,desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,
+                                        pol1,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,colinear2);
+          //MEDCouplingUMeshAssignOnLoc(pol1,pol2,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,colinear2);
+          pol1.buildPartitionsAbs(pol2,mapp,i,*it2,offset3,addCoordsQuadratic,cr,crI,cNb1,cNb2);
+        }
+      if(!crTmp.empty())
+        {
+          cr.insert(cr.end(),crTmp.begin(),crTmp.end());
+          crI.insert(crI.end(),crITmp.begin()+1,crITmp.end());
+        }
+      for(std::map<int,INTERP_KERNEL::Node *>::const_iterator it=mappRev.begin();it!=mappRev.end();it++)
+        (*it).second->decrRef();
+    }
+}
+
+/*!
+ * This method is private and is the first step of Partition of 2D mesh (spaceDim==2 and meshDim==2).
+ * 
+ */
+void MEDCouplingUMesh::IntersectDescending2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps,
+                                                   std::vector< std::vector<int> >& intersectEdge1, std::vector< std::vector<int> >& colinear2, std::vector< std::vector<int> >& subDiv2,
+                                                   MEDCouplingUMesh *& m1Desc, DataArrayInt *&desc1, DataArrayInt *&descIndx1, DataArrayInt *&revDesc1, DataArrayInt *&revDescIndx1,
+                                                   MEDCouplingUMesh *& m2Desc, DataArrayInt *&desc2, DataArrayInt *&descIndx2, DataArrayInt *&revDesc2, DataArrayInt *&revDescIndx2,
+                                                   std::vector<double>& addCoo) throw(INTERP_KERNEL::Exception)
+{
+  static const int SPACEDIM=2;
+  desc1=DataArrayInt::New(); descIndx1=DataArrayInt::New(); revDesc1=DataArrayInt::New(); revDescIndx1=DataArrayInt::New();
+  desc2=DataArrayInt::New();
+  descIndx2=DataArrayInt::New();
+  revDesc2=DataArrayInt::New();
+  revDescIndx2=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dd1(desc1),dd2(descIndx1),dd3(revDesc1),dd4(revDescIndx1);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dd5(desc2),dd6(descIndx2),dd7(revDesc2),dd8(revDescIndx2);
+  m1Desc=m1->buildDescendingConnectivity2(desc1,descIndx1,revDesc1,revDescIndx1);
+  m2Desc=m2->buildDescendingConnectivity2(desc2,descIndx2,revDesc2,revDescIndx2);
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> dd9(m1Desc),dd10(m2Desc);
+  const int *c1=m1Desc->getNodalConnectivity()->getConstPointer();
+  const int *ci1=m1Desc->getNodalConnectivityIndex()->getConstPointer();
+  std::vector<double> bbox1,bbox2;
+  m1Desc->getBoundingBoxForBBTree(bbox1);
+  m2Desc->getBoundingBoxForBBTree(bbox2);
+  int ncell1=m1Desc->getNumberOfCells();
+  int ncell2=m2Desc->getNumberOfCells();
+  intersectEdge1.resize(ncell1);
+  colinear2.resize(ncell2);
+  subDiv2.resize(ncell2);
+  BBTree<SPACEDIM,int> myTree(&bbox2[0],0,0,m2Desc->getNumberOfCells(),-eps);
+  std::vector<int> candidates1(1);
+  int offset1=m1->getNumberOfNodes();
+  int offset2=offset1+m2->getNumberOfNodes();
+  for(int i=0;i<ncell1;i++)
+    {
+      std::vector<int> candidates2;
+      myTree.getIntersectingElems(&bbox1[i*2*SPACEDIM],candidates2);
+      if(!candidates2.empty())
+        {
+          std::map<INTERP_KERNEL::Node *,int> map1,map2;
+          INTERP_KERNEL::QuadraticPolygon *pol2=MEDCouplingUMeshBuildQPFromMesh(m2Desc,candidates2,map2);
+          candidates1[0]=i;
+          INTERP_KERNEL::QuadraticPolygon *pol1=MEDCouplingUMeshBuildQPFromMesh(m1Desc,candidates1,map1);
+          pol1->splitAbs(*pol2,map1,map2,offset1,offset2,candidates2,intersectEdge1[i],i,colinear2,subDiv2,addCoo);
+          delete pol2;
+          delete pol1;
+        }
+      else
+        intersectEdge1[i].insert(intersectEdge1[i].end(),c1+ci1[i]+1,c1+ci1[i+1]);
+    }
+  m1Desc->incrRef(); desc1->incrRef(); descIndx1->incrRef(); revDesc1->incrRef(); revDescIndx1->incrRef();
+  m2Desc->incrRef(); desc2->incrRef(); descIndx2->incrRef(); revDesc2->incrRef(); revDescIndx2->incrRef();
+}
+
+/*!
+ * This method performs the 2nd step of Partition of 2D mesh.
+ * This method has 4 inputs :
+ *  - a mesh 'm1' with meshDim==1 and a SpaceDim==2
+ *  - a mesh 'm2' with meshDim==1 and a SpaceDim==2
+ *  - subDiv of size 'm2->getNumberOfCells()' that lists for each seg cell in 'm' the splitting node ids in randomly sorted.
+ * The aim of this method is to sort the splitting nodes, if any, and to put in 'intersectEdge' output paramter based on edges of mesh 'm2'
+ * @param m1 is expected to be a mesh of meshDimension equal to 1 and spaceDim equal to 2. No check of that is performed by this method. Only present for its coords in case of 'subDiv' shares some nodes of 'm1'
+ * @param m2 is expected to be a mesh of meshDimension equal to 1 and spaceDim equal to 2. No check of that is performed by this method.
+ * @param addCoo input parameter with additionnal nodes linked to intersection of the 2 meshes.
+ */
+void MEDCouplingUMesh::BuildIntersectEdges(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, const std::vector<double>& addCoo, const std::vector< std::vector<int> >& subDiv, std::vector< std::vector<int> >& intersectEdge) throw(INTERP_KERNEL::Exception)
+{
+  int offset1=m1->getNumberOfNodes();
+  int ncell=m2->getNumberOfCells();
+  const int *c=m2->getNodalConnectivity()->getConstPointer();
+  const int *cI=m2->getNodalConnectivityIndex()->getConstPointer();
+  const double *coo=m2->getCoords()->getConstPointer();
+  const double *cooBis=m1->getCoords()->getConstPointer();
+  int offset2=offset1+m2->getNumberOfNodes();
+  intersectEdge.resize(ncell);
+  for(int i=0;i<ncell;i++,cI++)
+    {
+      const std::vector<int>& divs=subDiv[i];
+      int nnode=cI[1]-cI[0]-1;
+      std::map<int, std::pair<INTERP_KERNEL::Node *,bool> > mapp2;
+      std::map<INTERP_KERNEL::Node *, int> mapp22;
+      for(int j=0;j<nnode;j++)
+        {
+          INTERP_KERNEL::Node *nn=new INTERP_KERNEL::Node(coo[2*c[(*cI)+j+1]],coo[2*c[(*cI)+j+1]+1]);
+          int nnid=c[(*cI)+j+1];
+          mapp2[nnid]=std::pair<INTERP_KERNEL::Node *,bool>(nn,true);
+          mapp22[nn]=nnid+offset1;
+        }
+      INTERP_KERNEL::Edge *e=MEDCouplingUMeshBuildQPFromEdge((INTERP_KERNEL::NormalizedCellType)c[*cI],mapp2,c+(*cI)+1);
+      for(std::map<int, std::pair<INTERP_KERNEL::Node *,bool> >::const_iterator it=mapp2.begin();it!=mapp2.end();it++)
+        ((*it).second.first)->decrRef();
+      std::vector<INTERP_KERNEL::Node *> addNodes(divs.size());
+      std::map<INTERP_KERNEL::Node *,int> mapp3;
+      for(std::size_t j=0;j<divs.size();j++)
+        {
+          int id=divs[j];
+          INTERP_KERNEL::Node *tmp=0;
+          if(id<offset1)
+            tmp=new INTERP_KERNEL::Node(cooBis[2*id],cooBis[2*id+1]);
+          else if(id<offset2)
+            tmp=new INTERP_KERNEL::Node(coo[2*(id-offset1)],coo[2*(id-offset1)+1]);//if it happens, bad news mesh 'm2' is non conform.
+          else
+            tmp=new INTERP_KERNEL::Node(addCoo[2*(id-offset2)],addCoo[2*(id-offset2)+1]);
+          addNodes[j]=tmp;
+          mapp3[tmp]=id;
+        }
+      e->sortIdsAbs(addNodes,mapp22,mapp3,intersectEdge[i]);
+      for(std::vector<INTERP_KERNEL::Node *>::const_iterator it=addNodes.begin();it!=addNodes.end();it++)
+        (*it)->decrRef();
+      e->decrRef();
+    }
+}
+
+/*!
+ * This method is part of the Slice3D algorithm. It is the first step of assembly process, ones coordinates have been computed (by MEDCouplingUMesh::split3DCurveWithPlane method).
+ * This method allows to compute given the status of 3D curve cells and the descending connectivity 3DSurf->3DCurve to deduce the intersection of each 3D surf cells
+ * with a plane. The result will be put in 'cut3DSuf' out parameter.
+ * @param cut3DCurve  input paramter that gives for each 3DCurve cell if it owns fully to the plane or partially.
+ * @param nodesOnPlane, returns all the nodes that are on the plane.
+ * @param nodal3DSurf is the nodal connectivity of 3D surf mesh.
+ * @param nodalIndx3DSurf is the nodal connectivity index of 3D surf mesh.
+ * @param nodal3DCurve is the nodal connectivity of 3D curve mesh.
+ * @param nodal3DIndxCurve is the nodal connectivity index of 3D curve mesh.
+ * @param desc is the descending connectivity 3DSurf->3DCurve
+ * @param descIndx is the descending connectivity index 3DSurf->3DCurve
+ * @param cut3DSuf input/output param.
+ */
+void MEDCouplingUMesh::AssemblyForSplitFrom3DCurve(const std::vector<int>& cut3DCurve, std::vector<int>& nodesOnPlane, const int *nodal3DSurf, const int *nodalIndx3DSurf,
+                                                   const int *nodal3DCurve, const int *nodalIndx3DCurve,
+                                                   const int *desc, const int *descIndx, 
+                                                   std::vector< std::pair<int,int> >& cut3DSurf) throw(INTERP_KERNEL::Exception)
+{
+  std::set<int> nodesOnP(nodesOnPlane.begin(),nodesOnPlane.end());
+  int nbOf3DSurfCell=(int)cut3DSurf.size();
+  for(int i=0;i<nbOf3DSurfCell;i++)
+    {
+      std::vector<int> res;
+      int offset=descIndx[i];
+      int nbOfSeg=descIndx[i+1]-offset;
+      for(int j=0;j<nbOfSeg;j++)
+        {
+          int edgeId=desc[offset+j];
+          int status=cut3DCurve[edgeId];
+          if(status!=-2)
+            {
+              if(status>-1)
+                res.push_back(status);
+              else
+                {
+                  res.push_back(nodal3DCurve[nodalIndx3DCurve[edgeId]+1]);
+                  res.push_back(nodal3DCurve[nodalIndx3DCurve[edgeId]+2]);
+                }
+            }
+        }
+      switch(res.size())
+        {
+        case 2:
+          {
+            cut3DSurf[i].first=res[0]; cut3DSurf[i].second=res[1];
+            break;
+          }
+        case 1:
+        case 0:
+          {
+            std::set<int> s1(nodal3DSurf+nodalIndx3DSurf[i]+1,nodal3DSurf+nodalIndx3DSurf[i+1]);
+            std::set_intersection(nodesOnP.begin(),nodesOnP.end(),s1.begin(),s1.end(),std::back_insert_iterator< std::vector<int> >(res));
+            if(res.size()==2)
+              {
+                cut3DSurf[i].first=res[0]; cut3DSurf[i].second=res[1];
+              }
+            else
+              {
+                cut3DSurf[i].first=-1; cut3DSurf[i].second=-1;
+              }
+            break;
+          }
+        default:
+          {// case when plane is on a multi colinear edge of a polyhedron
+            if((int)res.size()==2*nbOfSeg)
+              {
+                cut3DSurf[i].first=-2; cut3DSurf[i].second=i;
+              }
+            else
+              throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AssemblyPointsFrom3DCurve : unexpected situation !");
+          }
+        }
+    }
+}
+
+/*!
+ * 'this' is expected to be a mesh with spaceDim==3 and meshDim==3. If not an exception will be thrown.
+ * This method is part of the Slice3D algorithm. It is the second step of assembly process, ones coordinates have been computed (by MEDCouplingUMesh::split3DCurveWithPlane method).
+ * This method allows to compute given the result of 3D surf cells with plane and the descending connectivity 3D->3DSurf to deduce the intersection of each 3D cells
+ * with a plane. The result will be put in 'nodalRes' 'nodalResIndx' and 'cellIds' out parameters.
+ * @param cut3DSurf  input paramter that gives for each 3DSurf its intersection with plane (result of MEDCouplingUMesh::AssemblyForSplitFrom3DCurve).
+ * @param desc is the descending connectivity 3D->3DSurf
+ * @param descIndx is the descending connectivity index 3D->3DSurf
+ */
+void MEDCouplingUMesh::assemblyForSplitFrom3DSurf(const std::vector< std::pair<int,int> >& cut3DSurf,
+                                                  const int *desc, const int *descIndx,
+                                                  std::vector<int>& nodalRes, std::vector<int>& nodalResIndx, std::vector<int>& cellIds) const throw(INTERP_KERNEL::Exception)
+{
+  checkFullyDefined();
+  if(getMeshDimension()!=3 || getSpaceDimension()!=3)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::assemblyForSplitFrom3DSurf works on umeshes with meshdim equal to 3 and spaceDim equal to 3 too!");
+  const int *nodal3D=_nodal_connec->getConstPointer();
+  const int *nodalIndx3D=_nodal_connec_index->getConstPointer();
+  int nbOfCells=getNumberOfCells();
+  for(int i=0;i<nbOfCells;i++)
+    {
+      std::map<int, std::set<int> > m;
+      int offset=descIndx[i];
+      int nbOfFaces=descIndx[i+1]-offset;
+      int start=-1;
+      int end=-1;
+      for(int j=0;j<nbOfFaces;j++)
+        {
+          const std::pair<int,int>& p=cut3DSurf[desc[offset+j]];
+          if(p.first!=-1 && p.second!=-1)
+            {
+              if(p.first!=-2)
+                {
+                  start=p.first; end=p.second;
+                  m[p.first].insert(p.second);
+                  m[p.second].insert(p.first);
+                }
+              else
+                {
+                  const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)nodal3D[nodalIndx3D[i]]);
+                  int sz=nodalIndx3D[i+1]-nodalIndx3D[i]-1;
+                  INTERP_KERNEL::AutoPtr<int> tmp=new int[sz];
+                  INTERP_KERNEL::NormalizedCellType cmsId;
+                  unsigned nbOfNodesSon=cm.fillSonCellNodalConnectivity2(j,nodal3D+nodalIndx3D[i]+1,sz,tmp,cmsId);
+                  start=tmp[0]; end=tmp[nbOfNodesSon-1];
+                  for(unsigned k=0;k<nbOfNodesSon;k++)
+                    {
+                      m[tmp[k]].insert(tmp[(k+1)%nbOfNodesSon]);
+                      m[tmp[(k+1)%nbOfNodesSon]].insert(tmp[k]);
+                    }
+                }
+            }
+        }
+      if(m.empty())
+        continue;
+      std::vector<int> conn(1,(int)INTERP_KERNEL::NORM_POLYGON);
+      int prev=end;
+      while(end!=start)
+        {
+          std::map<int, std::set<int> >::const_iterator it=m.find(start);
+          const std::set<int>& s=(*it).second;
+          std::set<int> s2; s2.insert(prev);
+          std::set<int> s3;
+          std::set_difference(s.begin(),s.end(),s2.begin(),s2.end(),inserter(s3,s3.begin()));
+          if(s3.size()==1)
+            {
+              int val=*s3.begin();
+              conn.push_back(start);
+              prev=start;
+              start=val;
+            }
+          else
+            start=end;
+        }
+      conn.push_back(end);
+      if(conn.size()>3)
+        {
+          nodalRes.insert(nodalRes.end(),conn.begin(),conn.end());
+          nodalResIndx.push_back((int)nodalRes.size());
+          cellIds.push_back(i);
+        }
+    }
+}
+
+/*!
+ * This method compute the convex hull of a single 2D cell. This method tries to conserve at maximum the given input connectivity. In particular, if the orientation of cell is not clockwise
+ * as in MED format norm. If definitely the result of Jarvis algorithm is not matchable with the input connectivity, the result will be copied into \b nodalConnecOut parameter and
+ * the geometric cell type set to INTERP_KERNEL::NORM_POLYGON.
+ * This method excepts that \b coords parameter is expected to be in dimension 2. [\b nodalConnBg, \b nodalConnEnd) is the nodal connectivity of the input
+ * cell (geometric cell type included at the position 0). If the meshdimension of the input cell is not equal to 2 an INTERP_KERNEL::Exception will be thrown.
+ * 
+ * @return false if the input connectivity represents already the convex hull, true if the input cell needs to be reordered.
+ */
+bool MEDCouplingUMesh::BuildConvexEnvelopOf2DCellJarvis(const double *coords, const int *nodalConnBg, const int *nodalConnEnd, std::vector<int>& nodalConnecOut) throw(INTERP_KERNEL::Exception)
+{
+  std::size_t sz=std::distance(nodalConnBg,nodalConnEnd);
+  if(sz>=4)
+    {
+      const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)*nodalConnBg);
+      if(cm.getDimension()==2)
+        {
+          const int *node=nodalConnBg+1;
+          int startNode=*node++;
+          double refX=coords[2*startNode];
+          for(;node!=nodalConnEnd;node++)
+            {
+              if(coords[2*(*node)]<refX)
+                {
+                  startNode=*node;
+                  refX=coords[2*startNode];
+                }
+            }
+          std::vector<int> tmpOut; tmpOut.reserve(sz); tmpOut.push_back(startNode);
+          refX=1e300;
+          double tmp1;
+          double tmp2[2];
+          double angle0=-M_PI/2;
+          //
+          int nextNode=-1;
+          int prevNode=-1;
+          double resRef;
+          double angleNext;
+          while(nextNode!=startNode)
+            {
+              nextNode=-1;
+              resRef=1e300;
+              for(node=nodalConnBg+1;node!=nodalConnEnd;node++)
+                {
+                  if(*node!=tmpOut.back() && *node!=prevNode)
+                    {
+                      tmp2[0]=coords[2*(*node)]-coords[2*tmpOut.back()]; tmp2[1]=coords[2*(*node)+1]-coords[2*tmpOut.back()+1];
+                      double angleM=INTERP_KERNEL::EdgeArcCircle::GetAbsoluteAngle(tmp2,tmp1);
+                      double res;
+                      if(angleM<=angle0)
+                        res=angle0-angleM;
+                      else
+                        res=angle0-angleM+2.*M_PI;
+                      if(res<resRef)
+                        {
+                          nextNode=*node;
+                          resRef=res;
+                          angleNext=angleM;
+                        }
+                    }
+                }
+              if(nextNode!=startNode)
+                {
+                  angle0=angleNext-M_PI;
+                  if(angle0<-M_PI)
+                    angle0+=2*M_PI;
+                  prevNode=tmpOut.back();
+                  tmpOut.push_back(nextNode);
+                }
+            }
+          std::vector<int> tmp3(2*(sz-1));
+          std::vector<int>::iterator it=std::copy(nodalConnBg+1,nodalConnEnd,tmp3.begin());
+          std::copy(nodalConnBg+1,nodalConnEnd,it);
+          if(std::search(tmp3.begin(),tmp3.end(),tmpOut.begin(),tmpOut.end())!=tmp3.end())
+            {
+              nodalConnecOut.insert(nodalConnecOut.end(),nodalConnBg,nodalConnEnd);
+              return false;
+            }
+          if(std::search(tmp3.rbegin(),tmp3.rend(),tmpOut.begin(),tmpOut.end())!=tmp3.rend())
+            {
+              nodalConnecOut.insert(nodalConnecOut.end(),nodalConnBg,nodalConnEnd);
+              return false;
+            }
+          else
+            {
+              nodalConnecOut.push_back((int)INTERP_KERNEL::NORM_POLYGON);
+              nodalConnecOut.insert(nodalConnecOut.end(),tmpOut.begin(),tmpOut.end());
+              return true;
+            }
+        }
+    }
+  else
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::BuildConvexEnvelopOf2DCellJarvis : invalid 2D cell connectivity !");
+}
+
+/*!
+ * This method works on an input pair (\b arr, \b arrIndx) where \b arr indexes is in \b arrIndx.
+ * This method will not impact the size of inout parameter \b arrIndx but the size of \b arr will be modified in case of suppression.
+ * 
+ * \param [in] idsToRemoveBg begin of set of ids to remove in \b arr (included)
+ * \param [in] idsToRemoveEnd end of set of ids to remove in \b arr (excluded)
+ * \param [in,out] arr array in which the remove operation will be done.
+ * \param [in,out] arrIndx array in the remove operation will modify
+ * \param [in] offsetForRemoval (by default 0) offset so that for each i in [0,arrIndx->getNumberOfTuples()-1) removal process will be performed in the following range [arr+arrIndx[i]+offsetForRemoval,arr+arr[i+1])
+ * \return true if \b arr and \b arrIndx have been modified, false if not.
+ */
+bool MEDCouplingUMesh::RemoveIdsFromIndexedArrays(const int *idsToRemoveBg, const int *idsToRemoveEnd, DataArrayInt *arr, DataArrayInt *arrIndx, int offsetForRemoval) throw(INTERP_KERNEL::Exception)
+{
+  if(!arrIndx || !arr)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::RemoveIdsFromIndexedArrays : some input arrays are empty !");
+  if(offsetForRemoval<0)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::RemoveIdsFromIndexedArrays : offsetForRemoval should be >=0 !");
+  std::set<int> s(idsToRemoveBg,idsToRemoveEnd);
+  int nbOfGrps=arrIndx->getNumberOfTuples()-1;
+  int *arrIPtr=arrIndx->getPointer();
+  *arrIPtr++=0;
+  int previousArrI=0;
+  const int *arrPtr=arr->getConstPointer();
+  std::vector<int> arrOut;
+  for(int i=0;i<nbOfGrps;i++,arrIPtr++)
+    {
+      if(*arrIPtr-previousArrI>offsetForRemoval)
+        {
+          for(const int *work=arrPtr+previousArrI+offsetForRemoval;work!=arrPtr+*arrIPtr;work++)
+            {
+              if(s.find(*work)==s.end())
+                arrOut.push_back(*work);
+            }
+        }
+      previousArrI=*arrIPtr;
+      *arrIPtr=(int)arrOut.size();
+    }
+  if(arr->getNumberOfTuples()==(int)arrOut.size())
+    return false;
+  arr->alloc((int)arrOut.size(),1);
+  std::copy(arrOut.begin(),arrOut.end(),arr->getPointer());
+  return true;
+}
+
+/*!
+ * This method works on a pair input (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
+ * This method returns the result of the extraction ( specified by a set of ids in [\b idsOfSelectBg , \b idsOfSelectEnd ) ).
+ * The selection of extraction is done standardly in new2old format.
+ * This method returns indexed arrays using 2 arrays (arrOut,arrIndexOut).
+ *
+ * \param [in] idsOfSelectBg begin of set of ids of the input extraction (included)
+ * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded)
+ * \param [in] arrIn arr origin array from which the extraction will be done.
+ * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
+ * \param [out] arrOut the resulting array
+ * \param [out] arrIndexOut the index array of the resulting array \b arrOut
+ */
+void MEDCouplingUMesh::ExtractFromIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn,
+                                                DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut) throw(INTERP_KERNEL::Exception)
+{
+  if(!arrIn || !arrIndxIn)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays : input pointer is NULL !");
+  std::size_t sz=std::distance(idsOfSelectBg,idsOfSelectEnd);
+  const int *arrInPtr=arrIn->getConstPointer();
+  const int *arrIndxPtr=arrIndxIn->getConstPointer();
+  int nbOfGrps=arrIndxIn->getNumberOfTuples()-1;
+  int maxSizeOfArr=arrIn->getNumberOfTuples();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arro=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arrIo=DataArrayInt::New();
+  arrIo->alloc((int)(sz+1),1);
+  const int *idsIt=idsOfSelectBg;
+  int *work=arrIo->getPointer();
+  *work++=0;
+  int lgth=0;
+  for(std::size_t i=0;i<sz;i++,work++,idsIt++)
+    {
+      if(*idsIt>=0 && *idsIt<nbOfGrps)
+        lgth+=arrIndxPtr[*idsIt+1]-arrIndxPtr[*idsIt];
+      else
+        {
+          std::ostringstream oss; oss << "MEDCouplingUMesh::ExtractFromIndexedArrays : id located on pos #" << i << " value is " << *idsIt << " ! Must be in [0," << nbOfGrps << ") !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+      if(lgth>=work[-1])
+        *work=lgth;
+      else
+        {
+          std::ostringstream oss; oss << "MEDCouplingUMesh::ExtractFromIndexedArrays : id located on pos #" << i << " value is " << *idsIt << " and at this pos arrIndxIn[" << *idsIt;
+          oss << "+1]-arrIndxIn[" << *idsIt << "] < 0 ! The input index array is bugged !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  arro->alloc(lgth,1);
+  work=arro->getPointer();
+  idsIt=idsOfSelectBg;
+  for(std::size_t i=0;i<sz;i++,idsIt++)
+    {
+      if(arrIndxPtr[*idsIt]>=0 && arrIndxPtr[*idsIt+1]<=maxSizeOfArr)
+        work=std::copy(arrInPtr+arrIndxPtr[*idsIt],arrInPtr+arrIndxPtr[*idsIt+1],work);
+      else
+        {
+          std::ostringstream oss; oss << "MEDCouplingUMesh::ExtractFromIndexedArrays : id located on pos #" << i << " value is " << *idsIt << " arrIndx[" << *idsIt << "] must be >= 0 and arrIndx[";
+          oss << *idsIt << "+1] <= " << maxSizeOfArr << " (the size of arrIn)!";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  arrOut=arro;
+  arrIndexOut=arrIo;
+  arro->incrRef();
+  arrIo->incrRef();
+}
+
+/*!
+ * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
+ * This method builds an output pair (\b arrOut,\b arrIndexOut) that is a copy from \b arrIn for all cell ids \b not \b in [\b idsOfSelectBg, \b idsOfSelectEnd) and for
+ * cellIds \b in [\b idsOfSelectBg, \b idsOfSelectEnd) a copy coming from the corresponding values in input pair (\b srcArr, \b srcArrIndex).
+ * This method is an generalization of MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx that performs the same thing but by without building explicitely a result output arrays.
+ *
+ * \param [in] idsOfSelectBg begin of set of ids of the input extraction (included)
+ * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded)
+ * \param [in] arrIn arr origin array from which the extraction will be done.
+ * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
+ * \param [in] srcArr input array that will be used as source of copy for ids in [\b idsOfSelectBg, \b idsOfSelectEnd)
+ * \param [in] srcArrIndex index array of \b srcArr
+ * \param [out] arrOut the resulting array
+ * \param [out] arrIndexOut the index array of the resulting array \b arrOut
+ * 
+ * \sa MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx
+ */
+void MEDCouplingUMesh::SetPartOfIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn,
+                                              const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex,
+                                              DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut) throw(INTERP_KERNEL::Exception)
+{
+  if(arrIn==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArrays : presence of null pointer in input parameter !");
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arro=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arrIo=DataArrayInt::New();
+  int nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
+  std::vector<bool> v(nbOfTuples,true);
+  int offset=0;
+  const int *arrIndxInPtr=arrIndxIn->getConstPointer();
+  const int *srcArrIndexPtr=srcArrIndex->getConstPointer();
+  for(const int *it=idsOfSelectBg;it!=idsOfSelectEnd;it++,srcArrIndexPtr++)
+    {
+      if(*it>=0 && *it<nbOfTuples)
+        {
+          v[*it]=false;
+          offset+=(srcArrIndexPtr[1]-srcArrIndexPtr[0])-(arrIndxInPtr[*it+1]-arrIndxInPtr[*it]);
+        }
+      else
+        {
+          std::ostringstream oss; oss << "MEDCouplingUMesh::SetPartOfIndexedArrays : On pos #" << std::distance(idsOfSelectBg,it) << " value is " << *it << " not in [0," << nbOfTuples << ") !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  srcArrIndexPtr=srcArrIndex->getConstPointer();
+  arrIo->alloc(nbOfTuples+1,1);
+  arro->alloc(arrIn->getNumberOfTuples()+offset,1);
+  const int *arrInPtr=arrIn->getConstPointer();
+  const int *srcArrPtr=srcArr->getConstPointer();
+  int *arrIoPtr=arrIo->getPointer(); *arrIoPtr++=0;
+  int *arroPtr=arro->getPointer();
+  for(int ii=0;ii<nbOfTuples;ii++,arrIoPtr++)
+    {
+      if(v[ii])
+        {
+          arroPtr=std::copy(arrInPtr+arrIndxInPtr[ii],arrInPtr+arrIndxInPtr[ii+1],arroPtr);
+          *arrIoPtr=arrIoPtr[-1]+(arrIndxInPtr[ii+1]-arrIndxInPtr[ii]);
+        }
+      else
+        {
+          std::size_t pos=std::distance(idsOfSelectBg,std::find(idsOfSelectBg,idsOfSelectEnd,ii));
+          arroPtr=std::copy(srcArrPtr+srcArrIndexPtr[pos],srcArrPtr+srcArrIndexPtr[pos+1],arroPtr);
+          *arrIoPtr=arrIoPtr[-1]+(srcArrIndexPtr[pos+1]-srcArrIndexPtr[pos]);
+        }
+    }
+  arrOut=arro; arro->incrRef();
+  arrIndexOut=arrIo; arrIo->incrRef();
+}
+
+/*!
+ * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
+ * This method is an specialization of MEDCouplingUMesh::SetPartOfIndexedArrays in the case of assignement do not modify the index in \b arrIndxIn.
+ *
+ * \param [in] idsOfSelectBg begin of set of ids of the input extraction (included)
+ * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded)
+ * \param [in,out] arrInOut arr origin array from which the extraction will be done.
+ * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
+ * \param [in] srcArr input array that will be used as source of copy for ids in [\b idsOfSelectBg, \b idsOfSelectEnd)
+ * \param [in] srcArrIndex index array of \b srcArr
+ * 
+ * \sa MEDCouplingUMesh::SetPartOfIndexedArrays
+ */
+void MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx(const int *idsOfSelectBg, const int *idsOfSelectEnd, DataArrayInt *arrInOut, const DataArrayInt *arrIndxIn,
+                                                     const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex) throw(INTERP_KERNEL::Exception)
+{
+  if(arrInOut==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx : presence of null pointer in input parameter !");
+  int nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
+  const int *arrIndxInPtr=arrIndxIn->getConstPointer();
+  const int *srcArrIndexPtr=srcArrIndex->getConstPointer();
+  int *arrInOutPtr=arrInOut->getPointer();
+  const int *srcArrPtr=srcArr->getConstPointer();
+  for(const int *it=idsOfSelectBg;it!=idsOfSelectEnd;it++,srcArrIndexPtr++)
+    {
+      if(*it>=0 && *it<nbOfTuples)
+        {
+          if(srcArrIndexPtr[1]-srcArrIndexPtr[0]==arrIndxInPtr[*it+1]-arrIndxInPtr[*it])
+            std::copy(srcArrPtr+srcArrIndexPtr[0],srcArrPtr+srcArrIndexPtr[1],arrInOutPtr+arrIndxInPtr[*it]);
+          else
+            {
+              std::ostringstream oss; oss << "MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx : On pos #" << std::distance(idsOfSelectBg,it) << " id (idsOfSelectBg[" << std::distance(idsOfSelectBg,it)<< "]) is " << *it << " arrIndxIn[id+1]-arrIndxIn[id]!=srcArrIndex[pos+1]-srcArrIndex[pos] !";
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }
+        }
+      else
+        {
+          std::ostringstream oss; oss << "MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx : On pos #" << std::distance(idsOfSelectBg,it) << " value is " << *it << " not in [0," << nbOfTuples << ") !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+}
+
+/*!
+ * This method works on a pair input (\b arrIn, \b arrIndxIn) where \b arr indexes is in \b arrIndxIn.
+ * This method expects that these two input arrays come from the output of MEDCouplingUMesh::computeNeighborsOfCells method.
+ * This method start from id 0 that will be contained in output DataArrayInt. It searches then all neighbors of id0 regarding arrIn[arrIndxIn[0]:arrIndxIn[0+1]].
+ * Then it is repeated recursively until either all ids are fetched or no more ids are reachable step by step.
+ * A negative value in \b arrIn means that it is ignored.
+ * This method is usefull to see if a mesh is contiguous regarding its connectivity. If it is not the case the size of returned array is different from arrIndxIn->getNumberOfTuples()-1.
+ * 
+ * \param [in] arrIn arr origin array from which the extraction will be done.
+ * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
+ * \return a newly allocated DataArray that stores all ids fetched by the gradually spread process.
+ */
+DataArrayInt *MEDCouplingUMesh::ComputeSpreadZoneGradually(const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn) throw(INTERP_KERNEL::Exception)
+{
+  if(!arrIn || !arrIndxIn)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays : input pointer is NULL !");
+  int nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
+  if(nbOfTuples<=0)
+    {
+      DataArrayInt *ret=DataArrayInt::New(); ret->alloc(0,1);
+      return ret;
+    }
+  const int *arrInPtr=arrIn->getConstPointer();
+  const int *arrIndxPtr=arrIndxIn->getConstPointer();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arro=DataArrayInt::New();
+  arro->alloc(nbOfTuples,1);
+  arro->fillWithValue(-1);
+  int *arroPtr=arro->getPointer();
+  std::set<int> s; s.insert(0);
+  while(!s.empty())
+    {
+      std::set<int> s2;
+      for(std::set<int>::const_iterator it=s.begin();it!=s.end();it++)
+        {
+          for(const int *work=arrInPtr+arrIndxPtr[*it];work!=arrInPtr+arrIndxPtr[*it+1];work++)
+            {
+              if(*work>=0 && arroPtr[*work]<0)
+                {
+                  arroPtr[*work]=1;
+                  s2.insert(*work);
+                }
+            }
+        }
+      s=s2;
+    }
+  return arro->getIdsEqual(1);
+}
+
+/*!
+ * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
+ * This method builds an output pair (\b arrOut,\b arrIndexOut) that is a copy from \b arrIn for all cell ids \b not \b in [\b idsOfSelectBg, \b idsOfSelectEnd) and for
+ * cellIds \b in [\b idsOfSelectBg, \b idsOfSelectEnd) a copy coming from the corresponding values in input pair (\b srcArr, \b srcArrIndex).
+ * This method is an generalization of MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx that performs the same thing but by without building explicitely a result output arrays.
+ *
+ * \param [in] start begin of set of ids of the input extraction (included)
+ * \param [in] end end of set of ids of the input extraction (excluded)
+ * \param [in] step step of the set of ids in range mode.
+ * \param [in] arrIn arr origin array from which the extraction will be done.
+ * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
+ * \param [in] srcArr input array that will be used as source of copy for ids in [\b idsOfSelectBg, \b idsOfSelectEnd)
+ * \param [in] srcArrIndex index array of \b srcArr
+ * \param [out] arrOut the resulting array
+ * \param [out] arrIndexOut the index array of the resulting array \b arrOut
+ * 
+ * \sa MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx MEDCouplingUMesh::SetPartOfIndexedArrays
+ */
+void MEDCouplingUMesh::SetPartOfIndexedArrays2(int start, int end, int step, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn,
+                                               const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex,
+                                               DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut) throw(INTERP_KERNEL::Exception)
+{
+  if(arrIn==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArrays2 : presence of null pointer in input parameter !");
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arro=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arrIo=DataArrayInt::New();
+  int nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
+  int offset=0;
+  const int *arrIndxInPtr=arrIndxIn->getConstPointer();
+  const int *srcArrIndexPtr=srcArrIndex->getConstPointer();
+  int nbOfElemsToSet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::SetPartOfIndexedArrays2 : ");
+  int it=start;
+  for(int i=0;i<nbOfElemsToSet;i++,srcArrIndexPtr++,it+=step)
+    {
+      if(it>=0 && it<nbOfTuples)
+        offset+=(srcArrIndexPtr[1]-srcArrIndexPtr[0])-(arrIndxInPtr[it+1]-arrIndxInPtr[it]);
+      else
+        {
+          std::ostringstream oss; oss << "MEDCouplingUMesh::SetPartOfIndexedArrays2 : On pos #" << i << " value is " << it << " not in [0," << nbOfTuples << ") !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+  srcArrIndexPtr=srcArrIndex->getConstPointer();
+  arrIo->alloc(nbOfTuples+1,1);
+  arro->alloc(arrIn->getNumberOfTuples()+offset,1);
+  const int *arrInPtr=arrIn->getConstPointer();
+  const int *srcArrPtr=srcArr->getConstPointer();
+  int *arrIoPtr=arrIo->getPointer(); *arrIoPtr++=0;
+  int *arroPtr=arro->getPointer();
+  for(int ii=0;ii<nbOfTuples;ii++,arrIoPtr++)
+    {
+      int pos=DataArray::GetPosOfItemGivenBESRelativeNoThrow(ii,start,end,step);
+      if(pos<0)
+        {
+          arroPtr=std::copy(arrInPtr+arrIndxInPtr[ii],arrInPtr+arrIndxInPtr[ii+1],arroPtr);
+          *arrIoPtr=arrIoPtr[-1]+(arrIndxInPtr[ii+1]-arrIndxInPtr[ii]);
+        }
+      else
+        {
+          arroPtr=std::copy(srcArrPtr+srcArrIndexPtr[pos],srcArrPtr+srcArrIndexPtr[pos+1],arroPtr);
+          *arrIoPtr=arrIoPtr[-1]+(srcArrIndexPtr[pos+1]-srcArrIndexPtr[pos]);
+        }
+    }
+  arrOut=arro; arro->incrRef();
+  arrIndexOut=arrIo; arrIo->incrRef();
+}
+
+/*!
+ * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn.
+ * This method is an specialization of MEDCouplingUMesh::SetPartOfIndexedArrays in the case of assignement do not modify the index in \b arrIndxIn.
+ *
+ * \param [in] start begin of set of ids of the input extraction (included)
+ * \param [in] end end of set of ids of the input extraction (excluded)
+ * \param [in] step step of the set of ids in range mode.
+ * \param [in,out] arrInOut arr origin array from which the extraction will be done.
+ * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn
+ * \param [in] srcArr input array that will be used as source of copy for ids in [\b idsOfSelectBg, \b idsOfSelectEnd)
+ * \param [in] srcArrIndex index array of \b srcArr
+ * 
+ * \sa MEDCouplingUMesh::SetPartOfIndexedArrays2 MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx
+ */
+void MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2(int start, int end, int step, DataArrayInt *arrInOut, const DataArrayInt *arrIndxIn,
+                                                      const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex) throw(INTERP_KERNEL::Exception)
+{
+  if(arrInOut==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2 : presence of null pointer in input parameter !");
+  int nbOfTuples=arrIndxIn->getNumberOfTuples()-1;
+  const int *arrIndxInPtr=arrIndxIn->getConstPointer();
+  const int *srcArrIndexPtr=srcArrIndex->getConstPointer();
+  int *arrInOutPtr=arrInOut->getPointer();
+  const int *srcArrPtr=srcArr->getConstPointer();
+  int nbOfElemsToSet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2 : ");
+  int it=start;
+  for(int i=0;i<nbOfElemsToSet;i++,srcArrIndexPtr++,it+=step)
+    {
+      if(it>=0 && it<nbOfTuples)
+        {
+          if(srcArrIndexPtr[1]-srcArrIndexPtr[0]==arrIndxInPtr[it+1]-arrIndxInPtr[it])
+            std::copy(srcArrPtr+srcArrIndexPtr[0],srcArrPtr+srcArrIndexPtr[1],arrInOutPtr+arrIndxInPtr[it]);
+          else
+            {
+              std::ostringstream oss; oss << "MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2 : On pos #" << i << " id (idsOfSelectBg[" << i << "]) is " << it << " arrIndxIn[id+1]-arrIndxIn[id]!=srcArrIndex[pos+1]-srcArrIndex[pos] !";
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }
+        }
+      else
+        {
+          std::ostringstream oss; oss << "MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2 : On pos #" << i << " value is " << it << " not in [0," << nbOfTuples << ") !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
+    }
+}
+
+/*!
+ * \b this is expected to be a mesh fully defined whose spaceDim==meshDim.
+ * It returns a new allocated mesh having the same mesh dimension and lying on same coordinates.
+ * The returned mesh contains as poly cells as number of contiguous zone (regarding connectivity).
+ * A spread contiguous zone is built using poly cells (polyhedra in 3D, polygons in 2D and polyline in 1D).
+ * The sum of measure field of returned mesh is equal to the sum of measure field of this.
+ * 
+ * \return a newly allocated mesh lying on the same coords than \b this with same meshdimension than \b this.
+ */
+MEDCouplingUMesh *MEDCouplingUMesh::buildSpreadZonesWithPoly() const throw(INTERP_KERNEL::Exception)
+{
+  checkFullyDefined();
+  int mdim=getMeshDimension();
+  int spaceDim=getSpaceDimension();
+  if(mdim!=spaceDim)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSpreadZonesWithPoly : meshdimension and spacedimension do not match !");
+  int nbCells=getNumberOfCells();
+  std::vector<DataArrayInt *> partition=partitionBySpreadZone();
+  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > partitionAuto; partitionAuto.reserve(partition.size());
+  std::copy(partition.begin(),partition.end(),std::back_insert_iterator<std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > >(partitionAuto));
+  MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),mdim);
+  ret->setCoords(getCoords());
+  ret->allocateCells((int)partition.size());
+  //
+  for(std::vector<DataArrayInt *>::const_iterator it=partition.begin();it!=partition.end();it++)
+    {
+      MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp=static_cast<MEDCouplingUMesh *>(buildPartOfMySelf((*it)->begin(),(*it)->end(),true));
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cell;
+      switch(mdim)
+        {
+        case 2:
+          cell=tmp->buildUnionOf2DMesh();
+          break;
+        case 3:
+          cell=tmp->buildUnionOf3DMesh();
+          break;
+        default:
+          throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSpreadZonesWithPoly : meshdimension supported are [2,3] ! Not implemented yet for others !");
+        }
+      
+      ret->insertNextCell((INTERP_KERNEL::NormalizedCellType)cell->getIJSafe(0,0),cell->getNumberOfTuples()-1,cell->getConstPointer()+1);
+    }
+  //
+  ret->finishInsertingCells();
+  ret->incrRef(); return ret;
+}
+
+/*!
+ * This method partitions \b this into contiguous zone.
+ * This method only needs a well defined connectivity. Coordinates are not considered here.
+ * This method returns a vector of \b newly allocated arrays that the caller has to deal with.
+ */
+std::vector<DataArrayInt *> MEDCouplingUMesh::partitionBySpreadZone() const throw(INTERP_KERNEL::Exception)
+{
+  int nbOfCellsCur=getNumberOfCells();
+  DataArrayInt *neigh=0,*neighI=0;
+  computeNeighborsOfCells(neigh,neighI);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> neighAuto(neigh),neighIAuto(neighI);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=DataArrayInt::New(); ids->alloc(nbOfCellsCur,1); ids->iota();
+  std::vector<DataArrayInt *> ret;
+  std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret2;
+  while(nbOfCellsCur>0)
+    {
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=MEDCouplingUMesh::ComputeSpreadZoneGradually(neighAuto,neighIAuto);
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp3=tmp->buildComplement(nbOfCellsCur);
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp2=ids->selectByTupleId(tmp->begin(),tmp->end());
+      ret2.push_back(tmp2);  ret.push_back(tmp2);
+      nbOfCellsCur=tmp3->getNumberOfTuples();
+      if(nbOfCellsCur>0)
+        {
+          ids=ids->selectByTupleId(tmp3->begin(),tmp3->end());
+          MEDCouplingUMesh::ExtractFromIndexedArrays(tmp3->begin(),tmp3->end(),neighAuto,neighIAuto,neigh,neighI);
+          neighAuto=neigh;
+          neighIAuto=neighI;
+          MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renum=tmp3->invertArrayN2O2O2N(nbOfCellsCur+tmp->getNumberOfTuples());
+          neighAuto->transformWithIndArr(renum->begin(),renum->end());
+        }
+    }
+  for(std::vector<DataArrayInt *>::const_iterator it=ret.begin();it!=ret.end();it++)
+    (*it)->incrRef();
+  return ret;
+}
+
+/*!
+ * This method returns given a distribution of cell type (returned for example by MEDCouplingUMesh::getDistributionOfTypes method and customized after) a
+ * newly allocated DataArrayInt instance with 2 components ready to be interpreted as input of DataArrayInt::findRangeIdForEachTuple method.
+ *
+ * \param [in] code a code with the same format than those returned by MEDCouplingUMesh::getDistributionOfTypes except for the code[3*k+2] that should contain start id of chunck.
+ * \return a newly allocated DataArrayInt to be managed by the caller.
+ * \throw In case of \a code has not the right format (typically of size 3*n)
+ */
+DataArrayInt *MEDCouplingUMesh::ComputeRangesFromTypeDistribution(const std::vector<int>& code) throw(INTERP_KERNEL::Exception)
+{
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
+  std::size_t nb=code.size()/3;
+  if(code.size()%3!=0)
+    throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ComputeRangesFromTypeDistribution : invalid input code !");
+  ret->alloc((int)nb,2);
+  int *retPtr=ret->getPointer();
+  for(std::size_t i=0;i<nb;i++,retPtr+=2)
+    {
+      retPtr[0]=code[3*i+2];
+      retPtr[1]=code[3*i+2]+code[3*i+1];
+    }
+  ret->incrRef();
+  return ret;
+}
+
+MEDCouplingUMeshCellIterator::MEDCouplingUMeshCellIterator(MEDCouplingUMesh *mesh):_mesh(mesh),_cell(new MEDCouplingUMeshCell(mesh)),
+                                                                                   _own_cell(true),_cell_id(-1),_nb_cell(0)
+{
+  if(mesh)
+    {
+      mesh->incrRef();
+      _nb_cell=mesh->getNumberOfCells();
+    }
+}
+
+MEDCouplingUMeshCellIterator::~MEDCouplingUMeshCellIterator()
+{
+  if(_mesh)
+    _mesh->decrRef();
+  if(_own_cell)
+    delete _cell;
+}
+
+MEDCouplingUMeshCellIterator::MEDCouplingUMeshCellIterator(MEDCouplingUMesh *mesh, MEDCouplingUMeshCell *itc, int bg, int end):_mesh(mesh),_cell(itc),
+                                                                                                                               _own_cell(false),_cell_id(bg-1),
+                                                                                                                               _nb_cell(end)
+{
+  if(mesh)
+    mesh->incrRef();
+}
+
+MEDCouplingUMeshCell *MEDCouplingUMeshCellIterator::nextt()
+{
+  _cell_id++;
+  if(_cell_id<_nb_cell)
+    {
+      _cell->next();
+      return _cell;
+    }
+  else
+    return 0;
+}
+
+MEDCouplingUMeshCellByTypeEntry::MEDCouplingUMeshCellByTypeEntry(MEDCouplingUMesh *mesh):_mesh(mesh)
+{
+  if(_mesh)
+    _mesh->incrRef();
+}
+
+MEDCouplingUMeshCellByTypeIterator *MEDCouplingUMeshCellByTypeEntry::iterator()
+{
+  return new MEDCouplingUMeshCellByTypeIterator(_mesh);
+}
+
+MEDCouplingUMeshCellByTypeEntry::~MEDCouplingUMeshCellByTypeEntry()
+{
+  if(_mesh)
+    _mesh->decrRef();
+}
+
+MEDCouplingUMeshCellEntry::MEDCouplingUMeshCellEntry(MEDCouplingUMesh *mesh,  INTERP_KERNEL::NormalizedCellType type, MEDCouplingUMeshCell *itc, int bg, int end):_mesh(mesh),_type(type),
+                                                                                                                                                                  _itc(itc),
+                                                                                                                                                                  _bg(bg),_end(end)
+{
+  if(_mesh)
+    _mesh->incrRef();
+}
+
+MEDCouplingUMeshCellEntry::~MEDCouplingUMeshCellEntry()
+{
+  if(_mesh)
+    _mesh->decrRef();
+}
+
+INTERP_KERNEL::NormalizedCellType MEDCouplingUMeshCellEntry::getType() const
+{
+  return _type;
+}
+
+int MEDCouplingUMeshCellEntry::getNumberOfElems() const
+{
+  return _end-_bg;
+}
+
+MEDCouplingUMeshCellIterator *MEDCouplingUMeshCellEntry::iterator()
+{
+  return new MEDCouplingUMeshCellIterator(_mesh,_itc,_bg,_end);
+}
+
+MEDCouplingUMeshCellByTypeIterator::MEDCouplingUMeshCellByTypeIterator(MEDCouplingUMesh *mesh):_mesh(mesh),_cell(new MEDCouplingUMeshCell(mesh)),_cell_id(0),_nb_cell(0)
+{
+  if(mesh)
+    {
+      mesh->incrRef();
+      _nb_cell=mesh->getNumberOfCells();
+    }
+}
+
+MEDCouplingUMeshCellByTypeIterator::~MEDCouplingUMeshCellByTypeIterator()
+{
+  if(_mesh)
+    _mesh->decrRef();
+  delete _cell;
+}
+
+MEDCouplingUMeshCellEntry *MEDCouplingUMeshCellByTypeIterator::nextt()
+{
+  const int *c=_mesh->getNodalConnectivity()->getConstPointer();
+  const int *ci=_mesh->getNodalConnectivityIndex()->getConstPointer();
+  if(_cell_id<_nb_cell)
+    {
+      INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)c[ci[_cell_id]];
+      int nbOfElems=(int)std::distance(ci+_cell_id,std::find_if(ci+_cell_id,ci+_nb_cell,ParaMEDMEMImpl::ConnReader(c,type)));
+      int startId=_cell_id;
+      _cell_id+=nbOfElems;
+      return new MEDCouplingUMeshCellEntry(_mesh,type,_cell,startId,_cell_id);
+    }
+  else
+    return 0;
+}
+
+MEDCouplingUMeshCell::MEDCouplingUMeshCell(MEDCouplingUMesh *mesh):_conn(0),_conn_indx(0),_conn_lgth(NOTICABLE_FIRST_VAL)
+{
+  if(mesh)
+    {
+      _conn=mesh->getNodalConnectivity()->getPointer();
+      _conn_indx=mesh->getNodalConnectivityIndex()->getPointer();
+    }
+}
+
+void MEDCouplingUMeshCell::next()
+{
+  if(_conn_lgth!=NOTICABLE_FIRST_VAL)
+    {
+      _conn+=_conn_lgth;
+      _conn_indx++;
+    }
+  _conn_lgth=_conn_indx[1]-_conn_indx[0];
+}
+
+std::string MEDCouplingUMeshCell::repr() const
+{
+  if(_conn_lgth!=NOTICABLE_FIRST_VAL)
+    {
+      std::ostringstream oss; oss << "Cell Type " << INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)_conn[0]).getRepr();
+      oss << " : ";
+      std::copy(_conn+1,_conn+_conn_lgth,std::ostream_iterator<int>(oss," "));
+      return oss.str();
+    }
+  else
+    return std::string("MEDCouplingUMeshCell::repr : Invalid pos");
+}
+
+INTERP_KERNEL::NormalizedCellType MEDCouplingUMeshCell::getType() const
+{
+  if(_conn_lgth!=NOTICABLE_FIRST_VAL)
+    return (INTERP_KERNEL::NormalizedCellType)_conn[0];
+  else
+    return INTERP_KERNEL::NORM_ERROR;
+}
+
+const int *MEDCouplingUMeshCell::getAllConn(int& lgth) const
+{
+  lgth=_conn_lgth;
+  if(_conn_lgth!=NOTICABLE_FIRST_VAL)
+    return _conn;
+  else
+    return 0;
 }