Salome HOME
On the road
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingMemArray.cxx
index 743e7dd7a9aec2e61036f5e2c3a6111101d6d817..566c0797687b55bd7ccf6a474920ee22e46d64ec 100644 (file)
@@ -16,7 +16,7 @@
 //
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
-// Author : Anthony Geay (CEA/DEN)
+// Author : Anthony Geay (EDF R&D)
 
 #include "MEDCouplingMemArray.txx"
 
@@ -36,8 +36,17 @@ typedef double (*MYFUNCPTR)(double);
 
 using namespace MEDCoupling;
 
-template class DataArrayTemplate<int>;
-template class DataArrayTemplate<double>;
+template class MEDCoupling::MemArray<int>;
+template class MEDCoupling::MemArray<double>;
+template class MEDCoupling::DataArrayTemplate<int>;
+template class MEDCoupling::DataArrayTemplate<double>;
+template class MEDCoupling::DataArrayTemplateClassic<int>;
+template class MEDCoupling::DataArrayTemplateClassic<double>;
+template class MEDCoupling::DataArrayTemplateFP<double>;
+template class MEDCoupling::DataArrayIterator<double>;
+template class MEDCoupling::DataArrayIterator<int>;
+template class MEDCoupling::DataArrayDiscrete<Int32>;
+template class MEDCoupling::DataArrayDiscreteSigned<Int32>;
 
 template<int SPACEDIM>
 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
@@ -112,6 +121,22 @@ void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTre
     }
 }
 
+int DataArray::EffectiveCircPerm(int nbOfShift, int nbOfTuples)
+{
+  if(nbOfTuples<=0)
+    throw INTERP_KERNEL::Exception("DataArray::EffectiveCircPerm : number of tuples is expected to be > 0 !");
+  if(nbOfShift>=0)
+    {
+      return nbOfShift%nbOfTuples;
+    }
+  else
+    {
+      int tmp(-nbOfShift);
+      tmp=tmp%nbOfTuples;
+      return nbOfTuples-tmp;
+    }
+}
+
 std::size_t DataArray::getHeapMemorySizeWithoutChildren() const
 {
   std::size_t sz1=_name.capacity();
@@ -784,78 +809,6 @@ DataArrayDouble *DataArrayDouble::deepCopy() const
   return new DataArrayDouble(*this);
 }
 
-/*!
- * Returns either a \a deep or \a shallow copy of this array. For more info see
- * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
- *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
- *  \return DataArrayDouble * - either a new instance of DataArrayDouble (if \a dCpy
- *          == \a true) or \a this instance (if \a dCpy == \a false).
- */
-DataArrayDouble *DataArrayDouble::performCopyOrIncrRef(bool dCpy) const
-{
-  if(dCpy)
-    return deepCopy();
-  else
-    {
-      incrRef();
-      return const_cast<DataArrayDouble *>(this);
-    }
-}
-
-/*!
- * Assign zero to all values in \a this array. To know more on filling arrays see
- * \ref MEDCouplingArrayFill.
- * \throw If \a this is not allocated.
- */
-void DataArrayDouble::fillWithZero()
-{
-  fillWithValue(0.);
-}
-
-/*!
- * Set all values in \a this array so that the i-th element equals to \a init + i
- * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
- *  \param [in] init - value to assign to the first element of array.
- *  \throw If \a this->getNumberOfComponents() != 1
- *  \throw If \a this is not allocated.
- */
-void DataArrayDouble::iota(double init)
-{
-  checkAllocated();
-  if(getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
-  double *ptr=getPointer();
-  int ntuples=getNumberOfTuples();
-  for(int i=0;i<ntuples;i++)
-    ptr[i]=init+double(i);
-  declareAsNew();
-}
-
-/*!
- * Checks if all values in \a this array are equal to \a val at precision \a eps.
- *  \param [in] val - value to check equality of array values to.
- *  \param [in] eps - precision to check the equality.
- *  \return bool - \a true if all values are in range (_val_ - _eps_; _val_ + _eps_),
- *                 \a false else.
- *  \throw If \a this->getNumberOfComponents() != 1
- *  \throw If \a this is not allocated.
- */
-bool DataArrayDouble::isUniform(double val, double eps) const
-{
-  checkAllocated();
-  if(getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !");
-  int nbOfTuples=getNumberOfTuples();
-  const double *w=getConstPointer();
-  const double *end2=w+nbOfTuples;
-  const double vmin=val-eps;
-  const double vmax=val+eps;
-  for(;w!=end2;w++)
-    if(*w<vmin || *w>vmax)
-      return false;
-  return true;
-}
-
 /*!
  * Checks that \a this array is consistently **increasing** or **decreasing** in value,
  * with at least absolute difference value of |\a eps| at each step.
@@ -1033,8 +986,8 @@ void DataArrayDouble::reprNotTooLongWithoutNameStream(std::ostream& stream) cons
 
 void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const
 {
-  int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
-  const double *data=getConstPointer();
+  int nbTuples(getNumberOfTuples()),nbComp(getNumberOfComponents());
+  const double *data(getConstPointer());
   stream.precision(17);
   stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
   if(nbTuples*nbComp>=1)
@@ -1150,102 +1103,6 @@ bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other,
   return _mem.isEqual(other._mem,prec,tmp);
 }
 
-/*!
- * Creates a new DataArrayInt and assigns all (textual and numerical) data of \a this
- * array to the new one.
- *  \return DataArrayInt * - the new instance of DataArrayInt.
- */
-DataArrayInt *DataArrayDouble::convertToIntArr() const
-{
-  DataArrayInt *ret=DataArrayInt::New();
-  ret->alloc(getNumberOfTuples(),getNumberOfComponents());
-  int *dest=ret->getPointer();
-  // to make Visual C++ happy : instead of std::size_t nbOfVals=getNbOfElems(); std::copy(src,src+nbOfVals,dest);
-  for(const double *src=begin();src!=end();src++,dest++)
-    *dest=(int)*src;
-  ret->copyStringInfoFrom(*this);
-  return ret;
-}
-
-/*!
- * Returns a new DataArrayDouble holding the same values as \a this array but differently
- * arranged in memory. If \a this array holds 2 components of 3 values:
- * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
- * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
- *  \warning Do not confuse this method with transpose()!
- *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
- *          is to delete using decrRef() as it is no more needed.
- *  \throw If \a this is not allocated.
- */
-DataArrayDouble *DataArrayDouble::fromNoInterlace() const
-{
-  if(_mem.isNull())
-    throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
-  double *tab=_mem.fromNoInterlace(getNumberOfComponents());
-  DataArrayDouble *ret=DataArrayDouble::New();
-  ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
-  return ret;
-}
-
-/*!
- * Returns a new DataArrayDouble holding the same values as \a this array but differently
- * arranged in memory. If \a this array holds 2 components of 3 values:
- * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
- * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
- *  \warning Do not confuse this method with transpose()!
- *  \return DataArrayDouble * - the new instance of DataArrayDouble that the caller
- *          is to delete using decrRef() as it is no more needed.
- *  \throw If \a this is not allocated.
- */
-DataArrayDouble *DataArrayDouble::toNoInterlace() const
-{
-  if(_mem.isNull())
-    throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
-  double *tab=_mem.toNoInterlace(getNumberOfComponents());
-  DataArrayDouble *ret=DataArrayDouble::New();
-  ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
-  return ret;
-}
-
-/*!
- * Appends components of another array to components of \a this one, tuple by tuple.
- * So that the number of tuples of \a this array remains the same and the number of 
- * components increases.
- *  \param [in] other - the DataArrayDouble to append to \a this one.
- *  \throw If \a this is not allocated.
- *  \throw If \a this and \a other arrays have different number of tuples.
- *
- *  \if ENABLE_EXAMPLES
- *  \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example".
- *
- *  \ref py_mcdataarraydouble_meldwith "Here is a Python example".
- *  \endif
- */
-void DataArrayDouble::meldWith(const DataArrayDouble *other)
-{
-  checkAllocated();
-  other->checkAllocated();
-  int nbOfTuples=getNumberOfTuples();
-  if(nbOfTuples!=other->getNumberOfTuples())
-    throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !");
-  int nbOfComp1=getNumberOfComponents();
-  int nbOfComp2=other->getNumberOfComponents();
-  double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double));
-  double *w=newArr;
-  const double *inp1=getConstPointer();
-  const double *inp2=other->getConstPointer();
-  for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
-    {
-      w=std::copy(inp1,inp1+nbOfComp1,w);
-      w=std::copy(inp2,inp2+nbOfComp2,w);
-    }
-  useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
-  std::vector<int> compIds(nbOfComp2);
-  for(int i=0;i<nbOfComp2;i++)
-    compIds[i]=nbOfComp1+i;
-  copyPartOfStringInfoFrom2(compIds,*other);
-}
-
 /*!
  * This method checks that all tuples in \a other are in \a this.
  * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this.
@@ -1337,34 +1194,6 @@ void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayI
   commIndex=cI.retn();
 }
 
-/*!
- * 
- * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance.
- *             \a nbTimes  should be at least equal to 1.
- * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
- * \throw if \a this is not allocated or if \a this has not number of components set to one or if \a nbTimes is lower than 1.
- */
-DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const
-{
-  checkAllocated();
-  if(getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !");
-  if(nbTimes<1)
-    throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !");
-  int nbTuples=getNumberOfTuples();
-  const double *inPtr=getConstPointer();
-  MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1);
-  double *retPtr=ret->getPointer();
-  for(int i=0;i<nbTuples;i++,inPtr++)
-    {
-      double val=*inPtr;
-      for(int j=0;j<nbTimes;j++,retPtr++)
-        *retPtr=val;
-    }
-  ret->copyStringInfoFrom(*this);
-  return ret.retn();
-}
-
 /*!
  * This methods returns the minimal distance between the two set of points \a this and \a other.
  * So \a this and \a other have to have the same number of components. If not an INTERP_KERNEL::Exception will be thrown.
@@ -1576,27 +1405,6 @@ void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std:
       nc[nbOfCompo*i+compoIds[j]]=*ac;
 }
 
-void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet)
-{
-  if(newArray!=arrayToSet)
-    {
-      if(arrayToSet)
-        arrayToSet->decrRef();
-      arrayToSet=newArray;
-      if(arrayToSet)
-        arrayToSet->incrRef();
-    }
-}
-
-void DataArrayDouble::aggregate(const DataArrayDouble *other)
-{
-  if(!other)
-    throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : null pointer !");
-  if(getNumberOfComponents()!=other->getNumberOfComponents())
-    throw INTERP_KERNEL::Exception("DataArrayDouble::aggregate : mismatch number of components !");
-  _mem.insertAtTheEnd(other->begin(),other->end());
-}
-
 /*!
  * Checks if 0.0 value is present in \a this array. If it is the case, an exception
  * is thrown.
@@ -2037,6 +1845,27 @@ DataArrayDouble *DataArrayDouble::accumulatePerChunck(const int *bgOfIndex, cons
   return ret.retn();
 }
 
+/*!
+ * This method is close to numpy cumSum except that number of element is equal to \a this->getNumberOfTuples()+1. First element of DataArray returned is equal to 0.
+ * This method expects that \a this as only one component. The returned array will have \a this->getNumberOfTuples()+1 tuple with also one component.
+ * The ith element of returned array is equal to the sum of elements in \a this with rank strictly lower than i.
+ *
+ * \return DataArrayDouble - A newly built array containing cum sum of \a this.
+ */
+MCAuto<DataArrayDouble> DataArrayDouble::cumSum() const
+{
+  checkAllocated();
+  checkNbOfComps(1,"DataArrayDouble::cumSum : this is expected to be single component");
+  int nbOfTuple(getNumberOfTuples());
+  MCAuto<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfTuple+1,1);
+  double *ptr(ret->getPointer());
+  ptr[0]=0.;
+  const double *thisPtr(begin());
+  for(int i=0;i<nbOfTuple;i++)
+    ptr[i+1]=ptr[i]+thisPtr[i];
+  return ret;
+}
+
 /*!
  * Converts each 2D point defined by the tuple of \a this array from the Polar to the
  * Cartesian coordinate system. The two components of the tuple of \a this array are 
@@ -2566,28 +2395,6 @@ DataArrayDouble *DataArrayDouble::magnitude() const
   return ret;
 }
 
-/*!
- * Computes for each tuple the sum of number of components values in the tuple and return it.
- * 
- * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
- *          same number of tuples as \a this array and one component.
- *          The caller is to delete this result array using decrRef() as it is no more
- *          needed.
- *  \throw If \a this is not allocated.
- */
-DataArrayDouble *DataArrayDouble::sumPerTuple() const
-{
-  checkAllocated();
-  int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
-  MCAuto<DataArrayDouble> ret(DataArrayDouble::New());
-  ret->alloc(nbOfTuple,1);
-  const double *src(getConstPointer());
-  double *dest(ret->getPointer());
-  for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
-    *dest=std::accumulate(src,src+nbOfComp,0.);
-  return ret.retn();
-}
-
 /*!
  * Computes the maximal value within every tuple of \a this array.
  *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
@@ -2754,86 +2561,6 @@ void DataArrayDouble::sortPerTuple(bool asc)
   declareAsNew();
 }
 
-/*!
- * Converts every value of \a this array to its absolute value.
- * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs
- * should be called instead.
- *
- * \throw If \a this is not allocated.
- * \sa DataArrayDouble::computeAbs
- */
-void DataArrayDouble::abs()
-{
-  checkAllocated();
-  double *ptr(getPointer());
-  std::size_t nbOfElems(getNbOfElems());
-  std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
-  declareAsNew();
-}
-
-/*!
- * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
- * This method is a const method (that do not change any values in \a this) contrary to  DataArrayDouble::abs method.
- *
- * \return DataArrayDouble * - the new instance of DataArrayDouble containing the
- *         same number of tuples and component as \a this array.
- *         The caller is to delete this result array using decrRef() as it is no more
- *         needed.
- * \throw If \a this is not allocated.
- * \sa DataArrayDouble::abs
- */
-DataArrayDouble *DataArrayDouble::computeAbs() const
-{
-  checkAllocated();
-  DataArrayDouble *newArr(DataArrayDouble::New());
-  int nbOfTuples(getNumberOfTuples());
-  int nbOfComp(getNumberOfComponents());
-  newArr->alloc(nbOfTuples,nbOfComp);
-  std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<double,double>(fabs));
-  newArr->copyStringInfoFrom(*this);
-  return newArr;
-}
-
-/*!
- * Apply a linear function to a given component of \a this array, so that
- * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
- *  \param [in] a - the first coefficient of the function.
- *  \param [in] b - the second coefficient of the function.
- *  \param [in] compoId - the index of component to modify.
- *  \throw If \a this is not allocated, or \a compoId is not in [0,\c this->getNumberOfComponents() ).
- */
-void DataArrayDouble::applyLin(double a, double b, int compoId)
-{
-  checkAllocated();
-  double *ptr(getPointer()+compoId);
-  int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
-  if(compoId<0 || compoId>=nbOfComp)
-    {
-      std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !";
-      throw INTERP_KERNEL::Exception(oss.str().c_str());
-    }
-  for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
-    *ptr=a*(*ptr)+b;
-  declareAsNew();
-}
-
-/*!
- * Apply a linear function to all elements of \a this array, so that
- * an element _x_ becomes \f$ a * x + b \f$.
- *  \param [in] a - the first coefficient of the function.
- *  \param [in] b - the second coefficient of the function.
- *  \throw If \a this is not allocated.
- */
-void DataArrayDouble::applyLin(double a, double b)
-{
-  checkAllocated();
-  double *ptr=getPointer();
-  std::size_t nbOfElems=getNbOfElems();
-  for(std::size_t i=0;i<nbOfElems;i++,ptr++)
-    *ptr=a*(*ptr)+b;
-  declareAsNew();
-}
-
 /*!
  * Modify all elements of \a this array, so that
  * an element _x_ becomes \f$ numerator / x \f$.
@@ -2865,27 +2592,6 @@ void DataArrayDouble::applyInv(double numerator)
   declareAsNew();
 }
 
-/*!
- * Returns a full copy of \a this array except that sign of all elements is reversed.
- *  \return DataArrayDouble * - the new instance of DataArrayDouble containing the
- *          same number of tuples and component as \a this array.
- *          The caller is to delete this result array using decrRef() as it is no more
- *          needed.
- *  \throw If \a this is not allocated.
- */
-DataArrayDouble *DataArrayDouble::negate() const
-{
-  checkAllocated();
-  DataArrayDouble *newArr=DataArrayDouble::New();
-  int nbOfTuples=getNumberOfTuples();
-  int nbOfComp=getNumberOfComponents();
-  newArr->alloc(nbOfTuples,nbOfComp);
-  const double *cptr=getConstPointer();
-  std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>());
-  newArr->copyStringInfoFrom(*this);
-  return newArr;
-}
-
 /*!
  * Modify all elements of \a this array, so that
  * an element _x_ becomes <em> val ^ x </em>. Contrary to DataArrayInt::applyPow
@@ -3468,85 +3174,6 @@ DataArrayDouble *DataArrayDouble::Aggregate(const std::vector<const DataArrayDou
   return ret.retn();
 }
 
-/*!
- * Returns a new DataArrayDouble by aggregating two given arrays, so that (1) the number
- * of components in the result array is a sum of the number of components of given arrays
- * and (2) the number of tuples in the result array is same as that of each of given
- * arrays. In other words the i-th tuple of result array includes all components of
- * i-th tuples of all given arrays.
- * Number of tuples in the given arrays must be  the same.
- *  \param [in] a1 - an array to include in the result array.
- *  \param [in] a2 - another array to include in the result array.
- *  \return DataArrayDouble * - the new instance of DataArrayDouble.
- *          The caller is to delete this result array using decrRef() as it is no more
- *          needed.
- *  \throw If both \a a1 and \a a2 are NULL.
- *  \throw If any given array is not allocated.
- *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
- */
-DataArrayDouble *DataArrayDouble::Meld(const DataArrayDouble *a1, const DataArrayDouble *a2)
-{
-  std::vector<const DataArrayDouble *> arr(2);
-  arr[0]=a1; arr[1]=a2;
-  return Meld(arr);
-}
-
-/*!
- * Returns a new DataArrayDouble by aggregating all given arrays, so that (1) the number
- * of components in the result array is a sum of the number of components of given arrays
- * and (2) the number of tuples in the result array is same as that of each of given
- * arrays. In other words the i-th tuple of result array includes all components of
- * i-th tuples of all given arrays.
- * Number of tuples in the given arrays must be  the same.
- *  \param [in] arr - a sequence of arrays to include in the result array.
- *  \return DataArrayDouble * - the new instance of DataArrayDouble.
- *          The caller is to delete this result array using decrRef() as it is no more
- *          needed.
- *  \throw If all arrays within \a arr are NULL.
- *  \throw If any given array is not allocated.
- *  \throw If getNumberOfTuples() of arrays within \a arr is different.
- */
-DataArrayDouble *DataArrayDouble::Meld(const std::vector<const DataArrayDouble *>& arr)
-{
-  std::vector<const DataArrayDouble *> a;
-  for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
-    if(*it4)
-      a.push_back(*it4);
-  if(a.empty())
-    throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !");
-  std::vector<const DataArrayDouble *>::const_iterator it;
-  for(it=a.begin();it!=a.end();it++)
-    (*it)->checkAllocated();
-  it=a.begin();
-  int nbOfTuples=(*it)->getNumberOfTuples();
-  std::vector<int> nbc(a.size());
-  std::vector<const double *> pts(a.size());
-  nbc[0]=(*it)->getNumberOfComponents();
-  pts[0]=(*it++)->getConstPointer();
-  for(int i=1;it!=a.end();it++,i++)
-    {
-      if(nbOfTuples!=(*it)->getNumberOfTuples())
-        throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : mismatch of number of tuples !");
-      nbc[i]=(*it)->getNumberOfComponents();
-      pts[i]=(*it)->getConstPointer();
-    }
-  int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
-  DataArrayDouble *ret=DataArrayDouble::New();
-  ret->alloc(nbOfTuples,totalNbOfComp);
-  double *retPtr=ret->getPointer();
-  for(int i=0;i<nbOfTuples;i++)
-    for(int j=0;j<(int)a.size();j++)
-      {
-        retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
-        pts[j]+=nbc[j];
-      }
-  int k=0;
-  for(int i=0;i<(int)a.size();i++)
-    for(int j=0;j<nbc[i];j++,k++)
-      ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
-  return ret;
-}
-
 /*!
  * Returns a new DataArrayDouble containing a dot product of two given arrays, so that
  * the i-th tuple of the result array is a sum of products of j-th components of i-th
@@ -3707,766 +3334,170 @@ DataArrayDouble *DataArrayDouble::Min(const DataArrayDouble *a1, const DataArray
 }
 
 /*!
- * Returns a new DataArrayDouble that is a sum of two given arrays. There are 3
+ * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
  * valid cases.
- * 1.  The arrays have same number of tuples and components. Then each value of
- *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
- *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
- * 2.  The arrays have same number of tuples and one array, say _a2_, has one
- *   component. Then
- *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
- * 3.  The arrays have same number of components and one array, say _a2_, has one
- *   tuple. Then
- *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
  *
- * Info on components is copied either from the first array (in the first case) or from
- * the array with maximal number of elements (getNbOfElems()).
- *  \param [in] a1 - an array to sum up.
+ *  \param [in] a1 - an array to pow up.
  *  \param [in] a2 - another array to sum up.
  *  \return DataArrayDouble * - the new instance of DataArrayDouble.
  *          The caller is to delete this result array using decrRef() as it is no more
  *          needed.
  *  \throw If either \a a1 or \a a2 is NULL.
- *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
- *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
- *         none of them has number of tuples or components equal to 1.
+ *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
+ *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
+ *  \throw If there is a negative value in \a a1.
  */
-DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArrayDouble *a2)
+DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
 {
   if(!a1 || !a2)
-    throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !");
+    throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
   int nbOfTuple=a1->getNumberOfTuples();
   int nbOfTuple2=a2->getNumberOfTuples();
   int nbOfComp=a1->getNumberOfComponents();
   int nbOfComp2=a2->getNumberOfComponents();
-  MCAuto<DataArrayDouble> ret=0;
-  if(nbOfTuple==nbOfTuple2)
+  if(nbOfTuple!=nbOfTuple2)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
+  if(nbOfComp!=1 || nbOfComp2!=1)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
+  MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
+  const double *ptr1(a1->begin()),*ptr2(a2->begin());
+  double *ptr=ret->getPointer();
+  for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
     {
-      if(nbOfComp==nbOfComp2)
+      if(*ptr1>=0)
         {
-          ret=DataArrayDouble::New();
-          ret->alloc(nbOfTuple,nbOfComp);
-          std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>());
-          ret->copyStringInfoFrom(*a1);
+          *ptr=pow(*ptr1,*ptr2);
         }
       else
         {
-          int nbOfCompMin,nbOfCompMax;
-          const DataArrayDouble *aMin, *aMax;
-          if(nbOfComp>nbOfComp2)
-            {
-              nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
-              aMin=a2; aMax=a1;
-            }
-          else
-            {
-              nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
-              aMin=a1; aMax=a2;
-            }
-          if(nbOfCompMin==1)
-            {
-              ret=DataArrayDouble::New();
-              ret->alloc(nbOfTuple,nbOfCompMax);
-              const double *aMinPtr=aMin->getConstPointer();
-              const double *aMaxPtr=aMax->getConstPointer();
-              double *res=ret->getPointer();
-              for(int i=0;i<nbOfTuple;i++)
-                res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i]));
-              ret->copyStringInfoFrom(*aMax);
-            }
-          else
-            throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
-        }
-    }
-  else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
-    {
-      if(nbOfComp==nbOfComp2)
-        {
-          int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
-          const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
-          const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
-          const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
-          ret=DataArrayDouble::New();
-          ret->alloc(nbOfTupleMax,nbOfComp);
-          double *res=ret->getPointer();
-          for(int i=0;i<nbOfTupleMax;i++)
-            res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>());
-          ret->copyStringInfoFrom(*aMax);
+          std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
-      else
-        throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
     }
-  else
-    throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
   return ret.retn();
 }
 
 /*!
- * Adds values of another DataArrayDouble to values of \a this one. There are 3
- * valid cases.
- * 1.  The arrays have same number of tuples and components. Then each value of
- *   \a other array is added to the corresponding value of \a this array, i.e.:
- *   _a_ [ i, j ] += _other_ [ i, j ].
- * 2.  The arrays have same number of tuples and \a other array has one component. Then
- *   _a_ [ i, j ] += _other_ [ i, 0 ].
- * 3.  The arrays have same number of components and \a other array has one tuple. Then
- *   _a_ [ i, j ] += _a2_ [ 0, j ].
+ * Apply pow on values of another DataArrayDouble to values of \a this one.
  *
- *  \param [in] other - an array to add to \a this one.
+ *  \param [in] other - an array to pow to \a this one.
  *  \throw If \a other is NULL.
- *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
- *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
- *         \a other has number of both tuples and components not equal to 1.
+ *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
+ *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
+ *  \throw If there is a negative value in \a this.
  */
-void DataArrayDouble::addEqual(const DataArrayDouble *other)
+void DataArrayDouble::powEqual(const DataArrayDouble *other)
 {
   if(!other)
-    throw INTERP_KERNEL::Exception("DataArrayDouble::addEqual : input DataArrayDouble instance is NULL !");
-  const char *msg="Nb of tuples mismatch for DataArrayDouble::addEqual  !";
-  checkAllocated();
-  other->checkAllocated();
+    throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
   int nbOfTuple=getNumberOfTuples();
   int nbOfTuple2=other->getNumberOfTuples();
   int nbOfComp=getNumberOfComponents();
   int nbOfComp2=other->getNumberOfComponents();
-  if(nbOfTuple==nbOfTuple2)
+  if(nbOfTuple!=nbOfTuple2)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
+  if(nbOfComp!=1 || nbOfComp2!=1)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
+  double *ptr=getPointer();
+  const double *ptrc=other->begin();
+  for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
     {
-      if(nbOfComp==nbOfComp2)
-        {
-          std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>());
-        }
-      else if(nbOfComp2==1)
-        {
-          double *ptr=getPointer();
-          const double *ptrc=other->getConstPointer();
-          for(int i=0;i<nbOfTuple;i++)
-            std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++));
-        }
+      if(*ptr>=0)
+        *ptr=pow(*ptr,*ptrc);
       else
-        throw INTERP_KERNEL::Exception(msg);
-    }
-  else if(nbOfTuple2==1)
-    {
-      if(nbOfComp2==nbOfComp)
         {
-          double *ptr=getPointer();
-          const double *ptrc=other->getConstPointer();
-          for(int i=0;i<nbOfTuple;i++)
-            std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>());
+          std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
-      else
-        throw INTERP_KERNEL::Exception(msg);
     }
-  else
-    throw INTERP_KERNEL::Exception(msg);
   declareAsNew();
 }
 
 /*!
- * Returns a new DataArrayDouble that is a subtraction of two given arrays. There are 3
- * valid cases.
- * 1.  The arrays have same number of tuples and components. Then each value of
- *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
- *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
- * 2.  The arrays have same number of tuples and one array, say _a2_, has one
- *   component. Then
- *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
- * 3.  The arrays have same number of components and one array, say _a2_, has one
- *   tuple. Then
- *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
+ * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
+ * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
+ * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
  *
- * Info on components is copied either from the first array (in the first case) or from
- * the array with maximal number of elements (getNbOfElems()).
- *  \param [in] a1 - an array to subtract from.
- *  \param [in] a2 - an array to subtract.
- *  \return DataArrayDouble * - the new instance of DataArrayDouble.
- *          The caller is to delete this result array using decrRef() as it is no more
- *          needed.
- *  \throw If either \a a1 or \a a2 is NULL.
- *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
- *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
- *         none of them has number of tuples or components equal to 1.
+ * \throw if \a this is not allocated.
+ * \throw if \a this has not exactly one component.
  */
-DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const DataArrayDouble *a2)
+std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
 {
-  if(!a1 || !a2)
-    throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !");
-  int nbOfTuple1=a1->getNumberOfTuples();
-  int nbOfTuple2=a2->getNumberOfTuples();
-  int nbOfComp1=a1->getNumberOfComponents();
-  int nbOfComp2=a2->getNumberOfComponents();
-  if(nbOfTuple2==nbOfTuple1)
+  checkAllocated();
+  if(getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
+  int nbt(getNumberOfTuples());
+  std::vector<bool> ret(nbt);
+  const double *pt(begin());
+  for(int i=0;i<nbt;i++)
     {
-      if(nbOfComp1==nbOfComp2)
-        {
-          MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
-          ret->alloc(nbOfTuple2,nbOfComp1);
-          std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
-          ret->copyStringInfoFrom(*a1);
-          return ret.retn();
-        }
-      else if(nbOfComp2==1)
-        {
-          MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
-          ret->alloc(nbOfTuple1,nbOfComp1);
-          const double *a2Ptr=a2->getConstPointer();
-          const double *a1Ptr=a1->getConstPointer();
-          double *res=ret->getPointer();
-          for(int i=0;i<nbOfTuple1;i++)
-            res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i]));
-          ret->copyStringInfoFrom(*a1);
-          return ret.retn();
-        }
+      if(fabs(pt[i])<eps)
+        ret[i]=false;
+      else if(fabs(pt[i]-1.)<eps)
+        ret[i]=true;
       else
         {
-          a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
-          return 0;
+          std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
     }
-  else if(nbOfTuple2==1)
+  return ret;
+}
+
+/*!
+ * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
+ * Server side.
+ */
+void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
+{
+  tinyInfo.resize(2);
+  if(isAllocated())
     {
-      a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
-      MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
-      ret->alloc(nbOfTuple1,nbOfComp1);
-      const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
-      double *pt=ret->getPointer();
-      for(int i=0;i<nbOfTuple1;i++)
-        pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>());
-      ret->copyStringInfoFrom(*a1);
-      return ret.retn();
+      tinyInfo[0]=getNumberOfTuples();
+      tinyInfo[1]=getNumberOfComponents();
     }
   else
     {
-      a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
-      return 0;
+      tinyInfo[0]=-1;
+      tinyInfo[1]=-1;
     }
 }
 
 /*!
- * Subtract values of another DataArrayDouble from values of \a this one. There are 3
- * valid cases.
- * 1.  The arrays have same number of tuples and components. Then each value of
- *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
- *   _a_ [ i, j ] -= _other_ [ i, j ].
- * 2.  The arrays have same number of tuples and \a other array has one component. Then
- *   _a_ [ i, j ] -= _other_ [ i, 0 ].
- * 3.  The arrays have same number of components and \a other array has one tuple. Then
- *   _a_ [ i, j ] -= _a2_ [ 0, j ].
- *
- *  \param [in] other - an array to subtract from \a this one.
- *  \throw If \a other is NULL.
- *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
- *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
- *         \a other has number of both tuples and components not equal to 1.
+ * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
+ * Server side.
  */
-void DataArrayDouble::substractEqual(const DataArrayDouble *other)
+void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
 {
-  if(!other)
-    throw INTERP_KERNEL::Exception("DataArrayDouble::substractEqual : input DataArrayDouble instance is NULL !");
-  const char *msg="Nb of tuples mismatch for DataArrayDouble::substractEqual  !";
-  checkAllocated();
-  other->checkAllocated();
-  int nbOfTuple=getNumberOfTuples();
-  int nbOfTuple2=other->getNumberOfTuples();
-  int nbOfComp=getNumberOfComponents();
-  int nbOfComp2=other->getNumberOfComponents();
-  if(nbOfTuple==nbOfTuple2)
+  if(isAllocated())
     {
-      if(nbOfComp==nbOfComp2)
-        {
-          std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>());
-        }
-      else if(nbOfComp2==1)
-        {
-          double *ptr=getPointer();
-          const double *ptrc=other->getConstPointer();
-          for(int i=0;i<nbOfTuple;i++)
-            std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); 
-        }
-      else
-        throw INTERP_KERNEL::Exception(msg);
+      int nbOfCompo=getNumberOfComponents();
+      tinyInfo.resize(nbOfCompo+1);
+      tinyInfo[0]=getName();
+      for(int i=0;i<nbOfCompo;i++)
+        tinyInfo[i+1]=getInfoOnComponent(i);
     }
-  else if(nbOfTuple2==1)
+  else
     {
-      if(nbOfComp2==nbOfComp)
-        {
-          double *ptr=getPointer();
-          const double *ptrc=other->getConstPointer();
-          for(int i=0;i<nbOfTuple;i++)
-            std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>());
-        }
-      else
-        throw INTERP_KERNEL::Exception(msg);
+      tinyInfo.resize(1);
+      tinyInfo[0]=getName();
     }
-  else
-    throw INTERP_KERNEL::Exception(msg);
-  declareAsNew();
 }
 
 /*!
- * Returns a new DataArrayDouble that is a product of two given arrays. There are 3
- * valid cases.
- * 1.  The arrays have same number of tuples and components. Then each value of
- *   the result array (_a_) is a product of the corresponding values of \a a1 and
- *   \a a2, i.e. _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
- * 2.  The arrays have same number of tuples and one array, say _a2_, has one
- *   component. Then
- *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
- * 3.  The arrays have same number of components and one array, say _a2_, has one
- *   tuple. Then
- *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
- *
- * Info on components is copied either from the first array (in the first case) or from
- * the array with maximal number of elements (getNbOfElems()).
- *  \param [in] a1 - a factor array.
- *  \param [in] a2 - another factor array.
- *  \return DataArrayDouble * - the new instance of DataArrayDouble.
- *          The caller is to delete this result array using decrRef() as it is no more
- *          needed.
- *  \throw If either \a a1 or \a a2 is NULL.
- *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
- *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
- *         none of them has number of tuples or components equal to 1.
+ * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
+ * This method returns if a feeding is needed.
  */
-DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2)
+bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
 {
-  if(!a1 || !a2)
-    throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !");
-  int nbOfTuple=a1->getNumberOfTuples();
-  int nbOfTuple2=a2->getNumberOfTuples();
-  int nbOfComp=a1->getNumberOfComponents();
-  int nbOfComp2=a2->getNumberOfComponents();
-  MCAuto<DataArrayDouble> ret=0;
-  if(nbOfTuple==nbOfTuple2)
-    {
-      if(nbOfComp==nbOfComp2)
-        {
-          ret=DataArrayDouble::New();
-          ret->alloc(nbOfTuple,nbOfComp);
-          std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>());
-          ret->copyStringInfoFrom(*a1);
-        }
-      else
-        {
-          int nbOfCompMin,nbOfCompMax;
-          const DataArrayDouble *aMin, *aMax;
-          if(nbOfComp>nbOfComp2)
-            {
-              nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
-              aMin=a2; aMax=a1;
-            }
-          else
-            {
-              nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
-              aMin=a1; aMax=a2;
-            }
-          if(nbOfCompMin==1)
-            {
-              ret=DataArrayDouble::New();
-              ret->alloc(nbOfTuple,nbOfCompMax);
-              const double *aMinPtr=aMin->getConstPointer();
-              const double *aMaxPtr=aMax->getConstPointer();
-              double *res=ret->getPointer();
-              for(int i=0;i<nbOfTuple;i++)
-                res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i]));
-              ret->copyStringInfoFrom(*aMax);
-            }
-          else
-            throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
-        }
-    }
-  else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
+  int nbOfTuple=tinyInfoI[0];
+  int nbOfComp=tinyInfoI[1];
+  if(nbOfTuple!=-1 || nbOfComp!=-1)
     {
-      if(nbOfComp==nbOfComp2)
-        {
-          int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
-          const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1;
-          const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2;
-          const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
-          ret=DataArrayDouble::New();
-          ret->alloc(nbOfTupleMax,nbOfComp);
-          double *res=ret->getPointer();
-          for(int i=0;i<nbOfTupleMax;i++)
-            res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>());
-          ret->copyStringInfoFrom(*aMax);
-        }
-      else
-        throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
+      alloc(nbOfTuple,nbOfComp);
+      return true;
     }
