Index: /XIOS/dev/dev_olga/bld.cfg
===================================================================
--- /XIOS/dev/dev_olga/bld.cfg	(revision 1128)
+++ /XIOS/dev/dev_olga/bld.cfg	(revision 1129)
@@ -36,5 +36,6 @@
 #bld::target test_regular.exe
 #bld::target test_new_features.exe test_unstruct_complete.exe 
-#bld::target test_client.exe test_complete.exe
+#bld::target test_client.exe 
+bld::target test_complete.exe
 bld::target test_client.exe
 bld::exe_dep
Index: /XIOS/dev/dev_olga/inputs/COMPLETE/iodef.xml
===================================================================
--- /XIOS/dev/dev_olga/inputs/COMPLETE/iodef.xml	(revision 1128)
+++ /XIOS/dev/dev_olga/inputs/COMPLETE/iodef.xml	(revision 1129)
@@ -8,4 +8,9 @@
   <context id="xios">
       <variable_definition>
+        <variable_group id="server">
+            <variable id="using_server2" type="bool">true</variable>
+            <variable id="ratio_server2" type="int">50</variable>
+        </variable_group>
+
         <variable_group id="buffer">
             <variable id="optimal_buffer_size" type="string">memory</variable>
Index: /XIOS/dev/dev_olga/src/distribution.cpp
===================================================================
--- /XIOS/dev/dev_olga/src/distribution.cpp	(revision 1128)
+++ /XIOS/dev/dev_olga/src/distribution.cpp	(revision 1129)
@@ -18,4 +18,9 @@
 }
 
+const CArray<size_t,1>& CDistribution:: getGlobalIndex() const 
+{ 
+  return globalIndex_; 
+}
+
 CDistribution::~CDistribution()
 { /* Nothing to do */ }
Index: /XIOS/dev/dev_olga/src/distribution.hpp
===================================================================
--- /XIOS/dev/dev_olga/src/distribution.hpp	(revision 1128)
+++ /XIOS/dev/dev_olga/src/distribution.hpp	(revision 1129)
@@ -35,5 +35,6 @@
     int getDims() const; //! Get dimension size
     int getRank() const; //! Get rank of current process
-
+    const CArray<size_t,1>& getGlobalIndex() const;
+    
   protected:
     virtual void createGlobalIndex() {};
Index: /XIOS/dev/dev_olga/src/distribution_client.cpp
===================================================================
--- /XIOS/dev/dev_olga/src/distribution_client.cpp	(revision 1128)
+++ /XIOS/dev/dev_olga/src/distribution_client.cpp	(revision 1129)
@@ -291,6 +291,6 @@
       nBeginLocal_.at(indexMap_[idx]+1) = 0;
       nBeginGlobal_.at(indexMap_[idx]+1) = domList[domIndex]->jbegin;
-      nZoomBegin_.at((indexMap_[idx]+1)) = domList[domIndex]->global_zoom_jbegin;
-      nZoomEnd_.at((indexMap_[idx]+1))   = domList[domIndex]->global_zoom_jbegin + domList[domIndex]->global_zoom_nj-1;
+      nZoomBegin_.at((indexMap_[idx]+1)) = 0; //domList[domIndex]->global_zoom_jbegin;
+      nZoomEnd_.at((indexMap_[idx]+1))   = domList[domIndex]->nj_glo.getValue()- 1; //domList[domIndex]->global_zoom_jbegin + domList[domIndex]->global_zoom_nj-1;
 
       dataBegin_.at(indexMap_[idx]+1) = domList[domIndex]->data_jbegin.getValue();
@@ -303,6 +303,6 @@
       nBeginLocal_.at(indexMap_[idx]) = 0;
       nBeginGlobal_.at(indexMap_[idx]) = domList[domIndex]->ibegin;
-      nZoomBegin_.at((indexMap_[idx])) = domList[domIndex]->global_zoom_ibegin;
-      nZoomEnd_.at((indexMap_[idx]))   = domList[domIndex]->global_zoom_ibegin + domList[domIndex]->global_zoom_ni-1;
+      nZoomBegin_.at((indexMap_[idx])) = 0; // domList[domIndex]->global_zoom_ibegin;
+      nZoomEnd_.at((indexMap_[idx]))   = domList[domIndex]->ni_glo.getValue() -1; //domList[domIndex]->global_zoom_ibegin + domList[domIndex]->global_zoom_ni-1;
 
       dataBegin_.at(indexMap_[idx]) = domList[domIndex]->data_ibegin.getValue();
@@ -325,6 +325,6 @@
       nBeginLocal_.at(indexMap_[idx]) = 0;
       nBeginGlobal_.at(indexMap_[idx]) = axisList[axisIndex]->begin.getValue();
-      nZoomBegin_.at((indexMap_[idx])) = axisList[axisIndex]->global_zoom_begin;
-      nZoomEnd_.at((indexMap_[idx])) = axisList[axisIndex]->global_zoom_begin + axisList[axisIndex]->global_zoom_n-1;
+      nZoomBegin_.at((indexMap_[idx])) = 0; //axisList[axisIndex]->global_zoom_begin;
+      nZoomEnd_.at((indexMap_[idx])) = axisList[axisIndex]->n_glo.getValue() - 1; //axisList[axisIndex]->global_zoom_begin + axisList[axisIndex]->global_zoom_n-1;
 
       dataBegin_.at(indexMap_[idx]) = axisList[axisIndex]->data_begin.getValue();
@@ -587,4 +587,5 @@
   localDataIndex_.resize(indexLocalDataOnClientCount);
   localMaskIndex_.resize(indexSend2ServerCount);
+  globalDataIndex_.rehash(std::ceil(indexLocalDataOnClientCount/globalDataIndex_.max_load_factor())); //globalLocalDataSendToServerMap_.reserve(indexSend2ServerCount);
   globalLocalDataSendToServerMap_.rehash(std::ceil(indexSend2ServerCount/globalLocalDataSendToServerMap_.max_load_factor())); //globalLocalDataSendToServerMap_.reserve(indexSend2ServerCount);
 
@@ -652,4 +653,10 @@
           if (gridMask_(gridMaskIndex))
           {
+            size_t globalIndex = 0;
+            for (int k = 0; k < numElement_; ++k)
+            {
+              globalIndex += (currentGlobalIndex[k])*elementNGlobal_[k];
+            }
+            globalDataIndex_[globalIndex] = indexLocalDataOnClientCount;
             localDataIndex_[indexLocalDataOnClientCount] = countLocalData;
             bool isIndexOnServer = true;
@@ -661,9 +668,4 @@
             if (isIndexOnServer)
             {
-              size_t globalIndex = 0;
-              for (int k = 0; k < numElement_; ++k)
-              {
-                globalIndex += (currentGlobalIndex[k])*elementNGlobal_[k];
-              }
               globalLocalDataSendToServerMap_[globalIndex] = indexLocalDataOnClientCount;
               localMaskIndex_[indexSend2ServerCount] = gridMaskIndex;
@@ -736,4 +738,10 @@
 }
 
+CDistributionClient::GlobalLocalDataMap& CDistributionClient::getGlobalDataIndexOnClient()
+{
+  if (!isComputed_) createGlobalIndexSendToServer();
+  return globalDataIndex_;
+}
+
 /*!
   Return local data index of client
Index: /XIOS/dev/dev_olga/src/distribution_client.hpp
===================================================================
--- /XIOS/dev/dev_olga/src/distribution_client.hpp	(revision 1128)
+++ /XIOS/dev/dev_olga/src/distribution_client.hpp	(revision 1129)
@@ -45,4 +45,5 @@
     virtual const std::vector<int>& getLocalDataIndexOnClient();
     GlobalLocalDataMap& getGlobalLocalDataSendToServer();
+    GlobalLocalDataMap& getGlobalDataIndexOnClient();
     const std::vector<int>& getLocalMaskIndexOnClient();
 
@@ -80,4 +81,5 @@
     //!< LocalData index on client
     GlobalLocalDataMap globalLocalDataSendToServerMap_;
+    GlobalLocalDataMap globalDataIndex_;
     std::vector<int> localDataIndex_;
     std::vector<int> localMaskIndex_;
Index: /XIOS/dev/dev_olga/src/distribution_server.cpp
===================================================================
--- /XIOS/dev/dev_olga/src/distribution_server.cpp	(revision 1128)
+++ /XIOS/dev/dev_olga/src/distribution_server.cpp	(revision 1129)
@@ -37,13 +37,13 @@
 }
 
-CDistributionServer::CDistributionServer(int rank, 
-                                         const std::vector<CArray<int,1> >& globalIndexEachDimension,
-                                         const std::vector<int>& nGlobal)
-  : CDistribution(rank, nGlobal.size()), nGlobal_(nGlobal), nZoomBeginGlobal_(),
-    nZoomSize_(), nZoomBegin_(), globalLocalIndexMap_(), 
-    globalIndexEachDimension_(globalIndexEachDimension)
-{
-  createGlobalIndexFromIndex(globalIndexEachDimension, nGlobal);
-}
+// CDistributionServer::CDistributionServer(int rank, 
+//                                          const std::vector<CArray<int,1> >& globalIndexEachDimension,
+//                                          const std::vector<int>& nGlobal)
+//   : CDistribution(rank, nGlobal.size()), nGlobal_(nGlobal), nZoomBeginGlobal_(),
+//     nZoomSize_(), nZoomBegin_(), globalLocalIndexMap_(), 
+//     globalIndexEachDimension_(globalIndexEachDimension)
+// {
+//   createGlobalIndexFromIndex(globalIndexEachDimension, nGlobal);
+// }
 
 CDistributionServer::~CDistributionServer()
@@ -101,51 +101,51 @@
 }
 
-void CDistributionServer::createGlobalIndexFromIndex(const std::vector<CArray<int,1> >& globalIndexOnEachDimension,
-                                                     const std::vector<int>& nbGlobal)
-{
-  size_t idx = 0, ssize = 1;
-  for (int i = 0; i < globalIndexOnEachDimension.size(); ++i) ssize *= globalIndexOnEachDimension[i].numElements();
-
-  this->globalIndex_.resize(ssize);
-  size_t nbDim = nbGlobal.size();
-  std::vector<int> idxLoop(nbDim,0);
-  std::vector<int> currentIndex(nbDim);
-  int innerLoopSize = globalIndexOnEachDimension[0].numElements();
-
-  globalLocalIndexMap_.rehash(std::ceil(ssize/globalLocalIndexMap_.max_load_factor()));
-  while (idx<ssize)
-  {
-    for (int i = 0; i < nbDim-1; ++i)
-    {
-      if (idxLoop[i] == globalIndexOnEachDimension[i].numElements())
-      {
-        idxLoop[i] = 0;
-        ++idxLoop[i+1];
-      }
-    }
-
-    for (int i = 1; i < nbDim; ++i)
-      currentIndex[i] = globalIndexOnEachDimension[i](idxLoop[i]);
-
-    size_t mulDim, globalIndex;
-    for (int i = 0; i < innerLoopSize; ++i)
-    {
-      mulDim = 1;
-      globalIndex = globalIndexOnEachDimension[0](i);
-
-      for (int k = 0; k < nbDim; ++k)
-      {
-        mulDim *= nbGlobal[k];
-        globalIndex += (currentIndex[k])*mulDim;
-      }
-      globalLocalIndexMap_[globalIndex] = idx;
-      this->globalIndex_(idx) = globalIndex;
-
-      ++idx;
-    }
-    idxLoop[0] += innerLoopSize;
-  }
-
-}
+// void CDistributionServer::createGlobalIndexFromIndex(const std::vector<CArray<int,1> >& globalIndexOnEachDimension,
+//                                                      const std::vector<int>& nbGlobal)
+// {
+//   size_t idx = 0, ssize = 1;
+//   for (int i = 0; i < globalIndexOnEachDimension.size(); ++i) ssize *= globalIndexOnEachDimension[i].numElements();
+
+//   this->globalIndex_.resize(ssize);
+//   size_t nbDim = nbGlobal.size();
+//   std::vector<int> idxLoop(nbDim,0);
+//   std::vector<int> currentIndex(nbDim);
+//   int innerLoopSize = globalIndexOnEachDimension[0].numElements();
+
+//   globalLocalIndexMap_.rehash(std::ceil(ssize/globalLocalIndexMap_.max_load_factor()));
+//   while (idx<ssize)
+//   {
+//     for (int i = 0; i < nbDim-1; ++i)
+//     {
+//       if (idxLoop[i] == globalIndexOnEachDimension[i].numElements())
+//       {
+//         idxLoop[i] = 0;
+//         ++idxLoop[i+1];
+//       }
+//     }
+
+//     for (int i = 1; i < nbDim; ++i)
+//       currentIndex[i] = globalIndexOnEachDimension[i](idxLoop[i]);
+
+//     size_t mulDim, globalIndex;
+//     for (int i = 0; i < innerLoopSize; ++i)
+//     {
+//       mulDim = 1;
+//       globalIndex = globalIndexOnEachDimension[0](i);
+
+//       for (int k = 0; k < nbDim; ++k)
+//       {
+//         mulDim *= nbGlobal[k];
+//         globalIndex += (currentIndex[k])*mulDim;
+//       }
+//       globalLocalIndexMap_[globalIndex] = idx;
+//       this->globalIndex_(idx) = globalIndex;
+
+//       ++idx;
+//     }
+//     idxLoop[0] += innerLoopSize;
+//   }
+
+// }
 
 /*!
@@ -156,12 +156,16 @@
 CArray<size_t,1> CDistributionServer::computeLocalIndex(const CArray<size_t,1>& globalIndex)
 {
-  int ssize = globalIndex.numElements();
-  CArray<size_t,1> localIndex(ssize);
+  size_t ssize = globalIndex.numElements();
+  size_t localIndexSize = std::min(globalIndex_.numElements(), ssize);
+  CArray<size_t,1> localIndex(localIndexSize);
   GlobalLocalMap::const_iterator ite = globalLocalIndexMap_.end(), it;
-  for (int idx = 0; idx < ssize; ++idx)
+  for (int idx = 0, i = 0; idx < ssize; ++idx)
   {
     it = globalLocalIndexMap_.find(globalIndex(idx));
     if (ite != it)
+    {
       localIndex(idx) = it->second;
+      ++i;
+    }
   }
 
Index: /XIOS/dev/dev_olga/src/io/nc4_data_output.cpp
===================================================================
--- /XIOS/dev/dev_olga/src/io/nc4_data_output.cpp	(revision 1128)
+++ /XIOS/dev/dev_olga/src/io/nc4_data_output.cpp	(revision 1129)
@@ -50,4 +50,5 @@
       void CNc4DataOutput::writeDomain_(CDomain* domain)
       {
+        domain->computeWrittenIndex();
         if (domain->type == CDomain::type_attr::unstructured)
         {
@@ -59,4 +60,5 @@
         }
 
+        
          CContext* context = CContext::getCurrent() ;
          CContextServer* server=context->server ;
@@ -107,4 +109,46 @@
                              : latid;
 */
+
+         CArray<size_t, 1>& indexToWrite = domain->localIndexToWriteOnServer;
+         int nbWritten = indexToWrite.numElements();
+         CArray<double,1> writtenLat, writtenLon;
+         CArray<double,2> writtenBndsLat, writtenBndsLon;
+         CArray<double,1> writtenArea;
+
+         if (domain->hasLonLat)
+         {
+           writtenLat.resize(nbWritten);
+           writtenLon.resize(nbWritten);
+           for (int idx = 0; idx < nbWritten; ++idx)
+           {
+              writtenLat(idx) = domain->latvalue(indexToWrite(idx));
+              writtenLon(idx) = domain->lonvalue(indexToWrite(idx));
+           }
+         
+
+           if (domain->hasBounds)
+           {         
+             int nvertex = domain->nvertex, idx;
+             writtenBndsLat.resize(nvertex, nbWritten);
+             writtenBndsLon.resize(nvertex, nbWritten);
+             CArray<double,2>& boundslat = domain->bounds_latvalue;
+             CArray<double,2>& boundslon = domain->bounds_lonvalue;   
+             for (idx = 0; idx < nbWritten; ++idx)
+               for (int nv = 0; nv < nvertex; ++nv)
+               {
+                 writtenBndsLat(nv, idx) = boundslat(nv, int(indexToWrite(idx)));
+                 writtenBndsLon(nv, idx) = boundslon(nv, int(indexToWrite(idx)));
+               }
+           }
+         }
+
+         if (domain->hasArea)
+         {
+           writtenArea.resize(nbWritten);           
+           for (int idx = 0; idx < nbWritten; ++idx)
+           {
+              writtenArea(idx) = domain->areavalue(indexToWrite(idx));                      
+           }
+         }
 
          try
@@ -225,14 +269,31 @@
                  if (domain->hasLonLat)
                  {
+                   // CArray<size_t, 1>& indexToWrite = domain->localIndexToWriteOnServer;
+                   // int nbWritten = indexToWrite.numElements();
+                   // CArray<double,1> writtenLat(nbWritten), writtenLon(nbWritten);
+                   // for (int idx = 0; idx < nbWritten; ++idx)
+                   // {
+                   //    writtenLat(idx) = domain->latvalue(indexToWrite(idx));
+                   //    writtenLon(idx) = domain->lonvalue(indexToWrite(idx));
+                   // }
                    switch (domain->type)
                    {
-                     case CDomain::type_attr::curvilinear :
-                       SuperClassWriter::writeData(domain->latvalue, latid, isCollective, 0);
-                       SuperClassWriter::writeData(domain->lonvalue, lonid, isCollective, 0);
+                     case CDomain::type_attr::curvilinear :                       
+                        
+                       // SuperClassWriter::writeData(domain->latvalue, latid, isCollective, 0);
+                       // SuperClassWriter::writeData(domain->lonvalue, lonid, isCollective, 0);
+                       SuperClassWriter::writeData(writtenLat, latid, isCollective, 0);
+                       SuperClassWriter::writeData(writtenLon, lonid, isCollective, 0);
                        break;
                      case CDomain::type_attr::rectilinear :
-                       CArray<double,1> lat = domain->latvalue(Range(fromStart,toEnd,domain->zoom_ni)) ;
+//                        CArray<double,1> lat = domain->latvalue(Range(fromStart,toEnd,domain->zoom_ni)) ;
+//                        SuperClassWriter::writeData(CArray<double,1>(lat.copy()), latid, isCollective, 0);
+//                        CArray<double,1> lon = domain->lonvalue(Range(0,domain->zoom_ni-1)) ;
+// //                       CArray<double,1> lon = domain->lonvalue(Range(0,local_size_write[1]-1)) ;
+//                        SuperClassWriter::writeData(CArray<double,1>(lon.copy()), lonid, isCollective, 0);
+
+                       CArray<double,1> lat = writtenLat(Range(fromStart,toEnd,domain->zoom_ni)) ;
                        SuperClassWriter::writeData(CArray<double,1>(lat.copy()), latid, isCollective, 0);
-                       CArray<double,1> lon = domain->lonvalue(Range(0,domain->zoom_ni-1)) ;
+                       CArray<double,1> lon = writtenLon(Range(0,domain->zoom_ni-1)) ;
 //                       CArray<double,1> lon = domain->lonvalue(Range(0,local_size_write[1]-1)) ;
                        SuperClassWriter::writeData(CArray<double,1>(lon.copy()), lonid, isCollective, 0);
@@ -242,11 +303,32 @@
                    if (domain->hasBounds)
                    {
-                     SuperClassWriter::writeData(domain->bounds_lonvalue, bounds_lonid, isCollective, 0);
-                     SuperClassWriter::writeData(domain->bounds_latvalue, bounds_latid, isCollective, 0);
+                     // CArray<double,2> writtenBndsLat(nbWritten,2), writtenBndsLon(nbWritten,2);
+                     // for (int idx = 0; idx < nbWritten; ++idx)
+                     //   for (int nv = 0; nv < domain->nvertex; ++nv)
+                     //   {
+                     //     writtenBndsLat(idx) = domain->bounds_latvalue(nv, indexToWrite(idx));
+                     //     writtenBndsLon(idx) = domain->bounds_lonvalue(nv, indexToWrite(idx));
+                     //   }
+
+                     // SuperClassWriter::writeData(domain->bounds_lonvalue, bounds_lonid, isCollective, 0);
+                     // SuperClassWriter::writeData(domain->bounds_latvalue, bounds_latid, isCollective, 0);
+                     SuperClassWriter::writeData(writtenBndsLon, bounds_lonid, isCollective, 0);
+                     SuperClassWriter::writeData(writtenBndsLat, bounds_latid, isCollective, 0);
                    }
                  }
 
                  if (domain->hasArea)
-                   SuperClassWriter::writeData(domain->areavalue, areaId, isCollective, 0);
+                 {
+                   // CArray<size_t, 1>& indexToWrite = domain->localIndexToWriteOnServer;
+                   // int nbWritten = indexToWrite.numElements();
+                   // CArray<double,1> writtenArea(nbWritten);
+                   // for (int idx = 0; idx < nbWritten; ++idx)
+                   // {
+                   //    writtenArea(idx) = domain->areavalue(indexToWrite(idx));                      
+                   // }
+
+                   SuperClassWriter::writeData(writtenArea, areaId, isCollective, 0);
+                   // SuperClassWriter::writeData(domain->areavalue, areaId, isCollective, 0);
+                 }
 
                  SuperClassWriter::definition_start();
@@ -334,14 +416,12 @@
                        start[0]=domain->zoom_jbegin-domain->global_zoom_jbegin;
                        count[1]=domain->zoom_ni ; count[0]=domain->zoom_nj ;
-                       // start[1]= start_write[0];
-                       // start[0]= start_write[1];
-                       // count[1]= count_write[0];
-                       // count[0]= count_write[1];
                      }
 
                      if (domain->hasLonLat)
                      {
-                       SuperClassWriter::writeData(domain->latvalue, latid, isCollective, 0,&start,&count);
-                       SuperClassWriter::writeData(domain->lonvalue, lonid, isCollective, 0,&start,&count);
+                       // SuperClassWriter::writeData(domain->latvalue, latid, isCollective, 0,&start,&count);
+                       // SuperClassWriter::writeData(domain->lonvalue, lonid, isCollective, 0,&start,&count);
+                       SuperClassWriter::writeData(writtenLat, latid, isCollective, 0,&start,&count);
+                       SuperClassWriter::writeData(writtenLon, lonid, isCollective, 0,&start,&count);
                      }
                      break;
@@ -357,22 +437,22 @@
                          start[0]=0 ;
                          count[0]=0 ;
-                         SuperClassWriter::writeData(domain->latvalue, latid, isCollective, 0,&start,&count);
-                         SuperClassWriter::writeData(domain->lonvalue, lonid, isCollective, 0,&start,&count);
-
+                         // SuperClassWriter::writeData(domain->latvalue, latid, isCollective, 0,&start,&count);
+                         // SuperClassWriter::writeData(domain->lonvalue, lonid, isCollective, 0,&start,&count);
+
+                         SuperClassWriter::writeData(writtenLat, latid, isCollective, 0,&start,&count);
+                         SuperClassWriter::writeData(writtenLon, lonid, isCollective, 0,&start,&count);
                        }
                        else
