Salome HOME
Merge from V6_main 28/02/2013
[tools/medcoupling.git] / src / MEDCoupling / MEDCouplingMemArray.cxx
index 2dabb36d33c8ccfc693bb8dcbd4077f5b963b23c..a49ba2d8dab2714955859ef235235de5dcb17fcc 100644 (file)
@@ -16,6 +16,7 @@
 //
 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+// Author : Anthony Geay (CEA/DEN)
 
 #include "MEDCouplingMemArray.txx"
 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
@@ -27,6 +28,7 @@
 #include <cmath>
 #include <limits>
 #include <numeric>
+#include <algorithm>
 #include <functional>
 
 typedef double (*MYFUNCPTR)(double);
@@ -34,7 +36,7 @@ typedef double (*MYFUNCPTR)(double);
 using namespace ParaMEDMEM;
 
 template<int SPACEDIM>
-void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, std::vector<int>& c, std::vector<int>& cI) const
+void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const
 {
   const double *coordsPtr=getConstPointer();
   BBTree<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec/10);
@@ -57,9 +59,9 @@ void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int l
                     }
               if(!commonNodes.empty())
                 {
-                  cI.push_back(cI.back()+(int)commonNodes.size()+1);
-                  c.push_back(i);
-                  c.insert(c.end(),commonNodes.begin(),commonNodes.end());
+                  cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1);
+                  c->pushBackSilent(i);
+                  c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
                 }
             }
         }
@@ -67,10 +69,9 @@ void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int l
 }
 
 template<int SPACEDIM>
-void DataArrayDouble::findTupleIdsNearTuplesAlg(const BBTree<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
-                                                std::vector<int>& c, std::vector<int>& cI) const
+void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTree<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps,
+                                                DataArrayInt *c, DataArrayInt *cI)
 {
-  const double *coordsPtr=getConstPointer();
   for(int i=0;i<nbOfTuples;i++)
     {
       std::vector<int> intersectingElems;
@@ -78,11 +79,21 @@ void DataArrayDouble::findTupleIdsNearTuplesAlg(const BBTree<SPACEDIM,int>& myTr
       std::vector<int> commonNodes;
       for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++)
         commonNodes.push_back(*it);
-      cI.push_back(cI.back()+(int)commonNodes.size());
-      c.insert(c.end(),commonNodes.begin(),commonNodes.end());
+      cI->pushBackSilent(cI->back()+(int)commonNodes.size());
+      c->insertAtTheEnd(commonNodes.begin(),commonNodes.end());
     }
 }
 