-  else
-    throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
-  return ret.retn();
-}
-
-/*!
- * Multiply values of another DataArrayDouble to values of \a this one. There are 3
- * valid cases.
- * 1.  The arrays have same number of tuples and components. Then each value of
- *   \a other array is multiplied to the corresponding value of \a this array, i.e.
- *   _this_ [ i, j ] *= _other_ [ i, j ].
- * 2.  The arrays have same number of tuples and \a other array has one component. Then
- *   _this_ [ i, j ] *= _other_ [ i, 0 ].
- * 3.  The arrays have same number of components and \a other array has one tuple. Then
- *   _this_ [ i, j ] *= _a2_ [ 0, j ].
- *
- *  \param [in] other - an array to multiply to \a this one.
- *  \throw If \a other is NULL.
- *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
- *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
- *         \a other has number of both tuples and components not equal to 1.
- */
-void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
-{
-  if(!other)
-    throw INTERP_KERNEL::Exception("DataArrayDouble::multiplyEqual : input DataArrayDouble instance is NULL !");
-  const char *msg="Nb of tuples mismatch for DataArrayDouble::multiplyEqual !";
-  checkAllocated();
-  other->checkAllocated();
-  int nbOfTuple=getNumberOfTuples();
-  int nbOfTuple2=other->getNumberOfTuples();
-  int nbOfComp=getNumberOfComponents();
-  int nbOfComp2=other->getNumberOfComponents();
-  if(nbOfTuple==nbOfTuple2)
-    {
-      if(nbOfComp==nbOfComp2)
-        {
-          std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>());
-        }
-      else if(nbOfComp2==1)
-        {
-          double *ptr=getPointer();
-          const double *ptrc=other->getConstPointer();
-          for(int i=0;i<nbOfTuple;i++)
-            std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++));
-        }
-      else
-        throw INTERP_KERNEL::Exception(msg);
-    }
-  else if(nbOfTuple2==1)
-    {
-      if(nbOfComp2==nbOfComp)
-        {
-          double *ptr=getPointer();
-          const double *ptrc=other->getConstPointer();
-          for(int i=0;i<nbOfTuple;i++)
-            std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>());
-        }
-      else
-        throw INTERP_KERNEL::Exception(msg);
-    }
-  else
-    throw INTERP_KERNEL::Exception(msg);
-  declareAsNew();
-}
-
-/*!
- * Returns a new DataArrayDouble that is a division of two given arrays. There are 3
- * valid cases.
- * 1.  The arrays have same number of tuples and components. Then each value of
- *   the result array (_a_) is a division of the corresponding values of \a a1 and
- *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
- * 2.  The arrays have same number of tuples and one array, say _a2_, has one
- *   component. Then
- *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
- * 3.  The arrays have same number of components and one array, say _a2_, has one
- *   tuple. Then
- *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
- *
- * Info on components is copied either from the first array (in the first case) or from
- * the array with maximal number of elements (getNbOfElems()).
- *  \warning No check of division by zero is performed!
- *  \param [in] a1 - a numerator array.
- *  \param [in] a2 - a denominator array.
- *  \return DataArrayDouble * - the new instance of DataArrayDouble.
- *          The caller is to delete this result array using decrRef() as it is no more
- *          needed.
- *  \throw If either \a a1 or \a a2 is NULL.
- *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
- *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
- *         none of them has number of tuples or components equal to 1.
- */
-DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataArrayDouble *a2)
-{
-  if(!a1 || !a2)
-    throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !");
-  int nbOfTuple1=a1->getNumberOfTuples();
-  int nbOfTuple2=a2->getNumberOfTuples();
-  int nbOfComp1=a1->getNumberOfComponents();
-  int nbOfComp2=a2->getNumberOfComponents();
-  if(nbOfTuple2==nbOfTuple1)
-    {
-      if(nbOfComp1==nbOfComp2)
-        {
-          MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
-          ret->alloc(nbOfTuple2,nbOfComp1);
-          std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
-          ret->copyStringInfoFrom(*a1);
-          return ret.retn();
-        }
-      else if(nbOfComp2==1)
-        {
-          MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
-          ret->alloc(nbOfTuple1,nbOfComp1);
-          const double *a2Ptr=a2->getConstPointer();
-          const double *a1Ptr=a1->getConstPointer();
-          double *res=ret->getPointer();
-          for(int i=0;i<nbOfTuple1;i++)
-            res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i]));
-          ret->copyStringInfoFrom(*a1);
-          return ret.retn();
-        }
-      else
-        {
-          a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
-          return 0;
-        }
-    }
-  else if(nbOfTuple2==1)
-    {
-      a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
-      MCAuto<DataArrayDouble> ret=DataArrayDouble::New();
-      ret->alloc(nbOfTuple1,nbOfComp1);
-      const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
-      double *pt=ret->getPointer();
-      for(int i=0;i<nbOfTuple1;i++)
-        pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>());
-      ret->copyStringInfoFrom(*a1);
-      return ret.retn();
-    }
-  else
-    {
-      a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
-      return 0;
-    }
-}
-
-/*!
- * Divide values of \a this array by values of another DataArrayDouble. There are 3
- * valid cases.
- * 1.  The arrays have same number of tuples and components. Then each value of
- *    \a this array is divided by the corresponding value of \a other one, i.e.:
- *   _a_ [ i, j ] /= _other_ [ i, j ].
- * 2.  The arrays have same number of tuples and \a other array has one component. Then
- *   _a_ [ i, j ] /= _other_ [ i, 0 ].
- * 3.  The arrays have same number of components and \a other array has one tuple. Then
- *   _a_ [ i, j ] /= _a2_ [ 0, j ].
- *
- *  \warning No check of division by zero is performed!
- *  \param [in] other - an array to divide \a this one by.
- *  \throw If \a other is NULL.
- *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
- *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
- *         \a other has number of both tuples and components not equal to 1.
- */
-void DataArrayDouble::divideEqual(const DataArrayDouble *other)
-{
-  if(!other)
-    throw INTERP_KERNEL::Exception("DataArrayDouble::divideEqual : input DataArrayDouble instance is NULL !");
-  const char *msg="Nb of tuples mismatch for DataArrayDouble::divideEqual !";
-  checkAllocated();
-  other->checkAllocated();
-  int nbOfTuple=getNumberOfTuples();
-  int nbOfTuple2=other->getNumberOfTuples();
-  int nbOfComp=getNumberOfComponents();
-  int nbOfComp2=other->getNumberOfComponents();
-  if(nbOfTuple==nbOfTuple2)
-    {
-      if(nbOfComp==nbOfComp2)
-        {
-          std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>());
-        }
-      else if(nbOfComp2==1)
-        {
-          double *ptr=getPointer();
-          const double *ptrc=other->getConstPointer();
-          for(int i=0;i<nbOfTuple;i++)
-            std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++));
-        }
-      else
-        throw INTERP_KERNEL::Exception(msg);
-    }
-  else if(nbOfTuple2==1)
-    {
-      if(nbOfComp2==nbOfComp)
-        {
-          double *ptr=getPointer();
-          const double *ptrc=other->getConstPointer();
-          for(int i=0;i<nbOfTuple;i++)
-            std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>());
-        }
-      else
-        throw INTERP_KERNEL::Exception(msg);
-    }
-  else
-    throw INTERP_KERNEL::Exception(msg);
-  declareAsNew();
-}
-
-/*!
- * Returns a new DataArrayDouble that is the result of pow of two given arrays. There are 3
- * valid cases.
- *
- *  \param [in] a1 - an array to pow up.
- *  \param [in] a2 - another array to sum up.
- *  \return DataArrayDouble * - the new instance of DataArrayDouble.
- *          The caller is to delete this result array using decrRef() as it is no more
- *          needed.
- *  \throw If either \a a1 or \a a2 is NULL.
- *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
- *  \throw If \a a1->getNumberOfComponents() != 1 or \a a2->getNumberOfComponents() != 1.
- *  \throw If there is a negative value in \a a1.
- */
-DataArrayDouble *DataArrayDouble::Pow(const DataArrayDouble *a1, const DataArrayDouble *a2)
-{
-  if(!a1 || !a2)
-    throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : at least one of input instances is null !");
-  int nbOfTuple=a1->getNumberOfTuples();
-  int nbOfTuple2=a2->getNumberOfTuples();
-  int nbOfComp=a1->getNumberOfComponents();
-  int nbOfComp2=a2->getNumberOfComponents();
-  if(nbOfTuple!=nbOfTuple2)
-    throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of tuples mismatches !");
-  if(nbOfComp!=1 || nbOfComp2!=1)
-    throw INTERP_KERNEL::Exception("DataArrayDouble::Pow : number of components of both arrays must be equal to 1 !");
-  MCAuto<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1);
-  const double *ptr1(a1->begin()),*ptr2(a2->begin());
-  double *ptr=ret->getPointer();
-  for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++)
-    {
-      if(*ptr1>=0)
-        {
-          *ptr=pow(*ptr1,*ptr2);
-        }
-      else
-        {
-          std::ostringstream oss; oss << "DataArrayDouble::Pow : on tuple #" << i << " of a1 value is < 0 (" << *ptr1 << ") !";
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
-        }
-    }
-  return ret.retn();
-}
-
-/*!
- * Apply pow on values of another DataArrayDouble to values of \a this one.
- *
- *  \param [in] other - an array to pow to \a this one.
- *  \throw If \a other is NULL.
- *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples()
- *  \throw If \a this->getNumberOfComponents() != 1 or \a other->getNumberOfComponents() != 1
- *  \throw If there is a negative value in \a this.
- */
-void DataArrayDouble::powEqual(const DataArrayDouble *other)
-{
-  if(!other)
-    throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : input instance is null !");
-  int nbOfTuple=getNumberOfTuples();
-  int nbOfTuple2=other->getNumberOfTuples();
-  int nbOfComp=getNumberOfComponents();
-  int nbOfComp2=other->getNumberOfComponents();
-  if(nbOfTuple!=nbOfTuple2)
-    throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of tuples mismatches !");
-  if(nbOfComp!=1 || nbOfComp2!=1)
-    throw INTERP_KERNEL::Exception("DataArrayDouble::powEqual : number of components of both arrays must be equal to 1 !");
-  double *ptr=getPointer();
-  const double *ptrc=other->begin();
-  for(int i=0;i<nbOfTuple;i++,ptrc++,ptr++)
-    {
-      if(*ptr>=0)
-        *ptr=pow(*ptr,*ptrc);
-      else
-        {
-          std::ostringstream oss; oss << "DataArrayDouble::powEqual : on tuple #" << i << " of this value is < 0 (" << *ptr << ") !";
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
-        }
-    }
-  declareAsNew();
-}
-
-/*!
- * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context.
- * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true.
- * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown.
- *
- * \throw if \a this is not allocated.
- * \throw if \a this has not exactly one component.
- */
-std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const
-{
-  checkAllocated();
-  if(getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !");
-  int nbt(getNumberOfTuples());
-  std::vector<bool> ret(nbt);
-  const double *pt(begin());
-  for(int i=0;i<nbt;i++)
-    {
-      if(fabs(pt[i])<eps)
-        ret[i]=false;
-      else if(fabs(pt[i]-1.)<eps)
-        ret[i]=true;
-      else
-        {
-          std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !";
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
-        }
-    }
-  return ret;
-}
-
-/*!
- * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
- * Server side.
- */
-void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const
-{
-  tinyInfo.resize(2);
-  if(isAllocated())
-    {
-      tinyInfo[0]=getNumberOfTuples();
-      tinyInfo[1]=getNumberOfComponents();
-    }
-  else
-    {
-      tinyInfo[0]=-1;
-      tinyInfo[1]=-1;
-    }
-}
-
-/*!
- * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
- * Server side.
- */
-void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const
-{
-  if(isAllocated())
-    {
-      int nbOfCompo=getNumberOfComponents();
-      tinyInfo.resize(nbOfCompo+1);
-      tinyInfo[0]=getName();
-      for(int i=0;i<nbOfCompo;i++)
-        tinyInfo[i+1]=getInfoOnComponent(i);
-    }
-  else
-    {
-      tinyInfo.resize(1);
-      tinyInfo[0]=getName();
-    }
-}
-
-/*!
- * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
- * This method returns if a feeding is needed.
- */
-bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI)
-{
-  int nbOfTuple=tinyInfoI[0];
-  int nbOfComp=tinyInfoI[1];
-  if(nbOfTuple!=-1 || nbOfComp!=-1)
-    {
-      alloc(nbOfTuple,nbOfComp);
-      return true;
-    }
-  return false;
+  return false;
 }
 
 /*!
@@ -4589,40 +3620,11 @@ void DataArrayDouble::Rotate2DAlg(const double *center, double angle, int nbNode
     }
 }
 
-DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
-{
-  if(_da)
-    {
-      _da->incrRef();
-      if(_da->isAllocated())
-        {
-          _nb_comp=da->getNumberOfComponents();
-          _nb_tuple=da->getNumberOfTuples();
-          _pt=da->getPointer();
-        }
-    }
-}
-
-DataArrayDoubleIterator::~DataArrayDoubleIterator()
+DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):DataArrayIterator<double>(da)
 {
-  if(_da)
-    _da->decrRef();
 }
 
-DataArrayDoubleTuple *DataArrayDoubleIterator::nextt()
-{
-  if(_tuple_id<_nb_tuple)
-    {
-      _tuple_id++;
-      DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp);
-      _pt+=_nb_comp;
-      return ret;
-    }
-  else
-    return 0;
-}
-
-DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
+DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):DataArrayTuple<double>(pt,nbOfComp)
 {
 }
 
@@ -4638,9 +3640,7 @@ std::string DataArrayDoubleTuple::repr() const
 
 double DataArrayDoubleTuple::doubleValue() const
 {
-  if(_nb_of_compo==1)
-    return *_pt;
-  throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !");
+  return this->zeValue();
 }
 
 /*!
@@ -4651,18 +3651,7 @@ double DataArrayDoubleTuple::doubleValue() const
  */
 DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const
 {
-  if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
-    {
-      DataArrayDouble *ret=DataArrayDouble::New();
-      ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
-      return ret;
-    }
-  else
-    {
-      std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
-      oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
-      throw INTERP_KERNEL::Exception(oss.str().c_str());
-    }
+  return this->buildDA(nbOfTuples,nbOfCompo);
 }
 
 /*!
@@ -4721,56 +3710,9 @@ int DataArrayInt::getHashCode() const
  * \ref MEDCouplingArrayBasicsCopyDeep.
  *  \return DataArrayInt * - a new instance of DataArrayInt.
  */