-                       {
-                         // start[0]= start_write[1];
-                         // count[0]= count_write[1];
+                       { 
                          start[0]=domain->zoom_jbegin-domain->global_zoom_jbegin;
                          count[0]=domain->zoom_nj;
-                         CArray<double,1> lat = domain->latvalue(Range(fromStart,toEnd,domain->zoom_ni)) ;
+                         // CArray<double,1> lat = domain->latvalue(Range(fromStart,toEnd,domain->zoom_ni));
+                         CArray<double,1> lat = writtenLat(Range(fromStart,toEnd,domain->zoom_ni));
                          SuperClassWriter::writeData(CArray<double,1>(lat.copy()), latid, isCollective, 0,&start,&count);
 
-                         // start[0]= start_write[0];
-                         // count[0]= count_write[0];
                          start[0]=domain->zoom_ibegin-domain->global_zoom_ibegin;
                          count[0]=domain->zoom_ni;
-                         CArray<double,1> lon=domain->lonvalue(Range(0,domain->zoom_ni-1)) ;
+                         // CArray<double,1> lon=domain->lonvalue(Range(0,domain->zoom_ni-1));
+                         CArray<double,1> lon = writtenLon(Range(0,domain->zoom_ni-1));
                          SuperClassWriter::writeData(CArray<double,1>(lon.copy()), lonid, isCollective, 0,&start,&count);
                        }
@@ -401,6 +481,8 @@
                    }
 
-                 SuperClassWriter::writeData(domain->bounds_lonvalue, bounds_lonid, isCollective, 0, &start, &count);
-                 SuperClassWriter::writeData(domain->bounds_latvalue, bounds_latid, isCollective, 0, &start, &count);
+                 // SuperClassWriter::writeData(domain->bounds_lonvalue, bounds_lonid, isCollective, 0, &start, &count);
+                 // SuperClassWriter::writeData(domain->bounds_latvalue, bounds_latid, isCollective, 0, &start, &count);
+                   SuperClassWriter::writeData(writtenBndsLon, bounds_lonid, isCollective, 0, &start, &count);
+                   SuperClassWriter::writeData(writtenBndsLat, bounds_latid, isCollective, 0, &start, &count);
                  }
 
@@ -421,12 +503,8 @@
                      count[1] = domain->zoom_ni;
                      count[0] = domain->zoom_nj;
-
-                     // start[1]= start_write[0];
-                     // start[0]= start_write[1];
-                     // count[1]= count_write[0];
-                     // count[0]= count_write[1];
                    }
 
-                   SuperClassWriter::writeData(domain->areavalue, areaId, isCollective, 0, &start, &count);
+                   // SuperClassWriter::writeData(domain->areavalue, areaId, isCollective, 0, &start, &count);
+                   SuperClassWriter::writeData(writtenArea, areaId, isCollective, 0, &start, &count);
                  }
 
@@ -1056,12 +1134,6 @@
         axis->checkAttributes();
 
-        // int local_size_write  = axis->getLocalWriteSize();
-        // int global_size_write = axis->getGlobalWriteSize();
-        // int start_write = axis->getStartWriteIndex();
-        // int count_write = axis->getCountWriteIndex();
-
-
-        // if ((0 == local_size_write) && (MULTI_FILE == SuperClass::type)) return;
-
+        axis->computeWrittenIndex();
+       
         int zoom_size  = (MULTI_FILE == SuperClass::type) ? axis->zoom_n
                                                           : axis->global_zoom_n;
@@ -1114,10 +1186,16 @@
             SuperClassWriter::definition_end();
 
+            CArray<size_t, 1>& indexToWrite = axis->localIndexToWriteOnServer;
+            int nbWritten = indexToWrite.numElements();
+            CArray<double,1> axis_value(indexToWrite.numElements());
+            for (int i = 0; i < nbWritten; i++) axis_value(i) = axis->value(indexToWrite(i));
+            CArray<double,2> axis_bounds;
+
             switch (SuperClass::type)
             {
               case MULTI_FILE:
               {
-                CArray<double,1> axis_value(axis->zoom_n);
-                for (int i = 0; i < axis->zoom_n; i++) axis_value(i) = axis->value(i);
+                // CArray<double,1> axis_value(axis->zoom_n);
+                // for (int i = 0; i < axis->zoom_n; i++) axis_value(i) = axis->value(i);
                 SuperClassWriter::writeData(axis_value, axisid, isCollective, 0);
 
@@ -1131,6 +1209,6 @@
               case ONE_FILE:
               {
-                CArray<double,1> axis_value(axis->zoom_n);
-                axis_value = axis->value;
+                // CArray<double,1> axis_value(axis->zoom_n);
+                // axis_value = axis->value;
                 std::vector<StdSize> start(1), startBounds(2) ;
                 std::vector<StdSize> count(1), countBounds(2) ;
@@ -1142,5 +1220,13 @@
 
                 if (!axis->bounds.isEmpty())
+                {
+                  axis_bounds.resize(2, indexToWrite.numElements());
+                  for (int i = 0; i < nbWritten; ++i)
+                  {
+                    axis_bounds(0, i) = axis->bounds(0, int(indexToWrite(i)));
+                    axis_bounds(1, i) = axis->bounds(1, int(indexToWrite(i)));
+                  }
                   SuperClassWriter::writeData(axis->bounds, axisBoundsId, isCollective, 0, &startBounds, &countBounds);
+                }
 
                 SuperClassWriter::definition_start();
@@ -2371,5 +2457,5 @@
            msg.append(context->getId()); msg.append("\n");
            msg.append(e.what());
-           ERROR("CNc4DataOutput::writeFieldData_ (CField*  field)", << msg);
+               ERROR("CNc4DataOutput::writeFieldData_ (CField*  field)", << msg);
          }
       }
Index: /XIOS/dev/dev_olga/src/node/axis.cpp
===================================================================
--- /XIOS/dev/dev_olga/src/node/axis.cpp	(revision 1128)
+++ /XIOS/dev/dev_olga/src/node/axis.cpp	(revision 1129)
@@ -28,4 +28,5 @@
       , numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0)
       , transformationMap_(), hasValue(false), doZoomByIndex_(false)
+      , computedWrittenIndex_(false)
    {
    }
@@ -38,4 +39,5 @@
       , numberWrittenIndexes_(0), totalNumberWrittenIndexes_(0), offsetWrittenIndexes_(0)
       , transformationMap_(), hasValue(false), doZoomByIndex_(false)
+      , computedWrittenIndex_(false)
    {
    }
@@ -129,38 +131,4 @@
    {
      return offsetWrittenIndexes_;
-   }
-
-   /*!
-     Returns the start of indexes written by each server.
-     \return the start of indexes written by each server
-   */
-   int CAxis::getStartWriteIndex() const
-   {
-     return start_write_index_;
-   }
-
-   /*!
-     Returns the count of indexes written by each server.
-     \return the count of indexes written by each server
-   */
-   int CAxis::getCountWriteIndex() const
-   {
-     return count_write_index_;
-   }
-
-   /*!
-     Returns the local data written by each server.     
-   */
-   int CAxis::getLocalWriteSize() const
-   {
-     return local_write_size_;
-   }
-
-   /*!
-     Returns the global data written by all server.     
-   */
-   int CAxis::getGlobalWriteSize() const
-   {
-     return global_write_size_;
    }
 