+std::size_t DataArray::getHeapMemorySize() const
+{
+  std::size_t sz1=_name.capacity();
+  std::size_t sz2=_info_on_compo.capacity();
+  std::size_t sz3=0;
+  for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++)
+    sz3+=(*it).capacity();
+  return sz1+sz2+sz3;
+}
+
 void DataArray::setName(const char *name)
 {
   _name=name;
@@ -129,12 +140,6 @@ void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, cons
 bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const
 {
   std::ostringstream oss;
-  if(_nb_of_tuples!=other._nb_of_tuples)
-    {
-      oss << "Number of tuples of DataArray mismatch : this number of tuples=" << _nb_of_tuples << " other number of tuples=" << other._nb_of_tuples;
-      reason=oss.str();
-      return false;
-    }
   if(_name!=other._name)
     {
       oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !";
@@ -170,6 +175,13 @@ void DataArray::reprWithoutNameStream(std::ostream& stream) const
   stream << "\n";
 }
 
+std::string DataArray::cppRepr(const char *varName) const throw(INTERP_KERNEL::Exception)
+{
+  std::ostringstream ret;
+  reprCppStream(varName,ret);
+  return ret.str();
+}
+
 void DataArray::setInfoOnComponents(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception)
 {
   if(getNumberOfComponents()!=(int)info.size())
@@ -348,13 +360,13 @@ void DataArray::CheckValueInRangeEx(int value, int start, int end, const char *m
     {
       if(value!=start || end!=start)
         {
-          std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg  << " ! Expected start " << start << " of range in [0," << value << "[ !";
+          std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected start " << start << " of input range, in [0," << value << "[ !";
           throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
     }
   if(end<0 || end>value)
     {
-      std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected start " << end << " of range in [0," << value << "[ !";
+      std::ostringstream oss; oss << "DataArray::CheckValueInRangeEx : " << msg  << " ! Expected end " << end << " of input range, in [0," << value << "] !";
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
 }
@@ -363,7 +375,7 @@ void DataArray::CheckClosingParInRange(int ref, int value, const char *msg) thro
 {
   if(value<0 || value>ref)
     {
-      std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected a range in [0," << ref << "] having closing open parenthesis " << value << " !";
+      std::ostringstream oss; oss << "DataArray::CheckClosingParInRange : " << msg  << " ! Expected input range in [0," << ref << "] having closing open parenthesis " << value << " !";
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
 }
@@ -375,6 +387,8 @@ int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const char
       std::ostringstream oss; oss << msg << " : end before begin !";
       throw INTERP_KERNEL::Exception(oss.str().c_str());
     }
+  if(end==begin)
+    return 0;
   if(step<=0)
     {
       std::ostringstream oss; oss << msg << " : invalid step should be > 0 !";
@@ -452,6 +466,13 @@ void DataArrayDouble::checkAllocated() const throw(INTERP_KERNEL::Exception)
     throw INTERP_KERNEL::Exception("DataArrayDouble::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
 }
 
+std::size_t DataArrayDouble::getHeapMemorySize() const
+{
+  std::size_t sz=(std::size_t)_mem.getNbOfElemAllocated();
+  sz*=sizeof(double);
+  return DataArray::getHeapMemorySize()+sz;
+}
+
 /*!
  * This method differs from DataArray::setInfoOnComponents in the sense that if 'this->getNumberOfComponents()!=info.size()'
  * and if 'this' is not allocated it will change the number of components of 'this'.
@@ -533,6 +554,63 @@ void DataArrayDouble::cpyFrom(const DataArrayDouble& other) throw(INTERP_KERNEL:
   copyStringInfoFrom(other);
 }
 
+void DataArrayDouble::reserve(int nbOfElems) throw(INTERP_KERNEL::Exception)
+{
+  int nbCompo=getNumberOfComponents();
+  if(nbCompo==1)
+    {
+      _mem.reserve(nbOfElems);
+    }
+  else if(nbCompo==0)
+    {
+      _mem.reserve(nbOfElems);
+      _info_on_compo.resize(1);
+    }
+  else
+    throw INTERP_KERNEL::Exception("DataArrayDouble::reserve : not available for DataArrayDouble with number of components different than 1 !");
+}
+
+void DataArrayDouble::pushBackSilent(double val) throw(INTERP_KERNEL::Exception)
+{
+  int nbCompo=getNumberOfComponents();
+  if(nbCompo==1)
+    _mem.pushBack(val);
+  else if(nbCompo==0)
+    {
+      _info_on_compo.resize(1);
+      _mem.pushBack(val);
+    }
+  else
+    throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !");
+}
+
+void DataArrayDouble::pushBackValsSilent(const double *valsBg, const double *valsEnd) throw(INTERP_KERNEL::Exception)
+{
+  int nbCompo=getNumberOfComponents();
+  if(nbCompo==1)
+    _mem.insertAtTheEnd(valsBg,valsEnd);
+  else if(nbCompo==0)
+    {
+      _info_on_compo.resize(1);
+      _mem.insertAtTheEnd(valsBg,valsEnd);
+    }
+  else
+    throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackValsSilent : not available for DataArrayDouble with number of components different than 1 !");
+}
+
+double DataArrayDouble::popBackSilent() throw(INTERP_KERNEL::Exception)
+{
+  if(getNumberOfComponents()==1)
+    return _mem.popBack();
+  else
+    throw INTERP_KERNEL::Exception("DataArrayDouble::popBackSilent : not available for DataArrayDouble with number of components different than 1 !");
+}
+
+void DataArrayDouble::pack() const throw(INTERP_KERNEL::Exception)
+{
+  _mem.pack();
+}
+
 void DataArrayDouble::allocIfNecessary(int nbOfTuple, int nbOfCompo)
 {
   if(isAllocated())
@@ -548,9 +626,8 @@ void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::E
 {
   if(nbOfTuple<0 || nbOfCompo<0)
     throw INTERP_KERNEL::Exception("DataArrayDouble::alloc : request for negative length of data !");
-  _nb_of_tuples=nbOfTuple;
   _info_on_compo.resize(nbOfCompo);
-  _mem.alloc(nbOfCompo*_nb_of_tuples);
+  _mem.alloc(nbOfCompo*nbOfTuple);
   declareAsNew();
 }
 
@@ -619,16 +696,12 @@ void DataArrayDouble::reverse() throw(INTERP_KERNEL::Exception)
  */
  void DataArrayDouble::checkMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception)
 {
-  if(!isMonotonic(increasing, eps))
+  if(!isMonotonic(increasing,eps))
     {
       if (increasing)
-        {
-          throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
-        }
+        throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !");
       else
-        {
-          throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
-        }
+        throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !");
     }
 }
 
@@ -647,7 +720,7 @@ bool DataArrayDouble::isMonotonic(bool increasing, double eps) const throw(INTER
     return true;
   double ref=ptr[0];
   double absEps=fabs(eps);
-  if (increasing)
+  if(increasing)
     {
       for(int i=1;i<nbOfElements;i++)
         {
@@ -686,7 +759,7 @@ std::string DataArrayDouble::reprZip() const
 void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const char *nameInFile) const throw(INTERP_KERNEL::Exception)
 {
   std::string idt(indent,' ');
-  ofs.precision(15);
+  ofs.precision(17);
   ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
   ofs << " format=\"ascii\" RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\">\n" << idt;
   std::copy(begin(),end(),std::ostream_iterator<double>(ofs," "));
@@ -708,17 +781,35 @@ void DataArrayDouble::reprZipStream(std::ostream& stream) const
 void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const
 {
   DataArray::reprWithoutNameStream(stream);
-  stream.precision(15);
+  stream.precision(17);
   _mem.repr(getNumberOfComponents(),stream);
 }
 
 void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const
 {
   DataArray::reprWithoutNameStream(stream);
-  stream.precision(15);
+  stream.precision(17);
   _mem.reprZip(getNumberOfComponents(),stream);
 }
 
+void DataArrayDouble::reprCppStream(const char *varName, std::ostream& stream) const
+{
+  int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
+  const double *data=getConstPointer();
+  stream.precision(17);
+  stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl;
+  if(nbTuples*nbComp>=1)
+    {
+      stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={";
+      std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(stream,","));
+      stream << data[nbTuples*nbComp-1] << "};" << std::endl;
+      stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
+    }
+  else
+    stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
+  stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
+}
+
 bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const
 {
   if(!areInfoEqualsIfNotWhy(other,reason))
@@ -741,8 +832,7 @@ bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other,
 void DataArrayDouble::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
 {
   checkAllocated();
-  _mem.reAlloc((int)(_info_on_compo.size())*nbOfTuples);
-  _nb_of_tuples=nbOfTuples;
+  _mem.reAlloc(getNumberOfComponents()*nbOfTuples);
   declareAsNew();
 }
 
@@ -771,7 +861,7 @@ DataArrayDouble *DataArrayDouble::fromNoInterlace() const throw(INTERP_KERNEL::E
 DataArrayDouble *DataArrayDouble::toNoInterlace() const throw(INTERP_KERNEL::Exception)
 {
   if(_mem.isNull())
-    throw INTERP_KERNEL::Exception("DataArrayDouble::fromNoInterlace : Not defined array !");
+    throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !");
   double *tab=_mem.toNoInterlace(getNumberOfComponents());
   DataArrayDouble *ret=DataArrayDouble::New();
   ret->useArray(tab,true,CPP_DEALLOC,getNumberOfTuples(),getNumberOfComponents());
@@ -784,6 +874,7 @@ DataArrayDouble *DataArrayDouble::toNoInterlace() const throw(INTERP_KERNEL::Exc
  */
 void DataArrayDouble::renumberInPlace(const int *old2New)
 {
+  checkAllocated();
   int nbTuples=getNumberOfTuples();
   int nbOfCompo=getNumberOfComponents();
   double *tmp=new double[nbTuples*nbOfCompo];
@@ -801,6 +892,7 @@ void DataArrayDouble::renumberInPlace(const int *old2New)
  */
 void DataArrayDouble::renumberInPlaceR(const int *new2Old)
 {
+  checkAllocated();
   int nbTuples=getNumberOfTuples();
   int nbOfCompo=getNumberOfComponents();
   double *tmp=new double[nbTuples*nbOfCompo];
@@ -818,6 +910,7 @@ void DataArrayDouble::renumberInPlaceR(const int *new2Old)
  */
 DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const
 {
+  checkAllocated();
   int nbTuples=getNumberOfTuples();
   int nbOfCompo=getNumberOfComponents();
   DataArrayDouble *ret=DataArrayDouble::New();
@@ -837,6 +930,7 @@ DataArrayDouble *DataArrayDouble::renumber(const int *old2New) const
  */
 DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const
 {
+  checkAllocated();
   int nbTuples=getNumberOfTuples();
   int nbOfCompo=getNumberOfComponents();
   DataArrayDouble *ret=DataArrayDouble::New();
@@ -858,6 +952,7 @@ DataArrayDouble *DataArrayDouble::renumberR(const int *new2Old) const
  */
 DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newNbOfTuple) const
 {
+  checkAllocated();
   int nbTuples=getNumberOfTuples();
   int nbOfCompo=getNumberOfComponents();
   DataArrayDouble *ret=DataArrayDouble::New();
@@ -880,7 +975,8 @@ DataArrayDouble *DataArrayDouble::renumberAndReduce(const int *old2New, int newN
  */
 DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
 {
-  DataArrayDouble *ret=DataArrayDouble::New();
+  checkAllocated();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
   int nbComp=getNumberOfComponents();
   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
   ret->copyStringInfoFrom(*this);
@@ -890,7 +986,7 @@ DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const in
   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
   ret->copyStringInfoFrom(*this);
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -898,6 +994,7 @@ DataArrayDouble *DataArrayDouble::selectByTupleId(const int *new2OldBg, const in
  */
 DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
   int nbComp=getNumberOfComponents();
   int oldNbOfTuples=getNumberOfTuples();
@@ -912,8 +1009,7 @@ DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, cons
     else
       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
   ret->copyStringInfoFrom(*this);
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -926,6 +1022,7 @@ DataArrayDouble *DataArrayDouble::selectByTupleIdSafe(const int *new2OldBg, cons
  */
 DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New();
   int nbComp=getNumberOfComponents();
   int newNbOfTuples=GetNumberOfItemGivenBES(bg,end2,step,"DataArrayDouble::selectByTupleId2 : ");
@@ -935,8 +1032,7 @@ DataArrayDouble *DataArrayDouble::selectByTupleId2(int bg, int end2, int step) c
   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
   ret->copyStringInfoFrom(*this);
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -993,8 +1089,7 @@ DataArrayDouble *DataArrayDouble::selectByTupleRanges(const std::vector<std::pai
   double *work=ret->getPointer();
   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -1007,6 +1102,7 @@ DataArrayDouble *DataArrayDouble::selectByTupleRanges(const std::vector<std::pai
  */
 DataArrayDouble *DataArrayDouble::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   int nbt=getNumberOfTuples();
   if(tupleIdBg<0)
     throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !");
@@ -1071,7 +1167,6 @@ void DataArrayDouble::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception
   int nbOfElems=getNbOfElems();
   if(nbOfElems%newNbOfCompo!=0)
     throw INTERP_KERNEL::Exception("DataArrayDouble::rearrange : nbOfElems%newNbOfCompo!=0 !");
-  _nb_of_tuples=nbOfElems/newNbOfCompo;
   _info_on_compo.clear();
   _info_on_compo.resize(newNbOfCompo);
   declareAsNew();
@@ -1109,8 +1204,7 @@ DataArrayDouble *DataArrayDouble::keepSelectedComponents(const std::vector<int>&
   for(int i=0;i<nbOfTuples;i++)
     for(std::size_t j=0;j<newNbOfCompo;j++,nc++)
       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -1167,12 +1261,10 @@ void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayI
     throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2 or 3.");
   
   int nbOfTuples=getNumberOfTuples();
-  comm=DataArrayInt::New();
-  commIndex=DataArrayInt::New();
   //
   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=computeBBoxPerTuple(prec);
   //
-  std::vector<int> c,cI(1);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0);
   switch(nbOfCompo)
     {
     case 3:
@@ -1187,10 +1279,8 @@ void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayI
     default:
       throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2 and 3 ! not implemented for other number of components !");
     }
-  commIndex->alloc((int)cI.size(),1);
-  std::copy(cI.begin(),cI.end(),commIndex->getPointer());
-  comm->alloc(cI.back(),1);
-  std::copy(c.begin(),c.end(),comm->getPointer());
+  comm=c.retn();
+  commIndex=cI.retn();
 }
 
 /*!
@@ -1218,8 +1308,7 @@ DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const th
         *retPtr=val;
     }
   ret->copyStringInfoFrom(*this);
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -1233,11 +1322,12 @@ DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const th
  */
 DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   DataArrayInt *c0=0,*cI0=0;
   findCommonTuples(prec,limitTupleId,c0,cI0);
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(c0),cI(cI0);
   int newNbOfTuples=-1;
-  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0,cI0,newNbOfTuples);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples);
   return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples);
 }
 
@@ -1245,10 +1335,11 @@ void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std:
 {
   if(!a)
     throw INTERP_KERNEL::Exception("DataArrayDouble::setSelectedComponents : input DataArrayDouble is NULL !");
+  checkAllocated();
   copyPartOfStringInfoFrom2(compoIds,*a);
   std::size_t partOfCompoSz=compoIds.size();
   int nbOfCompo=getNumberOfComponents();
-  int nbOfTuples=getNumberOfTuples();
+  int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
   const double *ac=a->getConstPointer();
   double *nc=getPointer();
   for(int i=0;i<nbOfTuples;i++)
@@ -1273,14 +1364,34 @@ void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, i
   int nbOfTuples=getNumberOfTuples();
   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
-  a->checkNbOfElems(newNbOfTuples*newNbOfComp,msg);
-  if(strictCompoCompare)
-    a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
-  double *pt=getPointer()+bgTuples*nbComp+bgComp;
+  bool assignTech=true;
+  if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
+    {
+      if(strictCompoCompare)
+        a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
+    }
+  else
+    {
+      a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
+      assignTech=false;
+    }
   const double *srcPt=a->getConstPointer();
-  for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
-    for(int j=0;j<newNbOfComp;j++,srcPt++)
-      pt[j*stepComp]=*srcPt;
+  double *pt=getPointer()+bgTuples*nbComp+bgComp;
+  if(assignTech)
+    {
+      for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
+        for(int j=0;j<newNbOfComp;j++,srcPt++)
+          pt[j*stepComp]=*srcPt;
+    }
+  else
+    {
+      for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
+        {
+          const double *srcPt2=srcPt;
+          for(int j=0;j<newNbOfComp;j++,srcPt2++)
+            pt[j*stepComp]=*srcPt2;
+        }
+    }
 }
 
 /*!
@@ -1448,6 +1559,66 @@ void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, cons
       }
 }
 
+void DataArrayDouble::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
+{
+  if(!a)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues4 : input DataArrayDouble is NULL !");
+  const char msg[]="DataArrayDouble::setPartOfValues4";
+  checkAllocated();
+  a->checkAllocated();
+  int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
+  int newNbOfComp=(int)std::distance(bgComp,endComp);
+  int nbComp=getNumberOfComponents();
+  for(const int *z=bgComp;z!=endComp;z++)
+    DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
+  int nbOfTuples=getNumberOfTuples();
+  DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
+  bool assignTech=true;
+  if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
+    {
+      if(strictCompoCompare)
+        a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
+    }
+  else
+    {
+      a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
+      assignTech=false;
+    }
+  const double *srcPt=a->getConstPointer();
+  double *pt=getPointer()+bgTuples*nbComp;
+  if(assignTech)
+    {
+      for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
+        for(const int *z=bgComp;z!=endComp;z++,srcPt++)
+          pt[*z]=*srcPt;
+    }
+  else
+    {
+      for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
+        {
+          const double *srcPt2=srcPt;
+          for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
+            pt[*z]=*srcPt2;
+        }
+    }
+}
+
+void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
+{
+  const char msg[]="DataArrayDouble::setPartOfValuesSimple4";
+  checkAllocated();
+  int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
+  int nbComp=getNumberOfComponents();
+  for(const int *z=bgComp;z!=endComp;z++)
+    DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
+  int nbOfTuples=getNumberOfTuples();
+  DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
+  double *pt=getPointer()+bgTuples*nbComp;
+  for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
+    for(const int *z=bgComp;z!=endComp;z++)
+      pt[*z]=a;
+}
+
 /*!
  * 'this', 'a' and 'tuplesSelec' are expected to be defined. If not an exception will be thrown.
  * @param a is an array having exactly the same number of components than 'this'
@@ -1455,7 +1626,7 @@ void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, cons
  */
 void DataArrayDouble::setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
 {
-  if(!a)
+  if(!a || !tuplesSelec)
     throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !");
   checkAllocated();
   a->checkAllocated();
@@ -1611,14 +1782,20 @@ void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &ar
     }
 }
 
-void DataArrayDouble::useArray(const double *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo)
+void DataArrayDouble::useArray(const double *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo)
 {
-  _nb_of_tuples=nbOfTuple;
   _info_on_compo.resize(nbOfCompo);
   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
   declareAsNew();
 }
 
+void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo)
+{
+  _info_on_compo.resize(nbOfCompo);
+  _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
+  declareAsNew();
+}
+
 void DataArrayDouble::checkNoNullValues() const throw(INTERP_KERNEL::Exception)
 {
   const double *tmp=getConstPointer();
@@ -1689,8 +1866,7 @@ DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon)const throw
           bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon;
         }
     }
-  bbox->incrRef();
-  return bbox;
+  return bbox.retn();
 }
 
 /*!
@@ -1711,10 +1887,11 @@ DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon)const throw
  *
  * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues
  */
-void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, std::vector<int>& c, std::vector<int>& cI) const throw(INTERP_KERNEL::Exception)
+void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const throw(INTERP_KERNEL::Exception)
 {
   if(!other)
     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !");
+  checkAllocated();
   MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=computeBBoxPerTuple(eps);
   other->checkAllocated();
   int nbOfCompo=getNumberOfComponents();
@@ -1722,32 +1899,31 @@ void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, do
   if(nbOfCompo!=otherNbOfCompo)
     throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : number of components should be equal between this and other !");
   int nbOfTuplesOther=other->getNumberOfTuples();
-  std::vector<int> ret;
-  c.clear();
-  cI.resize(1); cI[0]=0;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0);
   switch(nbOfCompo)
     {
     case 3:
       {
         BBTree<3,int> myTree(bbox->getConstPointer(),0,0,getNumberOfTuples(),eps/10);
-        findTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,c,cI);
+        FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
         break;
       }
     case 2:
       {
         BBTree<2,int> myTree(bbox->getConstPointer(),0,0,getNumberOfTuples(),eps/10);
-        findTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,c,cI);
+        FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
         break;
       }
     case 1:
       {
         BBTree<1,int> myTree(bbox->getConstPointer(),0,0,getNumberOfTuples(),eps/10);
-        findTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,c,cI);
+        FindTupleIdsNearTuplesAlg<1>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr);
         break;
       }
     default:
       throw INTERP_KERNEL::Exception("Unexpected spacedim of coords for computeTupleIdsNearTuples. Must be 1, 2 or 3.");
     }
+  c=cArr.retn(); cI=cIArr.retn();
 }
 
 /*!
@@ -1775,6 +1951,7 @@ void DataArrayDouble::recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::E
 
 double DataArrayDouble::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   if(getNumberOfComponents()!=1)
     throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before or call 'getMaxValueInArray' method !");
   int nbOfTuples=getNumberOfTuples();
@@ -1807,6 +1984,7 @@ double DataArrayDouble::getMaxValue2(DataArrayInt*& tupleIds) const throw(INTERP
 
 double DataArrayDouble::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   if(getNumberOfComponents()!=1)
     throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before call 'getMinValueInArray' method !");
   int nbOfTuples=getNumberOfTuples();
@@ -1886,13 +2064,52 @@ void DataArrayDouble::accumulate(double *res) const throw(INTERP_KERNEL::Excepti
     std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>());
 }
 
+/*!
+ * This method returns the min distance from an external tuple defined by [ \a tupleBg , \a tupleEnd ) to \a this and
+ * the first tuple in \a this that matches the returned distance. If there is no tuples in \a this an exception will be thrown.
+ *
+ *
+ * \a this is expected to be allocated and expected to have a number of components equal to the distance from \a tupleBg to
+ * \a tupleEnd. If not an exception will be thrown.
+ *
+ * \param [in] tupleBg start pointer (included) of input external tuple
+ * \param [in] tupleEnd end pointer (not included) of input external tuple
+ * \param [out] tupleId the tuple id in \a this that matches the min of distance between \a this and input external tuple
+ * \return the min distance.
+ * \sa MEDCouplingUMesh::distanceToPoint
+ */
+double DataArrayDouble::distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const throw(INTERP_KERNEL::Exception)
+{
+  checkAllocated();
+  int nbTuple=getNumberOfTuples();
+  int nbComps=getNumberOfComponents();
+  if(nbComps!=(int)std::distance(tupleBg,tupleEnd))
+    { std::ostringstream oss; oss << "DataArrayDouble::distanceToTuple : size of input tuple is " << std::distance(tupleBg,tupleEnd) << " should be equal to the number of components in this : " << nbComps << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); }
+  if(nbTuple==0)
+    throw INTERP_KERNEL::Exception("DataArrayDouble::distanceToTuple : no tuple in this ! No distance to compute !");
+  double ret0=std::numeric_limits<double>::max();
+  tupleId=-1;
+  const double *work=getConstPointer();
+  for(int i=0;i<nbTuple;i++)
+    {
+      double val=0.;
+      for(int j=0;j<nbComps;j++,work++) 
+        val+=(*work-tupleBg[j])*((*work-tupleBg[j]));
+      if(val>=ret0)
+        continue;
+      else
+        { ret0=val; tupleId=i; }
+    }
+  return sqrt(ret0);
+}
+
 double DataArrayDouble::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
 {
   checkAllocated();
   const double *ptr=getConstPointer();
   int nbTuple=getNumberOfTuples();
   int nbComps=getNumberOfComponents();
-  if(compId>=nbComps)
+  if(compId<0 || compId>=nbComps)
     throw INTERP_KERNEL::Exception("DataArrayDouble::accumulate : Invalid compId specified : No such nb of components !");
   double ret=0.;
   for(int i=0;i<nbTuple;i++)
@@ -1902,6 +2119,7 @@ double DataArrayDouble::accumulate(int compId) const throw(INTERP_KERNEL::Except
 
 DataArrayDouble *DataArrayDouble::fromPolarToCart() const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   int nbOfComp=getNumberOfComponents();
   if(nbOfComp!=2)
     throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !");
@@ -1920,6 +2138,7 @@ DataArrayDouble *DataArrayDouble::fromPolarToCart() const throw(INTERP_KERNEL::E
 
 DataArrayDouble *DataArrayDouble::fromCylToCart() const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   int nbOfComp=getNumberOfComponents();
   if(nbOfComp!=3)
     throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !");
@@ -1940,6 +2159,7 @@ DataArrayDouble *DataArrayDouble::fromCylToCart() const throw(INTERP_KERNEL::Exc
 
 DataArrayDouble *DataArrayDouble::fromSpherToCart() const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   int nbOfComp=getNumberOfComponents();
   if(nbOfComp!=3)
     throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !");
@@ -1959,6 +2179,7 @@ DataArrayDouble *DataArrayDouble::fromSpherToCart() const throw(INTERP_KERNEL::E
 
 DataArrayDouble *DataArrayDouble::doublyContractedProduct() const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   int nbOfComp=getNumberOfComponents();
   if(nbOfComp!=6)
     throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !");
@@ -2002,6 +2223,7 @@ DataArrayDouble *DataArrayDouble::determinant() const throw(INTERP_KERNEL::Excep
 
 DataArrayDouble *DataArrayDouble::eigenValues() const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   int nbOfComp=getNumberOfComponents();
   if(nbOfComp!=6)
     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !");
@@ -2017,6 +2239,7 @@ DataArrayDouble *DataArrayDouble::eigenValues() const throw(INTERP_KERNEL::Excep
 
 DataArrayDouble *DataArrayDouble::eigenVectors() const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   int nbOfComp=getNumberOfComponents();
   if(nbOfComp!=6)
     throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !");
@@ -2037,6 +2260,7 @@ DataArrayDouble *DataArrayDouble::eigenVectors() const throw(INTERP_KERNEL::Exce
 
 DataArrayDouble *DataArrayDouble::inverse() const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   int nbOfComp=getNumberOfComponents();
   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
     throw INTERP_KERNEL::Exception("DataArrayDouble::inversion : must be an array with 4,6 or 9 components !");
@@ -2084,6 +2308,7 @@ if(nbOfComp==6)
 
 DataArrayDouble *DataArrayDouble::trace() const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   int nbOfComp=getNumberOfComponents();
   if(nbOfComp!=6 && nbOfComp!=9 && nbOfComp!=4)
     throw INTERP_KERNEL::Exception("DataArrayDouble::trace : must be an array with 4,6 or 9 components !");
@@ -2106,6 +2331,7 @@ DataArrayDouble *DataArrayDouble::trace() const throw(INTERP_KERNEL::Exception)
 
 DataArrayDouble *DataArrayDouble::deviator() const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   int nbOfComp=getNumberOfComponents();
   if(nbOfComp!=6)
     throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !");
@@ -2196,8 +2422,7 @@ DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const thro
           outData[j*nbOfTuples+i]=dist;
         }
     }
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -2247,8 +2472,7 @@ DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const Da
           outData[i*nbOfTuples+j]=dist;
         }
     }
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 void DataArrayDouble::sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception)
@@ -2272,6 +2496,7 @@ void DataArrayDouble::abs() throw(INTERP_KERNEL::Exception)
   double *ptr=getPointer();
   int nbOfElems=getNbOfElems();
   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs));
+  declareAsNew();
 }
 
 void DataArrayDouble::applyLin(double a, double b, int compoId) throw(INTERP_KERNEL::Exception)
@@ -2568,6 +2793,7 @@ DataArrayDoubleIterator *DataArrayDouble::iterator()
 
 DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   if(getNumberOfComponents()!=1)
     throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !");
   const double *cptr=getConstPointer();
@@ -2830,8 +3056,7 @@ DataArrayDouble *DataArrayDouble::Add(const DataArrayDouble *a1, const DataArray
     }
   else
     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 void DataArrayDouble::addEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
@@ -2839,6 +3064,8 @@ void DataArrayDouble::addEqual(const DataArrayDouble *other) throw(INTERP_KERNEL
   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();
   int nbOfTuple=getNumberOfTuples();
   int nbOfTuple2=other->getNumberOfTuples();
   int nbOfComp=getNumberOfComponents();
@@ -2892,8 +3119,7 @@ DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const Dat
           ret->alloc(nbOfTuple2,nbOfComp1);
           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>());
           ret->copyStringInfoFrom(*a1);
-          ret->incrRef();
-          return ret;
+          return ret.retn();
         }
       else if(nbOfComp2==1)
         {
@@ -2905,8 +3131,7 @@ DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const Dat
           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);
-          ret->incrRef();
-          return ret;
+          return ret.retn();
         }
       else
         {
@@ -2924,8 +3149,7 @@ DataArrayDouble *DataArrayDouble::Substract(const DataArrayDouble *a1, const Dat
       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);
-      ret->incrRef();
-      return ret;
+      return ret.retn();
     }
   else
     {
@@ -2939,6 +3163,8 @@ void DataArrayDouble::substractEqual(const DataArrayDouble *other) throw(INTERP_
   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();
@@ -3043,8 +3269,7 @@ DataArrayDouble *DataArrayDouble::Multiply(const DataArrayDouble *a1, const Data
     }
   else
     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception)
@@ -3052,6 +3277,8 @@ void DataArrayDouble::multiplyEqual(const DataArrayDouble *other) throw(INTERP_K
   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();
@@ -3105,8 +3332,7 @@ DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataAr
           ret->alloc(nbOfTuple2,nbOfComp1);
           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>());
           ret->copyStringInfoFrom(*a1);
-          ret->incrRef();
-          return ret;
+          return ret.retn();
         }
       else if(nbOfComp2==1)
         {
@@ -3118,8 +3344,7 @@ DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataAr
           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);
-          ret->incrRef();
-          return ret;
+          return ret.retn();
         }
       else
         {
@@ -3137,8 +3362,7 @@ DataArrayDouble *DataArrayDouble::Divide(const DataArrayDouble *a1, const DataAr
       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);
-      ret->incrRef();
-      return ret;
+      return ret.retn();
     }
   else
     {
@@ -3152,6 +3376,8 @@ void DataArrayDouble::divideEqual(const DataArrayDouble *other) throw(INTERP_KER
   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();
@@ -3299,7 +3525,7 @@ DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb
 
 std::string DataArrayDoubleTuple::repr() const
 {
-  std::ostringstream oss; oss.precision(15); oss << "(";
+  std::ostringstream oss; oss.precision(17); oss << "(";
   for(int i=0;i<_nb_of_compo-1;i++)
     oss << _pt[i] << ", ";
   oss << _pt[_nb_of_compo-1] << ")";
@@ -3324,7 +3550,7 @@ DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCom
   if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1))
     {
       DataArrayDouble *ret=DataArrayDouble::New();
-      ret->useArray(_pt,false,CPP_DEALLOC,nbOfTuples,nbOfCompo);
+      ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
       return ret;
     }
   else
@@ -3351,6 +3577,13 @@ void DataArrayInt::checkAllocated() const throw(INTERP_KERNEL::Exception)
     throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !");
 }
 
+std::size_t DataArrayInt::getHeapMemorySize() const
+{
+  std::size_t sz=(std::size_t)_mem.getNbOfElemAllocated();
+  sz*=sizeof(int);
+  return DataArray::getHeapMemorySize()+sz;
+}
+
 /*!
  * This method differs from DataArray::setInfoOnComponents in the sense that if 'this->getNumberOfComponents()!=info.size()'
  * and if 'this' is not allocated it will change the number of components of 'this'.
@@ -3450,6 +3683,63 @@ void DataArrayInt::cpyFrom(const DataArrayInt& other) throw(INTERP_KERNEL::Excep
   copyStringInfoFrom(other);
 }
 
+void DataArrayInt::reserve(int nbOfElems) throw(INTERP_KERNEL::Exception)
+{
+  int nbCompo=getNumberOfComponents();
+  if(nbCompo==1)
+    {
+      _mem.reserve(nbOfElems);
+    }
+  else if(nbCompo==0)
+    {
+      _mem.reserve(nbOfElems);
+      _info_on_compo.resize(1);
+    }
+  else
+    throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !");
+}
+
+void DataArrayInt::pushBackSilent(int val) throw(INTERP_KERNEL::Exception)
+{
+  int nbCompo=getNumberOfComponents();
+  if(nbCompo==1)
+    _mem.pushBack(val);
+  else if(nbCompo==0)
+    {
+      _info_on_compo.resize(1);
+      _mem.pushBack(val);
+    }
+  else
+    throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !");
+}
+
+void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd) throw(INTERP_KERNEL::Exception)
+{
+  int nbCompo=getNumberOfComponents();
+  if(nbCompo==1)
+    _mem.insertAtTheEnd(valsBg,valsEnd);
+  else if(nbCompo==0)
+    {
+      _info_on_compo.resize(1);
+      _mem.insertAtTheEnd(valsBg,valsEnd);
+    }
+  else
+    throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !");
+}
+
+int DataArrayInt::popBackSilent() throw(INTERP_KERNEL::Exception)
+{
+  if(getNumberOfComponents()==1)
+    return _mem.popBack();
+  else
+    throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !");
+}
+
+void DataArrayInt::pack() const throw(INTERP_KERNEL::Exception)
+{
+  _mem.pack();
+}
+
 void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo)
 {
   if(isAllocated())
@@ -3464,10 +3754,9 @@ void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo)
 void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception)
 {
   if(nbOfTuple<0 || nbOfCompo<0)
-    throw INTERP_KERNEL::Exception("DataArrayDouble::alloc : request for negative length of data !");
-  _nb_of_tuples=nbOfTuple;
+    throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !");
   _info_on_compo.resize(nbOfCompo);
-  _mem.alloc(nbOfCompo*_nb_of_tuples);
+  _mem.alloc(nbOfCompo*nbOfTuple);
   declareAsNew();
 }
 
@@ -3513,6 +3802,7 @@ std::string DataArrayInt::reprZip() const
 
 void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const char *type, const char *nameInFile) const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   std::string idt(indent,' ');
   ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\"";
   ofs << " format=\"ascii\" RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\">\n" << idt;
@@ -3544,6 +3834,23 @@ void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
   _mem.reprZip(getNumberOfComponents(),stream);
 }
 
+void DataArrayInt::reprCppStream(const char *varName, std::ostream& stream) const
+{
+  int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents();
+  const int *data=getConstPointer();
+  stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl;
+  if(nbTuples*nbComp>=1)
+    {
+      stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={";
+      std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(stream,","));
+      stream << data[nbTuples*nbComp-1] << "};" << std::endl;
+      stream << varName << "->useArray(" << varName << "Data,false,CPP_DEALLOC," << nbTuples << "," << nbComp << ");" << std::endl;
+    }
+  else
+    stream << varName << "->alloc(" << nbTuples << "," << nbComp << ");" << std::endl;
+  stream << varName << "->setName(\"" << getName() << "\");" << std::endl;
+}
+
 /*!
  * This method expects a number of components equal to 1.
  * This method sweeps all the values (tuples) in 'this' (it should be allocated) and for each value v is replaced by
@@ -3553,6 +3860,7 @@ void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const
  */
 void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd) throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   if(getNumberOfComponents()!=1)
     throw INTERP_KERNEL::Exception("Call transformWithIndArr method on DataArrayInt with only one component, you can call 'rearrange' method before !");
   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
@@ -3591,6 +3899,7 @@ void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd
 void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
                                      DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   if(getNumberOfComponents()!=1)
     throw INTERP_KERNEL::Exception("Call splitByValueRange  method on DataArrayInt with only one component, you can call 'rearrange' method before !");
   int nbOfTuples=getNumberOfTuples();
@@ -3629,12 +3938,9 @@ void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
     }
   ret3->alloc((int)castsDetected.size(),1);
   std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer());
-  ret1->incrRef();
-  castArr=ret1;
-  ret2->incrRef();
-  rankInsideCast=ret2;
-  ret3->incrRef();
-  castsPresent=ret3;
+  castArr=ret1.retn();
+  rankInsideCast=ret2.retn();
+  castsPresent=ret3.retn();
 }
 
 /*!
@@ -3642,11 +3948,12 @@ void DataArrayInt::splitByValueRange(const int *arrBg, const int *arrEnd,
  * This method sweeps all the values (tuples) in 'this' (it should be allocated) and for each value v on place i, place indArr[v] will have 
  * value i.
  * indArr[v] where 'indArr' is defined by ['indArrBg','indArrEnd').
- * This method is half/safe that is to say if there is location i so that indArr[v] is not in [0,this->getNumberOfTuples()) an exception
- * will be thrown.
+ * This method is safe that is to say if there is location i so that indArr[v] is not in [0,this->getNumberOfTuples()) an exception
+ * will be thrown. An exception is also thrown if there is a location i so that \a this[i] not in [0,distance(indArrBg,indArrEnd)) !
  */
 DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   if(getNumberOfComponents()!=1)
     throw INTERP_KERNEL::Exception("Call transformWithIndArrR method on DataArrayInt with only one component, you can call 'rearrange' method before !");
   int nbElemsIn=(int)std::distance(indArrBg,indArrEnd);
@@ -3658,25 +3965,33 @@ DataArrayInt *DataArrayInt::transformWithIndArrR(const int *indArrBg, const int
   int *tmp=ret->getPointer();
   for(int i=0;i<nbOfTuples;i++,pt++)
     {
-      int pos=indArrBg[*pt];
-      if(pos>=0 && pos<nbElemsIn)
-        tmp[pos]=i;
+      if(*pt>=0 && *pt<nbElemsIn)
+        {
+          int pos=indArrBg[*pt];
+          if(pos>=0 && pos<nbOfTuples)
+            tmp[pos]=i;
+          else
+            {
+              std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !";
+              throw INTERP_KERNEL::Exception(oss.str().c_str());
+            }
+        }
       else
         {
-          std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn;
+          std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !";
           throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
     }
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
  * This method invert array 'di' that is a conversion map from Old to New numbering to New to Old numbering.
+ * Example : If \a this contains [0,1,2,0,3,4,5,4,6,4] this method will return [3,1,2,4,9,6,8]
  */
 DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
 {
-  DataArrayInt *ret=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
   ret->alloc(newNbOfElem,1);
   int nbOfOldNodes=getNumberOfTuples();
   const int *old2New=getConstPointer();
@@ -3684,23 +3999,41 @@ DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const
   for(int i=0;i!=nbOfOldNodes;i++)
     if(old2New[i]!=-1)
       pt[old2New[i]]=i;
-  return ret;
+  return ret.retn();
 }
 
 /*!
- * This method invert array 'di' that is a conversion map from New to old numbering to Old to New numbering.
+ * This method is similar to DataArrayInt::invertArrayO2N2N2O except that 
+ * Example : If \a this contains [0,1,2,0,3,4,5,4,6,4] this method will return [0,1,2,4,5,6,8] whereas DataArrayInt::invertArrayO2N2N2O returns [3,1,2,4,9,6,8]
  */
-DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
+DataArrayInt *DataArrayInt::invertArrayO2N2N2OBis(int newNbOfElem) const throw(INTERP_KERNEL::Exception)
 {
-  DataArrayInt *ret=DataArrayInt::New();
-  ret->alloc(oldNbOfElem,1);
-  const int *new2Old=getConstPointer();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
+  ret->alloc(newNbOfElem,1);
+  int nbOfOldNodes=getNumberOfTuples();
+  const int *old2New=getConstPointer();
+  int *pt=ret->getPointer();
+  for(int i=nbOfOldNodes-1;i>=0;i--)
+    if(old2New[i]!=-1)
+      pt[old2New[i]]=i;
+  return ret.retn();
+}
+
+/*!
+ * This method invert array 'di' that is a conversion map from New to old numbering to Old to New numbering.
+ */
+DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const
+{
+  checkAllocated();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
+  ret->alloc(oldNbOfElem,1);
+  const int *new2Old=getConstPointer();
   int *pt=ret->getPointer();
   std::fill(pt,pt+oldNbOfElem,-1);
   int nbOfNewElems=getNumberOfTuples();
   for(int i=0;i<nbOfNewElems;i++)
     pt[new2Old[i]]=i;
-  return ret;
+  return ret.retn();
 }
 
 bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const
@@ -3747,6 +4080,106 @@ void DataArrayInt::reverse() throw(INTERP_KERNEL::Exception)
   _mem.reverse();
 }
 
+/*!
+ * This method check that array consistently INCREASING or DECREASING in value.
+ */
+void DataArrayInt::checkMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
+{
+  if(!isMonotonic(increasing))
+    {
+      if (increasing)
+        throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not INCREASING monotonic !");
+      else
+        throw INTERP_KERNEL::Exception("DataArrayInt::checkMonotonic : 'this' is not DECREASING monotonic !");
+    }
+}
+
+/*!
+ * This method check that array consistently INCREASING or DECREASING in value.
+ */
+bool DataArrayInt::isMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
+{
+  checkAllocated();
+  if(getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayInt::isMonotonic : only supported with 'this' array with ONE component !");
+  int nbOfElements=getNumberOfTuples();
+  const int *ptr=getConstPointer();
+  if(nbOfElements==0)
+    return true;
+  int ref=ptr[0];
+  if(increasing)
+    {
+      for(int i=1;i<nbOfElements;i++)
+        {
+          if(ptr[i]>=ref)
+            ref=ptr[i];
+          else
+            return false;
+        }
+    }
+  else
+    {
+      for(int i=1;i<nbOfElements;i++)
+        {
+          if(ptr[i]<=ref)
+            ref=ptr[i];
+          else
+            return false;
+        }
+    }
+  return true;
+}
+
+/*!
+ * This method check that array consistently INCREASING or DECREASING in value.
+ */
+bool DataArrayInt::isStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
+{
+  checkAllocated();
+  if(getNumberOfComponents()!=1)
+    throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : only supported with 'this' array with ONE component !");
+  int nbOfElements=getNumberOfTuples();
+  const int *ptr=getConstPointer();
+  if(nbOfElements==0)
+    return true;
+  int ref=ptr[0];
+  if(increasing)
+    {
+      for(int i=1;i<nbOfElements;i++)
+        {
+          if(ptr[i]>ref)
+            ref=ptr[i];
+          else
+            return false;
+        }
+    }
+  else
+    {
+      for(int i=1;i<nbOfElements;i++)
+        {
+          if(ptr[i]<ref)
+            ref=ptr[i];
+          else
+            return false;
+        }
+    }
+  return true;
+}
+
+/*!
+ * This method check that array consistently INCREASING or DECREASING in value.
+ */
+void DataArrayInt::checkStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception)
+{
+  if(!isStrictlyMonotonic(increasing))
+    {
+      if (increasing)
+        throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !");
+      else
+        throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !");
+    }
+}
+
 /*!
  * This method expects that 'this' and 'other' have the same number of tuples and exactly one component both. If not an exception will be thrown.
  * This method retrieves a newly created array with same number of tuples than 'this' and 'other' with one component.
@@ -3756,9 +4189,11 @@ void DataArrayInt::reverse() throw(INTERP_KERNEL::Exception)
  */
 DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   if(getNumberOfComponents()!=1 || other.getNumberOfComponents()!=1)
     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' have to have exactly ONE component !");
   int nbTuple=getNumberOfTuples();
+  other.checkAllocated();
   if(nbTuple!=other.getNumberOfTuples())
     throw INTERP_KERNEL::Exception("DataArrayInt::buildPermutationArr : 'this' and 'other' must have the same number of tuple !");
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
@@ -3780,20 +4215,26 @@ DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const
         }
       retToFill[i]=(*it).second;
     }
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 void DataArrayInt::useArray(const int *array, bool ownership,  DeallocType type, int nbOfTuple, int nbOfCompo)
 {
-  _nb_of_tuples=nbOfTuple;
   _info_on_compo.resize(nbOfCompo);
   _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo);
   declareAsNew();
 }
 