-DataArrayInt *DataArrayInt::deepCopy() const
-{
-  return new DataArrayInt(*this);
-}
-
-/*!
- * Returns either a \a deep or \a shallow copy of this array. For more info see
- * \ref MEDCouplingArrayBasicsCopyDeep and \ref MEDCouplingArrayBasicsCopyShallow.
- *  \param [in] dCpy - if \a true, a deep copy is returned, else, a shallow one.
- *  \return DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy
- *          == \a true) or \a this instance (if \a dCpy == \a false).
- */
-DataArrayInt *DataArrayInt::performCopyOrIncrRef(bool dCpy) const
-{
-  if(dCpy)
-    return deepCopy();
-  else
-    {
-      incrRef();
-      return const_cast<DataArrayInt *>(this);
-    }
-}
-
-/*!
- * Assign zero to all values in \a this array. To know more on filling arrays see
- * \ref MEDCouplingArrayFill.
- * \throw If \a this is not allocated.
- */
-void DataArrayInt::fillWithZero()
-{
-  fillWithValue(0);
-}
-
-/*!
- * Set all values in \a this array so that the i-th element equals to \a init + i
- * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill.
- *  \param [in] init - value to assign to the first element of array.
- *  \throw If \a this->getNumberOfComponents() != 1
- *  \throw If \a this is not allocated.
- */
-void DataArrayInt::iota(int init)
+DataArrayInt32 *DataArrayInt32::deepCopy() const
 {
-  checkAllocated();
-  if(getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !");
-  int *ptr=getPointer();
-  int ntuples=getNumberOfTuples();
-  for(int i=0;i<ntuples;i++)
-    ptr[i]=init+i;
-  declareAsNew();
+  return new DataArrayInt32(*this);
 }
 
 /*!
@@ -4959,38 +3901,6 @@ void DataArrayInt::reprQuickOverviewData(std::ostream& stream, std::size_t maxNb
   stream << "]";
 }
 
-/*!
- * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
- * i.e. a current value is used as in index to get a new value from \a indArrBg.
- *  \param [in] indArrBg - pointer to the first element of array of new values to assign
- *         to \a this array.
- *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
- *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
- *  \throw If \a this->getNumberOfComponents() != 1
- *  \throw If any value of \a this can't be used as a valid index for 
- *         [\a indArrBg, \a indArrEnd).
- *
- *  \sa changeValue
- */
-void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
-{
-  checkAllocated();
-  if(getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
-  int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
-  for(int i=0;i<nbOfTuples;i++,pt++)
-    {
-      if(*pt>=0 && *pt<nbElemsIn)
-        *pt=indArrBg[*pt];
-      else
-        {
-          std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
-        }
-    }
-  declareAsNew();
-}
-
 /*!
  * Computes distribution of values of \a this one-dimensional array between given value
  * ranges (casts). This method is typically useful for entity number spliting by types,
@@ -5113,28 +4023,82 @@ bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const
     return false;
   if(sttoopp>strt)
     {
-      sttoopp++;
-      int a(sttoopp-1-strt),tmp(strt);
-      if(a%(nbTuples-1)!=0)
-        return false;
-      stteepp=a/(nbTuples-1);
-      for(int i=0;i<nbTuples;i++,tmp+=stteepp)
-        if(pt[i]!=tmp)
-          return false;
-      return true;
+      sttoopp++;
+      int a(sttoopp-1-strt),tmp(strt);
+      if(a%(nbTuples-1)!=0)
+        return false;
+      stteepp=a/(nbTuples-1);
+      for(int i=0;i<nbTuples;i++,tmp+=stteepp)
+        if(pt[i]!=tmp)
+          return false;
+      return true;
+    }
+  else
+    {
+      sttoopp--;
+      int a(strt-sttoopp-1),tmp(strt);
+      if(a%(nbTuples-1)!=0)
+        return false;
+      stteepp=-(a/(nbTuples-1));
+      for(int i=0;i<nbTuples;i++,tmp+=stteepp)
+        if(pt[i]!=tmp)
+          return false;
+      return true;
+    }
+}
+
+
+/*!
+ * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ],
+ * i.e. a current value is used as in index to get a new value from \a indArrBg.
+ *  \param [in] indArrBg - pointer to the first element of array of new values to assign
+ *         to \a this array.
+ *  \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that
+ *              the last value of \a indArrBg is \a indArrEnd[ -1 ].
+ *  \throw If \a this->getNumberOfComponents() != 1
+ *  \throw If any value of \a this can't be used as a valid index for 
+ *         [\a indArrBg, \a indArrEnd).
+ *
+ *  \sa changeValue
+ */
+void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd)
+{
+  this->checkAllocated();
+  if(this->getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
+  int nbElemsIn((int)std::distance(indArrBg,indArrEnd)),nbOfTuples(getNumberOfTuples()),*pt(getPointer());
+  for(int i=0;i<nbOfTuples;i++,pt++)
+    {
+      if(*pt>=0 && *pt<nbElemsIn)
+        *pt=indArrBg[*pt];
+      else
+        {
+          std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
     }
-  else
+  this->declareAsNew();
+}
+
+void DataArrayInt::transformWithIndArr(const MapKeyVal<int>& m)
+{
+  this->checkAllocated();
+  if(this->getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
+  const std::map<int,int> dat(m.data());
+  int nbOfTuples(getNumberOfTuples()),*pt(getPointer());
+  for(int i=0;i<nbOfTuples;i++,pt++)
     {
-      sttoopp--;
-      int a(strt-sttoopp-1),tmp(strt);
-      if(a%(nbTuples-1)!=0)
-        return false;
-      stteepp=-(a/(nbTuples-1));
-      for(int i=0;i<nbTuples;i++,tmp+=stteepp)
-        if(pt[i]!=tmp)
-          return false;
-      return true;
+      std::map<int,int>::const_iterator it(dat.find(*pt));
+      if(it!=dat.end())
+        *pt=(*it).second;
+      else
+        {
+          std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << " not in map !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
     }
+  this->declareAsNew();
 }
 
 /*!
@@ -5204,11 +4168,11 @@ DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int
  */
 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
 {
-  MCAuto<DataArrayInt> ret=DataArrayInt::New();
+  MCAuto<DataArrayInt> ret(DataArrayInt::New());
   ret->alloc(newNbOfElem,1);
-  int nbOfOldNodes=getNumberOfTuples();
-  const int *old2New=getConstPointer();
-  int *pt=ret->getPointer();
+  int nbOfOldNodes(this->getNumberOfTuples());
+  const int *old2New(begin());
+  int *pt(ret->getPointer());
   for(int i=0;i!=nbOfOldNodes;i++)
     {
       int newp(old2New[i]);
@@ -5237,437 +4201,90 @@ DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const
   int nbOfOldNodes=getNumberOfTuples();
   const int *old2New=getConstPointer();
   int *pt=ret->getPointer();
-  for(int i=nbOfOldNodes-1;i>=0;i--)
-    {
-      int newp(old2New[i]);
-      if(newp!=-1)
-        {
-          if(newp>=0 && newp<newNbOfElem)
-            pt[newp]=i;
-          else
-            {
-              std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
-              throw INTERP_KERNEL::Exception(oss.str().c_str());
-            }
-        }
-    }
-  return ret.retn();
-}
-
-/*!
- * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
- * from values of \a this array, which is supposed to contain a renumbering map in 
- * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
- * To know how to use the renumbering maps see \ref numbering.
- *  \param [in] newNbOfElem - the number of tuples in the result array.
- *  \return DataArrayInt * - the new instance of DataArrayInt.
- *          The caller is to delete this result array using decrRef() as it is no more
- *          needed.
- * 
- *  \if ENABLE_EXAMPLES
- *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
- *
- *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
- *  \endif
- */
-DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
-{
-  checkAllocated();
-  MCAuto<DataArrayInt> ret=DataArrayInt::New();
-  ret->alloc(oldNbOfElem,1);
-  const int *new2Old=getConstPointer();
-  int *pt=ret->getPointer();
-  std::fill(pt,pt+oldNbOfElem,-1);
-  int nbOfNewElems=getNumberOfTuples();
-  for(int i=0;i<nbOfNewElems;i++)
-    {
-      int v(new2Old[i]);
-      if(v>=0 && v<oldNbOfElem)
-        pt[v]=i;
-      else
-        {
-          std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
-        }
-    }
-  return ret.retn();
-}
-
-/*!
- * Equivalent to DataArrayInt::isEqual except that if false the reason of
- * mismatch is given.
- * 
- * \param [in] other the instance to be compared with \a this
- * \param [out] reason In case of inequality returns the reason.
- * \sa DataArrayInt::isEqual
- */
-bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
-{
-  if(!areInfoEqualsIfNotWhy(other,reason))
-    return false;
-  return _mem.isEqual(other._mem,0,reason);
-}
-
-/*!
- * Checks if \a this and another DataArrayInt are fully equal. For more info see
- * \ref MEDCouplingArrayBasicsCompare.
- *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
- *  \return bool - \a true if the two arrays are equal, \a false else.
- */
-bool DataArrayInt::isEqual(const DataArrayInt& other) const
-{
-  std::string tmp;
-  return isEqualIfNotWhy(other,tmp);
-}
-
-/*!
- * Checks if values of \a this and another DataArrayInt are equal. For more info see
- * \ref MEDCouplingArrayBasicsCompare.
- *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
- *  \return bool - \a true if the values of two arrays are equal, \a false else.
- */
-bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const
-{
-  std::string tmp;
-  return _mem.isEqual(other._mem,0,tmp);
-}
-
-/*!
- * Checks if values of \a this and another DataArrayInt are equal. Comparison is
- * performed on sorted value sequences.
- * For more info see\ref MEDCouplingArrayBasicsCompare.
- *  \param [in] other - an instance of DataArrayInt to compare with \a this one.
- *  \return bool - \a true if the sorted values of two arrays are equal, \a false else.
- */
-bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const
-{
-  MCAuto<DataArrayInt> a=deepCopy();
-  MCAuto<DataArrayInt> b=other.deepCopy();
-  a->sort();
-  b->sort();
-  return a->isEqualWithoutConsideringStr(*b);
-}
-
-/*!
- * This method compares content of input vector \a v and \a this.
- * If for each id in \a this v[id]==True and for all other ids id2 not in \a this v[id2]==False, true is returned.
- * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown.
- *
- * \param [in] v - the vector of 'flags' to be compared with \a this.
- *
- * \throw If \a this is not sorted ascendingly.
- * \throw If \a this has not exactly one component.
- * \throw If \a this is not allocated.
- */
-bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const
-{
-  checkAllocated();
-  if(getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !");
-  const int *w(begin()),*end2(end());
-  int refVal=-std::numeric_limits<int>::max();
-  int i=0;
-  std::vector<bool>::const_iterator it(v.begin());
-  for(;it!=v.end();it++,i++)
-    {
-      if(*it)
-        {
-          if(w!=end2)
-            {
-              if(*w++==i)
-                {
-                  if(i>refVal)
-                    refVal=i;
-                  else
-                    {
-                      std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !";
-                      throw INTERP_KERNEL::Exception(oss.str().c_str());
-                    }
-                }
-              else
-                return false;
-            }
-          else
-            return false;
-        }
-    }
-  return w==end2;
-}
-
-/*!
- * This method assumes that \a this has one component and is allocated. This method scans all tuples in \a this and for all tuple equal to \a val
- * put True to the corresponding entry in \a vec.
- * \a vec is expected to be with the same size than the number of tuples of \a this.
- *
- *  \sa DataArrayInt::switchOnTupleNotEqualTo.
- */
-void DataArrayInt::switchOnTupleEqualTo(int val, std::vector<bool>& vec) const
-{
-  checkAllocated();
-  if(getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !");
-  int nbOfTuples(getNumberOfTuples());
-  if(nbOfTuples!=(int)vec.size())
-    throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !");
-  const int *pt(begin());
-  for(int i=0;i<nbOfTuples;i++)
-    if(pt[i]==val)
-      vec[i]=true;
-}
-
-/*!
- * This method assumes that \a this has one component and is allocated. This method scans all tuples in \a this and for all tuple different from \a val
- * put True to the corresponding entry in \a vec.
- * \a vec is expected to be with the same size than the number of tuples of \a this.
- * 
- *  \sa DataArrayInt::switchOnTupleEqualTo.
- */
-void DataArrayInt::switchOnTupleNotEqualTo(int val, std::vector<bool>& vec) const
-{
-  checkAllocated();
-  if(getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of components of this should be equal to one !");
-  int nbOfTuples(getNumberOfTuples());
-  if(nbOfTuples!=(int)vec.size())
-    throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleNotEqualTo : number of tuples of this should be equal to size of input vector of bool !");
-  const int *pt(begin());
-  for(int i=0;i<nbOfTuples;i++)
-    if(pt[i]!=val)
-      vec[i]=true;
-}
-
-/*!
- * Computes for each tuple the sum of number of components values in the tuple and return it.
- * 
- * \return DataArrayInt * - the new instance of DataArrayInt containing the
- *          same number of tuples as \a this array and one component.
- *          The caller is to delete this result array using decrRef() as it is no more
- *          needed.
- *  \throw If \a this is not allocated.
- */
-DataArrayInt *DataArrayInt::sumPerTuple() const
-{
-  checkAllocated();
-  int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples());
-  MCAuto<DataArrayInt> ret(DataArrayInt::New());
-  ret->alloc(nbOfTuple,1);
-  const int *src(getConstPointer());
-  int *dest(ret->getPointer());
-  for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp)
-    *dest=std::accumulate(src,src+nbOfComp,0);
-  return ret.retn();
-}
-
-/*!
- * Checks that \a this array is consistently **increasing** or **decreasing** in value.
- * If not an exception is thrown.
- *  \param [in] increasing - if \a true, the array values should be increasing.
- *  \throw If sequence of values is not strictly monotonic in agreement with \a
- *         increasing arg.
- *  \throw If \a this->getNumberOfComponents() != 1.
- *  \throw If \a this is not allocated.
- */
-void DataArrayInt::checkMonotonic(bool increasing) const
-{
-  if(!isMonotonic(increasing))
-    {
-      if (increasing)
-        throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
-      else
-        throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
-    }
-}
-
-/*!
- * Checks that \a this array is consistently **increasing** or **decreasing** in value.
- *  \param [in] increasing - if \a true, array values should be increasing.
- *  \return bool - \a true if values change in accordance with \a increasing arg.
- *  \throw If \a this->getNumberOfComponents() != 1.
- *  \throw If \a this is not allocated.
- */
-bool DataArrayInt::isMonotonic(bool increasing) const
-{
-  checkAllocated();
-  if(getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
-  int nbOfElements=getNumberOfTuples();
-  const int *ptr=getConstPointer();
-  if(nbOfElements==0)
-    return true;
-  int ref=ptr[0];
-  if(increasing)
-    {
-      for(int i=1;i<nbOfElements;i++)
-        {
-          if(ptr[i]>=ref)
-            ref=ptr[i];
-          else
-            return false;
-        }
-    }
-  else
-    {
-      for(int i=1;i<nbOfElements;i++)
-        {
-          if(ptr[i]<=ref)
-            ref=ptr[i];
-          else
-            return false;
-        }
-    }
-  return true;
-}
-
-/*!
- * This method check that array consistently INCREASING or DECREASING in value.
- */
-bool DataArrayInt::isStrictlyMonotonic(bool increasing) const
-{
-  checkAllocated();
-  if(getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
-  int nbOfElements=getNumberOfTuples();
-  const int *ptr=getConstPointer();
-  if(nbOfElements==0)
-    return true;
-  int ref=ptr[0];
-  if(increasing)
-    {
-      for(int i=1;i<nbOfElements;i++)
-        {
-          if(ptr[i]>ref)
-            ref=ptr[i];
-          else
-            return false;
-        }
-    }
-  else
+  for(int i=nbOfOldNodes-1;i>=0;i--)
     {
-      for(int i=1;i<nbOfElements;i++)
+      int newp(old2New[i]);
+      if(newp!=-1)
         {
-          if(ptr[i]<ref)
-            ref=ptr[i];
+          if(newp>=0 && newp<newNbOfElem)
+            pt[newp]=i;
           else
-            return false;
+            {
+              std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !";
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }
         }
     }
-  return true;
-}
-
-/*!
- * This method check that array consistently INCREASING or DECREASING in value.
- */
-void DataArrayInt::checkStrictlyMonotonic(bool increasing) const
-{
-  if(!isStrictlyMonotonic(increasing))
-    {
-      if (increasing)
-        throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
-      else
-        throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
-    }
+  return ret.retn();
 }
 
 /*!
- * Creates a new one-dimensional DataArrayInt of the same size as \a this and a given
- * one-dimensional arrays that must be of the same length. The result array describes
- * correspondence between \a this and \a other arrays, so that 
- * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. If such a permutation is
- * not possible because some element in \a other is not in \a this, an exception is thrown.
- *  \param [in] other - an array to compute permutation to.
- *  \return DataArrayInt * - a new instance of DataArrayInt, which is a permutation array
- * from \a this to \a other. The caller is to delete this array using decrRef() as it is
- * no more needed.
- *  \throw If \a this->getNumberOfComponents() != 1.
- *  \throw If \a other->getNumberOfComponents() != 1.
- *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples().
- *  \throw If \a other includes a value which is not in \a this array.
+ * Creates a one-dimensional DataArrayInt of given length, whose contents are computed
+ * from values of \a this array, which is supposed to contain a renumbering map in 
+ * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
+ * To know how to use the renumbering maps see \ref numbering.
+ *  \param [in] newNbOfElem - the number of tuples in the result array.
+ *  \return DataArrayInt * - the new instance of DataArrayInt.
+ *          The caller is to delete this result array using decrRef() as it is no more
+ *          needed.
  * 
  *  \if ENABLE_EXAMPLES
- *  \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example".
+ *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
  *
- *  \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example".
+ *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
+ *  \sa invertArrayN2O2O2NOptimized
  *  \endif
  */
-DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
+DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
 {
   checkAllocated();
-  if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
-  int nbTuple=getNumberOfTuples();
-  other.checkAllocated();
-  if(nbTuple!=other.getNumberOfTuples())
-    throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
   MCAuto<DataArrayInt> ret=DataArrayInt::New();
-  ret->alloc(nbTuple,1);
-  ret->fillWithValue(-1);
-  const int *pt=getConstPointer();
-  std::map<int,int> mm;
-  for(int i=0;i<nbTuple;i++)
-    mm[pt[i]]=i;
-  pt=other.getConstPointer();
-  int *retToFill=ret->getPointer();
-  for(int i=0;i<nbTuple;i++)
+  ret->alloc(oldNbOfElem,1);
+  const int *new2Old=getConstPointer();
+  int *pt=ret->getPointer();
+  std::fill(pt,pt+oldNbOfElem,-1);
+  int nbOfNewElems=getNumberOfTuples();
+  for(int i=0;i<nbOfNewElems;i++)
     {
-      std::map<int,int>::const_iterator it=mm.find(pt[i]);
-      if(it==mm.end())
+      int v(new2Old[i]);
+      if(v>=0 && v<oldNbOfElem)
+        pt[v]=i;
+      else
         {
-          std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !";
+          std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !";
           throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
-      retToFill[i]=(*it).second;
     }
   return ret.retn();
 }
 
-void DataArrayInt::aggregate(const DataArrayInt *other)
-{
-  if(!other)
-    throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : null pointer !");
-  if(getNumberOfComponents()!=other->getNumberOfComponents())
-    throw INTERP_KERNEL::Exception("DataArrayInt::aggregate : mismatch number of components !");
-  _mem.insertAtTheEnd(other->begin(),other->end());
-}
-
-/*!
- * Returns a new DataArrayInt holding the same values as \a this array but differently
- * arranged in memory. If \a this array holds 2 components of 3 values:
- * \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$, then the result array holds these values arranged
- * as follows: \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$.
- *  \warning Do not confuse this method with transpose()!
- *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
- *          is to delete using decrRef() as it is no more needed.
- *  \throw If \a this is not allocated.
- */
-DataArrayInt *DataArrayInt::fromNoInterlace() const
-{
-  checkAllocated();
-  if(_mem.isNull())
-    throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
-  int *tab=_mem.fromNoInterlace(getNumberOfComponents());
-  DataArrayInt *ret=DataArrayInt::New();
-  ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
-  return ret;
-}
-
 /*!
- * Returns a new DataArrayInt holding the same values as \a this array but differently
- * arranged in memory. If \a this array holds 2 components of 3 values:
- * \f$ x_0,y_0,x_1,y_1,x_2,y_2 \f$, then the result array holds these values arranged
- * as follows: \f$ x_0,x_1,x_2,y_0,y_1,y_2 \f$.
- *  \warning Do not confuse this method with transpose()!
- *  \return DataArrayInt * - the new instance of DataArrayInt that the caller
- *          is to delete using decrRef() as it is no more needed.
- *  \throw If \a this is not allocated.
+ * Creates a map, whose contents are computed
+ * from values of \a this array, which is supposed to contain a renumbering map in 
+ * "New to Old" mode. The result array contains a renumbering map in "Old to New" mode.
+ * To know how to use the renumbering maps see \ref numbering.
+ *  \param [in] newNbOfElem - the number of tuples in the result array.
+ *  \return MapII  - the new instance of Map.
+ * 
+ *  \if ENABLE_EXAMPLES
+ *  \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example".
+ *
+ *  \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example".
+ *  \sa invertArrayN2O2O2N
+ *  \endif
  */
-DataArrayInt *DataArrayInt::toNoInterlace() const
+MCAuto< MapKeyVal<int> > DataArrayInt::invertArrayN2O2O2NOptimized() const
 {
   checkAllocated();
-  if(_mem.isNull())
-    throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
-  int *tab=_mem.toNoInterlace(getNumberOfComponents());
-  DataArrayInt *ret=DataArrayInt::New();
-  ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
+  MCAuto< MapKeyVal<int> > ret(MapKeyVal<int>::New());
+  std::map<int,int>& m(ret->data());
+  const int *new2Old(begin());
+  int nbOfNewElems(this->getNumberOfTuples());
+  for(int i=0;i<nbOfNewElems;i++)
+    {
+      int v(new2Old[i]);
+      m[v]=i;
+    }
   return ret;
 }
 
@@ -5959,21 +4576,45 @@ bool DataArrayInt::isIota(int sizeExpected) const
  *  \return bool - \a true if all values are \a val.
  *  \throw If \a this is not allocated.
  *  \throw If \a this->getNumberOfComponents() != 1
+ *  \sa DataArrayInt::checkUniformAndGuess
  */
 bool DataArrayInt::isUniform(int val) const
 {
   checkAllocated();
   if(getNumberOfComponents()!=1)
     throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
-  int nbOfTuples=getNumberOfTuples();
-  const int *w=getConstPointer();
-  const int *end2=w+nbOfTuples;
+  const int *w(begin()),*end2(end());
   for(;w!=end2;w++)
     if(*w!=val)
       return false;
   return true;
 }
 
+/*!
+ * This method checks that \a this is uniform. If not and exception will be thrown.
+ * In case of uniformity the corresponding value is returned.
+ *
+ * \return int - the unique value contained in this
+ * \throw If \a this is not allocated.
+ * \throw If \a this->getNumberOfComponents() != 1
+ * \throw If \a this is not uniform.
+ * \sa DataArrayInt::isUniform
+ */
+int DataArrayInt::checkUniformAndGuess() const
+{
+  checkAllocated();
+  if(getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !");
+  if(empty())
+    throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is empty !");
+  const int *w(begin()),*end2(end());
+  int ret(*w);
+  for(;w!=end2;w++)
+    if(*w!=ret)
+      throw INTERP_KERNEL::Exception("DataArrayInt::checkUniformAndGuess : this is not uniform !");
+  return ret;
+}
+
 /*!
  * Checks if all values in \a this array are unique.
  *  \return bool - \a true if condition above is true
@@ -5992,65 +4633,6 @@ bool DataArrayInt::hasUniqueValues() const
   return true;
 }
 
-/*!
- * Creates a new DataArrayDouble and assigns all (textual and numerical) data of \a this
- * array to the new one.
- *  \return DataArrayDouble * - the new instance of DataArrayInt.
- */
-DataArrayDouble *DataArrayInt::convertToDblArr() const
-{
-  checkAllocated();
-  DataArrayDouble *ret=DataArrayDouble::New();
-  ret->alloc(getNumberOfTuples(),getNumberOfComponents());
-  std::size_t nbOfVals=getNbOfElems();
-  const int *src=getConstPointer();
-  double *dest=ret->getPointer();
-  std::copy(src,src+nbOfVals,dest);
-  ret->copyStringInfoFrom(*this);
-  return ret;
-}
-
-/*!
- * Appends components of another array to components of \a this one, tuple by tuple.
- * So that the number of tuples of \a this array remains the same and the number of 
- * components increases.
- *  \param [in] other - the DataArrayInt to append to \a this one.
- *  \throw If \a this is not allocated.
- *  \throw If \a this and \a other arrays have different number of tuples.
- *
- *  \if ENABLE_EXAMPLES
- *  \ref cpp_mcdataarrayint_meldwith "Here is a C++ example".
- *
- *  \ref py_mcdataarrayint_meldwith "Here is a Python example".
- *  \endif
- */
-void DataArrayInt::meldWith(const DataArrayInt *other)
-{
-  if(!other)
-    throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !");
-  checkAllocated();
-  other->checkAllocated();
-  int nbOfTuples=getNumberOfTuples();
-  if(nbOfTuples!=other->getNumberOfTuples())
-    throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !");
-  int nbOfComp1=getNumberOfComponents();
-  int nbOfComp2=other->getNumberOfComponents();
-  int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int));
-  int *w=newArr;
-  const int *inp1=getConstPointer();
-  const int *inp2=other->getConstPointer();
-  for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2)
-    {
-      w=std::copy(inp1,inp1+nbOfComp1,w);
-      w=std::copy(inp2,inp2+nbOfComp2,w);
-    }
-  useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2);
-  std::vector<int> compIds(nbOfComp2);
-  for(int i=0;i<nbOfComp2;i++)
-    compIds[i]=nbOfComp1+i;
-  copyPartOfStringInfoFrom2(compIds,*other);
-}
-
 /*!
  * Copy all components in a specified order from another DataArrayInt.
  * The specified components become the first ones in \a this array.
@@ -6084,24 +4666,6 @@ void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vecto
       nc[nbOfCompo*i+compoIds[j]]=*ac;
 }
 
-/*!
- * Assign pointer to one array to a pointer to another appay. Reference counter of
- * \a arrayToSet is incremented / decremented.
- *  \param [in] newArray - the pointer to array to assign to \a arrayToSet.
- *  \param [in,out] arrayToSet - the pointer to array to assign to.
- */
-void DataArrayInt::SetArrayIn(DataArrayInt *newArray, DataArrayInt* &arrayToSet)
-{
-  if(newArray!=arrayToSet)
-    {
-      if(arrayToSet)
-        arrayToSet->decrRef();
-      arrayToSet=newArray;
-      if(arrayToSet)
-        arrayToSet->incrRef();
-    }
-}
-
 DataArrayIntIterator *DataArrayInt::iterator()
 {
   return new DataArrayIntIterator(this);
@@ -6677,103 +5241,6 @@ void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const
     }
 }
 
-/*!
- * Converts every value of \a this array to its absolute value.
- * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs
- * should be called instead.
- *
- * \throw If \a this is not allocated.
- * \sa DataArrayInt::computeAbs
- */
-void DataArrayInt::abs()
-{
-  checkAllocated();
-  int *ptr(getPointer());
-  std::size_t nbOfElems(getNbOfElems());
-  std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
-  declareAsNew();
-}
-
-/*!
- * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this.
- * This method is a const method (that do not change any values in \a this) contrary to  DataArrayInt::abs method.
- *
- * \return DataArrayInt * - the new instance of DataArrayInt containing the
- *         same number of tuples and component as \a this array.
- *         The caller is to delete this result array using decrRef() as it is no more
- *         needed.
- * \throw If \a this is not allocated.
- * \sa DataArrayInt::abs
- */
-DataArrayInt *DataArrayInt::computeAbs() const
-{
-  checkAllocated();
-  DataArrayInt *newArr(DataArrayInt::New());
-  int nbOfTuples(getNumberOfTuples());
-  int nbOfComp(getNumberOfComponents());
-  newArr->alloc(nbOfTuples,nbOfComp);
-  std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs));
-  newArr->copyStringInfoFrom(*this);
-  return newArr;
-}
-
-/*!
- * Apply a liner function to a given component of \a this array, so that
- * an array element <em>(x)</em> becomes \f$ a * x + b \f$.
- *  \param [in] a - the first coefficient of the function.
- *  \param [in] b - the second coefficient of the function.
- *  \param [in] compoId - the index of component to modify.
- *  \throw If \a this is not allocated.
- */
-void DataArrayInt::applyLin(int a, int b, int compoId)
-{
-  checkAllocated();
-  int *ptr=getPointer()+compoId;
-  int nbOfComp=getNumberOfComponents();
-  int nbOfTuple=getNumberOfTuples();
-  for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp)
-    *ptr=a*(*ptr)+b;
-  declareAsNew();
-}
-
-/*!
- * Apply a liner function to all elements of \a this array, so that
- * an element _x_ becomes \f$ a * x + b \f$.
- *  \param [in] a - the first coefficient of the function.
- *  \param [in] b - the second coefficient of the function.
- *  \throw If \a this is not allocated.
- */
-void DataArrayInt::applyLin(int a, int b)
-{
-  checkAllocated();
-  int *ptr=getPointer();
-  std::size_t nbOfElems=getNbOfElems();
-  for(std::size_t i=0;i<nbOfElems;i++,ptr++)
-    *ptr=a*(*ptr)+b;
-  declareAsNew();
-}
-
-/*!
- * Returns a full copy of \a this array except that sign of all elements is reversed.
- *  \return DataArrayInt * - the new instance of DataArrayInt containing the
- *          same number of tuples and component as \a this array.
- *          The caller is to delete this result array using decrRef() as it is no more
- *          needed.
- *  \throw If \a this is not allocated.
- */
-DataArrayInt *DataArrayInt::negate() const
-{
-  checkAllocated();
-  DataArrayInt *newArr=DataArrayInt::New();
-  int nbOfTuples=getNumberOfTuples();
-  int nbOfComp=getNumberOfComponents();
-  newArr->alloc(nbOfTuples,nbOfComp);
-  const int *cptr=getConstPointer();
-  std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>());
-  newArr->copyStringInfoFrom(*this);
-  return newArr;
-}
-
 /*!
  * Modify all elements of \a this array, so that
  * an element _x_ becomes \f$ numerator / x \f$.
@@ -6854,15 +5321,8 @@ void DataArrayInt::applyModulus(int val)
  */
 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
 {
-  checkAllocated();
-  if(getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayInt::findIdsInRange : this must have exactly one component !");
-  const int *cptr(begin());
-  MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
-  int nbOfTuples(getNumberOfTuples());
-  for(int i=0;i<nbOfTuples;i++,cptr++)
-    if(*cptr>=vmin && *cptr<vmax)
-      ret->pushBackSilent(i);
+  InRange<int> ir(vmin,vmax);
+  MCAuto<DataArrayInt> ret(findIdsAdv(ir));
   return ret.retn();
 }
 
@@ -6879,35 +5339,8 @@ DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
  */
 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
 {
-  checkAllocated();
-  if(getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayInt::findIdsNotInRange : this must have exactly one component !");
-  const int *cptr(getConstPointer());
-  MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
-  int nbOfTuples(getNumberOfTuples());
-  for(int i=0;i<nbOfTuples;i++,cptr++)
-    if(*cptr<vmin || *cptr>=vmax)
-      ret->pushBackSilent(i);
-  return ret.retn();
-}
-
-/*!
- * This method works only on data array with one component. This method returns a newly allocated array storing stored ascendantly of tuple ids in \a this so that this[id]<0.
- *
- * \return a newly allocated data array that the caller should deal with.
- * \sa DataArrayInt::findIdsInRange
- */
-DataArrayInt *DataArrayInt::findIdsStricltyNegative() const
-{
-  checkAllocated();
-  if(getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayInt::findIdsStricltyNegative : this must have exactly one component !");
-  const int *cptr(getConstPointer());
-  MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
-  int nbOfTuples(getNumberOfTuples());
-  for(int i=0;i<nbOfTuples;i++,cptr++)
-    if(*cptr<0)
-      ret->pushBackSilent(i);
+  NotInRange<int> nir(vmin,vmax);
+  MCAuto<DataArrayInt> ret(findIdsAdv(nir));
   return ret.retn();
 }
 
@@ -7025,91 +5458,12 @@ void DataArrayInt::applyRPow(int val)
         }
       else
         {
-          std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
-          oss << " !";
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
-        }
-    }
-  declareAsNew();
-}
-
-/*!
- * Returns a new DataArrayInt by aggregating two given arrays, so that (1) the number
- * of components in the result array is a sum of the number of components of given arrays
- * and (2) the number of tuples in the result array is same as that of each of given
- * arrays. In other words the i-th tuple of result array includes all components of
- * i-th tuples of all given arrays.
- * Number of tuples in the given arrays must be the same.
- *  \param [in] a1 - an array to include in the result array.
- *  \param [in] a2 - another array to include in the result array.
- *  \return DataArrayInt * - the new instance of DataArrayInt.
- *          The caller is to delete this result array using decrRef() as it is no more
- *          needed.
- *  \throw If both \a a1 and \a a2 are NULL.
- *  \throw If any given array is not allocated.
- *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples()
- */
-DataArrayInt *DataArrayInt::Meld(const DataArrayInt *a1, const DataArrayInt *a2)
-{
-  std::vector<const DataArrayInt *> arr(2);
-  arr[0]=a1; arr[1]=a2;
-  return Meld(arr);
-}
-
-/*!
- * Returns a new DataArrayInt by aggregating all given arrays, so that (1) the number
- * of components in the result array is a sum of the number of components of given arrays
- * and (2) the number of tuples in the result array is same as that of each of given
- * arrays. In other words the i-th tuple of result array includes all components of
- * i-th tuples of all given arrays.
- * Number of tuples in the given arrays must be  the same.
- *  \param [in] arr - a sequence of arrays to include in the result array.
- *  \return DataArrayInt * - the new instance of DataArrayInt.
- *          The caller is to delete this result array using decrRef() as it is no more
- *          needed.
- *  \throw If all arrays within \a arr are NULL.
- *  \throw If any given array is not allocated.
- *  \throw If getNumberOfTuples() of arrays within \a arr is different.
- */
-DataArrayInt *DataArrayInt::Meld(const std::vector<const DataArrayInt *>& arr)
-{
-  std::vector<const DataArrayInt *> a;
-  for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++)
-    if(*it4)
-      a.push_back(*it4);
-  if(a.empty())
-    throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !");
-  std::vector<const DataArrayInt *>::const_iterator it;
-  for(it=a.begin();it!=a.end();it++)
-    (*it)->checkAllocated();
-  it=a.begin();
-  int nbOfTuples=(*it)->getNumberOfTuples();
-  std::vector<int> nbc(a.size());
-  std::vector<const int *> pts(a.size());
-  nbc[0]=(*it)->getNumberOfComponents();
-  pts[0]=(*it++)->getConstPointer();
-  for(int i=1;it!=a.end();it++,i++)
-    {
-      if(nbOfTuples!=(*it)->getNumberOfTuples())
-        throw INTERP_KERNEL::Exception("DataArrayInt::meld : mismatch of number of tuples !");
-      nbc[i]=(*it)->getNumberOfComponents();
-      pts[i]=(*it)->getConstPointer();
+          std::ostringstream oss; oss << "DataArrayInt::applyRPow : presence of negative value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents();
+          oss << " !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
+        }
     }
-  int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0);
-  DataArrayInt *ret=DataArrayInt::New();
-  ret->alloc(nbOfTuples,totalNbOfComp);
-  int *retPtr=ret->getPointer();
-  for(int i=0;i<nbOfTuples;i++)
-    for(int j=0;j<(int)a.size();j++)
-      {
-        retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr);
-        pts[j]+=nbc[j];
-      }
-  int k=0;
-  for(int i=0;i<(int)a.size();i++)
-    for(int j=0;j<nbc[i];j++,k++)
-      ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j));
-  return ret;
+  declareAsNew();
 }
 
 /*!
@@ -7375,1332 +5729,743 @@ DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const
     if(!tmp[i])
       retPtr[j++]=i;
   return ret;
-}
-
-/*!
- * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
- * from an \a other one-dimensional array.
- *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
- *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
- *         caller is to delete this array using decrRef() as it is no more needed.
- *  \throw If \a other is NULL.
- *  \throw If \a other is not allocated.
- *  \throw If \a other->getNumberOfComponents() != 1.
- *  \throw If \a this is not allocated.
- *  \throw If \a this->getNumberOfComponents() != 1.
- *  \sa DataArrayInt::buildSubstractionOptimized()
- */
-DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
-{
-  if(!other)
-    throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
-  checkAllocated();
-  other->checkAllocated();
-  if(getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
-  if(other->getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
-  const int *pt=getConstPointer();
-  int nbOfTuples=getNumberOfTuples();
-  std::set<int> s1(pt,pt+nbOfTuples);
-  pt=other->getConstPointer();
-  nbOfTuples=other->getNumberOfTuples();
-  std::set<int> s2(pt,pt+nbOfTuples);
-  std::vector<int> r;
-  std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
-  DataArrayInt *ret=DataArrayInt::New();
-  ret->alloc((int)r.size(),1);
-  std::copy(r.begin(),r.end(),ret->getPointer());
-  return ret;
-}
-
-/*!
- * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
- * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
- * 
- * \param [in] other an array with one component and expected to be sorted ascendingly.
- * \ret list of ids in \a this but not in \a other.
- * \sa DataArrayInt::buildSubstraction
- */
-DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
-{
-  static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
-  if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
-  checkAllocated(); other->checkAllocated();
-  if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
-  if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
-  const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
-  const int *work1(pt1Bg),*work2(pt2Bg);
-  MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
-  for(;work1!=pt1End;work1++)
-    {
-      if(work2!=pt2End && *work1==*work2)
-        work2++;
-      else
-        ret->pushBackSilent(*work1);
-    }
-  return ret.retn();
-}
-
-
-/*!
- * Returns a new DataArrayInt which contains all elements of \a this and a given
- * one-dimensional arrays. The result array does not contain any duplicates
- * and its values are sorted in ascending order.
- *  \param [in] other - an array to unite with \a this one.
- *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
- *         array using decrRef() as it is no more needed.
- *  \throw If \a this or \a other is not allocated.
- *  \throw If \a this->getNumberOfComponents() != 1.
- *  \throw If \a other->getNumberOfComponents() != 1.
- */
-DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
-{
-  std::vector<const DataArrayInt *>arrs(2);
-  arrs[0]=this; arrs[1]=other;
-  return BuildUnion(arrs);
-}
-
-
-/*!
- * Returns a new DataArrayInt which contains elements present in both \a this and a given
- * one-dimensional arrays. The result array does not contain any duplicates
- * and its values are sorted in ascending order.
- *  \param [in] other - an array to intersect with \a this one.
- *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
- *         array using decrRef() as it is no more needed.
- *  \throw If \a this or \a other is not allocated.
- *  \throw If \a this->getNumberOfComponents() != 1.
- *  \throw If \a other->getNumberOfComponents() != 1.
- */
-DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
-{
-  std::vector<const DataArrayInt *>arrs(2);
-  arrs[0]=this; arrs[1]=other;
-  return BuildIntersection(arrs);
-}
-
-/*!
- * This method can be applied on allocated with one component DataArrayInt instance.
- * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
- * Example : if \a this contains [1,2,2,3,3,3,3,4,5,5,7,7,7,19] the returned array will contain [1,2,3,4,5,7,19]
- * 
- * \return a newly allocated array that contain the result of the unique operation applied on \a this.
- * \throw if \a this is not allocated or if \a this has not exactly one component.
- * \sa DataArrayInt::buildUniqueNotSorted
- */
-DataArrayInt *DataArrayInt::buildUnique() const
-{
-  checkAllocated();
-  if(getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
-  int nbOfTuples=getNumberOfTuples();
-  MCAuto<DataArrayInt> tmp=deepCopy();
-  int *data=tmp->getPointer();
-  int *last=std::unique(data,data+nbOfTuples);
-  MCAuto<DataArrayInt> ret=DataArrayInt::New();
-  ret->alloc(std::distance(data,last),1);
-  std::copy(data,last,ret->getPointer());
-  return ret.retn();
-}
-
-/*!
- * This method can be applied on allocated with one component DataArrayInt instance.
- * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
- *
- * \return a newly allocated array that contain the result of the unique operation applied on \a this.
- *
- * \throw if \a this is not allocated or if \a this has not exactly one component.
- *
- * \sa DataArrayInt::buildUnique
- */
-DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
-{
-  checkAllocated();
-    if(getNumberOfComponents()!=1)
-      throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
-  int minVal,maxVal;
-  getMinMaxValues(minVal,maxVal);
-  std::vector<bool> b(maxVal-minVal+1,false);
-  const int *ptBg(begin()),*endBg(end());
-  MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
-  for(const int *pt=ptBg;pt!=endBg;pt++)
-    {
-      if(!b[*pt-minVal])
-        {
-          ret->pushBackSilent(*pt);
-          b[*pt-minVal]=true;
-        }
-    }
-  ret->copyStringInfoFrom(*this);
-  return ret.retn();
-}
-
-/*!
- * Returns a new DataArrayInt which contains size of every of groups described by \a this
- * "index" array. Such "index" array is returned for example by 
- * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
- * "MEDCouplingUMesh::buildDescendingConnectivity" and
- * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
- * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
- * This method preforms the reverse operation of DataArrayInt::computeOffsetsFull.
- *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
- *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
- *          The caller is to delete this array using decrRef() as it is no more needed. 
- *  \throw If \a this is not allocated.
- *  \throw If \a this->getNumberOfComponents() != 1.
- *  \throw If \a this->getNumberOfTuples() < 2.
- *
- *  \b Example: <br> 
- *         - this contains [1,3,6,7,7,9,15]
- *         - result array contains [2,3,1,0,2,6],
- *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
- *
- * \sa DataArrayInt::computeOffsetsFull
- */
-DataArrayInt *DataArrayInt::deltaShiftIndex() const
-{
-  checkAllocated();
-  if(getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
-  int nbOfTuples=getNumberOfTuples();
-  if(nbOfTuples<2)
-    throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
-  const int *ptr=getConstPointer();
-  DataArrayInt *ret=DataArrayInt::New();
-  ret->alloc(nbOfTuples-1,1);
-  int *out=ret->getPointer();
-  std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
-  return ret;
-}
-
-/*!
- * Modifies \a this one-dimensional array so that value of each element \a x
- * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
- * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
- * and components remains the same.<br>
- * This method is useful for allToAllV in MPI with contiguous policy. This method
- * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
- * this one.
- *  \throw If \a this is not allocated.
- *  \throw If \a this->getNumberOfComponents() != 1.
- *
- *  \b Example: <br>
- *          - Before \a this contains [3,5,1,2,0,8]
- *          - After \a this contains  [0,3,8,9,11,11]<br>
- *          Note that the last element 19 = 11 + 8 is missing because size of \a this
- *          array is retained and thus there is no space to store the last element.
- */
-void DataArrayInt::computeOffsets()
-{
-  checkAllocated();
-  if(getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
-  int nbOfTuples=getNumberOfTuples();
-  if(nbOfTuples==0)
-    return ;
-  int *work=getPointer();
-  int tmp=work[0];
-  work[0]=0;
-  for(int i=1;i<nbOfTuples;i++)
-    {
-      int tmp2=work[i];
-      work[i]=work[i-1]+tmp;
-      tmp=tmp2;
-    }
-  declareAsNew();
-}
-
-
-/*!
- * Modifies \a this one-dimensional array so that value of each element \a x
- * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
- * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
- * components remains the same and number of tuples is inceamented by one.<br>
- * This method is useful for allToAllV in MPI with contiguous policy. This method
- * differs from computeOffsets() in that the number of tuples is changed by this one.
- * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
+}
+
+/*!
+ * Returns a new DataArrayInt containing elements of \a this one-dimensional missing
+ * from an \a other one-dimensional array.
+ *  \param [in] other - a DataArrayInt containing elements not to include in the result array.
+ *  \return DataArrayInt * - a new instance of DataArrayInt with one component. The
+ *         caller is to delete this array using decrRef() as it is no more needed.
+ *  \throw If \a other is NULL.
+ *  \throw If \a other is not allocated.
+ *  \throw If \a other->getNumberOfComponents() != 1.
  *  \throw If \a this is not allocated.
  *  \throw If \a this->getNumberOfComponents() != 1.
- *
- *  \b Example: <br>
- *          - Before \a this contains [3,5,1,2,0,8]
- *          - After \a this contains  [0,3,8,9,11,11,19]<br>
- * \sa DataArrayInt::deltaShiftIndex
+ *  \sa DataArrayInt::buildSubstractionOptimized()
  */
-void DataArrayInt::computeOffsetsFull()
+DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const
 {
+  if(!other)
+    throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !");
   checkAllocated();
+  other->checkAllocated();
   if(getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
+    throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !");
+  if(other->getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !");
+  const int *pt=getConstPointer();
   int nbOfTuples=getNumberOfTuples();
-  int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
-  const int *work=getConstPointer();
-  ret[0]=0;
-  for(int i=0;i<nbOfTuples;i++)
-    ret[i+1]=work[i]+ret[i];
-  useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
-  declareAsNew();
+  std::set<int> s1(pt,pt+nbOfTuples);
+  pt=other->getConstPointer();
+  nbOfTuples=other->getNumberOfTuples();
+  std::set<int> s2(pt,pt+nbOfTuples);
+  std::vector<int> r;
+  std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r));
+  DataArrayInt *ret=DataArrayInt::New();
+  ret->alloc((int)r.size(),1);
+  std::copy(r.begin(),r.end(),ret->getPointer());
+  return ret;
 }
 
 /*!
- * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
- * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
- * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
- * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
- * filling completely one of the ranges in \a this.
- *
- * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
- * \param [out] rangeIdsFetched the range ids fetched
- * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
- *              \a idsInInputListThatFetch is a part of input \a listOfIds.
- *
- * \sa DataArrayInt::computeOffsetsFull
- *
- *  \b Example: <br>
- *          - \a this : [0,3,7,9,15,18]
- *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
- *          - \a rangeIdsFetched result array: [0,2,4]
- *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
- * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
- * <br>
+ * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
+ * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
+ * 
+ * \param [in] other an array with one component and expected to be sorted ascendingly.
+ * \ret list of ids in \a this but not in \a other.
+ * \sa DataArrayInt::buildSubstraction
  */
-void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
+DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const
 {
-  if(!listOfIds)
-    throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
-  listOfIds->checkAllocated(); checkAllocated();
-  if(listOfIds->getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
-  if(getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
-  MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
-  MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
-  const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
-  const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
-  while(tupPtr!=tupEnd && offPtr!=offEnd)
+  static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
+  if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
+  checkAllocated(); other->checkAllocated();
+  if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
+  if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
+  const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end());
+  const int *work1(pt1Bg),*work2(pt2Bg);
+  MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
+  for(;work1!=pt1End;work1++)
     {
-      if(*tupPtr==*offPtr)
-        {
-          int i=offPtr[0];
-          while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
-          if(i==offPtr[1])
-            {
-              ret0->pushBackSilent((int)std::distance(offBg,offPtr));
-              ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
-              offPtr++;
-            }
-        }
+      if(work2!=pt2End && *work1==*work2)
+        work2++;
       else
-        { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
+        ret->pushBackSilent(*work1);
     }
-  rangeIdsFetched=ret0.retn();
-  idsInInputListThatFetch=ret1.retn();
+  return ret.retn();
 }
 
+
 /*!
- * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
- * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
- * "index" array of a "iota" array, thus, whose each element gives an index of a group
- * beginning within the "iota" array. And \a this is a one-dimensional array
- * considered as a selector of groups described by \a offsets to include into the result array.
- *  \throw If \a offsets is NULL.
- *  \throw If \a offsets is not allocated.
- *  \throw If \a offsets->getNumberOfComponents() != 1.
- *  \throw If \a offsets is not monotonically increasing.
- *  \throw If \a this is not allocated.
+ * Returns a new DataArrayInt which contains all elements of \a this and a given
+ * one-dimensional arrays. The result array does not contain any duplicates
+ * and its values are sorted in ascending order.
+ *  \param [in] other - an array to unite with \a this one.
+ *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
+ *         array using decrRef() as it is no more needed.
+ *  \throw If \a this or \a other is not allocated.
  *  \throw If \a this->getNumberOfComponents() != 1.
- *  \throw If any element of \a this is not a valid index for \a offsets array.
- *
- *  \b Example: <br>
- *          - \a this: [0,2,3]
- *          - \a offsets: [0,3,6,10,14,20]
- *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
- *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
- *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
- *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
- *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
+ *  \throw If \a other->getNumberOfComponents() != 1.
  */
-DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
+DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const
 {
-  if(!offsets)
-    throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
-  checkAllocated();
-  if(getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
-  offsets->checkAllocated();
-  if(offsets->getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
-  int othNbTuples=offsets->getNumberOfTuples()-1;
-  int nbOfTuples=getNumberOfTuples();
-  int retNbOftuples=0;
-  const int *work=getConstPointer();
-  const int *offPtr=offsets->getConstPointer();
-  for(int i=0;i<nbOfTuples;i++)
-    {
-      int val=work[i];
-      if(val>=0 && val<othNbTuples)
-        {
-          int delta=offPtr[val+1]-offPtr[val];
-          if(delta>=0)
-            retNbOftuples+=delta;
-          else
-            {
-              std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
-              throw INTERP_KERNEL::Exception(oss.str().c_str());
-            }
-        }
-      else
-        {
-          std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
-          oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
-        }
-    }
-  MCAuto<DataArrayInt> ret=DataArrayInt::New();
-  ret->alloc(retNbOftuples,1);
-  int *retPtr=ret->getPointer();
-  for(int i=0;i<nbOfTuples;i++)
-    {
-      int val=work[i];
-      int start=offPtr[val];
-      int off=offPtr[val+1]-start;
-      for(int j=0;j<off;j++,retPtr++)
-        *retPtr=start+j;
-    }
-  return ret.retn();
+  std::vector<const DataArrayInt *>arrs(2);
+  arrs[0]=this; arrs[1]=other;
+  return BuildUnion(arrs);
 }
 
+
 /*!
- * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
- * scaled array (monotonically increasing).
-from that of \a this and \a
- * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
- * "index" array of a "iota" array, thus, whose each element gives an index of a group
- * beginning within the "iota" array. And \a this is a one-dimensional array
- * considered as a selector of groups described by \a offsets to include into the result array.
- *  \throw If \a  is NULL.
- *  \throw If \a this is not allocated.
+ * Returns a new DataArrayInt which contains elements present in both \a this and a given
+ * one-dimensional arrays. The result array does not contain any duplicates
+ * and its values are sorted in ascending order.
+ *  \param [in] other - an array to intersect with \a this one.
+ *  \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this
+ *         array using decrRef() as it is no more needed.
+ *  \throw If \a this or \a other is not allocated.
  *  \throw If \a this->getNumberOfComponents() != 1.
- *  \throw If \a this->getNumberOfTuples() == 0.
- *  \throw If \a this is not monotonically increasing.
- *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
- *
- *  \b Example: <br>
- *          - \a bg , \a stop and \a step : (0,5,2)
- *          - \a this: [0,3,6,10,14,20]
- *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
- */
-DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
-{
-  if(!isAllocated())
-    throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
-  if(getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
-  int nbOfTuples(getNumberOfTuples());
-  if(nbOfTuples==0)
-    throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
-  const int *ids(begin());
-  int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
-  for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
-    {
-      if(pos>=0 && pos<nbOfTuples-1)
-        {
-          int delta(ids[pos+1]-ids[pos]);
-          sz+=delta;
-          if(delta<0)
-            {
-              std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
-              throw INTERP_KERNEL::Exception(oss.str().c_str());
-            }          
-        }
-      else
-        {
-          std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
-        }
-    }
-  MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
-  int *retPtr(ret->getPointer());
-  pos=bg;
-  for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
-    {
-      int delta(ids[pos+1]-ids[pos]);
-      for(int j=0;j<delta;j++,retPtr++)
-        *retPtr=pos;
-    }
-  return ret.retn();
+ *  \throw If \a other->getNumberOfComponents() != 1.
+ */
+DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const
+{
+  std::vector<const DataArrayInt *>arrs(2);
+  arrs[0]=this; arrs[1]=other;
+  return BuildIntersection(arrs);
 }
 
 /*!
- * Given in input ranges \a ranges, it returns a newly allocated DataArrayInt instance having one component and the same number of tuples than \a this.
- * For each tuple at place **i** in \a this it tells which is the first range in \a ranges that contains value \c this->getIJ(i,0) and put the result
- * in tuple **i** of returned DataArrayInt.
- * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
- *
- * For example if \a this contains : [1,24,7,8,10,17] and \a ranges contains [(0,3),(3,8),(8,15),(15,22),(22,30)]
- * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
- * 
- * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
- *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
- * \throw If offsets is a null pointer or does not have 2 components or if \a this is not allocated or \a this do not have exactly one component. To finish an exception
- *        is thrown if no ranges in \a ranges contains value in \a this.
+ * This method can be applied on allocated with one component DataArrayInt instance.
+ * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
+ * Example : if \a this contains [1,2,2,3,3,3,3,4,5,5,7,7,7,19] the returned array will contain [1,2,3,4,5,7,19]
  * 
- * \sa DataArrayInt::findIdInRangeForEachTuple
+ * \return a newly allocated array that contain the result of the unique operation applied on \a this.
+ * \throw if \a this is not allocated or if \a this has not exactly one component.
+ * \sa DataArrayInt::buildUniqueNotSorted
  */
-DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
+DataArrayInt *DataArrayInt::buildUnique() const
 {
-  if(!ranges)
-    throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
-  if(ranges->getNumberOfComponents()!=2)
-    throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
   checkAllocated();
   if(getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
-  int nbTuples=getNumberOfTuples();
-  MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
-  int nbOfRanges=ranges->getNumberOfTuples();
-  const int *rangesPtr=ranges->getConstPointer();
-  int *retPtr=ret->getPointer();
-  const int *inPtr=getConstPointer();
-  for(int i=0;i<nbTuples;i++,retPtr++)
-    {
-      int val=inPtr[i];
-      bool found=false;
-      for(int j=0;j<nbOfRanges && !found;j++)
-        if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
-          { *retPtr=j; found=true; }
-      if(found)
-        continue;
-      else
-        {
-          std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
-        }
-    }
+    throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
+  int nbOfTuples=getNumberOfTuples();
+  MCAuto<DataArrayInt> tmp=deepCopy();
+  int *data=tmp->getPointer();
+  int *last=std::unique(data,data+nbOfTuples);
+  MCAuto<DataArrayInt> ret=DataArrayInt::New();
+  ret->alloc(std::distance(data,last),1);
+  std::copy(data,last,ret->getPointer());
   return ret.retn();
 }
 
 /*!
- * Given in input ranges \a ranges, it returns a newly allocated DataArrayInt instance having one component and the same number of tuples than \a this.
- * For each tuple at place **i** in \a this it tells which is the sub position of the first range in \a ranges that contains value \c this->getIJ(i,0) and put the result
- * in tuple **i** of returned DataArrayInt.
- * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
+ * This method can be applied on allocated with one component DataArrayInt instance.
+ * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted.
  *
- * For example if \a this contains : [1,24,7,8,10,17] and \a ranges contains [(0,3),(3,8),(8,15),(15,22),(22,30)]
- * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
- * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
- * 
- * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
- *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
- * \throw If offsets is a null pointer or does not have 2 components or if \a this is not allocated or \a this do not have exactly one component. To finish an exception
- *        is thrown if no ranges in \a ranges contains value in \a this.
- * \sa DataArrayInt::findRangeIdForEachTuple
+ * \return a newly allocated array that contain the result of the unique operation applied on \a this.
+ *
+ * \throw if \a this is not allocated or if \a this has not exactly one component.
+ *
+ * \sa DataArrayInt::buildUnique
  */
-DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
+DataArrayInt *DataArrayInt::buildUniqueNotSorted() const
 {
-  if(!ranges)
-    throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
-  if(ranges->getNumberOfComponents()!=2)
-    throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
   checkAllocated();
-  if(getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
-  int nbTuples=getNumberOfTuples();
-  MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
-  int nbOfRanges=ranges->getNumberOfTuples();
-  const int *rangesPtr=ranges->getConstPointer();
-  int *retPtr=ret->getPointer();
-  const int *inPtr=getConstPointer();
-  for(int i=0;i<nbTuples;i++,retPtr++)
+    if(getNumberOfComponents()!=1)
+      throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !");
+  int minVal,maxVal;
+  getMinMaxValues(minVal,maxVal);
+  std::vector<bool> b(maxVal-minVal+1,false);
+  const int *ptBg(begin()),*endBg(end());
+  MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
+  for(const int *pt=ptBg;pt!=endBg;pt++)
     {
-      int val=inPtr[i];
-      bool found=false;
-      for(int j=0;j<nbOfRanges && !found;j++)
-        if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
-          { *retPtr=val-rangesPtr[2*j]; found=true; }
-      if(found)
-        continue;
-      else
+      if(!b[*pt-minVal])
         {
-          std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
+          ret->pushBackSilent(*pt);
+          b[*pt-minVal]=true;
         }
     }
+  ret->copyStringInfoFrom(*this);
   return ret.retn();
 }
 
 /*!
- * \b WARNING this method is a \b non \a const \b method. This method works tuple by tuple. Each tuple is expected to be pairs (number of components must be equal to 2).
- * This method rearrange each pair in \a this so that, tuple with id \b tid will be after the call \c this->getIJ(tid,0)==this->getIJ(tid-1,1) and \c this->getIJ(tid,1)==this->getIJ(tid+1,0).
- * If it is impossible to reach such condition an exception will be thrown ! \b WARNING In case of throw \a this can be partially modified !
- * If this method has correctly worked, \a this will be able to be considered as a linked list.
- * This method does nothing if number of tuples is lower of equal to 1.
+ * Returns a new DataArrayInt which contains size of every of groups described by \a this
+ * "index" array. Such "index" array is returned for example by 
+ * \ref MEDCoupling::MEDCouplingUMesh::buildDescendingConnectivity
+ * "MEDCouplingUMesh::buildDescendingConnectivity" and
+ * \ref MEDCoupling::MEDCouplingUMesh::getNodalConnectivityIndex
+ * "MEDCouplingUMesh::getNodalConnectivityIndex" etc.
+ * This method preforms the reverse operation of DataArrayInt::computeOffsetsFull.
+ *  \return DataArrayInt * - a new instance of DataArrayInt, whose number of tuples
+ *          equals to \a this->getNumberOfComponents() - 1, and number of components is 1.
+ *          The caller is to delete this array using decrRef() as it is no more needed. 
+ *  \throw If \a this is not allocated.
+ *  \throw If \a this->getNumberOfComponents() != 1.
+ *  \throw If \a this->getNumberOfTuples() < 2.
  *
- * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
+ *  \b Example: <br> 
+ *         - this contains [1,3,6,7,7,9,15]
+ *         - result array contains [2,3,1,0,2,6],
+ *          where 2 = 3 - 1, 3 = 6 - 3, 1 = 7 - 6 etc.
  *
- * \sa MEDCouplingUMesh::orderConsecutiveCells1D
+ * \sa DataArrayInt::computeOffsetsFull
  */
-void DataArrayInt::sortEachPairToMakeALinkedList()
+DataArrayInt *DataArrayInt::deltaShiftIndex() const
 {
   checkAllocated();
-  if(getNumberOfComponents()!=2)
-    throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
-  int nbOfTuples(getNumberOfTuples());
-  if(nbOfTuples<=1)
-    return ;
-  int *conn(getPointer());
-  for(int i=1;i<nbOfTuples;i++,conn+=2)
-    {
-      if(i>1)
-        {
-          if(conn[2]==conn[3])
-            {
-              std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
-              throw INTERP_KERNEL::Exception(oss.str().c_str());
-            }
-          if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
-            std::swap(conn[2],conn[3]);
-          //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
-          if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
-            {
-              std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
-              throw INTERP_KERNEL::Exception(oss.str().c_str());
-            }
-        }
-      else
-        {
-          if(conn[0]==conn[1] || conn[2]==conn[3])
-            throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
-          int tmp[4];
-          std::set<int> s;
-          s.insert(conn,conn+4);
-          if(s.size()!=3)
-            throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
-          if(std::count(conn,conn+4,conn[0])==2)
-            {
-              tmp[0]=conn[1];
-              tmp[1]=conn[0];
-              tmp[2]=conn[0];
-              if(conn[2]==conn[0])
-                { tmp[3]=conn[3]; }
-              else
-                { tmp[3]=conn[2];}
-              std::copy(tmp,tmp+4,conn);
-            }
-          else
-            {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
-              if(conn[1]==conn[3])
-                std::swap(conn[2],conn[3]);
-            }
-        }
-    }
+  if(getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !");
+  int nbOfTuples=getNumberOfTuples();
+  if(nbOfTuples<2)
+    throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !");
+  const int *ptr=getConstPointer();
+  DataArrayInt *ret=DataArrayInt::New();
+  ret->alloc(nbOfTuples-1,1);
+  int *out=ret->getPointer();
+  std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>());
+  return ret;
 }
 
 /*!
- * 
- * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance.
- *             \a nbTimes  should be at least equal to 1.
- * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples.
- * \throw if \a this is not allocated or if \a this has not number of components set to one or if \a nbTimes is lower than 1.
+ * Modifies \a this one-dimensional array so that value of each element \a x
+ * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
+ * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number of tuples
+ * and components remains the same.<br>
+ * This method is useful for allToAllV in MPI with contiguous policy. This method
+ * differs from computeOffsetsFull() in that the number of tuples is \b not changed by
+ * this one.
+ *  \throw If \a this is not allocated.
+ *  \throw If \a this->getNumberOfComponents() != 1.
+ *
+ *  \b Example: <br>
+ *          - Before \a this contains [3,5,1,2,0,8]
+ *          - After \a this contains  [0,3,8,9,11,11]<br>
+ *          Note that the last element 19 = 11 + 8 is missing because size of \a this
+ *          array is retained and thus there is no space to store the last element.
  */
-DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
+void DataArrayInt::computeOffsets()
 {
   checkAllocated();
   if(getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !");
-  if(nbTimes<1)
-    throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !");
-  int nbTuples=getNumberOfTuples();
-  const int *inPtr=getConstPointer();
-  MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1);
-  int *retPtr=ret->getPointer();
-  for(int i=0;i<nbTuples;i++,inPtr++)
+    throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !");
+  int nbOfTuples=getNumberOfTuples();
+  if(nbOfTuples==0)
+    return ;
+  int *work=getPointer();
+  int tmp=work[0];
+  work[0]=0;
+  for(int i=1;i<nbOfTuples;i++)
     {
-      int val=*inPtr;
-      for(int j=0;j<nbTimes;j++,retPtr++)
-        *retPtr=val;
+      int tmp2=work[i];
+      work[i]=work[i-1]+tmp;
+      tmp=tmp2;
     }
-  ret->copyStringInfoFrom(*this);
-  return ret.retn();
-}
-
-/*!
- * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
- * But the number of components can be different from one.
- * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
- */
-DataArrayInt *DataArrayInt::getDifferentValues() const
-{
-  checkAllocated();
-  std::set<int> ret;
-  ret.insert(begin(),end());
-  MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
-  std::copy(ret.begin(),ret.end(),ret2->getPointer());
-  return ret2.retn();
+  declareAsNew();
 }
 
+
 /*!
- * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
- * them it tells which tuple id have this id.
- * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
- * This method returns two arrays having same size.
- * The instances of DataArrayInt in the returned vector have be specially allocated and computed by this method. Each of them should be dealt by the caller of this method.
- * Example : if this is equal to [1,0,1,2,0,2,2,-3,2] -> differentIds=[-3,0,1,2] and returned array will be equal to [[7],[1,4],[0,2],[3,5,6,8]]
+ * Modifies \a this one-dimensional array so that value of each element \a x
+ * of \a this array (\a a) is computed as \f$ x_i = \sum_{j=0}^{i-1} a[ j ] \f$.
+ * Or: for each i>0 new[i]=new[i-1]+old[i-1] for i==0 new[i]=0. Number
+ * components remains the same and number of tuples is inceamented by one.<br>
+ * This method is useful for allToAllV in MPI with contiguous policy. This method
+ * differs from computeOffsets() in that the number of tuples is changed by this one.
+ * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex.
+ *  \throw If \a this is not allocated.
+ *  \throw If \a this->getNumberOfComponents() != 1.
+ *
+ *  \b Example: <br>
+ *          - Before \a this contains [3,5,1,2,0,8]
+ *          - After \a this contains  [0,3,8,9,11,11,19]<br>
+ * \sa DataArrayInt::deltaShiftIndex
  */
-std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
+void DataArrayInt::computeOffsetsFull()
 {
   checkAllocated();
   if(getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
-  int id=0;
-  std::map<int,int> m,m2,m3;
-  for(const int *w=begin();w!=end();w++)
-    m[*w]++;
-  differentIds.resize(m.size());
-  std::vector<DataArrayInt *> ret(m.size());
-  std::vector<int *> retPtr(m.size());
-  for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
-    {
-      m2[(*it).first]=id;
-      ret[id]=DataArrayInt::New();
-      ret[id]->alloc((*it).second,1);
-      retPtr[id]=ret[id]->getPointer();
-      differentIds[id]=(*it).first;
-    }
-  id=0;
-  for(const int *w=begin();w!=end();w++,id++)
-    {
-      retPtr[m2[*w]][m3[*w]++]=id;
-    }
-  return ret;
+    throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsetsFull : only single component allowed !");
+  int nbOfTuples=getNumberOfTuples();
+  int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int));
+  const int *work=getConstPointer();
+  ret[0]=0;
+  for(int i=0;i<nbOfTuples;i++)
+    ret[i+1]=work[i]+ret[i];
+  useArray(ret,true,C_DEALLOC,nbOfTuples+1,1);
+  declareAsNew();
 }
 
 /*!
- * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
- * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
+ * Returns two new DataArrayInt instances whose contents is computed from that of \a this and \a listOfIds arrays as follows.
+ * \a this is expected to be an offset format ( as returned by DataArrayInt::computeOffsetsFull ) that is to say with one component
+ * and ** sorted strictly increasingly **. \a listOfIds is expected to be sorted ascendingly (not strictly needed for \a listOfIds).
+ * This methods searches in \a this, considered as a set of contiguous \c this->getNumberOfComponents() ranges, all ids in \a listOfIds
+ * filling completely one of the ranges in \a this.
  *
- * \param [in] nbOfSlices - number of slices expected.
- * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
- * 
- * \sa DataArray::GetSlice
- * \throw If \a this is not allocated or not with exactly one component.
- * \throw If an element in \a this if < 0.
+ * \param [in] listOfIds a list of ids that has to be sorted ascendingly.
+ * \param [out] rangeIdsFetched the range ids fetched
+ * \param [out] idsInInputListThatFetch contains the list of ids in \a listOfIds that are \b fully included in a range in \a this. So
+ *              \a idsInInputListThatFetch is a part of input \a listOfIds.
+ *
+ * \sa DataArrayInt::computeOffsetsFull
+ *
+ *  \b Example: <br>
+ *          - \a this : [0,3,7,9,15,18]
+ *          - \a listOfIds contains  [0,1,2,3,7,8,15,16,17]
+ *          - \a rangeIdsFetched result array: [0,2,4]
+ *          - \a idsInInputListThatFetch result array: [0,1,2,7,8,15,16,17]
+ * In this example id 3 in input \a listOfIds is alone so it do not appear in output \a idsInInputListThatFetch.
+ * <br>
  */
-std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
+void DataArrayInt::findIdsRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const
 {
-  if(!isAllocated() || getNumberOfComponents()!=1)
-    throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
-  if(nbOfSlices<=0)
-    throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
-  int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
-  int sumPerSlc(sum/nbOfSlices),pos(0);
-  const int *w(begin());
-  std::vector< std::pair<int,int> > ret(nbOfSlices);
-  for(int i=0;i<nbOfSlices;i++)
+  if(!listOfIds)
+    throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids is null !");
+  listOfIds->checkAllocated(); checkAllocated();
+  if(listOfIds->getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : input list of ids must have exactly one component !");
+  if(getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayInt::findIdsRangesInListOfIds : this must have exactly one component !");
+  MCAuto<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1);
+  MCAuto<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(0,1);
+  const int *tupEnd(listOfIds->end()),*offBg(begin()),*offEnd(end()-1);
+  const int *tupPtr(listOfIds->begin()),*offPtr(offBg);
+  while(tupPtr!=tupEnd && offPtr!=offEnd)
     {
-      std::pair<int,int> p(pos,-1);
-      int locSum(0);
-      while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
-      if(i!=nbOfSlices-1)
-        p.second=pos;
+      if(*tupPtr==*offPtr)
+        {
+          int i=offPtr[0];
+          while(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; }
+          if(i==offPtr[1])
+            {
+              ret0->pushBackSilent((int)std::distance(offBg,offPtr));
+              ret1->pushBackValsSilent(tupPtr-(offPtr[1]-offPtr[0]),tupPtr);
+              offPtr++;
+            }
+        }
       else
-        p.second=nbOfTuples;
-      ret[i]=p;
+        { if(*tupPtr<*offPtr) tupPtr++; else offPtr++; }
     }
-  return ret;
+  rangeIdsFetched=ret0.retn();
+  idsInInputListThatFetch=ret1.retn();
 }
 
 /*!
- * Returns a new DataArrayInt that is a sum of two given arrays. There are 3
- * valid cases.
- * 1.  The arrays have same number of tuples and components. Then each value of
- *   the result array (_a_) is a sum of the corresponding values of \a a1 and \a a2,
- *   i.e.: _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, j ].
- * 2.  The arrays have same number of tuples and one array, say _a2_, has one
- *   component. Then
- *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ i, 0 ].
- * 3.  The arrays have same number of components and one array, say _a2_, has one
- *   tuple. Then
- *   _a_ [ i, j ] = _a1_ [ i, j ] + _a2_ [ 0, j ].
+ * Returns a new DataArrayInt whose contents is computed from that of \a this and \a
+ * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
+ * "index" array of a "iota" array, thus, whose each element gives an index of a group
+ * beginning within the "iota" array. And \a this is a one-dimensional array
+ * considered as a selector of groups described by \a offsets to include into the result array.
+ *  \throw If \a offsets is NULL.
+ *  \throw If \a offsets is not allocated.
+ *  \throw If \a offsets->getNumberOfComponents() != 1.
+ *  \throw If \a offsets is not monotonically increasing.
+ *  \throw If \a this is not allocated.
+ *  \throw If \a this->getNumberOfComponents() != 1.
+ *  \throw If any element of \a this is not a valid index for \a offsets array.
  *
- * Info on components is copied either from the first array (in the first case) or from
- * the array with maximal number of elements (getNbOfElems()).
- *  \param [in] a1 - an array to sum up.
- *  \param [in] a2 - another array to sum up.
- *  \return DataArrayInt * - the new instance of DataArrayInt.
- *          The caller is to delete this result array using decrRef() as it is no more
- *          needed.
- *  \throw If either \a a1 or \a a2 is NULL.
- *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
- *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
- *         none of them has number of tuples or components equal to 1.
+ *  \b Example: <br>
+ *          - \a this: [0,2,3]
+ *          - \a offsets: [0,3,6,10,14,20]
+ *          - result array: [0,1,2,6,7,8,9,10,11,12,13] == <br>
+ *            \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br>
+ *            \c range( \a offsets[ \a this[0] ], offsets[ \a this[0]+1 ]) + 
+ *            \c range( \a offsets[ \a this[1] ], offsets[ \a this[1]+1 ]) + 
+ *            \c range( \a offsets[ \a this[2] ], offsets[ \a this[2]+1 ])
  */
-DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
+DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets) const
 {
-  if(!a1 || !a2)
-    throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !");
-  int nbOfTuple=a1->getNumberOfTuples();
-  int nbOfTuple2=a2->getNumberOfTuples();
-  int nbOfComp=a1->getNumberOfComponents();
-  int nbOfComp2=a2->getNumberOfComponents();
-  MCAuto<DataArrayInt> ret=0;
-  if(nbOfTuple==nbOfTuple2)
+  if(!offsets)
+    throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !");
+  checkAllocated();
+  if(getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !");
+  offsets->checkAllocated();
+  if(offsets->getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !");
+  int othNbTuples=offsets->getNumberOfTuples()-1;
+  int nbOfTuples=getNumberOfTuples();
+  int retNbOftuples=0;
+  const int *work=getConstPointer();
+  const int *offPtr=offsets->getConstPointer();
+  for(int i=0;i<nbOfTuples;i++)
     {
-      if(nbOfComp==nbOfComp2)
-        {
-          ret=DataArrayInt::New();
-          ret->alloc(nbOfTuple,nbOfComp);
-          std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>());
-          ret->copyStringInfoFrom(*a1);
-        }
-      else
+      int val=work[i];
+      if(val>=0 && val<othNbTuples)
         {
-          int nbOfCompMin,nbOfCompMax;
-          const DataArrayInt *aMin, *aMax;
-          if(nbOfComp>nbOfComp2)
-            {
-              nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
-              aMin=a2; aMax=a1;
-            }
+          int delta=offPtr[val+1]-offPtr[val];
+          if(delta>=0)
+            retNbOftuples+=delta;
           else
             {
-              nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
-              aMin=a1; aMax=a2;
-            }
-          if(nbOfCompMin==1)
-            {
-              ret=DataArrayInt::New();
-              ret->alloc(nbOfTuple,nbOfCompMax);
-              const int *aMinPtr=aMin->getConstPointer();
-              const int *aMaxPtr=aMax->getConstPointer();
-              int *res=ret->getPointer();
-              for(int i=0;i<nbOfTuple;i++)
-                res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i]));
-              ret->copyStringInfoFrom(*aMax);
+              std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !";
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
             }
-          else
-            throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
         }
-    }
-  else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
-    {
-      if(nbOfComp==nbOfComp2)
+      else
         {
-          int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
-          const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
-          const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
-          const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
-          ret=DataArrayInt::New();
-          ret->alloc(nbOfTupleMax,nbOfComp);
-          int *res=ret->getPointer();
-          for(int i=0;i<nbOfTupleMax;i++)
-            res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>());
-          ret->copyStringInfoFrom(*aMax);
+          std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val;
+          oss << " whereas offsets array is of size " << othNbTuples+1 << " !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
-      else
-        throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !");
     }
-  else
-    throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
+  MCAuto<DataArrayInt> ret=DataArrayInt::New();
+  ret->alloc(retNbOftuples,1);
+  int *retPtr=ret->getPointer();
+  for(int i=0;i<nbOfTuples;i++)
+    {
+      int val=work[i];
+      int start=offPtr[val];
+      int off=offPtr[val+1]-start;
+      for(int j=0;j<off;j++,retPtr++)
+        *retPtr=start+j;
+    }
   return ret.retn();
 }
 
 /*!
- * Adds values of another DataArrayInt to values of \a this one. There are 3
- * valid cases.
- * 1.  The arrays have same number of tuples and components. Then each value of
- *   \a other array is added to the corresponding value of \a this array, i.e.:
- *   _a_ [ i, j ] += _other_ [ i, j ].
- * 2.  The arrays have same number of tuples and \a other array has one component. Then
- *   _a_ [ i, j ] += _other_ [ i, 0 ].
- * 3.  The arrays have same number of components and \a other array has one tuple. Then
- *   _a_ [ i, j ] += _a2_ [ 0, j ].
+ * Returns a new DataArrayInt whose contents is computed using \a this that must be a 
+ * scaled array (monotonically increasing).
+from that of \a this and \a
+ * offsets arrays as follows. \a offsets is a one-dimensional array considered as an
+ * "index" array of a "iota" array, thus, whose each element gives an index of a group
+ * beginning within the "iota" array. And \a this is a one-dimensional array
+ * considered as a selector of groups described by \a offsets to include into the result array.
+ *  \throw If \a  is NULL.
+ *  \throw If \a this is not allocated.
+ *  \throw If \a this->getNumberOfComponents() != 1.
+ *  \throw If \a this->getNumberOfTuples() == 0.
+ *  \throw If \a this is not monotonically increasing.
+ *  \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this.
  *
- *  \param [in] other - an array to add to \a this one.
- *  \throw If \a other is NULL.
- *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
- *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
- *         \a other has number of both tuples and components not equal to 1.
+ *  \b Example: <br>
+ *          - \a bg , \a stop and \a step : (0,5,2)
+ *          - \a this: [0,3,6,10,14,20]
+ *          - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br>
  */
-void DataArrayInt::addEqual(const DataArrayInt *other)
-{
-  if(!other)
-    throw INTERP_KERNEL::Exception("DataArrayInt::addEqual : input DataArrayInt instance is NULL !");
-  const char *msg="Nb of tuples mismatch for DataArrayInt::addEqual  !";
-  checkAllocated(); other->checkAllocated();
-  int nbOfTuple=getNumberOfTuples();
-  int nbOfTuple2=other->getNumberOfTuples();
-  int nbOfComp=getNumberOfComponents();
-  int nbOfComp2=other->getNumberOfComponents();
-  if(nbOfTuple==nbOfTuple2)
+DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const
+{
+  if(!isAllocated())
+    throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !");
+  if(getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !");
+  int nbOfTuples(getNumberOfTuples());
+  if(nbOfTuples==0)
+    throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !");
+  const int *ids(begin());
+  int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg);
+  for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
     {
-      if(nbOfComp==nbOfComp2)
+      if(pos>=0 && pos<nbOfTuples-1)
         {
-          std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>());
+          int delta(ids[pos+1]-ids[pos]);
+          sz+=delta;
+          if(delta<0)
+            {
+              std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !";
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }          
         }
-      else if(nbOfComp2==1)
+      else
         {
-          int *ptr=getPointer();
-          const int *ptrc=other->getConstPointer();
-          for(int i=0;i<nbOfTuple;i++)
-            std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++));
+          std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !";  
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
-      else
-        throw INTERP_KERNEL::Exception(msg);
     }
-  else if(nbOfTuple2==1)
+  MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1);
+  int *retPtr(ret->getPointer());
+  pos=bg;
+  for(int i=0;i<nbOfEltsInSlc;i++,pos+=step)
     {
-      if(nbOfComp2==nbOfComp)
-        {
-          int *ptr=getPointer();
-          const int *ptrc=other->getConstPointer();
-          for(int i=0;i<nbOfTuple;i++)
-            std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>());
-        }
-      else
-        throw INTERP_KERNEL::Exception(msg);
+      int delta(ids[pos+1]-ids[pos]);
+      for(int j=0;j<delta;j++,retPtr++)
+        *retPtr=pos;
     }
-  else
-    throw INTERP_KERNEL::Exception(msg);
-  declareAsNew();
+  return ret.retn();
 }
 
 /*!
- * Returns a new DataArrayInt that is a subtraction of two given arrays. There are 3
- * valid cases.
- * 1.  The arrays have same number of tuples and components. Then each value of
- *   the result array (_a_) is a subtraction of the corresponding values of \a a1 and
- *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, j ].
- * 2.  The arrays have same number of tuples and one array, say _a2_, has one
- *   component. Then
- *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ i, 0 ].
- * 3.  The arrays have same number of components and one array, say _a2_, has one
- *   tuple. Then
- *   _a_ [ i, j ] = _a1_ [ i, j ] - _a2_ [ 0, j ].
+ * Given in input ranges \a ranges, it returns a newly allocated DataArrayInt instance having one component and the same number of tuples than \a this.
+ * For each tuple at place **i** in \a this it tells which is the first range in \a ranges that contains value \c this->getIJ(i,0) and put the result
+ * in tuple **i** of returned DataArrayInt.
+ * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range.
  *
- * Info on components is copied either from the first array (in the first case) or from
- * the array with maximal number of elements (getNbOfElems()).
- *  \param [in] a1 - an array to subtract from.
- *  \param [in] a2 - an array to subtract.
- *  \return DataArrayInt * - the new instance of DataArrayInt.
- *          The caller is to delete this result array using decrRef() as it is no more
- *          needed.
- *  \throw If either \a a1 or \a a2 is NULL.
- *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
- *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
- *         none of them has number of tuples or components equal to 1.
+ * For example if \a this contains : [1,24,7,8,10,17] and \a ranges contains [(0,3),(3,8),(8,15),(15,22),(22,30)]
+ * The return DataArrayInt will contain : **[0,4,1,2,2,3]**
+ * 
+ * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
+ *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
+ * \throw If offsets is a null pointer or does not have 2 components or if \a this is not allocated or \a this do not have exactly one component. To finish an exception
+ *        is thrown if no ranges in \a ranges contains value in \a this.
+ * 
+ * \sa DataArrayInt::findIdInRangeForEachTuple
  */
-DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt *a2)
+DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const
 {
-  if(!a1 || !a2)
-    throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !");
-  int nbOfTuple1=a1->getNumberOfTuples();
-  int nbOfTuple2=a2->getNumberOfTuples();
-  int nbOfComp1=a1->getNumberOfComponents();
-  int nbOfComp2=a2->getNumberOfComponents();
-  if(nbOfTuple2==nbOfTuple1)
+  if(!ranges)
+    throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !");
+  if(ranges->getNumberOfComponents()!=2)
+    throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !");
+  checkAllocated();
+  if(getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !");
+  int nbTuples=getNumberOfTuples();
+  MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
+  int nbOfRanges=ranges->getNumberOfTuples();
+  const int *rangesPtr=ranges->getConstPointer();
+  int *retPtr=ret->getPointer();
+  const int *inPtr=getConstPointer();
+  for(int i=0;i<nbTuples;i++,retPtr++)
     {
-      if(nbOfComp1==nbOfComp2)
-        {
-          MCAuto<DataArrayInt> ret=DataArrayInt::New();
-          ret->alloc(nbOfTuple2,nbOfComp1);
-          std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
-          ret->copyStringInfoFrom(*a1);
-          return ret.retn();
-        }
-      else if(nbOfComp2==1)
-        {
-          MCAuto<DataArrayInt> ret=DataArrayInt::New();
-          ret->alloc(nbOfTuple1,nbOfComp1);
-          const int *a2Ptr=a2->getConstPointer();
-          const int *a1Ptr=a1->getConstPointer();
-          int *res=ret->getPointer();
-          for(int i=0;i<nbOfTuple1;i++)
-            res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i]));
-          ret->copyStringInfoFrom(*a1);
-          return ret.retn();
-        }
+      int val=inPtr[i];
+      bool found=false;
+      for(int j=0;j<nbOfRanges && !found;j++)
+        if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
+          { *retPtr=j; found=true; }
+      if(found)
+        continue;
       else
         {
-          a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
-          return 0;
+          std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
     }
-  else if(nbOfTuple2==1)
-    {
-      a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !");
-      MCAuto<DataArrayInt> ret=DataArrayInt::New();
-      ret->alloc(nbOfTuple1,nbOfComp1);
-      const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
-      int *pt=ret->getPointer();
-      for(int i=0;i<nbOfTuple1;i++)
-        pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>());
-      ret->copyStringInfoFrom(*a1);
-      return ret.retn();
-    }
-  else
-    {
-      a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception
-      return 0;
-    }
+  return ret.retn();
 }
 
 /*!
- * Subtract values of another DataArrayInt from values of \a this one. There are 3
- * valid cases.
- * 1.  The arrays have same number of tuples and components. Then each value of
- *   \a other array is subtracted from the corresponding value of \a this array, i.e.:
- *   _a_ [ i, j ] -= _other_ [ i, j ].
- * 2.  The arrays have same number of tuples and \a other array has one component. Then
- *   _a_ [ i, j ] -= _other_ [ i, 0 ].
- * 3.  The arrays have same number of components and \a other array has one tuple. Then
- *   _a_ [ i, j ] -= _a2_ [ 0, j ].
+ * Given in input ranges \a ranges, it returns a newly allocated DataArrayInt instance having one component and the same number of tuples than \a this.
+ * For each tuple at place **i** in \a this it tells which is the sub position of the first range in \a ranges that contains value \c this->getIJ(i,0) and put the result
+ * in tuple **i** of returned DataArrayInt.
+ * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range.
  *
- *  \param [in] other - an array to subtract from \a this one.
- *  \throw If \a other is NULL.
- *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
- *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
- *         \a other has number of both tuples and components not equal to 1.
+ * For example if \a this contains : [1,24,7,8,10,17] and \a ranges contains [(0,3),(3,8),(8,15),(15,22),(22,30)]
+ * The return DataArrayInt will contain : **[1,2,4,0,2,2]**
+ * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method.
+ * 
+ * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is
+ *             for lower value included and 2nd component is the upper value of corresponding range **excluded**.
+ * \throw If offsets is a null pointer or does not have 2 components or if \a this is not allocated or \a this do not have exactly one component. To finish an exception
+ *        is thrown if no ranges in \a ranges contains value in \a this.
+ * \sa DataArrayInt::findRangeIdForEachTuple
  */
-void DataArrayInt::substractEqual(const DataArrayInt *other)
+DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const
 {
-  if(!other)
-    throw INTERP_KERNEL::Exception("DataArrayInt::substractEqual : input DataArrayInt instance is NULL !");
-  const char *msg="Nb of tuples mismatch for DataArrayInt::substractEqual  !";
-  checkAllocated(); other->checkAllocated();
-  int nbOfTuple=getNumberOfTuples();
-  int nbOfTuple2=other->getNumberOfTuples();
-  int nbOfComp=getNumberOfComponents();
-  int nbOfComp2=other->getNumberOfComponents();
-  if(nbOfTuple==nbOfTuple2)
+  if(!ranges)
+    throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !");
+  if(ranges->getNumberOfComponents()!=2)
+    throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !");
+  checkAllocated();
+  if(getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !");
+  int nbTuples=getNumberOfTuples();
+  MCAuto<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1);
+  int nbOfRanges=ranges->getNumberOfTuples();
+  const int *rangesPtr=ranges->getConstPointer();
+  int *retPtr=ret->getPointer();
+  const int *inPtr=getConstPointer();
+  for(int i=0;i<nbTuples;i++,retPtr++)
     {
-      if(nbOfComp==nbOfComp2)
-        {
-          std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>());
-        }
-      else if(nbOfComp2==1)
+      int val=inPtr[i];
+      bool found=false;
+      for(int j=0;j<nbOfRanges && !found;j++)
+        if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1])
+          { *retPtr=val-rangesPtr[2*j]; found=true; }
+      if(found)
+        continue;
+      else
         {
-          int *ptr=getPointer();
-          const int *ptrc=other->getConstPointer();
-          for(int i=0;i<nbOfTuple;i++)
-            std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++));
+          std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
+          throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
-      else
-        throw INTERP_KERNEL::Exception(msg);
-    }
-  else if(nbOfTuple2==1)
-    {
-      int *ptr=getPointer();
-      const int *ptrc=other->getConstPointer();
-      for(int i=0;i<nbOfTuple;i++)
-        std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>());
     }