@@ -454,7 +422,7 @@
      else
      {
-       sendDistributedAttributes();
-       sendDistributionAttribute(globalDim, orderPositionInGrid, distType);
+       sendDistributedAttributes();       
      }
+     sendDistributionAttribute(globalDim, orderPositionInGrid, distType);
   }
 
@@ -639,4 +607,39 @@
     }
   }
+
+   void CAxis::computeWrittenIndex()
+   {  
+      if (computedWrittenIndex_) return;
+      computedWrittenIndex_ = true;
+
+      CContext* context=CContext::getCurrent() ;
+      CContextClient* client = context->client; 
+
+      std::vector<int> nBegin(1), nSize(1), nBeginGlobal(1), nGlob(1);
+      nBegin[0]       = zoom_begin;
+      nSize[0]        = zoom_n;   
+      nBeginGlobal[0] = 0; 
+      nGlob[0]        = n_glo;
+      CDistributionServer srvDist(client->clientSize, nBegin, nSize, nBeginGlobal, nGlob); 
+      const CArray<size_t,1>& writtenGlobalIndex  = srvDist.getGlobalIndex();
+
+      size_t nbWritten = 0, indGlo;      
+      boost::unordered_map<size_t,size_t>::const_iterator itb = globalLocalIndexMap_.begin(),
+                                                          ite = globalLocalIndexMap_.end(), it;          
+      CArray<size_t,1>::const_iterator itSrvb = writtenGlobalIndex.begin(),
+                                       itSrve = writtenGlobalIndex.end(), itSrv;
+      localIndexToWriteOnServer.resize(writtenGlobalIndex.numElements());
+      for (itSrv = itSrvb; itSrv != itSrve; ++itSrv)
+      {
+        indGlo = *itSrv;
+        if (ite != globalLocalIndexMap_.find(indGlo))
+        {
+          localIndexToWriteOnServer(nbWritten) = globalLocalIndexMap_[indGlo];
+          ++nbWritten;
+        }                 
+      }
+
+   }
+
 
 
@@ -875,8 +878,10 @@
           CMessage& msg = msgs.back();
           msg << this->getId();
-          msg << index.getValue() << dataIndex << zoom_index.getValue() << mask.getValue();
+          msg << index.getValue() << dataIndex << mask.getValue();
+
+          msg << doZoomByIndex_;
+          if (doZoomByIndex_) msg << zoom_index.getValue();
           msg << hasValue;
           if (hasValue) msg << value.getValue();
-
           msg << hasBounds_;
           if (hasBounds_) msg << bounds.getValue();
@@ -913,8 +918,14 @@
     buffer >> tmp_data_index;
     data_index.reference(tmp_data_index);
-    buffer >> tmp_zoom_index;
-    zoom_index.reference(tmp_zoom_index);
     buffer >> tmp_mask;
     mask.reference(tmp_mask);
+
+    buffer >> doZoomByIndex_;
+    if (doZoomByIndex_)
+    {
+      buffer >> tmp_zoom_index;
+      zoom_index.reference(tmp_zoom_index);
+    }
+
     buffer >> hasValue;
     if (hasValue)
@@ -931,10 +942,7 @@
     }
 
-    {      
-      count_write_index_ = zoom_index.numElements();            
-      start_write_index_ = 0;
-      local_write_size_ = count_write_index_;
-      global_write_size_ = count_write_index_;
-    }
+    data_begin.setValue(0);
+    globalLocalIndexMap_.rehash(std::ceil(index.numElements()/globalLocalIndexMap_.max_load_factor()));
+    for (int idx = 0; idx < index.numElements(); ++idx) globalLocalIndexMap_[idx] = index(idx);
   }
 
@@ -1065,4 +1073,5 @@
     get(axisId)->recvDistributedAttributes(ranks, buffers);
   }
+
 
   void CAxis::recvDistributedAttributes(vector<int>& ranks, vector<CBufferIn*> buffers)
@@ -1099,6 +1108,7 @@
       nbData += vec_indi[idx].numElements();
     }
-    
+
     index.resize(nbData);
+    globalLocalIndexMap_.rehash(std::ceil(index.numElements()/globalLocalIndexMap_.max_load_factor()));
     CArray<int,1> nonCompressedData(nbData);    
     mask.resize(nbData);
@@ -1118,4 +1128,5 @@
       {
         index(nbData) = indi(n);
+        globalLocalIndexMap_[indi(n)] = nbData;
         nonCompressedData(nbData) = (0 <= dataIndi(n)) ? nbData : -1;
         mask(nbData) = maskIndi(n);
@@ -1149,4 +1160,5 @@
       }
     }
+    data_begin.setValue(0);
 
     if (doZoomByIndex_)
@@ -1170,14 +1182,4 @@
       }
     }
-
-
-    // {
-    //   CContextServer* server = CContext::getCurrent()->server;
-    //   count_write_index_ = zoom_index.numElements();      
-    //   MPI_Scan(&count_write_index_, &start_write_index_, 1, MPI_INT, MPI_SUM, server->intraComm);
-    //   global_write_size_ = start_write_index_;
-    //   start_write_index_ -= count_write_index_;
-    //   local_write_size_ = count_write_index_;      
-    // }
   }
 
Index: /XIOS/dev/dev_olga/src/node/axis.hpp
===================================================================
--- /XIOS/dev/dev_olga/src/node/axis.hpp	(revision 1128)
+++ /XIOS/dev/dev_olga/src/node/axis.hpp	(revision 1129)
@@ -78,9 +78,4 @@
          int getOffsetWrittenIndexes() const;
 
-         int getStartWriteIndex() const;
-         int getCountWriteIndex() const;
-         int getLocalWriteSize() const;
-         int getGlobalWriteSize() const;
-
          std::map<int, StdSize> getAttributesBufferSize();
 
@@ -119,4 +114,5 @@
          void checkEligibilityForCompressedOutput();
 
+         void computeWrittenIndex();
          bool hasTransformation();
          void solveInheritanceTransformation();
@@ -134,4 +130,5 @@
         CArray<int,1> globalDimGrid;
         int orderPosInGrid;
+        CArray<size_t,1> localIndexToWriteOnServer;
 
       private:
@@ -176,10 +173,6 @@
          bool hasBounds_;
 
-         int start_write_index_;
-         int count_write_index_;
-         int local_write_size_;
-         int global_write_size_;
-
          bool doZoomByIndex_;
+         bool computedWrittenIndex_;
 
        private:
Index: /XIOS/dev/dev_olga/src/node/context.cpp
===================================================================
--- /XIOS/dev/dev_olga/src/node/context.cpp	(revision 1128)
+++ /XIOS/dev/dev_olga/src/node/context.cpp	(revision 1129)
@@ -572,12 +572,11 @@
     postProcessingGlobalAttributes();
 
-    if (hasClient) sendPostProcessingGlobalAttributes();
-
-    // There are some processings that should be done after all of above. For example: check mask or index
+    if (hasClient) sendPostProcessingGlobalAttributes();   
+    
     this->buildFilterGraphOfEnabledFields();
     
-     if (hasClient && !hasServer)
+    if (hasClient && !hasServer)
     {
-      buildFilterGraphOfFieldsWithReadAccess();
+      buildFilterGraphOfFieldsWithReadAccess();      
     }
 
@@ -623,4 +622,5 @@
      {
        this->enabledFiles[i]->solveOnlyRefOfEnabledFields(false);
+       // this->enabledFiles[i]->solveAllReferenceEnabledField(false);
      }
 
@@ -663,17 +663,12 @@
        this->enabledFiles[i]->generateNewTransformationGridDest();
      }
-
-     for (int i = 0; i < size; ++i)
-     {
-       //this->enabledFiles[i]->checkGridOfEnabledFields();
-     }
-   }
-
-   void CContext::solveAllRefOfEnabledFields(bool sendToServer)
+   }
+
+   void CContext::solveAllRefOfEnabledFieldsAndTransform(bool sendToServer)
    {
      int size = this->enabledFiles.size();
      for (int i = 0; i < size; ++i)
      {
-       this->enabledFiles[i]->solveAllRefOfEnabledFields(sendToServer);
+       this->enabledFiles[i]->solveAllRefOfEnabledFieldsAndTransform(sendToServer);
      }
    }
@@ -1168,6 +1163,6 @@
 
       // Search and rebuild all reference object of enabled fields, and transform
-      this->solveAllEnabledFields();
-
+      // this->solveAllEnabledFields
+      this->solveAllRefOfEnabledFieldsAndTransform(false);
       // // Check grid and calculate its distribution
       // if (hasClient) checkGridEnabledFields();
Index: /XIOS/dev/dev_olga/src/node/context.hpp
===================================================================
--- /XIOS/dev/dev_olga/src/node/context.hpp	(revision 1128)
+++ /XIOS/dev/dev_olga/src/node/context.hpp	(revision 1129)
@@ -114,6 +114,5 @@
          void checkAxisDomainsGridsEligibilityForCompressedOutput();
          void prepareTimeseries(void);
-         void solveOnlyRefOfEnabledFields(bool sendToServer);
-         void solveAllRefOfEnabledFields(bool sendToServer);
+         void solveOnlyRefOfEnabledFields(bool sendToServer);         
          void buildFilterGraphOfEnabledFields();
          void startPrefetchingOfEnabledReadModeFiles();
@@ -125,4 +124,5 @@
          void postProcessingGlobalAttributes();         
 
+         void solveAllRefOfEnabledFieldsAndTransform(bool sendToServer);
          void solveAllEnabledFields();
          void checkGridEnabledFields();
