Salome HOME
To be continued
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingMemArray.cxx
index bd33d07853440ce11f3a900f94c439327db27160..3d4bed67ab3a03fd0b6b99a268d6696e0fceeeee 100644 (file)
@@ -44,6 +44,7 @@ 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<int SPACEDIM>
 void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
@@ -1122,85 +1123,6 @@ bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other,
   return _mem.isEqual(other._mem,prec,tmp);
 }
 
-/*!
- * 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.
@@ -1292,34 +1214,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.
@@ -1531,27 +1425,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.
@@ -2730,86 +2603,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$.
@@ -2841,27 +2634,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
@@ -3444,85 +3216,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
@@ -3683,787 +3376,191 @@ 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 ].
- *
- * 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.
+ * 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.
  */
-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();
+  return false;
 }
 
 /*!
- * 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.
+ * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
  */
-void DataArrayDouble::multiplyEqual(const DataArrayDouble *other)
+void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
 {
-  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)
+  setName(tinyInfoS[0]);
+  if(isAllocated())
     {
-      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);
+      int nbOfCompo=getNumberOfComponents();
+      for(int i=0;i<nbOfCompo;i++)
+        setInfoOnComponent(i,tinyInfoS[i+1]);
     }
-  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.
+ * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
+ * around an axe ( \a center, \a vect) and with angle \a angle.
  */
-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;
-}
-
-/*!
- * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class.
- */
-void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS)
-{
-  setName(tinyInfoS[0]);
-  if(isAllocated())
-    {
-      int nbOfCompo=getNumberOfComponents();
-      for(int i=0;i<nbOfCompo;i++)
-        setInfoOnComponent(i,tinyInfoS[i+1]);
-    }
-}
-
-/*!
- * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in \a coordsIn
- * around an axe ( \a center, \a vect) and with angle \a angle.
- */
-void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
+void DataArrayDouble::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, const double *coordsIn, double *coordsOut)
 {
   if(!center || !vect)
     throw INTERP_KERNEL::Exception("DataArrayDouble::Rotate3DAlg : null vector in input !");
@@ -4585,9 +3682,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();
 }
 
 /*!
@@ -4598,18 +3693,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);
 }
 
 /*!
@@ -5603,57 +4687,6 @@ DataArrayInt *DataArrayInt::indicesOfSubPart(const DataArrayInt& partOfThis) con
   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.
- */
-DataArrayInt *DataArrayInt::toNoInterlace() 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());
-  return ret;
-}
-
 /*!
  * Returns a new DataArrayInt containing a renumbering map in "Old to New" mode.
  * This map, if applied to \a this array, would make it sorted. For example, if
@@ -5975,47 +5008,6 @@ bool DataArrayInt::hasUniqueValues() const
   return true;
 }
 
-/*!
- * 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.
@@ -6049,24 +5041,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);
@@ -6642,103 +5616,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$.
@@ -6806,41 +5683,6 @@ void DataArrayInt::applyModulus(int val)
   declareAsNew();
 }
 
-struct GreatEqual
-{
-  GreatEqual(int v):_v(v) { }
-  bool operator()(int v) const { return v>=_v; }
-  int _v;
-};
-
-struct GreaterThan
-{
-  GreaterThan(int v):_v(v) { }
-  bool operator()(int v) const { return v>_v; }
-  int _v;
-};
-
-struct LowerEqual
-{
-  LowerEqual(int v):_v(v) { }
-  bool operator()(int v) const { return v<=_v; }
-  int _v;
-};
-
-struct LowerThan
-{
-  LowerThan(int v):_v(v) { }
-  bool operator()(int v) const { return v<_v; }
-  int _v;
-};
-
-struct InRange
-{
-  InRange(int a, int b):_a(a),_b(b) { }
-  bool operator()(int v) const { return v>=_a && v<_b; }
-  int _a,_b;
-};
-
 /*!
  * This method works only on data array with one component.
  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
@@ -6854,18 +5696,11 @@ struct InRange
  */
 DataArrayInt *DataArrayInt::findIdsInRange(int vmin, int vmax) const
 {
-  InRange ir(vmin,vmax);
+  InRange<int> ir(vmin,vmax);
   MCAuto<DataArrayInt> ret(findIdsAdv(ir));
   return ret.retn();
 }
 