-  else
-    throw INTERP_KERNEL::Exception(msg);
-  declareAsNew();
+  return ret.retn();
 }
 
 /*!
- * Returns a new DataArrayInt that is a product of two given arrays. There are 3
- * valid cases.
- * 1.  The arrays have same number of tuples and components. Then each value of
- *   the result array (_a_) is a product of the corresponding values of \a a1 and
- *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, j ].
- * 2.  The arrays have same number of tuples and one array, say _a2_, has one
- *   component. Then
- *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ i, 0 ].
- * 3.  The arrays have same number of components and one array, say _a2_, has one
- *   tuple. Then
- *   _a_ [ i, j ] = _a1_ [ i, j ] * _a2_ [ 0, j ].
+ * \b WARNING this method is a \b non \a const \b method. This method works tuple by tuple. Each tuple is expected to be pairs (number of components must be equal to 2).
+ * This method rearrange each pair in \a this so that, tuple with id \b tid will be after the call \c this->getIJ(tid,0)==this->getIJ(tid-1,1) and \c this->getIJ(tid,1)==this->getIJ(tid+1,0).
+ * If it is impossible to reach such condition an exception will be thrown ! \b WARNING In case of throw \a this can be partially modified !
+ * If this method has correctly worked, \a this will be able to be considered as a linked list.
+ * This method does nothing if number of tuples is lower of equal to 1.
  *
- * Info on components is copied either from the first array (in the first case) or from
- * the array with maximal number of elements (getNbOfElems()).
- *  \param [in] a1 - a factor array.
- *  \param [in] a2 - another factor array.
- *  \return DataArrayInt * - the new instance of DataArrayInt.
- *          The caller is to delete this result array using decrRef() as it is no more
- *          needed.
- *  \throw If either \a a1 or \a a2 is NULL.
- *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
- *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
- *         none of them has number of tuples or components equal to 1.
+ * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration.
+ *
+ * \sa MEDCouplingUMesh::orderConsecutiveCells1D, DataArrayInt::fromLinkedListOfPairToList
  */
-DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt *a2)
+void DataArrayInt::sortEachPairToMakeALinkedList()
 {
-  if(!a1 || !a2)
-    throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !");
-  int nbOfTuple=a1->getNumberOfTuples();
-  int nbOfTuple2=a2->getNumberOfTuples();
-  int nbOfComp=a1->getNumberOfComponents();
-  int nbOfComp2=a2->getNumberOfComponents();
-  MCAuto<DataArrayInt> ret=0;
-  if(nbOfTuple==nbOfTuple2)
+  checkAllocated();
+  if(getNumberOfComponents()!=2)
+    throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !");
+  int nbOfTuples(getNumberOfTuples());
+  if(nbOfTuples<=1)
+    return ;
+  int *conn(getPointer());
+  for(int i=1;i<nbOfTuples;i++,conn+=2)
     {
-      if(nbOfComp==nbOfComp2)
+      if(i>1)
         {
-          ret=DataArrayInt::New();
-          ret->alloc(nbOfTuple,nbOfComp);
-          std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>());
-          ret->copyStringInfoFrom(*a1);
+          if(conn[2]==conn[3])
+            {
+              std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !";
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }
+          if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0])
+            std::swap(conn[2],conn[3]);
+          //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0])
+          if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0])
+            {
+              std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !";
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }
         }
       else
         {
-          int nbOfCompMin,nbOfCompMax;
-          const DataArrayInt *aMin, *aMax;
-          if(nbOfComp>nbOfComp2)
+          if(conn[0]==conn[1] || conn[2]==conn[3])
+            throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !");
+          int tmp[4];
+          std::set<int> s;
+          s.insert(conn,conn+4);
+          if(s.size()!=3)
+            throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !");
+          if(std::count(conn,conn+4,conn[0])==2)
             {
-              nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp;
-              aMin=a2; aMax=a1;
+              tmp[0]=conn[1];
+              tmp[1]=conn[0];
+              tmp[2]=conn[0];
+              if(conn[2]==conn[0])
+                { tmp[3]=conn[3]; }
+              else
+                { tmp[3]=conn[2];}
+              std::copy(tmp,tmp+4,conn);
             }
           else
-            {
-              nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2;
-              aMin=a1; aMax=a2;
-            }
-          if(nbOfCompMin==1)
-            {
-              ret=DataArrayInt::New();
-              ret->alloc(nbOfTuple,nbOfCompMax);
-              const int *aMinPtr=aMin->getConstPointer();
-              const int *aMaxPtr=aMax->getConstPointer();
-              int *res=ret->getPointer();
-              for(int i=0;i<nbOfTuple;i++)
-                res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i]));
-              ret->copyStringInfoFrom(*aMax);
+            {//here we are sure to have (std::count(conn,conn+4,conn[1])==2)
+              if(conn[1]==conn[3])
+                std::swap(conn[2],conn[3]);
             }