+void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo)
+{
+  _info_on_compo.resize(nbOfCompo);
+  _mem.useExternalArrayWithRWAccess(array,nbOfTuple*nbOfCompo);
+  declareAsNew();
+}
+
 DataArrayInt *DataArrayInt::fromNoInterlace() const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   if(_mem.isNull())
     throw INTERP_KERNEL::Exception("DataArrayInt::fromNoInterlace : Not defined array !");
   int *tab=_mem.fromNoInterlace(getNumberOfComponents());
@@ -3804,6 +4245,7 @@ DataArrayInt *DataArrayInt::fromNoInterlace() const throw(INTERP_KERNEL::Excepti
 
 DataArrayInt *DataArrayInt::toNoInterlace() const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   if(_mem.isNull())
     throw INTERP_KERNEL::Exception("DataArrayInt::toNoInterlace : Not defined array !");
   int *tab=_mem.toNoInterlace(getNumberOfComponents());
@@ -3814,6 +4256,7 @@ DataArrayInt *DataArrayInt::toNoInterlace() const throw(INTERP_KERNEL::Exception
 
 void DataArrayInt::renumberInPlace(const int *old2New)
 {
+  checkAllocated();
   int nbTuples=getNumberOfTuples();
   int nbOfCompo=getNumberOfComponents();
   int *tmp=new int[nbTuples*nbOfCompo];
@@ -3827,6 +4270,7 @@ void DataArrayInt::renumberInPlace(const int *old2New)
 
 void DataArrayInt::renumberInPlaceR(const int *new2Old)
 {
+  checkAllocated();
   int nbTuples=getNumberOfTuples();
   int nbOfCompo=getNumberOfComponents();
   int *tmp=new int[nbTuples*nbOfCompo];
@@ -3845,6 +4289,7 @@ void DataArrayInt::renumberInPlaceR(const int *new2Old)
  */
 DataArrayInt *DataArrayInt::renumber(const int *old2New) const
 {
+  checkAllocated();
   int nbTuples=getNumberOfTuples();
   int nbOfCompo=getNumberOfComponents();
   DataArrayInt *ret=DataArrayInt::New();
@@ -3860,6 +4305,7 @@ DataArrayInt *DataArrayInt::renumber(const int *old2New) const
 
 DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const
 {
+  checkAllocated();
   int nbTuples=getNumberOfTuples();
   int nbOfCompo=getNumberOfComponents();
   DataArrayInt *ret=DataArrayInt::New();
@@ -3874,13 +4320,14 @@ DataArrayInt *DataArrayInt::renumberR(const int *new2Old) const
 }
 
 /*!
- * Idem DataArrayDouble::renumber method except that the number of tuples is reduced.
+ * Idem DataArrayInt::renumber method except that the number of tuples is reduced.
  * That is to say that it is expected that newNbOfTuple<this->getNumberOfTuples().
  * ['old2New','old2New'+getNumberOfTuples()) defines a range containing old to new array. For every negative value in ['old2NewBg','old2New'getNumberOfTuples()) the corresponding tuple is
  * omitted.
  */
 DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTuple) const
 {
+  checkAllocated();
   int nbTuples=getNumberOfTuples();
   int nbOfCompo=getNumberOfComponents();
   DataArrayInt *ret=DataArrayInt::New();
@@ -3898,12 +4345,13 @@ DataArrayInt *DataArrayInt::renumberAndReduce(const int *old2New, int newNbOfTup
 }
 
 /*!
- * This method is a generalization of DataArrayDouble::substr method because a not contigous range can be specified here.
+ * This method is a generalization of DataArrayInt::substr method because a not contigous range can be specified here.
  * This method is equavalent to DataArrayInt::renumberAndReduce except that convention in input is new2old and \b not old2new.
  */
 DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const
 {
-  DataArrayInt *ret=DataArrayInt::New();
+  checkAllocated();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
   int nbComp=getNumberOfComponents();
   ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp);
   ret->copyStringInfoFrom(*this);
@@ -3913,7 +4361,7 @@ DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new
   for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++)
     std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp);
   ret->copyStringInfoFrom(*this);
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -3921,6 +4369,7 @@ DataArrayInt *DataArrayInt::selectByTupleId(const int *new2OldBg, const int *new
  */
 DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
   int nbComp=getNumberOfComponents();
   int oldNbOfTuples=getNumberOfTuples();
@@ -3935,8 +4384,7 @@ DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int
     else
       throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !");
   ret->copyStringInfoFrom(*this);
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -3949,6 +4397,7 @@ DataArrayInt *DataArrayInt::selectByTupleIdSafe(const int *new2OldBg, const int
  */
 DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
   int nbComp=getNumberOfComponents();
   int newNbOfTuples=GetNumberOfItemGivenBES(bg,end2,step,"DataArrayInt::selectByTupleId2 : ");
@@ -3958,8 +4407,7 @@ DataArrayInt *DataArrayInt::selectByTupleId2(int bg, int end2, int step) const t
   for(int i=0;i<newNbOfTuples;i++,srcPt+=step*nbComp)
     std::copy(srcPt,srcPt+nbComp,pt+i*nbComp);
   ret->copyStringInfoFrom(*this);
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -3974,10 +4422,10 @@ DataArrayInt *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,
   int nbOfTuplesThis=getNumberOfTuples();
   if(ranges.empty())
     {
-      DataArrayInt *ret=DataArrayInt::New();
+      MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
       ret->alloc(0,nbOfComp);
       ret->copyStringInfoFrom(*this);
-      return ret;
+      return ret.retn();
     }
   int ref=ranges.front().first;
   int nbOfTuples=0;
@@ -4016,15 +4464,14 @@ DataArrayInt *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,
   int *work=ret->getPointer();
   for(std::vector<std::pair<int,int> >::const_iterator it=ranges.begin();it!=ranges.end();it++)
     work=std::copy(src+(*it).first*nbOfComp,src+(*it).second*nbOfComp,work);
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
  * This method works only for arrays having single component.
  * If this contains the array a1 containing [9,10,0,6,4,11,3,7] this method returns an array a2 [5,6,0,3,2,7,1,4].
  * By doing a1.renumber(a2) the user will obtain array a3 equal to a1 sorted.
- * This method is useful for renumbering (in MED file for example). This method is used by MEDCouplingFieldDouble::renumberCells when check is set to true.
+ * This method is useful for renumbering (in MED file for example). This method is used by MEDCouplingFieldInt::renumberCells when check is set to true.
  * This method throws an exception if more 2 or more elements in 'this' are same.
  */
 DataArrayInt *DataArrayInt::checkAndPreparePermutation() const throw(INTERP_KERNEL::Exception)
@@ -4065,11 +4512,11 @@ void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, Data
   for(int i=0;i<nbOfTuples;i++)
     {
       int tmp2=input[i];
-      if(tmp2<targetNb)
+      if(tmp2>=0 && tmp2<targetNb)
         tmp[tmp2].push_back(i);
       else
         {
-          std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " higher than " << targetNb;
+          std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !";
           throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
     }
@@ -4083,36 +4530,32 @@ void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, Data
   int *retPtr=ret->getPointer();
   for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++)
     retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr);
-  ret->incrRef();
-  retI->incrRef();
-  arr=ret;
-  arrI=retI;
+  arr=ret.retn();
+  arrI=retI.retn();
 }
 
 /*!
- * This static method computes a old 2 new format DataArrayInt instance from a zip representation of a surjective format (retrived by DataArrayDouble::findCommonTuples for example)
+ * This static method computes a old 2 new format DataArrayInt instance from a zip representation of a surjective format (retrived by DataArrayInt::findCommonTuples for example)
  * The retrieved array minimizes the permutation.
  * Let's take an example : 
  * If 'nbOfOldTuples'==10 and 'arr'==[0,3, 5,7,9] and 'arrI'==[0,2,5] it returns the following array [0,1,2,0,3,4,5,4,6,4] and newNbOfTuples==7.
  *
  * @param nbOfOldTuples is the number of tuples in initial array.
  * @param arr is the list of tuples ids grouped by 'arrI' array
- * @param arrI is the entry point of 'arr' array. arrI->getNumberOfTuples()-1 is the number of common groups > 1 tuple.
+ * @param arrIBg is the entry point of 'arr' array. arrI->getNumberOfTuples()-1 is the number of common groups > 1 tuple.
+ * @param arrIEnd is the entry point of 'arr' array (end not included)
  * @param newNbOfTuples output parameter that retrieves the new number of tuples after surjection application
  */
-DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const DataArrayInt *arr, const DataArrayInt *arrI, int &newNbOfTuples) throw(INTERP_KERNEL::Exception)
+DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) throw(INTERP_KERNEL::Exception)
 {
-  if(!arr || !arrI)
-    throw INTERP_KERNEL::Exception("DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : presence of NULL ref of DataArrayInt in input !");
-  DataArrayInt *ret=DataArrayInt::New();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
   ret->alloc(nbOfOldTuples,1);
   int *pt=ret->getPointer();
   std::fill(pt,pt+nbOfOldTuples,-1);
-  int nbOfGrps=arrI->getNumberOfTuples()-1;
-  const int *cIPtr=arrI->getConstPointer();
-  const int *cPtr=arr->getConstPointer();
+  int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1;
+  const int *cIPtr=arrIBg;
   for(int i=0;i<nbOfGrps;i++)
-    pt[cPtr[cIPtr[i]]]=-(i+2);
+    pt[arr[cIPtr[i]]]=-(i+2);
   int newNb=0;
   for(int iNode=0;iNode<nbOfOldTuples;iNode++)
     {
@@ -4124,13 +4567,21 @@ DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTu
             {
               int grpId=-(pt[iNode]+2);
               for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++)
-                pt[cPtr[j]]=newNb;
+                {
+                  if(arr[j]>=0 && arr[j]<nbOfOldTuples)
+                    pt[arr[j]]=newNb;
+                  else
+                    {
+                      std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !";
+                      throw INTERP_KERNEL::Exception(oss.str().c_str());
+                    }
+                }
               newNb++;
             }
         }
     }
   newNbOfTuples=newNb;
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -4181,8 +4632,7 @@ DataArrayInt *DataArrayInt::buildPermArrPerLevel() const throw(INTERP_KERNEL::Ex
   for(int i=0;i<nbOfTuples;i++,pt++,opt++)
     *opt+=m[*pt];
   //
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -4240,6 +4690,7 @@ DataArrayDouble *DataArrayInt::convertToDblArr() const
  */
 DataArrayInt *DataArrayInt::substr(int tupleIdBg, int tupleIdEnd) const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   int nbt=getNumberOfTuples();
   if(tupleIdBg<0)
     throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !");
@@ -4274,7 +4725,6 @@ void DataArrayInt::rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception)
   int nbOfElems=getNbOfElems();
   if(nbOfElems%newNbOfCompo!=0)
     throw INTERP_KERNEL::Exception("DataArrayInt::rearrange : nbOfElems%newNbOfCompo!=0 !");