-struct NotInRange
-{
-  NotInRange(int a, int b):_a(a),_b(b) { }
-  bool operator()(int v) const { return v<_a || v>=_b; }
-  int _a,_b;
-};
-
 /*!
  * This method works only on data array with one component.
  * This method returns a newly allocated array storing stored ascendantly tuple ids in \b this so that
@@ -6879,48 +5714,11 @@ struct NotInRange
  */
 DataArrayInt *DataArrayInt::findIdsNotInRange(int vmin, int vmax) const
 {
-  NotInRange nir(vmin,vmax);
+  NotInRange<int> nir(vmin,vmax);
   MCAuto<DataArrayInt> ret(findIdsAdv(nir));
   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
-{
-  LowerThan lt(0);
-  MCAuto<DataArrayInt> ret(findIdsAdv(lt));
-  return ret.retn();
-}
-
-MCAuto<DataArrayInt> DataArrayInt::findIdsGreaterOrEqualTo(int val) const
-{
-  GreatEqual ge(val);
-  return findIdsAdv(ge);
-}
-
-MCAuto<DataArrayInt> DataArrayInt::findIdsGreaterThan(int val) const
-{
-  GreaterThan gt(val);
-  return findIdsAdv(gt);
-}
-
-MCAuto<DataArrayInt> DataArrayInt::findIdsLowerOrEqualTo(int val) const
-{
-  LowerEqual le(val);
-  return findIdsAdv(le);
-}
-
-MCAuto<DataArrayInt> DataArrayInt::findIdsLowerThan(int val) const
-{
-  LowerThan lt(val);
-  return findIdsAdv(lt);
-}
-
 /*!
  * This method works only on data array with one component.
  * This method checks that all ids in \b this are in [ \b vmin, \b vmax ). If there is at least one element in \a this not in [ \b vmin, \b vmax ) an exception will be thrown.
@@ -7043,85 +5841,6 @@ void DataArrayInt::applyRPow(int val)
   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();
-    }
-  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;
-}
-
 /*!
  * Returns a new DataArrayInt which is a minimal partition of elements of \a groups.
  * The i-th item of the result array is an ID of a set of elements belonging to a
@@ -7804,942 +6523,324 @@ from that of \a this and \a
 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();
-}
-
-/*!
- * 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.
- * 
- * \sa DataArrayInt::findIdInRangeForEachTuple
- */
-DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) 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());
-        }
-    }
-  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.
- *
- * 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
- */
-DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) 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++)
-    {
-      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
-        {
-          std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !";
-          throw INTERP_KERNEL::Exception(oss.str().c_str());
-        }
-    }
-  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.
- *
- * 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
- */
-void DataArrayInt::sortEachPairToMakeALinkedList()
-{
-  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]);
-            }
-        }
-    }
-}
-
-/*!
- * \a this is expected to be a correctly linked list of pairs.
- * 
- * \sa DataArrayInt::sortEachPairToMakeALinkedList
- */
-MCAuto<DataArrayInt> DataArrayInt::fromLinkedListOfPairToList() const
-{
-  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++)
-    {
-      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());
-          }
-    }
-  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.
- */
-DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const
-{
-  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++)
-    {
-      int val=*inPtr;
-      for(int j=0;j<nbTimes;j++,retPtr++)
-        *retPtr=val;
-    }
-  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();
-}
-
-/*!
- * 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]]
- */
-std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const
-{
-  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;
-}
-
-/*!
- * 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.
- *
- * \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.
- */
-std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) 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++)
-    {
-      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
-        p.second=nbOfTuples;
-      ret[i]=p;
-    }
-  return ret;
-}
-
-/*!
- * 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 ].
- *
- * 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.
- */
-DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
-{
-  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(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 nbOfCompMin,nbOfCompMax;
-          const DataArrayInt *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=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);
-            }
-          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 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);
-        }
-      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 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 ].
- *
- *  \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.
- */
-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)
+    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.
@@ -9129,9 +7230,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();
 }
 
 /*!
@@ -9142,16 +7241,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);
 }