-          else
-            throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
         }
     }
-  else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1))
-    {
-      if(nbOfComp==nbOfComp2)
-        {
-          int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2);
-          const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1;
-          const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2;
-          const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer();
-          ret=DataArrayInt::New();
-          ret->alloc(nbOfTupleMax,nbOfComp);
-          int *res=ret->getPointer();
-          for(int i=0;i<nbOfTupleMax;i++)
-            res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>());
-          ret->copyStringInfoFrom(*aMax);
-        }
-      else
-        throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !");
-    }
-  else
-    throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
-  return ret.retn();
 }
 
-
 /*!
- * Multiply values of another DataArrayInt to values of \a this one. There are 3
- * valid cases.
- * 1.  The arrays have same number of tuples and components. Then each value of
- *   \a other array is multiplied to the corresponding value of \a this array, i.e.:
- *   _a_ [ i, j ] *= _other_ [ i, j ].
- * 2.  The arrays have same number of tuples and \a other array has one component. Then
- *   _a_ [ i, j ] *= _other_ [ i, 0 ].
- * 3.  The arrays have same number of components and \a other array has one tuple. Then
- *   _a_ [ i, j ] *= _a2_ [ 0, j ].
- *
- *  \param [in] other - an array to multiply to \a this one.
- *  \throw If \a other is NULL.
- *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
- *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
- *         \a other has number of both tuples and components not equal to 1.
+ * \a this is expected to be a correctly linked list of pairs.
+ * 
+ * \sa DataArrayInt::sortEachPairToMakeALinkedList
  */