-  _nb_of_tuples=nbOfElems/newNbOfCompo;
   _info_on_compo.clear();
   _info_on_compo.resize(newNbOfCompo);
   declareAsNew();
@@ -4325,8 +4775,7 @@ DataArrayInt *DataArrayInt::changeNbOfComponents(int newNbOfComp, int dftValue)
 void DataArrayInt::reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception)
 {
   checkAllocated();
-  _mem.reAlloc((int)_info_on_compo.size()*nbOfTuples);
-  _nb_of_tuples=nbOfTuples;
+  _mem.reAlloc(getNumberOfComponents()*nbOfTuples);
   declareAsNew();
 }
 
@@ -4346,8 +4795,7 @@ DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector<int>& compo
   for(int i=0;i<nbOfTuples;i++)
     for(int j=0;j<newNbOfCompo;j++,nc++)
       *nc=oldc[i*oldNbOfCompo+compoIds[j]];
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -4385,10 +4833,14 @@ void DataArrayInt::meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exce
 
 void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception)
 {
+  if(!a)
+    throw INTERP_KERNEL::Exception("DataArrayInt::setSelectedComponents : input DataArrayInt is NULL !");
+  checkAllocated();
+  a->checkAllocated();
   copyPartOfStringInfoFrom2(compoIds,*a);
   std::size_t partOfCompoSz=compoIds.size();
   int nbOfCompo=getNumberOfComponents();
-  int nbOfTuples=getNumberOfTuples();
+  int nbOfTuples=std::min(getNumberOfTuples(),a->getNumberOfTuples());
   const int *ac=a->getConstPointer();
   int *nc=getPointer();
   for(int i=0;i<nbOfTuples;i++)
@@ -4413,14 +4865,34 @@ void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int end
   int nbOfTuples=getNumberOfTuples();
   DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
   DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value");
-  a->checkNbOfElems(newNbOfTuples*newNbOfComp,msg);
-  if(strictCompoCompare)
-    a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
+  bool assignTech=true;
+  if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
+    {
+      if(strictCompoCompare)
+        a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
+    }
+  else
+    {
+      a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
+      assignTech=false;
+    }
   int *pt=getPointer()+bgTuples*nbComp+bgComp;
   const int *srcPt=a->getConstPointer();
-  for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
-    for(int j=0;j<newNbOfComp;j++,srcPt++)
-      pt[j*stepComp]=*srcPt;
+  if(assignTech)
+    {
+      for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
+        for(int j=0;j<newNbOfComp;j++,srcPt++)
+          pt[j*stepComp]=*srcPt;
+    }
+  else
+    {
+      for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
+        {
+          const int *srcPt2=srcPt;
+          for(int j=0;j<newNbOfComp;j++,srcPt2++)
+            pt[j*stepComp]=*srcPt2;
+        }
+    }
 }
 
 /*!
@@ -4588,6 +5060,66 @@ void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int
       }
 }
 
+void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) throw(INTERP_KERNEL::Exception)
+{
+  if(!a)
+    throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !");
+  const char msg[]="DataArrayInt::setPartOfValues4";
+  checkAllocated();
+  a->checkAllocated();
+  int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
+  int newNbOfComp=(int)std::distance(bgComp,endComp);
+  int nbComp=getNumberOfComponents();
+  for(const int *z=bgComp;z!=endComp;z++)
+    DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
+  int nbOfTuples=getNumberOfTuples();
+  DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
+  bool assignTech=true;
+  if(a->getNbOfElems()==newNbOfTuples*newNbOfComp)
+    {
+      if(strictCompoCompare)
+        a->checkNbOfTuplesAndComp(newNbOfTuples,newNbOfComp,msg);
+    }
+  else
+    {
+      a->checkNbOfTuplesAndComp(1,newNbOfComp,msg);
+      assignTech=false;
+    }
+  const int *srcPt=a->getConstPointer();
+  int *pt=getPointer()+bgTuples*nbComp;
+  if(assignTech)
+    {
+      for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
+        for(const int *z=bgComp;z!=endComp;z++,srcPt++)
+          pt[*z]=*srcPt;
+    }
+  else
+    {
+      for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
+        {
+          const int *srcPt2=srcPt;
+          for(const int *z=bgComp;z!=endComp;z++,srcPt2++)
+            pt[*z]=*srcPt2;
+        }
+    }
+}
+
+void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) throw(INTERP_KERNEL::Exception)
+{
+  const char msg[]="DataArrayInt::setPartOfValuesSimple4";
+  checkAllocated();
+  int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg);
+  int nbComp=getNumberOfComponents();
+  for(const int *z=bgComp;z!=endComp;z++)
+    DataArray::CheckValueInRange(nbComp,*z,"invalid component id");
+  int nbOfTuples=getNumberOfTuples();
+  DataArray::CheckValueInRangeEx(nbOfTuples,bgTuples,endTuples,"invalid tuple value");
+  int *pt=getPointer()+bgTuples*nbComp;
+  for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp)
+    for(const int *z=bgComp;z!=endComp;z++)
+      pt[*z]=a;
+}
+
 /*!
  * 'this', 'a' and 'tuplesSelec' are expected to be defined. If not an exception will be thrown.
  * @param a is an array having exactly the same number of components than 'this'
@@ -4595,7 +5127,7 @@ void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int
  */
 void DataArrayInt::setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception)
 {
-  if(!a)
+  if(!a || !tuplesSelec)
     throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !");
   checkAllocated();
   a->checkAllocated();
@@ -4754,34 +5286,30 @@ DataArrayIntIterator *DataArrayInt::iterator()
 
 DataArrayInt *DataArrayInt::getIdsEqual(int val) const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   if(getNumberOfComponents()!=1)
     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqual : the array must have only one component, you can call 'rearrange' method before !");
   const int *cptr=getConstPointer();
-  std::vector<int> res;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
   int nbOfTuples=getNumberOfTuples();
   for(int i=0;i<nbOfTuples;i++,cptr++)
     if(*cptr==val)
-      res.push_back(i);
-  DataArrayInt *ret=DataArrayInt::New();
-  ret->alloc((int)res.size(),1);
-  std::copy(res.begin(),res.end(),ret->getPointer());
-  return ret;
+      ret->pushBackSilent(i);
+  return ret.retn();
 }
 
 DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   if(getNumberOfComponents()!=1)
     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqual : the array must have only one component, you can call 'rearrange' method before !");
   const int *cptr=getConstPointer();