Index: /XIOS/dev/dev_olga/src/node/domain.cpp
===================================================================
--- /XIOS/dev/dev_olga/src/node/domain.cpp	(revision 1128)
+++ /XIOS/dev/dev_olga/src/node/domain.cpp	(revision 1129)
@@ -26,14 +26,14 @@
 namespace xios {
 
-   /// ////////////////////// DÃ©finitions ////////////////////// ///
+   /// ////////////////////// Dfinitions ////////////////////// ///
 
    CDomain::CDomain(void)
       : CObjectTemplate<CDomain>(), CDomainAttributes()
-      , isChecked(false), relFiles(), isClientChecked(false), nbConnectedClients_(), indSrv_(), connectedServerRank_()
+      , isChecked(false), relFiles(), isClientChecked(false), nbConnectedClients_(), indSrv_(), connectedServerRank_(), connectedServerZoomRank_()
       , hasBounds(false), hasArea(false), isDistributed_(false), isCompressible_(false), isUnstructed_(false)
       , isClientAfterTransformationChecked(false), hasLonLat(false)
       , isRedistributed_(false), hasPole(false), doZoomByIndex_(false)
       , lonvalue(), latvalue(), bounds_lonvalue(), bounds_latvalue()
-      , globalLocalIndexMap_()
+      , globalLocalIndexMap_(), computedWrittenIndex_(false)
    {
    }
@@ -41,10 +41,10 @@
    CDomain::CDomain(const StdString & id)
       : CObjectTemplate<CDomain>(id), CDomainAttributes()
-      , isChecked(false), relFiles(), isClientChecked(false), nbConnectedClients_(), indSrv_(), connectedServerRank_()
+      , isChecked(false), relFiles(), isClientChecked(false), nbConnectedClients_(), indSrv_(), connectedServerRank_(), connectedServerZoomRank_()
       , hasBounds(false), hasArea(false), isDistributed_(false), isCompressible_(false), isUnstructed_(false)
       , isClientAfterTransformationChecked(false), hasLonLat(false)
       , isRedistributed_(false), hasPole(false), doZoomByIndex_(false)
       , lonvalue(), latvalue(), bounds_lonvalue(), bounds_latvalue()
-      , globalLocalIndexMap_()
+      , globalLocalIndexMap_(), computedWrittenIndex_(false)
    {
 	 }
@@ -1082,4 +1082,8 @@
    //----------------------------------------------------------------
 
+   /*
+     Fill in longitude and latitude value from clients (or models) into internal values lonvalue, latvalue which
+     will be used by XIOS.
+   */
    void CDomain::completeLonLatClient(void)
    {
@@ -1181,4 +1185,107 @@
    }
 
+   /*
+     Convert internal longitude latitude value used by XIOS to "lonvalue_*" which can be retrieved with Fortran interface
+   */
+   void CDomain::convertLonLatValue(void)
+   {
+     bool lonlatValueExisted = (0 != lonvalue.numElements()) || (0 != latvalue.numElements());
+     if (!lonvalue_2d.isEmpty() && lonlatValueExisted)
+     {
+       lonvalue_2d.resize(ni,nj);
+       latvalue_2d.resize(ni,nj);
+       if (hasBounds)
+       {
+         bounds_lon_2d.resize(nvertex, ni, nj);
+         bounds_lat_2d.resize(nvertex, ni, nj);
+       }
+
+       for (int j = 0; j < nj; ++j)
+       {
+         for (int i = 0; i < ni; ++i)
+         {
+           int k = j * ni + i;
+
+           lonvalue_2d(i,j) = lonvalue(k);
+           latvalue_2d(i,j) = latvalue(k);
+
+           if (hasBounds)
+           {
+             for (int n = 0; n < nvertex; ++n)
+             {
+               bounds_lon_2d(n,i,j) = bounds_lonvalue(n,k);
+               bounds_lat_2d(n,i,j) = bounds_latvalue(n,k);
+             }
+           }
+         }
+       }
+     }
+     else if (!lonvalue_1d.isEmpty()  && lonlatValueExisted)
+     {
+       if (type_attr::rectilinear == type)
+       {
+         if (ni == lonvalue_1d.numElements() && nj == latvalue_1d.numElements())
+         {
+           lonvalue.resize(ni * nj);
+           latvalue.resize(ni * nj);
+           if (hasBounds)
+           {
+             bounds_lonvalue.resize(nvertex, ni * nj);
+             bounds_latvalue.resize(nvertex, ni * nj);
+           }
+
+           for (int j = 0; j < nj; ++j)
+           {
+             for (int i = 0; i < ni; ++i)
+             {
+               int k = j * ni + i;
+
+               lonvalue(k) = lonvalue_1d(i);
+               latvalue(k) = latvalue_1d(j);
+
+               if (hasBounds)
+               {
+                 for (int n = 0; n < nvertex; ++n)
+                 {
+                   bounds_lonvalue(n,k) = bounds_lon_1d(n,i);
+                   bounds_latvalue(n,k) = bounds_lat_1d(n,j);
+                 }
+               }
+             }
+           }
+         }
+         else if (i_index.numElements() == lonvalue_1d.numElements() && j_index.numElements() == latvalue_1d.numElements()  && !lonlatValueExisted)
+         {
+           lonvalue.reference(lonvalue_1d);
+           latvalue.reference(latvalue_1d);
+            if (hasBounds)
+           {
+             bounds_lonvalue.reference(bounds_lon_1d);
+             bounds_latvalue.reference(bounds_lat_1d);
+           }
+         }
+         else
+           ERROR("CDomain::completeLonClient(void)",
+                 << "[ id = " << this->getId() << " , context = '" << CObjectFactory::GetCurrentContextId() << " ] "
+                 << "'lonvalue_1d' and 'latvalue_1d' does not have the same size as the local domain." << std::endl
+                 << "'lonvalue_1d' size is " << lonvalue_1d.numElements() 
+                 << " and 'latvalue_1d' size is " << latvalue_1d.numElements() << std::endl 
+                 << " They should be correspondingly " << ni.getValue() << " and "  << nj.getValue() << " or " << std::endl
+                 << i_index.numElements() << " and "  << j_index.numElements() << ".");
+       }
+       else if (type == type_attr::curvilinear || type == type_attr::unstructured  && !lonlatValueExisted)
+       {
+         lonvalue.reference(lonvalue_1d);
+         latvalue.reference(latvalue_1d);
+         if (hasBounds)
+         {
+           bounds_lonvalue.reference(bounds_lon_1d);
+           bounds_latvalue.reference(bounds_lat_1d);
+         }
+       }
+     }
+   }
+
+
    void CDomain::checkBounds(void)
    {
@@ -1395,5 +1502,5 @@
 
       if (context->hasClient && !context->hasServer)
-      { // CÃŽtÃ© client uniquement
+      { // Ct client uniquement
          this->checkMask();
          this->checkDomainData();
@@ -1402,5 +1509,5 @@
       }
       else
-      { // CÃŽtÃ© serveur uniquement
+      { // Ct serveur uniquement
       }
 
@@ -1435,5 +1542,5 @@
 
       if (context->hasClient)
-      { // CÃŽtÃ© client uniquement
+      { // Ct client uniquement
          this->checkMask();
          this->checkDomainData();
@@ -1443,5 +1550,5 @@
       }
       else
-      { // CÃŽtÃ© serveur uniquement
+      { // Ct serveur uniquement
       }
 
@@ -1549,5 +1656,4 @@
         for (i = 0; i < nbIndex; ++i)
           globalLocalIndexMap_[globalIndexDomain(i)] = i;
-
       }
 
@@ -1598,4 +1704,11 @@
           zoom_nj     = zoom_jend-zoom_jbegin+1;
       }
+
+      // if (globalLocalIndexZoomMap_.empty())
+      // {
+      //   int nbIndexZoom = globalIndexDomainZoom.numElements();
+      //   for (i = 0; i < nbIndex; ++i)
+      //     globalLocalIndexZoomMap_[globalIndexDomainZoom(i)] = i;
+      // }
 
 
@@ -1690,7 +1803,4 @@
       for (it = globalIndexDomainOnServer.begin(); it != ite; ++it) {
         connectedServerRank_.push_back(it->first);
-        // std::vector<size_t> vec = it->second;
-        // std::sort(vec.begin(), vec.end());
-        // indSrv_[it->first] = vec;
       }
 
@@ -1700,16 +1810,10 @@
       clientServerMap->computeServerIndexMapping(globalIndexDomainZoom);
       CClientServerMapping::GlobalIndexMap& globalIndexDomainZoomOnServer = clientServerMap->getGlobalIndexOnServer();
-//      indZoomSrv_.swap(globalIndexDomainZoomOnServer);
-      std::vector<int> connectedServerZoomRank; //(indZoomSrv_.size());
-//      for (it = indZoomSrv_.begin(); it != indZoomSrv_.end(); ++it)
-//        connectedServerZoomRank.push_back(it->first);
-      for (it = globalIndexDomainZoomOnServer.begin(); it != globalIndexDomainZoomOnServer.end(); ++it)
-      {
-        connectedServerZoomRank.push_back(it->first);
-        std::vector<size_t> vec = it->second;
-        std::sort(vec.begin(), vec.end());
-        indZoomSrv_[it->first] = vec;
-      }
-      nbConnectedClientsZoom_ = clientServerMap->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerZoomRank);
+      indZoomSrv_.swap(globalIndexDomainZoomOnServer);
+      
+     for (it = indZoomSrv_.begin(); it != indZoomSrv_.end(); ++it)
+       connectedServerZoomRank_.push_back(it->first);
+
+      nbConnectedClientsZoom_ = clientServerMap->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerZoomRank_);
 
       delete clientServerMap;
@@ -1721,4 +1825,37 @@
     return indSrv_;
   }
+
+   void CDomain::computeWrittenIndex()
+   {  
+      if (computedWrittenIndex_) return;
+      computedWrittenIndex_ = true;
+
+      CContext* context=CContext::getCurrent() ;
+      CContextClient* client = context->client; 
+
+      std::vector<int> nBegin(2), nSize(2), nBeginGlobal(2), nGlob(2);
+      nBegin[0]       = zoom_ibegin;  nBegin[1] = zoom_jbegin;
+      nSize[0]        = zoom_ni;      nSize[1]  = zoom_nj;
+      nBeginGlobal[0] = 0; nBeginGlobal[1] = 0;
+      nGlob[0]        = ni_glo;   nGlob[1] = nj_glo;
+      CDistributionServer srvDist(client->clientSize, nBegin, nSize, nBeginGlobal, nGlob); 
+      const CArray<size_t,1>& writtenGlobalIndex  = srvDist.getGlobalIndex();
+
+      size_t nbWritten = 0, indGlo;      
+      boost::unordered_map<size_t,size_t>::const_iterator itb = globalLocalIndexMap_.begin(),
+                                                          ite = globalLocalIndexMap_.end(), it;          
+      CArray<size_t,1>::const_iterator itSrvb = writtenGlobalIndex.begin(),
+                                       itSrve = writtenGlobalIndex.end(), itSrv;
+      localIndexToWriteOnServer.resize(writtenGlobalIndex.numElements());
+      for (itSrv = itSrvb; itSrv != itSrve; ++itSrv)
+      {
+        indGlo = *itSrv;
+        if (ite != globalLocalIndexMap_.find(indGlo))
+        {
+          localIndexToWriteOnServer(nbWritten) = globalLocalIndexMap_[indGlo];
+          ++nbWritten;
+        }                 
+      }
+   }
 
   /*!
@@ -1729,6 +1866,6 @@
   {
     sendDistributionAttributes();
-    sendIndex();
-    sendIndex();    
+    sendIndex();   
+    // sendIndexZoom(); 
     sendMask();
     sendLonLat();
@@ -1757,6 +1894,6 @@
       list<CArray<int,1> > list_indZoom, list_writtenInd, list_indGlob;
 
-      boost::unordered_map<int, vector<size_t> >::const_iterator itIndex, iteIndex, itZoom, iteZoom;
-      iteIndex = indSrv_.end(); iteZoom = indZoomSrv_.end();
+      boost::unordered_map<int, vector<size_t> >::const_iterator itIndex, iteIndex;
+      iteIndex = indSrv_.end();
       for (int k = 0; k < connectedServerRank_.size(); ++k)
       {
@@ -1766,22 +1903,11 @@
         if (iteIndex != itIndex)
           nbIndGlob = itIndex->second.size();
-        int nbIndZoom = 0;
-        itZoom = indZoomSrv_.find(rank);
-        if (iteZoom != itZoom)
-          nbIndZoom = itZoom->second.size();
-
-        list_indGlob.push_back(CArray<int,1>(nbIndGlob));
-        list_indZoom.push_back(CArray<int,1>(nbIndZoom));
-
-        CArray<int,1>& indZoom = list_indZoom.back();
+
+        list_indGlob.push_back(CArray<int,1>(nbIndGlob));        
+
         CArray<int,1>& indGlob = list_indGlob.back();
         for (n = 0; n < nbIndGlob; ++n)
         {
           indGlob(n) = static_cast<int>(itIndex->second[n]);
-        }
-
-        for (n = 0; n < nbIndZoom; ++n)
-        {
-          indZoom(n) = static_cast<int>(itZoom->second[n]);
         }
 
@@ -1789,9 +1915,5 @@
         list_msgsIndex.back() << this->getId() << (int)type; // enum ne fonctionne pour les message => ToFix
         list_msgsIndex.back() << isCurvilinear;
-        list_msgsIndex.back() << list_indGlob.back() << list_indZoom.back() << doZoomByIndex_; //list_indi.back() << list_indj.back();
-        if (!doZoomByIndex_) 
-        {
-          //list_msgsIndex.back() << zoom_ni.getValue() << zoom_ibegin.getValue() << zoom_nj.getValue() << zoom_jbegin.getValue();
-        }
+        list_msgsIndex.back() << list_indGlob.back(); //list_indi.back() << list_indj.back();
        
         // if (isCompressible_)
@@ -1811,4 +1933,52 @@
 
       client->sendEvent(eventIndex);
+    }
+  }
+
+  /*!
+    Send global index and zoom index from client to connected client(s)
+    zoom index can be smaller than global index
+  */
+  void CDomain::sendIndexZoom()
+  {
+    int ns, n, i, j, ind, nv, idx;
+    CContext* context = CContext::getCurrent();
+
+    // int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
+    int nbSrvPools = (context->hasServer) ? (context->hasClient ? context->clientPrimServer.size() : 0) : 1;
+    for (int p = 0; p < nbSrvPools; ++p)
+    {
+      CContextClient* client = (0 != context->clientPrimServer.size()) ? context->clientPrimServer[p] : context->client;
+      CEventClient eventIndexZoom(getType(), EVENT_ID_INDEX_ZOOM);
+
+      list<CMessage> list_msgsIndex;
+      list<CArray<int,1> > list_indZoom;
+
+      boost::unordered_map<int, vector<size_t> >::const_iterator itZoom, iteZoom;
+      iteZoom = indZoomSrv_.end();
+      for (int k = 0; k < connectedServerZoomRank_.size(); ++k)
+      {
+        int nbIndGlob = 0;
+        int rank = connectedServerZoomRank_[k];
+        int nbIndZoom = 0;
+        itZoom = indZoomSrv_.find(rank);
+        if (iteZoom != itZoom)
+          nbIndZoom = itZoom->second.size();
+        
+        list_indZoom.push_back(CArray<int,1>(nbIndZoom));
+        CArray<int,1>& indZoom = list_indZoom.back();
+        for (n = 0; n < nbIndZoom; ++n)
+        {
+          indZoom(n) = static_cast<int>(itZoom->second[n]);
+        }
+
+        list_msgsIndex.push_back(CMessage());
+        list_msgsIndex.back() << this->getId(); // enum ne fonctionne pour les message => ToFix        
+        list_msgsIndex.back() << list_indZoom.back() << doZoomByIndex_; //list_indi.back() << list_indj.back      
+
+        eventIndexZoom.push(rank, nbConnectedClientsZoom_[rank], list_msgsIndex.back());
+      }
+
+      client->sendEvent(eventIndexZoom);
     }
   }
@@ -2036,10 +2206,19 @@
         list_msgsLat.push_back(CMessage());
 
-        list_msgsLon.back() << this->getId() << hasLonLat << list_lon.back() << hasBounds;
-        list_msgsLat.back() << this->getId() << hasLonLat << list_lat.back() << hasBounds;
-
+        list_msgsLon.back() << this->getId() << hasLonLat;
+        if (hasLonLat) 
+          list_msgsLon.back() << list_lon.back();
+        list_msgsLon.back()  << hasBounds;
         if (hasBounds)
         {
           list_msgsLon.back() << list_boundslon.back();
+        }
+
+        list_msgsLat.back() << this->getId() << hasLonLat;
+        if (hasLonLat)
+          list_msgsLat.back() << list_lat.back();
+        list_msgsLat.back() << hasBounds;
+        if (hasBounds)
+        {          
           list_msgsLat.back() << list_boundslat.back();
         }
@@ -2076,13 +2255,24 @@
 
       int nbIndex = i_index.numElements();
+      int niByIndex = max(i_index) - min(i_index) + 1;
+      int njByIndex = max(j_index) - min(j_index) + 1; 
+      int dataIindexBound = (1 == data_dim) ? (niByIndex * njByIndex) : niByIndex;
+      int dataJindexBound = (1 == data_dim) ? (niByIndex * njByIndex) : njByIndex;
+
+      
       CArray<int,1> dataIIndex(nbIndex), dataJIndex(nbIndex);
-      dataIIndex = -1; dataJIndex = -1, ind = 0;
+      dataIIndex = -1; 
+      dataJIndex = -1;
+      ind = 0;
+
       for (idx = 0; idx < data_i_index.numElements(); ++idx)
       {
-        if ((0 <= data_i_index(idx)) && (data_i_index(idx) < ni) && (ind < nbIndex))
-        {
-          dataIIndex(ind) = data_i_index(idx);
-          dataJIndex(ind) = data_j_index(idx);
-          ++ind;
+        int dataIidx = data_i_index(idx) + data_ibegin;
+        int dataJidx = data_j_index(idx) + data_jbegin;
+        if ((0 <= dataIidx) && (dataIidx < dataIindexBound) &&
+            (0 <= dataJidx) && (dataJidx < dataJindexBound))
+        {
+          dataIIndex((1 == data_dim) ? dataIidx : dataJidx * ni + dataIidx) = 1; //i_index(dataIidx);//dataIidx;
+          dataJIndex((1 == data_dim) ? dataIidx : dataJidx * ni + dataIidx) = 1; //j_index(dataJidx);//          
         }
       }
@@ -2131,4 +2321,8 @@
         case EVENT_ID_INDEX:
           recvIndex(event);
+          return true;
+          break;
+        case EVENT_ID_INDEX_ZOOM:
+          recvIndexZoom(event);
           return true;
           break;
@@ -2198,7 +2392,5 @@
   {
     int nbReceived = rankBuffers.size(), i, ind, index, type_int;
-    recvClientRanks_.resize(nbReceived);
-    vector<CArray<int,1> > recvZoomInd(nbReceived);
-    int ni_zoom_tmp, ibegin_zoom_tmp, nj_zoom_tmp, jbegin_zoom_tmp;
+    recvClientRanks_.resize(nbReceived);        
 
     std::map<int, CBufferIn*>::iterator it = rankBuffers.begin(), ite = rankBuffers.end();
@@ -2208,9 +2400,5 @@
        recvClientRanks_[ind] = it->first;
        CBufferIn& buffer = *(it->second);
-       buffer >> type_int >> isCurvilinear >> indGlob_[it->first] >> recvZoomInd[ind] >> doZoomByIndex_; 
-       if (!doZoomByIndex_)
-       {
-        //buffer >> ni_zoom_tmp >> ibegin_zoom_tmp >> nj_zoom_tmp >> jbegin_zoom_tmp;
-       }
+       buffer >> type_int >> isCurvilinear >> indGlob_[it->first]; 
        type.setValue((type_attr::t_enum)type_int); // probleme des type enum avec les buffers : ToFix
     }
@@ -2224,4 +2412,5 @@
     j_index.resize(nbIndGlob);
 
+    globalLocalIndexMap_.rehash(std::ceil(nbIndGlob/globalLocalIndexMap_.max_load_factor()));
     nbIndGlob = 0;
     for (i = 0; i < nbReceived; ++i)
@@ -2233,61 +2422,8 @@
          i_index(nbIndGlob) = index % ni_glo;
          j_index(nbIndGlob) = index / ni_glo;
+         globalLocalIndexMap_[index] = nbIndGlob;  
          ++nbIndGlob;
       } 
-    }
-
-    int nbZoomInd = 0;
-    for (i = 0; i < nbReceived; ++i)
-    {
-      nbZoomInd += recvZoomInd[i].numElements();
-    }
-
-    if (doZoomByIndex_)
-    {
-      zoom_i_index.resize(nbZoomInd);
-      zoom_j_index.resize(nbZoomInd);
-      
-      nbZoomInd = 0;
-      for (i = 0; i < nbReceived; ++i)
-      {
-        CArray<int,1>& tmp = recvZoomInd[i];
-        for (ind = 0; ind < tmp.numElements(); ++ind)
-        {
-           index = tmp(ind);
-           zoom_i_index(nbZoomInd) = index % ni_glo;
-           zoom_j_index(nbZoomInd) = index / ni_glo;
-           ++nbZoomInd;
-        } 
-      }      
-    }
-    else 
-    {
-      // zoom_ni.setValue(ni_zoom_tmp);
-      // zoom_ibegin.setValue(ibegin_zoom_tmp);
-      // zoom_nj.setValue(nj_zoom_tmp);
-      // zoom_jbegin.setValue(jbegin_zoom_tmp);
-      // int nbZoom = ni_zoom_tmp * nj_zoom_tmp;
-      // zoom_i_index.resize(nbZoom);
-      // zoom_j_index.resize(nbZoom);
-      // nbZoom = 0;
-      // for (int j = 0; j < nj_zoom_tmp; ++j) 
-      //   for (int i = 0; i < ni_zoom_tmp; ++i)
-      //   {
-      //     zoom_i_index(nbZoom) = ibegin_zoom_tmp + i;
-      //     zoom_j_index(nbZoom) = jbegin_zoom_tmp + j;
-      //     ++nbZoom;
-      //   }
-    }
-
-    globalLocalIndexMap_.rehash(std::ceil(nbIndGlob/globalLocalIndexMap_.max_load_factor()));
-    nbIndGlob = 0;
-    for (int j = 0; j < nj; ++j) 
-      for (int i = 0; i < ni; ++i)
-      {
-        globalLocalIndexMap_[(i + ibegin) + (j + jbegin) * ni_glo] = nbIndGlob;
-        ++nbIndGlob;
-      }
-
-
+    }   
     
     // {