-void DataArrayInt::multiplyEqual(const DataArrayInt *other)
+MCAuto<DataArrayInt> DataArrayInt::fromLinkedListOfPairToList() const
 {
-  if(!other)
-    throw INTERP_KERNEL::Exception("DataArrayInt::multiplyEqual : input DataArrayInt instance is NULL !");
-  const char *msg="Nb of tuples mismatch for DataArrayInt::multiplyEqual !";
-  checkAllocated(); other->checkAllocated();
-  int nbOfTuple=getNumberOfTuples();
-  int nbOfTuple2=other->getNumberOfTuples();
-  int nbOfComp=getNumberOfComponents();
-  int nbOfComp2=other->getNumberOfComponents();
-  if(nbOfTuple==nbOfTuple2)
-    {
-      if(nbOfComp==nbOfComp2)
-        {
-          std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>());
-        }
-      else if(nbOfComp2==1)
-        {
-          int *ptr=getPointer();
-          const int *ptrc=other->getConstPointer();
-          for(int i=0;i<nbOfTuple;i++)
-            std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++));    
-        }
-      else
-        throw INTERP_KERNEL::Exception(msg);
-    }
-  else if(nbOfTuple2==1)
+  checkAllocated();
+  checkNbOfComps(2,"DataArrayInt::fromLinkedListOfPairToList : this is expected to have 2 components");
+  int nbTuples(getNumberOfTuples());
+  if(nbTuples<1)
+    throw INTERP_KERNEL::Exception("DataArrayInt::fromLinkedListOfPairToList : no tuples in this ! Not a linked list !");
+  MCAuto<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbTuples+1,1);
+  const int *thisPtr(begin());
+  int *retPtr(ret->getPointer());
+  retPtr[0]=thisPtr[0];
+  for(int i=0;i<nbTuples;i++)
     {
-      if(nbOfComp2==nbOfComp)
-        {
-          int *ptr=getPointer();
-          const int *ptrc=other->getConstPointer();
-          for(int i=0;i<nbOfTuple;i++)
-            std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>());
-        }
-      else
-        throw INTERP_KERNEL::Exception(msg);
+      retPtr[i+1]=thisPtr[2*i+1];
+      if(i<nbTuples-1)
+        if(thisPtr[2*i+1]!=thisPtr[2*(i+1)+0])
+          {
+            std::ostringstream oss; oss << "DataArrayInt::fromLinkedListOfPairToList : this is not a proper linked list of pair. The link is broken between tuple #" << i << " and tuple #" << i+1 << " ! Call sortEachPairToMakeALinkedList ?";
+            throw INTERP_KERNEL::Exception(oss.str());
+          }
     }
-  else
-    throw INTERP_KERNEL::Exception(msg);
-  declareAsNew();
+  return ret;
 }
 
+/*!
+ * This method returns all different values found in \a this. This method throws if \a this has not been allocated.
+ * But the number of components can be different from one.
+ * \return a newly allocated array (that should be dealt by the caller) containing different values in \a this.
+ */
+DataArrayInt *DataArrayInt::getDifferentValues() const
+{
+  checkAllocated();
+  std::set<int> ret;
+  ret.insert(begin(),end());
+  MCAuto<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1);
+  std::copy(ret.begin(),ret.end(),ret2->getPointer());
+  return ret2.retn();
+}
 
 /*!
- * Returns a new DataArrayInt that is a division of two given arrays. There are 3
- * valid cases.
- * 1.  The arrays have same number of tuples and components. Then each value of
- *   the result array (_a_) is a division of the corresponding values of \a a1 and
- *   \a a2, i.e.: _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, j ].
- * 2.  The arrays have same number of tuples and one array, say _a2_, has one
- *   component. Then
- *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ i, 0 ].
- * 3.  The arrays have same number of components and one array, say _a2_, has one
- *   tuple. Then
- *   _a_ [ i, j ] = _a1_ [ i, j ] / _a2_ [ 0, j ].
- *
- * Info on components is copied either from the first array (in the first case) or from
- * the array with maximal number of elements (getNbOfElems()).
- *  \warning No check of division by zero is performed!
- *  \param [in] a1 - a numerator array.
- *  \param [in] a2 - a denominator array.
- *  \return DataArrayInt * - the new instance of DataArrayInt.
- *          The caller is to delete this result array using decrRef() as it is no more
- *          needed.
- *  \throw If either \a a1 or \a a2 is NULL.
- *  \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() and
- *         \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() and
- *         none of them has number of tuples or components equal to 1.
+ * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of
+ * them it tells which tuple id have this id.
+ * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ).
+ * This method returns two arrays having same size.
+ * The instances of DataArrayInt in the returned vector have be specially allocated and computed by this method. Each of them should be dealt by the caller of this method.
+ * Example : if this is equal to [1,0,1,2,0,2,2,-3,2] -> differentIds=[-3,0,1,2] and returned array will be equal to [[7],[1,4],[0,2],[3,5,6,8]]
  */
-DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a2)
+std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
 {
-  if(!a1 || !a2)
-    throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !");
-  int nbOfTuple1=a1->getNumberOfTuples();
-  int nbOfTuple2=a2->getNumberOfTuples();
-  int nbOfComp1=a1->getNumberOfComponents();
-  int nbOfComp2=a2->getNumberOfComponents();
-  if(nbOfTuple2==nbOfTuple1)
-    {
-      if(nbOfComp1==nbOfComp2)
-        {
-          MCAuto<DataArrayInt> ret=DataArrayInt::New();
-          ret->alloc(nbOfTuple2,nbOfComp1);
-          std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
-          ret->copyStringInfoFrom(*a1);
-          return ret.retn();
-        }
-      else if(nbOfComp2==1)
-        {
-          MCAuto<DataArrayInt> ret=DataArrayInt::New();
-          ret->alloc(nbOfTuple1,nbOfComp1);
-          const int *a2Ptr=a2->getConstPointer();
-          const int *a1Ptr=a1->getConstPointer();
-          int *res=ret->getPointer();
-          for(int i=0;i<nbOfTuple1;i++)
-            res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i]));
-          ret->copyStringInfoFrom(*a1);
-          return ret.retn();
-        }
-      else
-        {
-          a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
-          return 0;
-        }
-    }
-  else if(nbOfTuple2==1)
+  checkAllocated();
+  if(getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !");
+  int id=0;
+  std::map<int,int> m,m2,m3;
+  for(const int *w=begin();w!=end();w++)
+    m[*w]++;
+  differentIds.resize(m.size());
+  std::vector<DataArrayInt *> ret(m.size());
+  std::vector<int *> retPtr(m.size());
+  for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++)
     {
-      a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !");
-      MCAuto<DataArrayInt> ret=DataArrayInt::New();
-      ret->alloc(nbOfTuple1,nbOfComp1);
-      const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer();
-      int *pt=ret->getPointer();
-      for(int i=0;i<nbOfTuple1;i++)
-        pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>());
-      ret->copyStringInfoFrom(*a1);
-      return ret.retn();
+      m2[(*it).first]=id;
+      ret[id]=DataArrayInt::New();
+      ret[id]->alloc((*it).second,1);
+      retPtr[id]=ret[id]->getPointer();
+      differentIds[id]=(*it).first;
     }
-  else
+  id=0;
+  for(const int *w=begin();w!=end();w++,id++)
     {
-      a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception
-      return 0;
+      retPtr[m2[*w]][m3[*w]++]=id;
     }
+  return ret;
 }
 
 /*!
- * Divide values of \a this array by values of another DataArrayInt. There are 3
- * valid cases.
- * 1.  The arrays have same number of tuples and components. Then each value of
- *    \a this array is divided by the corresponding value of \a other one, i.e.:
- *   _a_ [ i, j ] /= _other_ [ i, j ].
- * 2.  The arrays have same number of tuples and \a other array has one component. Then
- *   _a_ [ i, j ] /= _other_ [ i, 0 ].
- * 3.  The arrays have same number of components and \a other array has one tuple. Then
- *   _a_ [ i, j ] /= _a2_ [ 0, j ].
+ * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each).
+ * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible.
  *
- *  \warning No check of division by zero is performed!
- *  \param [in] other - an array to divide \a this one by.
- *  \throw If \a other is NULL.
- *  \throw If \a this->getNumberOfTuples() != \a other->getNumberOfTuples() and
- *         \a this->getNumberOfComponents() != \a other->getNumberOfComponents() and
- *         \a other has number of both tuples and components not equal to 1.
+ * \param [in] nbOfSlices - number of slices expected.
+ * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks.
+ * 
+ * \sa DataArray::GetSlice
+ * \throw If \a this is not allocated or not with exactly one component.
+ * \throw If an element in \a this if < 0.
  */
-void DataArrayInt::divideEqual(const DataArrayInt *other)
+std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const
 {
-  if(!other)
-    throw INTERP_KERNEL::Exception("DataArrayInt::divideEqual : input DataArrayInt instance is NULL !");
-  const char *msg="Nb of tuples mismatch for DataArrayInt::divideEqual !";
-  checkAllocated(); other->checkAllocated();
-  int nbOfTuple=getNumberOfTuples();
-  int nbOfTuple2=other->getNumberOfTuples();
-  int nbOfComp=getNumberOfComponents();
-  int nbOfComp2=other->getNumberOfComponents();
-  if(nbOfTuple==nbOfTuple2)
-    {
-      if(nbOfComp==nbOfComp2)
-        {
-          std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>());
-        }
-      else if(nbOfComp2==1)
-        {
-          int *ptr=getPointer();
-          const int *ptrc=other->getConstPointer();
-          for(int i=0;i<nbOfTuple;i++)
-            std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++));
-        }
-      else
-        throw INTERP_KERNEL::Exception(msg);
-    }
-  else if(nbOfTuple2==1)
+  if(!isAllocated() || getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !");
+  if(nbOfSlices<=0)
+    throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !");
+  int sum(accumulate(0)),nbOfTuples(getNumberOfTuples());
+  int sumPerSlc(sum/nbOfSlices),pos(0);
+  const int *w(begin());
+  std::vector< std::pair<int,int> > ret(nbOfSlices);
+  for(int i=0;i<nbOfSlices;i++)
     {
-      if(nbOfComp2==nbOfComp)
-        {
-          int *ptr=getPointer();
-          const int *ptrc=other->getConstPointer();
-          for(int i=0;i<nbOfTuple;i++)
-            std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>());
-        }
+      std::pair<int,int> p(pos,-1);
+      int locSum(0);
+      while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; }
+      if(i!=nbOfSlices-1)
+        p.second=pos;
       else
-        throw INTERP_KERNEL::Exception(msg);
+        p.second=nbOfTuples;
+      ret[i]=p;
     }
-  else
-    throw INTERP_KERNEL::Exception(msg);
-  declareAsNew();
+  return ret;
 }
 
-
 /*!
  * Returns a new DataArrayInt that is a modulus of two given arrays. There are 3
  * valid cases.
@@ -9071,40 +6836,11 @@ void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, cons
     }
 }
 
-DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):_da(da),_pt(0),_tuple_id(0),_nb_comp(0),_nb_tuple(0)
-{
-  if(_da)
-    {
-      _da->incrRef();
-      if(_da->isAllocated())
-        {
-          _nb_comp=da->getNumberOfComponents();
-          _nb_tuple=da->getNumberOfTuples();
-          _pt=da->getPointer();
-        }
-    }
-}
-
-DataArrayIntIterator::~DataArrayIntIterator()
-{
-  if(_da)
-    _da->decrRef();
-}
-
-DataArrayIntTuple *DataArrayIntIterator::nextt()
+DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *da):DataArrayIterator<int>(da)
 {
-  if(_tuple_id<_nb_tuple)
-    {
-      _tuple_id++;
-      DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp);
-      _pt+=_nb_comp;
-      return ret;
-    }
-  else
-    return 0;
 }
 
-DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp)
+DataArrayInt32Tuple::DataArrayInt32Tuple(int *pt, int nbOfComp):DataArrayTuple<int>(pt,nbOfComp)
 {
 }
 
@@ -9119,9 +6855,7 @@ std::string DataArrayIntTuple::repr() const
 
 int DataArrayIntTuple::intValue() const
 {
-  if(_nb_of_compo==1)
-    return *_pt;
-  throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !");
+  return this->zeValue();
 }
 
 /*!
@@ -9132,16 +6866,5 @@ int DataArrayIntTuple::intValue() const
  */
 DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const
 {
-  if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
-    {
-      DataArrayInt *ret=DataArrayInt::New();
-      ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
-      return ret;
-    }
-  else
-    {
-      std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt instance with nbofTuple=" << nbOfTuples << " and nbOfCompo=" << nbOfCompo;
-      oss << ".\nBecause the number of elements in this is " << _nb_of_compo << " !";
-      throw INTERP_KERNEL::Exception(oss.str().c_str());
-    }
+  return this->buildDA(nbOfTuples,nbOfCompo);
 }