-  std::vector<int> res;
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
   int nbOfTuples=getNumberOfTuples();
   for(int i=0;i<nbOfTuples;i++,cptr++)
     if(*cptr!=val)
-      res.push_back(i);
-  DataArrayInt *ret=DataArrayInt::New();
-  ret->alloc((int)res.size(),1);
-  std::copy(res.begin(),res.end(),ret->getPointer());
-  return ret;
+      ret->pushBackSilent(i);
+  return ret.retn();
 }
 
 /*!
@@ -4792,9 +5320,9 @@ DataArrayInt *DataArrayInt::getIdsNotEqual(int val) const throw(INTERP_KERNEL::E
  */
 int DataArrayInt::changeValue(int oldValue, int newValue) throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   if(getNumberOfComponents()!=1)
     throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !");
-  checkAllocated();
   int *start=getPointer();
   int *end2=start+getNbOfElems();
   int ret=0;
@@ -4857,6 +5385,7 @@ DataArrayInt *DataArrayInt::getIdsNotEqualList(const int *valsBg, const int *val
  */
 int DataArrayInt::locateTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   int nbOfCompo=getNumberOfComponents();
   if(nbOfCompo==0)
     throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !");
@@ -4889,6 +5418,7 @@ int DataArrayInt::locateTuple(const std::vector<int>& tupl) const throw(INTERP_K
  */
 int DataArrayInt::search(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   int nbOfCompo=getNumberOfComponents();
   if(nbOfCompo!=1)
     throw INTERP_KERNEL::Exception("DataArrayInt::search : works only for DataArrayInt instance with one component !");
@@ -4908,6 +5438,7 @@ int DataArrayInt::search(const std::vector<int>& vals) const throw(INTERP_KERNEL
  */
 int DataArrayInt::locateValue(int value) const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   if(getNumberOfComponents()!=1)
     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
   const int *cptr=getConstPointer();
@@ -4926,6 +5457,7 @@ int DataArrayInt::locateValue(int value) const throw(INTERP_KERNEL::Exception)
  */
 int DataArrayInt::locateValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   if(getNumberOfComponents()!=1)
     throw INTERP_KERNEL::Exception("DataArrayInt::presenceOfValue : the array must have only one component, you can call 'rearrange' method before !");
   std::set<int> vals2(vals.begin(),vals.end());
@@ -4972,6 +5504,32 @@ bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const throw(INT
   return locateValue(vals)!=-1;
 }
 
+
+void DataArrayInt::accumulate(int *res) const throw(INTERP_KERNEL::Exception)
+{
+  checkAllocated();
+  const int *ptr=getConstPointer();
+  int nbTuple=getNumberOfTuples();
+  int nbComps=getNumberOfComponents();
+  std::fill(res,res+nbComps,0);
+  for(int i=0;i<nbTuple;i++)
+    std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>());
+}
+
+int DataArrayInt::accumulate(int compId) const throw(INTERP_KERNEL::Exception)
+{
+  checkAllocated();
+  const int *ptr=getConstPointer();
+  int nbTuple=getNumberOfTuples();
+  int nbComps=getNumberOfComponents();
+  if(compId<0 || compId>=nbComps)
+    throw INTERP_KERNEL::Exception("DataArrayInt::accumulate : Invalid compId specified : No such nb of components !");
+  int ret=0;
+  for(int i=0;i<nbTuple;i++)
+    ret+=ptr[i*nbComps+compId];
+  return ret;
+}
+
 DataArrayInt *DataArrayInt::Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2)
 {
   if(!a1 || !a2)
@@ -5017,6 +5575,7 @@ DataArrayInt *DataArrayInt::Aggregate(const std::vector<const DataArrayInt *>& a
 
 int DataArrayInt::getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   if(getNumberOfComponents()!=1)
     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
   int nbOfTuples=getNumberOfTuples();
@@ -5040,6 +5599,7 @@ int DataArrayInt::getMaxValueInArray() const throw(INTERP_KERNEL::Exception)
 
 int DataArrayInt::getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   if(getNumberOfComponents()!=1)
     throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !");
   int nbOfTuples=getNumberOfTuples();
@@ -5067,6 +5627,7 @@ void DataArrayInt::abs() throw(INTERP_KERNEL::Exception)
   int *ptr=getPointer();
   int nbOfElems=getNbOfElems();
   std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs));
+  declareAsNew();
 }
 
 void DataArrayInt::applyLin(int a, int b, int compoId) throw(INTERP_KERNEL::Exception)
@@ -5166,6 +5727,7 @@ void DataArrayInt::applyModulus(int val) throw(INTERP_KERNEL::Exception)
  */
 DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception)
 {
+  checkAllocated();
   if(getNumberOfComponents()!=1)
     throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !");
   const int *cptr=getConstPointer();
@@ -5315,8 +5877,7 @@ DataArrayInt *DataArrayInt::MakePartition(const std::vector<const DataArrayInt *
         tmp.insert(retPtr[*p]);
       fidsOfGroups[grId].insert(fidsOfGroups[grId].end(),tmp.begin(),tmp.end());
     }
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 DataArrayInt *DataArrayInt::BuildUnion(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception)
@@ -5361,12 +5922,12 @@ DataArrayInt *DataArrayInt::BuildIntersection(const std::vector<const DataArrayI
     {
       (*it)->checkAllocated();
       if((*it)->getNumberOfComponents()!=1)
-        throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : only single component allowed !");
+        throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !");
       int tmp1;
       valm=std::min((*it)->getMinValue(tmp1),valm);
     }
   if(valm<0)
-    throw INTERP_KERNEL::Exception("DataArrayInt::BuildUnion : a negative value has been detected !");
+    throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : a negative value has been detected !");
   //
   std::set<int> r;
   for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++)
@@ -5413,6 +5974,9 @@ DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const throw(INTERP_
    return ret;
 }
 
+/*!
+ * \sa DataArrayInt::buildSubstractionOptimized
+ */
 DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
 {
   if(!other)
@@ -5437,6 +6001,33 @@ DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const t
   return ret;
 }
 
+/*!
+ * \a this is expected to have one component and to be sorted ascendingly (as for \a other).
+ * \a other is expected to be a part of \a this. If not DataArrayInt::buildSubstraction should be called instead.
+ * 
+ * \param [in] other an array with one component and expected to be sorted ascendingly.
+ * \ret list of ids in \a this but not in \a other.
+ * \sa DataArrayInt::buildSubstraction
+ */
+DataArrayInt *DataArrayInt::buildSubstractionOptimized(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
+{
+  static const char *MSG="DataArrayInt::buildSubstractionOptimized : only single component allowed !";
+  if(!other) throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstractionOptimized : NULL input array !");
+  checkAllocated(); other->checkAllocated();
+  if(getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
+  if(other->getNumberOfComponents()!=1) throw INTERP_KERNEL::Exception(MSG);
+  const int *pt1Bg(begin()),*pt1End(end()),*pt2Bg(other->begin()),*pt2End(other->end()),*work1(pt1Bg),*work2(pt2Bg);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1);
+  for(;work1!=pt1End;work1++)
+    {
+      if(work2!=pt2End && *work1==*work2)
+        work2++;
+      else
+        ret->pushBackSilent(*work1);
+    }
+  return ret.retn();
+}
+
 DataArrayInt *DataArrayInt::buildUnion(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception)
 {
   std::vector<const DataArrayInt *>arrs(2);
@@ -5451,6 +6042,29 @@ DataArrayInt *DataArrayInt::buildIntersection(const DataArrayInt *other) const t
   return BuildIntersection(arrs);
 }
 
+/*!
+ * This method can be applied on allocated with one component DataArrayInt instance.
+ * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance.
+ * Example : if \a this contains [1,2,2,3,3,3,3,4,5,5,7,7,7,19] the returned array will contain [1,2,3,4,5,7,19]
+ * 
+ * \return a newly allocated array that contain the result of the unique operation applied on \a this.
+ * \throw if \a this is not allocated or if \a this has not exactly one component.
+ */
+DataArrayInt *DataArrayInt::buildUnique() const throw(INTERP_KERNEL::Exception)
+{
+  checkAllocated();
+  if(getNumberOfComponents()!=1)
+     throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !");
+  int nbOfTuples=getNumberOfTuples();
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy();
+  int *data=tmp->getPointer();
+  int *last=std::unique(data,data+nbOfTuples);
+  MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New();
+  ret->alloc(std::distance(data,last),1);
+  std::copy(data,last,ret->getPointer());
+  return ret.retn();
+}
+
 /*!
  * This method could be usefull for returned DataArrayInt marked as index. Some methods that generate such DataArrayInt instances:
  * - ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity
@@ -5578,8 +6192,7 @@ DataArrayInt *DataArrayInt::buildExplicitArrByRanges(const DataArrayInt *offsets
       for(int j=0;j<off;j++,retPtr++)
         *retPtr=start+j;
     }
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -5628,8 +6241,7 @@ DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges)
           throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
     }
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -5678,8 +6290,7 @@ DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges
           throw INTERP_KERNEL::Exception(oss.str().c_str());
         }
     }
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -5707,18 +6318,54 @@ DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const throw(IN
         *retPtr=val;
     }
   ret->copyStringInfoFrom(*this);
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
- * This method returns all different values found in 'this'.
+ * 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.
  */
 std::set<int> DataArrayInt::getDifferentValues() const throw(INTERP_KERNEL::Exception)
 {
   checkAllocated();
   std::set<int> ret;
-  ret.insert(getConstPointer(),getConstPointer()+getNbOfElems());
+  ret.insert(begin(),end());
+  return ret;
+}
+
+/*!
+ * 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 throw(INTERP_KERNEL::Exception)
+{
+  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;
 }
 
@@ -5789,8 +6436,7 @@ DataArrayInt *DataArrayInt::Add(const DataArrayInt *a1, const DataArrayInt *a2)
     }
   else
     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !");
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 void DataArrayInt::addEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
@@ -5798,6 +6444,7 @@ void DataArrayInt::addEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exce
   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();
@@ -5851,8 +6498,7 @@ DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt
           ret->alloc(nbOfTuple2,nbOfComp1);
           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>());
           ret->copyStringInfoFrom(*a1);
-          ret->incrRef();
-          return ret;
+          return ret.retn();
         }
       else if(nbOfComp2==1)
         {
@@ -5864,8 +6510,7 @@ DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt
           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);
-          ret->incrRef();
-          return ret;
+          return ret.retn();
         }
       else
         {
@@ -5883,8 +6528,7 @@ DataArrayInt *DataArrayInt::Substract(const DataArrayInt *a1, const DataArrayInt
       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);
-      ret->incrRef();
-      return ret;
+      return ret.retn();
     }
   else
     {
@@ -5898,6 +6542,7 @@ void DataArrayInt::substractEqual(const DataArrayInt *other) throw(INTERP_KERNEL
   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();
@@ -5997,8 +6642,7 @@ DataArrayInt *DataArrayInt::Multiply(const DataArrayInt *a1, const DataArrayInt
     }
   else
     throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !");
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 void DataArrayInt::multiplyEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception)
@@ -6006,6 +6650,7 @@ void DataArrayInt::multiplyEqual(const DataArrayInt *other) throw(INTERP_KERNEL:
   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();
@@ -6059,8 +6704,7 @@ DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a
           ret->alloc(nbOfTuple2,nbOfComp1);
           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>());
           ret->copyStringInfoFrom(*a1);
-          ret->incrRef();
-          return ret;
+          return ret.retn();
         }
       else if(nbOfComp2==1)
         {
@@ -6072,8 +6716,7 @@ DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a
           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);
-          ret->incrRef();
-          return ret;
+          return ret.retn();
         }
       else
         {
@@ -6091,8 +6734,7 @@ DataArrayInt *DataArrayInt::Divide(const DataArrayInt *a1, const DataArrayInt *a
       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);
-      ret->incrRef();
-      return ret;
+      return ret.retn();
     }
   else
     {
@@ -6106,6 +6748,7 @@ void DataArrayInt::divideEqual(const DataArrayInt *other) throw(INTERP_KERNEL::E
   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();
@@ -6159,8 +6802,7 @@ DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *
           ret->alloc(nbOfTuple2,nbOfComp1);
           std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>());
           ret->copyStringInfoFrom(*a1);
-          ret->incrRef();
-          return ret;
+          return ret.retn();
         }
       else if(nbOfComp2==1)
         {
@@ -6172,8 +6814,7 @@ DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *
           for(int i=0;i<nbOfTuple1;i++)
             res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i]));
           ret->copyStringInfoFrom(*a1);
-          ret->incrRef();
-          return ret;
+          return ret.retn();
         }
       else
         {
@@ -6191,8 +6832,7 @@ DataArrayInt *DataArrayInt::Modulus(const DataArrayInt *a1, const DataArrayInt *
       for(int i=0;i<nbOfTuple1;i++)
         pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>());
       ret->copyStringInfoFrom(*a1);
-      ret->incrRef();
-      return ret;
+      return ret.retn();
     }
   else
     {
@@ -6206,6 +6846,7 @@ void DataArrayInt::modulusEqual(const DataArrayInt *other) throw(INTERP_KERNEL::
   if(!other)
     throw INTERP_KERNEL::Exception("DataArrayInt::modulusEqual : input DataArrayInt instance is NULL !");
   const char *msg="Nb of tuples mismatch for DataArrayInt::modulusEqual !";
+  checkAllocated(); other->checkAllocated();
   int nbOfTuple=getNumberOfTuples();
   int nbOfTuple2=other->getNumberOfTuples();
   int nbOfComp=getNumberOfComponents();
@@ -6279,8 +6920,7 @@ DataArrayInt *DataArrayInt::Range(int begin, int end, int step) throw(INTERP_KER
       for(int i=begin;i>end;i+=step,ptr++)
         *ptr=i;
     }
-  ret->incrRef();
-  return ret;
+  return ret.retn();
 }
 
 /*!
@@ -6418,7 +7058,7 @@ 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->useArray(_pt,false,CPP_DEALLOC,nbOfTuples,nbOfCompo);
+      ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo);
       return ret;
     }
   else