@@ -2368,4 +2504,80 @@
 
   /*!
+    Receive index event from clients(s)
+    \param[in] event event contain info about rank and associated index
+  */
+  void CDomain::recvIndexZoom(CEventServer& event)
+  {
+    string domainId;
+    std::map<int, CBufferIn*> rankBuffers;
+
+    list<CEventServer::SSubEvent>::iterator it;
+    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
+    {      
+      CBufferIn* buffer = it->buffer;
+      *buffer >> domainId;
+      rankBuffers[it->rank] = buffer;        
+    }
+    get(domainId)->recvIndexZoom(rankBuffers);
+  }
+
+  /*!
+    Receive index information from client(s)
+    \param[in] rankBuffers rank of sending client and the corresponding receive buffer  
+  */
+  void CDomain::recvIndexZoom(std::map<int, CBufferIn*>& rankBuffers)
+  {
+    int nbReceived = rankBuffers.size(), i, ind, index, type_int;
+    recvClientZoomRanks_.resize(nbReceived);    
+    int ni_zoom_tmp, ibegin_zoom_tmp, nj_zoom_tmp, jbegin_zoom_tmp;
+
+    std::map<int, CBufferIn*>::iterator it = rankBuffers.begin(), ite = rankBuffers.end();
+    ind = 0;
+    for (ind = 0; it != ite; ++it, ++ind)
+    {       
+       recvClientZoomRanks_[ind] = it->first;
+       CBufferIn& buffer = *(it->second);
+       buffer >> indGlobZoom_[it->first] >> doZoomByIndex_;        
+    }
+
+    int nbZoomInd = 0;
+    for (i = 0; i < nbReceived; ++i)
+    {
+      nbZoomInd += indGlobZoom_[recvClientZoomRanks_[i]].numElements();
+    }
+
+    if (doZoomByIndex_)
+    {
+      zoom_i_index.resize(nbZoomInd);
+      zoom_j_index.resize(nbZoomInd);
+      
+      nbZoomInd = 0;
+      for (i = 0; i < nbReceived; ++i)
+      {
+        CArray<int,1>& tmp = indGlobZoom_[recvClientRanks_[i]];
+        for (ind = 0; ind < tmp.numElements(); ++ind)
+        {
+           index = tmp(ind);
+           zoom_i_index(nbZoomInd) = index % ni_glo;
+           zoom_j_index(nbZoomInd) = index / ni_glo;
+           ++nbZoomInd;
+        } 
+      }      
+    }
+    else 
+    {
+    }
+
+    // globalLocalIndexZoomMap_.rehash(std::ceil(nbZoomInd/globalLocalIndexZoomMap_.max_load_factor()));
+    // nbZoomInd = 0;
+    // for (int j = 0; j < zoom_nj; ++j) 
+    //   for (int i = 0; i < zoom_ni; ++i)
+    //   {
+    //     globalLocalIndexZoomMap_[(i + zoom_ibegin) + (j + zoom_jbegin) * ni_glo] = nbZoomInd;
+    //     ++nbZoomInd;
+    //   }
+  }
+
+  /*!
     Receive attributes event from clients(s)
     \param[in] event event contain info about rank and associated attributes
@@ -2506,5 +2718,5 @@
   void CDomain::recvLon(std::map<int, CBufferIn*>& rankBuffers)
   {
-    int nbReceived = rankBuffers.size(), i, ind, index, iindex, jindex;
+    int nbReceived = rankBuffers.size(), i, ind, index, iindex, jindex, lInd;
     if (nbReceived != recvClientRanks_.size())
       ERROR("void CDomain::recvLon(std::map<int, CBufferIn*>& rankBuffers)",
@@ -2519,5 +2731,6 @@
       CBufferIn& buffer = *(rankBuffers[rank]);
       buffer >> hasLonLat;
-      buffer >> recvLonValue[i];
+      if (hasLonLat)
+        buffer >> recvLonValue[i];
       buffer >> hasBounds;
       if (hasBounds)
@@ -2525,29 +2738,69 @@
     }
 
-    lonvalue.resize(zoom_ni*zoom_nj);
-    lonvalue = 0;
-
-    if (hasBounds)
+    if (hasLonLat)
     {
-      bounds_lonvalue.resize(nvertex,zoom_ni*zoom_nj);
-      bounds_lonvalue = 0.;
-    }
+      int nbLonInd = 0;
+      for (i = 0; i < nbReceived; ++i)
+      {
+        nbLonInd += recvLonValue[i].numElements();
+      }
     
-    for (i = 0; i < nbReceived; ++i)
-    {
-      int rank = recvClientRanks_[i];
-      CArray<int,1> &indi = indGlob_[rank], &indj = indGlob_[rank];      
-      for (ind = 0; ind < indi.numElements(); ++ind)
-      {
-         iindex = indi(ind) % ni_glo; jindex = indj(ind) / ni_glo;
-         index = (iindex - zoom_ibegin) + (jindex - zoom_jbegin) * zoom_ni;
-         lonvalue(index) = recvLonValue[i](ind);
-         if (hasBounds)
-         {          
-          for (int nv = 0; nv < nvertex; ++nv)
-            bounds_lonvalue(nv, index) = recvBoundsLonValue[i](nv, ind);
-         }         
-      }
-    }
+      if (nbLonInd != globalLocalIndexMap_.size())
+        info (0) << "Something wrong with longitude index "<< std::endl;
+
+      lonvalue.resize(nbLonInd);
+      if (hasBounds)
+      {
+        bounds_lonvalue.resize(nvertex,nbLonInd);
+        bounds_lonvalue = 0.;
+      }
+
+      nbLonInd = 0;
+      for (i = 0; i < nbReceived; ++i)
+      {
+        CArray<int,1>& tmpInd = indGlob_[recvClientRanks_[i]];
+        CArray<double,1>& tmp = recvLonValue[i];
+        for (ind = 0; ind < tmp.numElements(); ++ind)
+        {
+          lInd = globalLocalIndexMap_[size_t(tmpInd(ind))];
+          lonvalue(lInd) = tmp(ind); 
+           if (hasBounds)
+           {          
+            for (int nv = 0; nv < nvertex; ++nv)
+              bounds_lonvalue(nv, lInd) = recvBoundsLonValue[i](nv, ind);
+           }                  
+        }
+      }       
+    }
+
+
+
+    // lonvalue.resize(zoom_ni*zoom_nj);
+    // lonvalue = 0;
+
+    // if (hasBounds)
+    // {
+    //   bounds_lonvalue.resize(nvertex,zoom_ni*zoom_nj);
+    //   bounds_lonvalue = 0.;
+    // }
+    
+    // if (0 == lonvalue.numElements()) return;
+
+    // for (i = 0; i < nbReceived; ++i)
+    // {
+    //   int rank = recvClientRanks_[i];
+    //   CArray<int,1> &indi = indGlob_[rank], &indj = indGlob_[rank];      
+    //   for (ind = 0; ind < indi.numElements(); ++ind)
+    //   {
+    //      iindex = indi(ind) % ni_glo; jindex = indj(ind) / ni_glo;
+    //      index = (iindex - zoom_ibegin) + (jindex - zoom_jbegin) * zoom_ni;
+    //      lonvalue(index) = recvLonValue[i](ind);
+    //      if (hasBounds)
+    //      {          
+    //       for (int nv = 0; nv < nvertex; ++nv)
+    //         bounds_lonvalue(nv, index) = recvBoundsLonValue[i](nv, ind);
+    //      }         
+    //   }
+    // }
   }
 
@@ -2577,5 +2830,5 @@
   void CDomain::recvLat(std::map<int, CBufferIn*>& rankBuffers)
   {
-    int nbReceived = rankBuffers.size(), i, ind, index, iindex, jindex;
+    int nbReceived = rankBuffers.size(), i, ind, index, iindex, jindex, lInd;
     if (nbReceived != recvClientRanks_.size())
       ERROR("void CDomain::recvLat(std::map<int, CBufferIn*>& rankBuffers)",
@@ -2590,5 +2843,6 @@
       CBufferIn& buffer = *(rankBuffers[rank]);
       buffer >> hasLonLat;
-      buffer >> recvLatValue[i];
+      if (hasLonLat)
+        buffer >> recvLatValue[i];
       buffer >> hasBounds;
       if (hasBounds)
@@ -2596,30 +2850,40 @@
     }
 
-    latvalue.resize(zoom_ni*zoom_nj);
-    latvalue = 0;
-
-    if (hasBounds)
+    if (hasLonLat)
     {
-      bounds_latvalue.resize(nvertex,zoom_ni*zoom_nj);
-      bounds_latvalue = 0. ;
-    }
+      int nbLatInd = 0;
+      for (i = 0; i < nbReceived; ++i)
+      {
+        nbLatInd += recvLatValue[i].numElements();
+      }
     
-    for (i = 0; i < nbReceived; ++i)
-    {
-      int rank = recvClientRanks_[i];
-      CArray<int,1> &indi = indGlob_[rank], &indj = indGlob_[rank];
-      CArray<double,1>& lat = recvLatValue[i];
-      for (ind = 0; ind < indi.numElements(); ++ind)
-      {
-         iindex = indi(ind) % ni_glo; jindex = indj(ind) / ni_glo;
-         index = (iindex - zoom_ibegin) + (jindex - zoom_jbegin) * zoom_ni;
-         latvalue(index) = lat(ind);
-         if (hasBounds)
-         {
-          CArray<double,2>& boundslat = recvBoundsLatValue[i];
-          for (int nv = 0; nv < nvertex; ++nv)
-            bounds_latvalue(nv, index) = boundslat(nv, ind);
-         }         
-      }
+      if (nbLatInd != globalLocalIndexMap_.size())
+        info (0) << "Something wrong with latitude index "<< std::endl;
+
+      latvalue.resize(nbLatInd);
+      if (hasBounds)
+      {
+        bounds_latvalue.resize(nvertex,nbLatInd);
+        bounds_latvalue = 0. ;
+      }
+
+      nbLatInd = 0;
+      for (i = 0; i < nbReceived; ++i)
+      {
+        CArray<int,1>& tmpInd = indGlob_[recvClientRanks_[i]];
+        CArray<double,1>& tmp = recvLatValue[i];
+        for (ind = 0; ind < tmp.numElements(); ++ind)
+        {
+          lInd = globalLocalIndexMap_[size_t(tmpInd(ind))];
+          latvalue(lInd) = tmp(ind);    
+           if (hasBounds)
+           {
+            CArray<double,2>& boundslat = recvBoundsLatValue[i];
+            for (int nv = 0; nv < nvertex; ++nv)
+              bounds_latvalue(nv, lInd) = boundslat(nv, ind);
+           }   
+          ++nbLatInd;
+        }
+      }       
     }
   }
@@ -2651,5 +2915,5 @@
   void CDomain::recvArea(std::map<int, CBufferIn*>& rankBuffers)
   {
-    int nbReceived = rankBuffers.size(), i, ind, index;
+    int nbReceived = rankBuffers.size(), i, ind, index, lInd;
     if (nbReceived != recvClientRanks_.size())
       ERROR("void CDomain::recvArea(std::map<int, CBufferIn*>& rankBuffers)",
@@ -2669,22 +2933,26 @@
     int nbAreaInd = 0;
     for (i = 0; i < nbReceived; ++i)
-    {
-      if (hasArea)
-        nbAreaInd += recvAreaValue[i].numElements();
+    {      
+      nbAreaInd += recvAreaValue[i].numElements();
     }
   
-    areavalue.resize(nbAreaInd);
-    nbAreaInd = 0;
+    if (nbAreaInd != globalLocalIndexMap_.size())
+      info (0) << "Something wrong with latitude index "<< std::endl;
+
     if (hasArea)
     {
+      areavalue.resize(nbAreaInd);
+      nbAreaInd = 0;      
       for (i = 0; i < nbReceived; ++i)
       {
+        CArray<int,1>& tmpInd = indGlob_[recvClientRanks_[i]];
         CArray<double,1>& tmp = recvAreaValue[i];
         for (ind = 0; ind < tmp.numElements(); ++ind)
         {
-          area(nbAreaInd) = tmp(ind);      
-          ++nbAreaInd;
-        }
-      }
+          lInd = globalLocalIndexMap_[size_t(tmpInd(ind))];
+          areavalue(lInd) = tmp(ind);          
+        }
+      }
+      
     }
   }
@@ -2728,7 +2996,7 @@
   void CDomain::recvDataIndex(std::map<int, CBufferIn*>& rankBuffers)
   {
-    int nbReceived = rankBuffers.size(), i, ind, index, indexI, type_int;    
+    int nbReceived = rankBuffers.size(), i, ind, index, indexI, indexJ, type_int, lInd;    
     if (nbReceived != recvClientRanks_.size())
-      ERROR("void CDomain::recvLat(std::map<int, CBufferIn*>& rankBuffers)",
+      ERROR("void CDomain::recvDataIndex(std::map<int, CBufferIn*>& rankBuffers)",
            << "The number of sending clients is not correct."
            << "Expected number: " << recvClientRanks_.size() << " but received " << nbReceived);
@@ -2743,36 +3011,53 @@
     }
    
-    int nbCompressedData = 0; 
+    int nbIndex = i_index.numElements();
+    CArray<int,1> dataIIndex(nbIndex), dataJIndex(nbIndex);
+    dataIIndex = -1; dataJIndex = -1;
+
+    nbIndex = 0;
     for (i = 0; i < nbReceived; ++i)
+    {      
+      CArray<int,1>& tmpInd = indGlob_[recvClientRanks_[i]];
+      CArray<int,1>& tmpI = recvDataIIndex[i];    
+      CArray<int,1>& tmpJ = recvDataJIndex[i];     
+      if ((tmpI.numElements() != tmpInd.numElements()) || (tmpJ.numElements() != tmpInd.numElements()))
+          ERROR("void CDomain::recvDataIndex(std::map<int, CBufferIn*>& rankBuffers)",
+             << "The number of global received index is not coherent with the number of received data index."
+             << "Expected number of global index: " << tmpI.numElements() << " but received " << tmpInd.numElements());
+
+      for (ind = 0; ind < tmpI.numElements(); ++ind)
+      {
+         lInd = globalLocalIndexMap_[size_t(tmpInd(ind))];
+         dataIIndex(lInd) = tmpI(ind);
+         dataJIndex(lInd) = tmpJ(ind);         
+      } 
+    }
+
+    int nbCompressedData = 0;  
+    for (ind = 0; ind < dataIIndex.numElements(); ++ind)
     {
-      CArray<int,1>& tmp = recvDataIIndex[i];
-      for (ind = 0; ind < tmp.numElements(); ++ind)
-      {
-         index = tmp(ind);
-         if (0 <= index)
-           ++nbCompressedData;
-      }        
-    }
-
+       indexI = dataIIndex(ind); indexJ = dataJIndex(ind);
+       if ((0 <= indexI) && (0 <= indexJ))
+         ++nbCompressedData;
+    }        
+  
     data_i_index.resize(nbCompressedData);
     data_j_index.resize(nbCompressedData);
 
-    nbCompressedData = 0;
-    for (i = 0; i < nbReceived; ++i)
+    nbCompressedData = 0;  
+    for (ind = 0; ind < dataIIndex.numElements(); ++ind)
     {
-      CArray<int,1>& tmpI = recvDataIIndex[i];      
-      CArray<int,1>& tmpIndex = indGlob_[recvClientRanks_[i]];
-      for (ind = 0; ind < tmpI.numElements(); ++ind)
-      {
-         indexI = tmpI(ind);
-         index  = tmpIndex(ind);
-         if (0 <= indexI)
-         {
-          data_i_index(nbCompressedData) = index % ni_glo - ibegin;
-          data_j_index(nbCompressedData) = index / ni_glo - jbegin;
-          ++nbCompressedData;
-         }         
-      } 
-    }
+       indexI = dataIIndex(ind); indexJ = dataJIndex(ind);
+       if ((0 <= indexI) && (0 <= indexJ))
+       {
+          data_i_index(nbCompressedData) = (1 == data_dim) ? ind : i_index(ind) - i_index(0);
+          data_j_index(nbCompressedData) = (1 == data_dim) ? 0   : j_index(ind) - j_index(0);  
+         ++nbCompressedData;
+       }
+    }
+
+    // Reset data_ibegin, data_jbegin
+    data_ibegin.setValue(0);
+    data_jbegin.setValue(0);
   }
 
Index: /XIOS/dev/dev_olga/src/node/domain.hpp
===================================================================
--- /XIOS/dev/dev_olga/src/node/domain.hpp	(revision 1128)
+++ /XIOS/dev/dev_olga/src/node/domain.hpp	(revision 1129)
@@ -51,5 +51,6 @@
            EVENT_ID_INDEX, EVENT_ID_LON, EVENT_ID_LAT, 
            EVENT_ID_AREA, EVENT_ID_MASK,
-           EVENT_ID_DATA_INDEX, EVENT_ID_SERVER_ATTRIBUT
+           EVENT_ID_DATA_INDEX, EVENT_ID_SERVER_ATTRIBUT,
+           EVENT_ID_INDEX_ZOOM
          } ;
 
@@ -106,4 +107,5 @@
 
          std::map<int, StdSize> getAttributesBufferSize();
+         CArray<size_t,1> localIndexToWriteOnServer;
 
          bool isEmpty(void) const;
@@ -127,4 +129,5 @@
          void completeLonLatClient(void);         
          void computeConnectedClients();
+         void computeWrittenIndex();
 
          void AllgatherRectilinearLonLat(CArray<double,1>& lon, CArray<double,1>& lat,
@@ -138,4 +141,5 @@
          static void recvDistributionAttributes(CEventServer& event);
          static void recvIndex(CEventServer& event);
+         static void recvIndexZoom(CEventServer& event);
          static void recvMask(CEventServer& event);
          static void recvZoom(CEventServer& event);
@@ -144,7 +148,7 @@
          static void recvArea(CEventServer& event);
          static void recvDataIndex(CEventServer& event);
-         void recvDistributionAttributes(CBufferIn& buffer);         
-         void recvZoom(std::vector<int>& rank, std::vector<CBufferIn*>& buffers);
+         void recvDistributionAttributes(CBufferIn& buffer);                  
          void recvIndex(std::map<int, CBufferIn*>& rankBuffers);
+         void recvIndexZoom(std::map<int, CBufferIn*>& rankBuffers);
          void recvMask(std::map<int, CBufferIn*>& rankBuffers);
          void recvLon(std::map<int, CBufferIn*>& rankBuffers);
@@ -192,6 +196,8 @@
          void sendArea();
          void sendLonLat();
-         void sendZoom();
+         void sendIndexZoom();
          void sendDataIndex();
+
+         void convertLonLatValue();
 
        private:         
@@ -202,9 +208,9 @@
 
          bool doZoomByIndex_;
-         bool isChecked;
+         bool isChecked, computedWrittenIndex_;
          std::set<StdString> relFiles, relFilesCompressed;
          bool isClientChecked; // Verify whether all attributes of domain on the client side are good
          bool isClientAfterTransformationChecked;
-         std::map<int, CArray<int,1> > indiSrv, indjSrv, indGlob_;
+         std::map<int, CArray<int,1> > indiSrv, indjSrv, indGlob_, indGlobZoom_;
          std::map<int,int> nbConnectedClients_, nbConnectedClientsZoom_; // Mapping of number of communicating client to a server
 
@@ -213,7 +219,7 @@
          std::map<int, vector<int> > indWrittenSrv_; // Global written index of each client sent to server
          std::vector<int> indexesToWrite;
-         std::vector<int> recvClientRanks_;
+         std::vector<int> recvClientRanks_, recvClientZoomRanks_;
          int numberWrittenIndexes_, totalNumberWrittenIndexes_, offsetWrittenIndexes_;
-         std::vector<int> connectedServerRank_;
+         std::vector<int> connectedServerRank_, connectedServerZoomRank_;
          bool isDistributed_;
          //! True if and only if the data defined on the domain can be outputted in a compressed way
@@ -222,5 +228,5 @@
          TransMapTypes transformationMap_;         
          bool isUnstructed_;
-         boost::unordered_map<size_t,size_t> globalLocalIndexMap_;
+         boost::unordered_map<size_t,size_t> globalLocalIndexMap_, globalLocalIndexZoomMap_;
        
        private:
Index: /XIOS/dev/dev_olga/src/node/field.cpp
===================================================================
--- /XIOS/dev/dev_olga/src/node/field.cpp	(revision 1128)
+++ /XIOS/dev/dev_olga/src/node/field.cpp	(revision 1129)
@@ -35,5 +35,6 @@
       , nstep(0), nstepMax(0)
       , hasOutputFile(false)
-      , domAxisScalarIds_(vector<StdString>(3,"")), areAllReferenceSolved(false), isReferenceSolved(false)
+      , domAxisScalarIds_(vector<StdString>(3,""))
+      , areAllReferenceSolved(false), isReferenceSolved(false), isReferenceSolvedAndTransformed(false)
       , useCompressedOutput(false)
       , wasDataAlreadyReceivedFromServer(false)
@@ -46,5 +47,6 @@
       , nstep(0), nstepMax(0)
       , hasOutputFile(false)
-      , domAxisScalarIds_(vector<StdString>(3,"")), areAllReferenceSolved(false), isReferenceSolved(false)
+      , domAxisScalarIds_(vector<StdString>(3,""))
+      , areAllReferenceSolved(false), isReferenceSolved(false), isReferenceSolvedAndTransformed(false)
       , useCompressedOutput(false)
       , wasDataAlreadyReceivedFromServer(false)
@@ -257,13 +259,21 @@
     size_t sizeData = 0;
     if (0 == recvDataSrv.numElements())
-    {      
-      for (map<int, CArray<size_t, 1> >::iterator it = grid->outIndexFromClient.begin(); it != grid->outIndexFromClient.end(); ++it)
-      {
-        sizeData += it->second.numElements();
-        data_srv.insert(std::make_pair(it->first, CArray<double,1>(it->second.numElements())));
-      }
+    {            
+      CArray<int,1>& storeClient = grid->storeIndex_client;
+      // for (map<int, CArray<size_t, 1> >::iterator it = grid->outIndexFromClient.begin(); it != grid->outIndexFromClient.end(); ++it)
+      // {
+      //   // sizeData += it->second.numElements();
+      //   data_srv.insert(std::make_pair(it->first, CArray<double,1>(it->second.numElements())));
+      // }
+
+      // for (map<int, CArray<size_t, 1> >::iterator it = grid->outLocalIndexStoreOnClient.begin(); it != grid->outLocalIndexStoreOnClient.end(); ++it)
+      // {
+      //   // sizeData += it->second.numElements();
+      //   data_srv.insert(std::make_pair(it->first, CArray<double,1>(it->second.numElements())));
+      // }
 
       // Gather all data from different clients
-      recvDataSrv.resize(sizeData);
+      // recvDataSrv.resize(sizeData);
+      recvDataSrv.resize(storeClient.numElements());
       recvFoperationSrv = boost::shared_ptr<func::CFunctor>(new func::CInstant(recvDataSrv));
     }
@@ -276,6 +286,6 @@
     if (opeDate <= currDate)
     {
-      for (map<int, CArray<size_t, 1> >::iterator it = grid->outIndexFromClient.begin(); it != grid->outIndexFromClient.end(); ++it)
-      {        
+       for (map<int, CArray<size_t, 1> >::iterator it = grid->outLocalIndexStoreOnClient.begin(); it != grid->outLocalIndexStoreOnClient.end(); ++it)
+      {
         CArray<double,1> tmp;
         CArray<size_t,1>& indexTmp = it->second;
@@ -288,4 +298,17 @@
         // sizeData += it->second.numElements();      
       }
+
+      // for (map<int, CArray<size_t, 1> >::iterator it = grid->outIndexFromClient.begin(); it != grid->outIndexFromClient.end(); ++it)
+      // {        
+      //   CArray<double,1> tmp;
+      //   CArray<size_t,1>& indexTmp = it->second;
+      //   *(rankBuffers[it->first]) >> tmp;
+      //   for (int idx = 0; idx < indexTmp.numElements(); ++idx)
+      //   {
+      //     recv_data_tmp(indexTmp(idx)) = tmp(idx);
+      //   }
+      //   // recv_data_tmp(Range(sizeData,sizeData+it->second.numElements()-1)) = tmp;  
+      //   // sizeData += it->second.numElements();      
+      // }
     }
 
@@ -316,4 +339,5 @@
       recvFoperationSrv->final();
       last_Write_srv = writeDate;
+      grid->computeWrittenIndex();
       writeField();
       lastlast_Write_srv = last_Write_srv;
@@ -813,5 +837,9 @@
    }
    
-   void CField::solveAllEnabledFields()
+   /*!
+     Solve reference of all enabled fields even the source fields .
+     In this step, we do transformations.
+   */
+   void CField::solveAllEnabledFieldsAndTransform()
    {
      CContext* context = CContext::getCurrent();
@@ -819,12 +847,12 @@
      bool hasServer = context->hasServer;
 
-     if (!isReferenceSolved)
-     {
-        isReferenceSolved = true;
+     if (!isReferenceSolvedAndTransformed)
+     {
+        isReferenceSolvedAndTransformed = true;
 
         if (hasClient && !hasServer)
         {
           solveRefInheritance(true);
-          if (hasDirectFieldReference()) getDirectFieldReference()->solveAllEnabledFields();
+          if (hasDirectFieldReference()) getDirectFieldReference()->solveAllEnabledFieldsAndTransform();
         }
 
@@ -992,5 +1020,5 @@
    {
      // if (!areAllReferenceSolved) solveAllReferenceEnabledField(false);
-    if (!isReferenceSolved) solveAllEnabledFields();
+    if (!isReferenceSolvedAndTransformed) solveAllEnabledFieldsAndTransform();
      CContext* context = CContext::getCurrent();
      bool hasWriterServer = context->hasServer && !context->hasClient;
@@ -1428,8 +1456,13 @@
    void CField::outputField(CArray<double,1>& fieldOut)
    {
-      map<int, CArray<double,1> >::iterator it;
-      
-      fieldOut = recvDataSrv;
-      
+      map<int, CArray<double,1> >::iterator it;      
+     
+      CArray<size_t,1>& outIndexClient = grid->localIndexToWriteOnClient;
+      CArray<size_t,1>& outIndexServer = grid->localIndexToWriteOnServer;
+      for (size_t idx = 0; idx < outIndexServer.numElements(); ++idx)
+      {
+        fieldOut(outIndexServer(idx)) = recvDataSrv(outIndexClient(idx));
+      }
+
       // for (it = data_srv.begin(); it != data_srv.end(); it++)
       // {
Index: /XIOS/dev/dev_olga/src/node/field.hpp
===================================================================
--- /XIOS/dev/dev_olga/src/node/field.hpp	(revision 1128)
+++ /XIOS/dev/dev_olga/src/node/field.hpp	(revision 1129)
@@ -122,5 +122,5 @@
          void solveGridDomainAxisBaseRef();
 
-         void solveAllEnabledFields();
+         void solveAllEnabledFieldsAndTransform();
          void checkGridOfEnabledFields();
          void sendGridOfEnabledFields();
@@ -216,6 +216,4 @@
          string content;
 
-         bool areAllReferenceSolved;
-         bool isReferenceSolved;
          std::vector<StdString> domAxisScalarIds_;
          bool useCompressedOutput;
@@ -225,5 +223,11 @@
          bool hasTimeCentered;
 
+
          DECLARE_REF_FUNC(Field,field)
+
+      private:
+         bool areAllReferenceSolved;
+         bool isReferenceSolved;
+         bool isReferenceSolvedAndTransformed;
 
       private:
Index: /XIOS/dev/dev_olga/src/node/file.cpp
===================================================================
--- /XIOS/dev/dev_olga/src/node/file.cpp	(revision 1128)
+++ /XIOS/dev/dev_olga/src/node/file.cpp	(revision 1129)
@@ -695,6 +695,6 @@
      for (int i = 0; i < size; ++i)
      {
-       // this->enabledFields[i]->solveOnlyReferenceEnabledField(sendToServer);
-       this->enabledFields[i]->solveAllEnabledFields();
+       this->enabledFields[i]->solveOnlyReferenceEnabledField(sendToServer);
+       // this->enabledFields[i]->solveAllEnabledFields();
 //       this->enabledFields[i]->buildGridTransformationGraph();
      }
@@ -736,10 +736,11 @@
    \param [in] sendToServer: Send all info to server (true) or only a part of it (false)
    */
-   void CFile::solveAllRefOfEnabledFields(bool sendToServer)
+   void CFile::solveAllRefOfEnabledFieldsAndTransform(bool sendToServer)
    {
      int size = this->enabledFields.size();
      for (int i = 0; i < size; ++i)
      {
-       this->enabledFields[i]->solveAllReferenceEnabledField(sendToServer);
+       // this->enabledFields[i]->solveAllReferenceEnabledField(sendToServer);
+      this->enabledFields[i]->solveAllEnabledFieldsAndTransform();
      }
    }
Index: /XIOS/dev/dev_olga/src/node/file.hpp
===================================================================
--- /XIOS/dev/dev_olga/src/node/file.hpp	(revision 1128)
+++ /XIOS/dev/dev_olga/src/node/file.hpp	(revision 1129)
@@ -105,9 +105,10 @@
          void solveOnlyRefOfEnabledFields(bool sendToServer);
          void generateNewTransformationGridDest();
-         void solveAllRefOfEnabledFields(bool sendToServer);
+         
          void buildFilterGraphOfEnabledFields(CGarbageCollector& gc);
          void prefetchEnabledReadModeFields();
          void prefetchEnabledReadModeFieldsIfNeeded();
 
+         void solveAllRefOfEnabledFieldsAndTransform(bool sendToServer);
          void checkGridOfEnabledFields();
          void sendGridOfEnabledFields();
Index: /XIOS/dev/dev_olga/src/node/grid.cpp
===================================================================
--- /XIOS/dev/dev_olga/src/node/grid.cpp	(revision 1128)
+++ /XIOS/dev/dev_olga/src/node/grid.cpp	(revision 1129)
@@ -35,4 +35,5 @@
       , axisPositionInGrid_(), positionDimensionDistributed_(1), hasDomainAxisBaseRef_(false)
       , gridSrc_(), hasTransform_(false), isGenerated_(false), order_(), globalIndexOnServer_()
+      , computedWrittenIndex_(false)
    {
      setVirtualDomainGroup(CDomainGroup::create(getId() + "_virtual_domain_group"));
@@ -53,4 +54,5 @@
       , axisPositionInGrid_(), positionDimensionDistributed_(1), hasDomainAxisBaseRef_(false)
       , gridSrc_(), hasTransform_(false), isGenerated_(false), order_(), globalIndexOnServer_()
+      , computedWrittenIndex_(false)
    {
      setVirtualDomainGroup(CDomainGroup::create(getId() + "_virtual_domain_group"));
@@ -403,5 +405,5 @@
    }
 
-   void CGrid::modifyMask(const CArray<int,1>& indexToModify)
+   void CGrid::modifyMask(const CArray<int,1>& indexToModify, bool modifyValue)
    {
       using namespace std;
@@ -412,23 +414,56 @@
       switch (dim) {
         case 1:
-          modifyGridMask(mask_1d, indexToModify);
+          modifyGridMask(mask_1d, indexToModify, modifyValue);
           break;
         case 2:
-          modifyGridMask(mask_2d, indexToModify);
+          modifyGridMask(mask_2d, indexToModify, modifyValue);
           break;
         case 3:
-          modifyGridMask(mask_3d, indexToModify);
+          modifyGridMask(mask_3d, indexToModify, modifyValue);
           break;
         case 4:
-          modifyGridMask(mask_4d, indexToModify);
+          modifyGridMask(mask_4d, indexToModify, modifyValue);
           break;
         case 5:
-          modifyGridMask(mask_5d, indexToModify);
+          modifyGridMask(mask_5d, indexToModify, modifyValue);
           break;
         case 6:
-          modifyGridMask(mask_6d, indexToModify);
+          modifyGridMask(mask_6d, indexToModify, modifyValue);
           break;
         case 7:
-          modifyGridMask(mask_7d, indexToModify);
+          modifyGridMask(mask_7d, indexToModify, modifyValue);
+          break;
+        default:
+          break;
+      }
+   }
+
+   void CGrid::modifyMaskSize(const std::vector<int>& newDimensionSize, bool newValue)
+   {      
+      std::vector<CDomain*> domainP = this->getDomains();
+      std::vector<CAxis*> axisP = this->getAxis();
+      int dim = domainP.size() * 2 + axisP.size();
+
+      switch (dim) {
+        case 1:
+          modifyGridMaskSize(mask_1d, newDimensionSize, newValue);
+          break;
+        case 2:
+          modifyGridMaskSize(mask_2d, newDimensionSize, newValue);
+          break;
+        case 3:
+          modifyGridMaskSize(mask_3d, newDimensionSize, newValue);
+          break;
+        case 4:
+          modifyGridMaskSize(mask_4d, newDimensionSize, newValue);
+          break;
+        case 5:
+          modifyGridMaskSize(mask_5d, newDimensionSize, newValue);
+          break;
+        case 6:
+          modifyGridMaskSize(mask_6d, newDimensionSize, newValue);
+          break;
+        case 7:
+          modifyGridMaskSize(mask_7d, newDimensionSize, newValue);
           break;
         default:
@@ -504,4 +539,40 @@
    {
      return axisPositionInGrid_;
+   }
+
+   void CGrid::computeWrittenIndex()
+   {      
+      if (computedWrittenIndex_) return;
+      computedWrittenIndex_ = true;
+
+      size_t nbWritten = 0, indGlo;
+      CDistributionClient::GlobalLocalDataMap& globalDataIndex = clientDistribution_->getGlobalDataIndexOnClient();
+      CDistributionClient::GlobalLocalDataMap::const_iterator itb = globalDataIndex.begin(),
+                                                              ite = globalDataIndex.end(), it;    
+      const CDistributionServer::GlobalLocalMap& globalLocalIndex = serverDistribution_->getGlobalLocalIndex();                                                              
+      CDistributionServer::GlobalLocalMap::const_iterator itSrvb = globalLocalIndex.begin(),
+                                                          itSrve = globalLocalIndex.end(), itSrv;
+      for (it = itb; it != ite; ++it)
+      {
+        indGlo = it->first;
+        if (globalLocalIndex.end() != globalLocalIndex.find(indGlo)) ++nbWritten;                
+      }
+
+      localIndexToWriteOnClient.resize(nbWritten);  
+      localIndexToWriteOnServer.resize(nbWritten);
+
+      nbWritten = 0; 
+      for (it = itb; it != ite; ++it)
+      {
+        indGlo = it->first;
+        itSrv = globalLocalIndex.find(indGlo);
+        if (itSrve != itSrv)
+        {
+          localIndexToWriteOnServer(nbWritten) = itSrv->second;
+          localIndexToWriteOnClient(nbWritten) = it->second;
+          ++nbWritten;                
+        } 
+      }
+
    }
 
@@ -526,13 +597,15 @@
 
        // First of all, compute distribution on client side
-       if (0 != serverDistribution_)
-       {
-         clientDistribution_ = new CDistributionClient(rank, this, serverDistribution_->getGlobalLocalIndex());
-         storeIndex_client.resize(serverDistribution_->getGridSize());
-         int nbStoreIndex = storeIndex_client.numElements();
-         for (int idx = 0; idx < nbStoreIndex; ++idx) storeIndex_client(idx) = idx;
-       }
-       else
-       {
+       // if (0 != serverDistribution_)
+       // {
+       //   // clientDistribution_ = new CDistributionClient(rank, this, serverDistribution_->getGlobalLocalIndex());
+       //   clientDistribution_ = new CDistributionClient(rank, this);
+       //   storeIndex_client.resize(clientDistribution_->getLocalDataIndexOnClient().size());
+       //   // storeIndex_client.resize(serverDistribution_->getGridSize());
+       //   int nbStoreIndex = storeIndex_client.numElements();
+       //   for (int idx = 0; idx < nbStoreIndex; ++idx) storeIndex_client(idx) = idx;
+       // }
+       // else
+       // {
          clientDistribution_ = new CDistributionClient(rank, this);
          // Get local data index on client
@@ -540,8 +613,50 @@
          int nbStoreIndex = storeIndex_client.numElements();
          for (int idx = 0; idx < nbStoreIndex; ++idx) storeIndex_client(idx) = (clientDistribution_->getLocalDataIndexOnClient())[idx];
-       }
+       // }
      
-       if (0 == serverDistribution_) 
-        isDataDistributed_= clientDistribution_->isDataDistributed();
+       if (0 == serverDistribution_) isDataDistributed_= clientDistribution_->isDataDistributed();
+       else          
+       {
+          
+          // Mapping global index received from clients to the storeIndex_client
+          CDistributionClient::GlobalLocalDataMap& globalDataIndex = clientDistribution_->getGlobalDataIndexOnClient();
+          CDistributionClient::GlobalLocalDataMap::const_iterator itGloe = globalDataIndex.end();
+          map<int, CArray<size_t, 1> >::iterator itb = outGlobalIndexFromClient.begin(),
+                                                 ite = outGlobalIndexFromClient.end(), it;
+                  
+          for (it = itb; it != ite; ++it)
+          {
+            int rank = it->first;
+            CArray<size_t,1>& globalIndex = outGlobalIndexFromClient[rank];
+            outLocalIndexStoreOnClient.insert(make_pair(rank, CArray<size_t,1>(globalIndex.numElements())));            
+            CArray<size_t,1>& localIndex = outLocalIndexStoreOnClient[rank];
+            size_t nbIndex = 0;
+            for (size_t idx = 0; idx < globalIndex.numElements(); ++idx)
+            {
+              if (itGloe != globalDataIndex.find(globalIndex(idx)))
+              {
+                ++nbIndex;                           
+              }              
+            }
+
+            if (nbIndex != localIndex.numElements())
+                 ERROR("void CGrid::computeClientIndex()",
+                    << "Number of local index on client is different from number of received global index" 
+                    << "Rank of sent client " << rank <<"."
+                    << "Number of local index " << nbIndex << ". "
+                    << "Number of received global index " << localIndex.numElements() << ".");
+
+            nbIndex = 0;
+            for (size_t idx = 0; idx < globalIndex.numElements(); ++idx)
+            {
+              if (itGloe != globalDataIndex.find(globalIndex(idx)))
+              {            
+                localIndex(idx) = globalDataIndex[globalIndex(idx)];                
+              }              
+            }
+
+
+          }          
+        }
       }
    }
@@ -1341,15 +1456,64 @@
       else
       {
-        CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itGlobalMap, itbGlobalMap;
-        itbGlobalMap = globalIndexOnServer_.begin(), itGlobalMap;
+        // CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itGlobalMap, itbGlobalMap;
+        // itbGlobalMap = globalIndexOnServer_.begin(), itGlobalMap;
+        // iteGlobalMap = globalIndexOnServer_.end();
+        
+        // std::map<int,int > nbGlobalLocalTmp;
+        // for (itGlobalMap = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap)
+        // {
+        //   int serverRank = itGlobalMap->first;
+        //   nbGlobalLocalTmp[serverRank] = 0;
+        //   const std::vector<size_t>& indexVec = itGlobalMap->second;
+        //   int indexSize = indexVec.size();          
+        //   for (int idx = 0; idx < indexSize; ++idx)
+        //   {
+        //     itIndex = globalLocalIndexSendToServer.find(indexVec[idx]);
+        //     if (iteIndex != itIndex)
+        //     {
+        //       ++nbGlobalLocalTmp[serverRank];
+        //     }
+        //   }
+        // }
+
+        // std::map<int,std::vector<int> >localIndexTmp;
+        // std::map<int,std::vector<size_t> > globalIndexTmp;
+        // for (std::map<int,int>::iterator it = nbGlobalLocalTmp.begin(); it != nbGlobalLocalTmp.end(); ++it)
+        // {
+        //   localIndexTmp[it->first].resize(it->second);
+        //   globalIndexTmp[it->first].resize(it->second);
+        //   it->second = 0;
+        // }
+
+        // for (itGlobalMap = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap)
+        // {
+        //   int serverRank = itGlobalMap->first;          
+        //   const std::vector<size_t>& indexVec = itGlobalMap->second;
+        //   int indexSize = indexVec.size();          
+        //   int ind = 0;
+        //   for (int idx = 0; idx < indexSize; ++idx)
+        //   {
+        //     itIndex = globalLocalIndexSendToServer.find(indexVec[idx]);
+        //     if (iteIndex != itIndex)
+        //     {              
+        //       ind = nbGlobalLocalTmp[serverRank];
+        //       globalIndexTmp[serverRank][ind] = itIndex->first;
+        //       localIndexTmp[serverRank][ind]  = itIndex->second;
+        //       ++nbGlobalLocalTmp[serverRank];
+        //     }
+        //   }
+        // }
+
+        CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itGlobalMap;
+        itGlobalMap = globalIndexOnServer_.begin();
         iteGlobalMap = globalIndexOnServer_.end();
-        
-        std::map<int,int > nbGlobalLocalTmp;
-        for (itGlobalMap = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap)
+
+        std::map<int,std::vector<int> >localIndexTmp;
+        std::map<int,std::vector<size_t> > globalIndexTmp;
+        for (; itGlobalMap != iteGlobalMap; ++itGlobalMap)
         {
           int serverRank = itGlobalMap->first;
-          nbGlobalLocalTmp[serverRank] = 0;
+          int indexSize = itGlobalMap->second.size();
           const std::vector<size_t>& indexVec = itGlobalMap->second;
-          int indexSize = indexVec.size();          
           for (int idx = 0; idx < indexSize; ++idx)
           {
@@ -1357,33 +1521,6 @@
             if (iteIndex != itIndex)
             {
-              ++nbGlobalLocalTmp[serverRank];
-            }
-          }
-        }
-
-        std::map<int,std::vector<int> >localIndexTmp;
-        std::map<int,std::vector<size_t> > globalIndexTmp;
-        for (std::map<int,int>::iterator it = nbGlobalLocalTmp.begin(); it != nbGlobalLocalTmp.end(); ++it)
-        {
-          localIndexTmp[it->first].resize(it->second);
-          globalIndexTmp[it->first].resize(it->second);
-          it->second = 0;
-        }
-
-        for (itGlobalMap = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap)
-        {
-          int serverRank = itGlobalMap->first;          
-          const std::vector<size_t>& indexVec = itGlobalMap->second;
-          int indexSize = indexVec.size();          
-          int ind = 0;
-          for (int idx = 0; idx < indexSize; ++idx)
-          {
-            itIndex = globalLocalIndexSendToServer.find(indexVec[idx]);
-            if (iteIndex != itIndex)
-            {              
-              ind = nbGlobalLocalTmp[serverRank];
-              globalIndexTmp[serverRank][ind] = itIndex->first;
-              localIndexTmp[serverRank][ind]  = itIndex->second;
-              ++nbGlobalLocalTmp[serverRank];
+              globalIndexTmp[serverRank].push_back(itIndex->first);
+              localIndexTmp[serverRank].push_back(itIndex->second);
             }
           }
@@ -1455,4 +1592,19 @@
       //connectedServerRank_[p] = ranks;
 
+      int idx = 0, numElement = axis_domain_order.numElements();
+      int ssize = numElement;
+      std::vector<int> indexMap(numElement);
+      for (int i = 0; i < numElement; ++i)
+      {
+        indexMap[i] = idx;
+        if (2 == axis_domain_order(i))
+        {
+          ++ssize;
+          idx += 2;
+        }
+        else
+          ++idx;
+      }
+
       for (int n = 0; n < ranks.size(); n++)
       {
@@ -1465,19 +1617,4 @@
         if (0 == serverDistribution_)
         {
-          int idx = 0, numElement = axis_domain_order.numElements();
-          int ssize = numElement;
-          std::vector<int> indexMap(numElement);
-          for (int i = 0; i < numElement; ++i)
-          {
-            indexMap[i] = idx;
-            if (2 == axis_domain_order(i))
-            {
-              ++ssize;
-              idx += 2;
-            }
-            else
-              ++idx;
-          }
-
           int axisId = 0, domainId = 0, scalarId = 0, globalSize = 1;
           std::vector<CDomain*> domainList = getDomains();
@@ -1492,23 +1629,12 @@
               nZoomBegin[indexMap[i]] = domainList[domainId]->zoom_ibegin;
               nZoomSize[indexMap[i]]  = domainList[domainId]->zoom_ni;
-              nZoomBeginGlobal[indexMap[i]] = domainList[domainId]->global_zoom_ibegin;
-              // zoomIndex.push_back(domainList[domainId]->zoom_i_index);
+              nZoomBeginGlobal[indexMap[i]] = domainList[domainId]->global_zoom_ibegin;              
               nGlob[indexMap[i]] = domainList[domainId]->ni_glo;
 
               nZoomBegin[indexMap[i] + 1] = domainList[domainId]->zoom_jbegin;
               nZoomSize[indexMap[i] + 1] = domainList[domainId]->zoom_nj;
-              nZoomBeginGlobal[indexMap[i] + 1] = domainList[domainId]->global_zoom_jbegin;
-              // zoomIndex.push_back(domainList[domainId]->zoom_j_index);
+              nZoomBeginGlobal[indexMap[i] + 1] = domainList[domainId]->global_zoom_jbegin;              
               nGlob[indexMap[i] + 1] = domainList[domainId]->nj_glo;
 
-              // int nbZoom = domainList[domainId]->zoom_i_index.numElements();
-              // zoomIndex.push_back(CArray<int,1>(nbZoom));
-              // CArray<int,1>& zoomDomain = zoomIndex.back();
-              // for (int ind = 0; ind < nbZoom; ++ind)
-              // {
-              //   zoomDomain(ind) = domainList[domainId]->zoom_i_index(ind) + domainList[domainId]->zoom_j_index(ind) * domainList[domainId]->ni_glo;
-              // }
-
-              // globalSize *= domainList[domainId]->ni_glo * domainList[domainId]->nj_glo;
               ++domainId;
             }
@@ -1517,19 +1643,15 @@
               nZoomBegin[indexMap[i]] = axisList[axisId]->zoom_begin;
               nZoomSize[indexMap[i]]  = axisList[axisId]->zoom_n;
-              nZoomBeginGlobal[indexMap[i]] = axisList[axisId]->global_zoom_begin;
-              // zoomIndex.push_back(axisList[axisId]->zoom_index);
-              nGlob[indexMap[i]] = axisList[axisId]->n_glo;
-              // globalSize *= axisList[axisId]->n_glo;
+              nZoomBeginGlobal[indexMap[i]] = axisList[axisId]->global_zoom_begin;              
+              nGlob[indexMap[i]] = axisList[axisId]->n_glo;              
               ++axisId;
             }
             else // scalar
-            {
-              // CArray<int,1> zoomScalar(1);
-              // zoomScalar(0) = 0;
+            { 
               nZoomBegin[indexMap[i]] = 0;
               nZoomSize[indexMap[i]]  = 1;
-              nZoomBeginGlobal[indexMap[i]] = 0;
-              // zoomIndex.push_back(zoomScalar);
+              nZoomBeginGlobal[indexMap[i]] = 0;              
               nGlob[indexMap[i]] = 1;
+
               ++scalarId;
             }
@@ -1541,14 +1663,9 @@
           serverDistribution_ = new CDistributionServer(server->intraCommRank, nZoomBegin, nZoomSize,
                                                         nZoomBeginGlobal, nGlob);
-          // for (int i = 0; i < zoomIndex.size(); ++i)
-          // {
-          //   dataSize *= zoomIndex[i].numElements();
-          // }
-          // serverDistribution_ = new CDistributionServer(server->intraCommRank, zoomIndex, nGlobElement);
         }
 
         CArray<size_t,1> outIndex;
         buffer >> outIndex;
-        serverDistribution_->computeLocalIndex(outIndex);
+        outGlobalIndexFromClient.insert(std::make_pair(rank, outIndex));        
 
         if (isDataDistributed_)
@@ -1568,23 +1685,86 @@
         writtenDataSize_ += dataSize;
 
-        outIndexFromClient.insert(std::make_pair(rank, outIndex));
+        // outIndexFromClient.insert(std::make_pair(rank, outIndex));
         // connectedDataSize_[p][rank] = outIndex.numElements();
         numberWrittenIndexes_ += outIndex.numElements();
       }
 
-      // int sizeData = 0;
-      // for (map<int, CArray<size_t, 1> >::iterator it = outIndexFromClient.begin(); it != outIndexFromClient.end(); ++it)
-      // {
-      //   sizeData += it->second.numElements();
-      // }
-      // indexFromClients.resize(sizeData);
-      // sizeData = 0;
-      // for (map<int, CArray<size_t, 1> >::iterator it = outIndexFromClient.begin(); it != outIndexFromClient.end(); ++it)
-      // {
-      //    CArray<size_t, 1>& tmp0 = it->second;
-      //    CArray<size_t, 1> tmp1 = indexFromClients(Range(sizeData, sizeData + tmp0.numElements() - 1));
-      //    tmp1 = tmp0;
-      //    sizeData += tmp0.numElements();
-      // }
+
+      // Compute mask of the current grid
+      {
+        int axisId = 0, domainId = 0, scalarId = 0, globalSize = 1;
+        std::vector<CDomain*> domainList = getDomains();
+        std::vector<CAxis*> axisList = getAxis();
+        std::vector<int> nBegin(ssize), nSize(ssize), nGlob(ssize), nBeginGlobal(ssize);        
+        for (int i = 0; i < numElement; ++i)
+        {          
+          if (2 == axis_domain_order(i)) //domain
+          {
+            nBegin[indexMap[i]] = domainList[domainId]->ibegin;
+            nSize[indexMap[i]]  = domainList[domainId]->ni;
+            nBeginGlobal[indexMap[i]] = 0;              
+            nGlob[indexMap[i]] = domainList[domainId]->ni_glo;
+
+            nBegin[indexMap[i] + 1] = domainList[domainId]->jbegin;
+            nSize[indexMap[i] + 1] = domainList[domainId]->nj;
+            nBeginGlobal[indexMap[i] + 1] = 0;              
+            nGlob[indexMap[i] + 1] = domainList[domainId]->nj_glo;
+
+            ++domainId;
+          }
+          else if (1 == axis_domain_order(i)) // axis
+          {
+            nBegin[indexMap[i]] = axisList[axisId]->begin;
+            nSize[indexMap[i]]  = axisList[axisId]->n;
+            nBeginGlobal[indexMap[i]] = 0;              
+            nGlob[indexMap[i]] = axisList[axisId]->n_glo;              
+            ++axisId;
+          }
+          else // scalar
+          { 
+            nBegin[indexMap[i]] = 0;
+            nSize[indexMap[i]]  = 1;
+            nBeginGlobal[indexMap[i]] = 0;              
+            nGlob[indexMap[i]] = 1;
+
+            ++scalarId;
+          }
+        }
+        
+        modifyMaskSize(nSize, true);
+        // These below codes are reserved for future
+        // CDistributionServer srvDist(server->intraCommRank, nBegin, nSize, nBeginGlobal, nGlob); 
+        // map<int, CArray<size_t, 1> >::iterator itb = outGlobalIndexFromClient.begin(),
+        //                                        ite = outGlobalIndexFromClient.end(), it;  
+        // const CDistributionServer::GlobalLocalMap&  globalLocalMask = srvDist.getGlobalLocalIndex();
+        // CDistributionServer::GlobalLocalMap::const_iterator itSrv;
+        // size_t nb = 0;
+        // for (it = itb; it != ite; ++it)
+        // {
+        //   CArray<size_t,1>& globalInd = it->second;
+        //   for (size_t idx = 0; idx < globalInd.numElements(); ++idx)
+        //   {
+        //     if (globalLocalMask.end() != globalLocalMask.find(globalInd(idx))) ++nb;
+        //   }
+        // }
+        
+        // CArray<int,1> indexToModify(nb);
+        // nb = 0;    
+        // for (it = itb; it != ite; ++it)
+        // {
+        //   CArray<size_t,1>& globalInd = it->second;
+        //   for (size_t idx = 0; idx < globalInd.numElements(); ++idx)
+        //   {
+        //     itSrv = globalLocalMask.find(globalInd(idx));
+        //     if (globalLocalMask.end() != itSrv) 
+        //     {
+        //       indexToModify(nb) = itSrv->second;
+        //       ++nb;
+        //     }
+        //   }
+        // }
+
+        // modifyMask(indexToModify, true);
+      }
 
       // if (isScalarGrid()) return;
Index: /XIOS/dev/dev_olga/src/node/grid.hpp
===================================================================
--- /XIOS/dev/dev_olga/src/node/grid.hpp	(revision 1128)
+++ /XIOS/dev/dev_olga/src/node/grid.hpp	(revision 1129)
@@ -140,4 +140,5 @@
          void computeIndexScalarGrid();
          void computeCompressedIndex();
+         void computeWrittenIndex();
 
          void solveDomainRef(bool checkAtt);
@@ -224,9 +225,22 @@
          std::vector<map<int,int> > nbSenders;
 
-         map<int, CArray<size_t, 1> > outIndexFromClient, compressedOutIndexFromClient;
+         map<int, CArray<size_t, 1> > outIndexFromClient, compressedOutIndexFromClient, outGlobalIndexFromClient;
+
+         // A client receives global index from other clients (via recvIndex)
+         // then does mapping these index into local index of STORE_CLIENTINDEX
+         // In this way, store_clientIndex can be used as an input of a source filter
+         // Maybe we need a flag to determine whether a client wants to write. TODO
+         map<int, CArray<size_t, 1> > outLocalIndexStoreOnClient; 
+
+         // If a client wants to write out data, it'll use this index.
+         // A client receives global index of data from other clients (via recvIndex),
+         // then does remapping these index into local index to WRITE into a file
+         CArray<size_t,1> localIndexToWriteOnClient, localIndexToWriteOnServer;
+
          CArray<size_t,1> indexFromClients;
          void checkMask(void);
          void createMask(void);
-         void modifyMask(const CArray<int,1>& indexToModify);
+         void modifyMask(const CArray<int,1>& indexToModify, bool valueToModify = false);
+         void modifyMaskSize(const std::vector<int>& newDimensionSize, bool newValue = false);
 
          void computeGridGlobalDimension(const std::vector<CDomain*>& domains,
@@ -243,5 +257,8 @@
                           bool createMask = false);
         template<int N>
-        void modifyGridMask(CArray<bool,N>& gridMask, const CArray<int,1>& indexToModify);
+        void modifyGridMask(CArray<bool,N>& gridMask, const CArray<int,1>& indexToModify, bool valueToModify);
+
+        template<int N>
+        void modifyGridMaskSize(CArray<bool,N>& gridMask, const std::vector<int>& eachDimSize, bool newValue);
 
         void setVirtualDomainGroup(CDomainGroup* newVDomainGroup);
@@ -285,6 +302,6 @@
         std::set<std::string> relFilesCompressed;
 
-        bool isTransformed_;
-        bool isGenerated_;
+        bool isTransformed_, isGenerated_;
+        bool computedWrittenIndex_;
         std::vector<int> axisPositionInGrid_;
         CGridTransformation* transformations_;
@@ -416,4 +433,24 @@
    }
 
+   template<int N>
+   void CGrid::modifyGridMaskSize(CArray<bool,N>& gridMask,
+                                  const std::vector<int>& eachDimSize,
+                                  bool newValue)
+   {
+      if (N != eachDimSize.size())
+      {
+        // ERROR("CGrid::modifyGridMaskSize(CArray<bool,N>& gridMask,
+        //                                  const std::vector<int>& eachDimSize,
+        //                                  bool newValue)",
+        //       << "Dimension size of the mask is different from input dimension size." << std::endl
+        //       << "Mask dimension is " << N << "." << std::endl
+        //       << "Input dimension is " << eachDimSize.size() << "." << std::endl
+        //       << "Grid = " << this->GetName())
+      }
+      CArrayBoolTraits<CArray<bool,N> >::resizeArray(gridMask,eachDimSize);
+      gridMask = newValue;
+   }
+                                 
+
    /*!
      Modify the current mask of grid, the local index to be modified will take value false
@@ -422,7 +459,6 @@
    */
    template<int N>
-   void CGrid::modifyGridMask(CArray<bool,N>& gridMask, const CArray<int,1>& indexToModify)
-   {
-     bool valueToModify = false;
+   void CGrid::modifyGridMask(CArray<bool,N>& gridMask, const CArray<int,1>& indexToModify, bool valueToModify)
+   {     
      int num = indexToModify.numElements();
      for (int idx = 0; idx < num; ++idx)
Index: /XIOS/dev/dev_olga/src/transformation/axis_algorithm_zoom.cpp
===================================================================
--- /XIOS/dev/dev_olga/src/transformation/axis_algorithm_zoom.cpp	(revision 1128)
+++ /XIOS/dev/dev_olga/src/transformation/axis_algorithm_zoom.cpp	(revision 1129)
@@ -60,4 +60,7 @@
 void CAxisAlgorithmZoom::computeIndexSourceMapping_(const std::vector<CArray<double,1>* >& dataAuxInputs)
 {
+  // We use all index of source and destination to calculate the mapping index of zoom.
+  // The server who receives the "zoomed" fields will decide whether it will forward these fields or write "real zoomed" fields into file
+  // That means servers need to change to cover this problem.
   StdSize niSource = axisSrc_->n.getValue();
   StdSize ibeginSource = axisSrc_->begin.getValue();
@@ -66,4 +69,6 @@
   StdSize ibegin = std::max(ibeginSource, zoomBegin_);
   StdSize iend = std::min(iendSource, zoomEnd_);
+  // StdSize ibegin = ibeginSource;
+  // StdSize iend = iendSource;
   StdSize ni = iend + 1 - ibegin;
   if (iend < ibegin) ni = 0;
@@ -82,5 +87,5 @@
 
   updateZoom();
-  updateAxisDestinationMask();
+  // updateAxisDestinationMask();
 }
 
Index: /XIOS/dev/dev_olga/src/transformation/domain_algorithm_zoom.cpp
===================================================================
--- /XIOS/dev/dev_olga/src/transformation/domain_algorithm_zoom.cpp	(revision 1128)
+++ /XIOS/dev/dev_olga/src/transformation/domain_algorithm_zoom.cpp	(revision 1129)
@@ -113,5 +113,5 @@
 
   updateZoom();
-  updateDomainDestinationMask();
+  // updateDomainDestinationMask();
 }
 
