Index: /XIOS/trunk/src/distribution_client.cpp
===================================================================
--- /XIOS/trunk/src/distribution_client.cpp	(revision 1636)
+++ /XIOS/trunk/src/distribution_client.cpp	(revision 1637)
@@ -15,5 +15,5 @@
    , axisDomainOrder_()
    , nLocal_(), nGlob_(), nBeginLocal_(), nBeginGlobal_()
-   , dataNIndex_(), dataDims_(), dataBegin_(), dataIndex_(), domainMasks_(), axisMasks_()
+   , dataNIndex_(), dataDims_(), dataBegin_(), dataIndex_()
    , gridMask_(), indexMap_()
    , isDataDistributed_(true), axisNum_(0), domainNum_(0)
@@ -36,5 +36,5 @@
   GlobalLocalMap void2 ;
   std::vector<int> void3 ;
-  std::vector<int> void4 ;
+  std::vector<bool> void4 ;
 
   globalLocalDataSendToServerMap_.swap(void1) ;
@@ -61,5 +61,4 @@
   // Then check mask of grid
   int gridDim = domList.size() * 2 + axisList.size();
-  grid->checkMask();
   switch (gridDim) {
     case 0:
@@ -117,19 +116,4 @@
   axisDomainOrder_ = axisDomainOrder;
 
-  // Each domain or axis has its mask, of course
-  domainMasks_.resize(domainNum_);
-  for (int i = 0; i < domainNum_;++i)
-  {
-    domainMasks_[i].resize(domList[i]->domainMask.numElements());
-    domainMasks_[i] = domList[i]->domainMask;
-  }
-
-  axisMasks_.resize(axisNum_);
-  for (int i = 0; i < axisNum_; ++i)
-  {
-    axisMasks_[i].resize(axisList[i]->mask.numElements());
-    axisMasks_[i] = axisList[i]->mask;
-  }
-
   // Because domain and axis can be in any order (axis1, domain1, axis2, axis3, )
   // their position should be specified. In axisDomainOrder, domain == true, axis == false
@@ -282,6 +266,5 @@
 
         if ((iIdx >= nBeginLocal_[indexMap_[i]]) && (iIdx < nLocal_[indexMap_[i]]) &&
-           (jIdx >= nBeginLocal_[indexMap_[i]+1]) && (jIdx < nLocal_[indexMap_[i]+1]) &&
-           (domainMasks_[idxDomain](iIdx + jIdx*nLocal_[indexMap_[i]])))
+           (jIdx >= nBeginLocal_[indexMap_[i]+1]) && (jIdx < nLocal_[indexMap_[i]+1]))
         {
           ++count;
@@ -325,10 +308,10 @@
       elementIndexData_[i].resize(dataNIndex_[i]);
       elementIndexData_[i] = false;
-      int iIdx = 0, count = 0, localIndex = 0;
+      int iIdx = 0, count = 0;
       for (int j = 0; j < dataNIndex_[i]; ++j)
       {
         iIdx = getAxisIndex((dataIndex_[indexMap_[i]])(j), dataBegin_[indexMap_[i]], nLocal_[indexMap_[i]]);
         if ((iIdx >= nBeginLocal_[indexMap_[i]]) &&
-           (iIdx < nLocal_[indexMap_[i]]) && (axisMasks_[idxAxis](iIdx)))
+           (iIdx < nLocal_[indexMap_[i]]) )//&& (axisMasks_[idxAxis](iIdx)))
         {
           ++count;
@@ -413,70 +396,11 @@
 
   for (int i = 0; i < numElement_; ++i) ssize *= eachElementSize[i];
-  while (idx < ssize)
-  {
-    for (int i = 0; i < numElement_-1; ++i)
-    {
-      if (idxLoop[i] == eachElementSize[i])
-      {
-        idxLoop[i] = 0;
-        ++idxLoop[i+1];
-      }
-    }
-
-    // Find out outer index
-    // Depending the inner-most element is axis or domain,
-    // The outer loop index begins correspondingly at one (1) or zero (0)
-    for (int i = 1; i < numElement_; ++i)
-    {
-      currentIndex[i] = elementLocalIndex_[i](idxLoop[i]);
-    }
-
-    // Inner most index
-    for (int i = 0; i < innerLoopSize; ++i)
-    {
-      int gridMaskIndex = 0;
-      currentIndex[0] = elementLocalIndex_[0](i);
-
-      // If defined, iterate on grid mask
-      if (!gridMask_.isEmpty())
-      {
-        for (int k = 0; k < this->numElement_; ++k)
-        {
-          gridMaskIndex += (currentIndex[k])*elementNLocal_[k];
-        }
-        if (gridMask_(gridMaskIndex)) ++indexLocalDataOnClientCount;
-      }
-      // If grid mask is not defined, iterate on elements' mask
-      else
-      {
-        bool maskTmp = true;
-        int idxDomain = 0, idxAxis = 0;
-        for (int elem = 0; elem < numElement_; ++elem)
-        {
-          if (2 == axisDomainOrder_(elem))
-          {
-            maskTmp = maskTmp && domainMasks_[idxDomain](currentIndex[elem]);
-            ++idxDomain;
-          }
-          else if (1 == axisDomainOrder_(elem))
-          {
-            maskTmp = maskTmp && axisMasks_[idxAxis](currentIndex[elem]);
-            ++idxAxis;
-          }
-        }
-        if (maskTmp) ++indexLocalDataOnClientCount;
-      }
-
-    }
-    idxLoop[0] += innerLoopSize;
-    idx += innerLoopSize;
-  }
-
-  // Now allocate these arrays
-  localDataIndex_.resize(indexLocalDataOnClientCount);
-  localMaskIndex_.resize(indexLocalDataOnClientCount);
-  localMaskedDataIndex_.resize(indexLocalDataOnClientCount);
-  globalDataIndex_.rehash(std::ceil(indexLocalDataOnClientCount/globalDataIndex_.max_load_factor()));
-  globalLocalDataSendToServerMap_.rehash(std::ceil(indexLocalDataOnClientCount/globalLocalDataSendToServerMap_.max_load_factor()));
+
+  localDataIndex_.resize(ssize);
+  if (!gridMask_.isEmpty()) localMaskIndex_.resize(ssize);
+  localMaskedDataIndex_.resize(ssize);
+  globalDataIndex_.rehash(std::ceil(ssize/globalDataIndex_.max_load_factor()));
+  globalLocalDataSendToServerMap_.rehash(std::ceil(ssize/globalLocalDataSendToServerMap_.max_load_factor()));
+
 
   // We need to loop with data index
@@ -535,49 +459,33 @@
         if (isCurrentIndexDataCorrect)
         {
-          int gridMaskIndex = 0;
-          for (int k = 0; k < this->numElement_; ++k)
+          bool maskTmp = true;
+          bool maskGridTmp = true;
+          size_t globalIndex = 0;
+          for (int k = 0; k < numElement_; ++k)
           {
-            gridMaskIndex += (currentIndex[k])*elementNLocal_[k];
+            globalIndex += (currentGlobalIndex[k])*elementNGlobal_[k];
           }
-
-          bool maskTmp = true;
-          // If defined, apply grid mask
-         if (!gridMask_.isEmpty())
+          globalDataIndex_[globalIndex] = indexLocalDataOnClientCount;
+          localDataIndex_[indexLocalDataOnClientCount] = countLocalData;
+          globalLocalDataSendToServerMap_[globalIndex] = indexLocalDataOnClientCount;
+          localMaskedDataIndex_[indexLocalDataOnClientCount] = indexLocalDataOnClientCount;
+
+          // Grid mask: unmasked values will be replaces by NaN and then all values will be sent
+          if (!gridMask_.isEmpty())
           {
-            maskTmp =  gridMask_(gridMaskIndex);
+            int gridMaskIndex = 0;
+            for (int k = 0; k < this->numElement_; ++k)
+            {
+              gridMaskIndex += (currentIndex[k])*elementNLocal_[k];
+            }
+            maskGridTmp =  gridMask_(gridMaskIndex);
+            if (maskGridTmp)
+              localMaskIndex_[indexLocalDataOnClientCount] = true;
+            else
+              localMaskIndex_[indexLocalDataOnClientCount] = false;
           }
-          // If grid mask is not defined, apply elements' mask
-          else
-          {
-            int idxDomain = 0, idxAxis = 0;
-            for (int elem = 0; elem < numElement_; ++elem)
-            {
-              if (2 == axisDomainOrder_(elem))
-              {
-                maskTmp = maskTmp && domainMasks_[idxDomain](currentIndex[elem]);
-                ++idxDomain;
-              }
-              else if (1 == axisDomainOrder_(elem))
-              {
-                maskTmp = maskTmp && axisMasks_[idxAxis](currentIndex[elem]);
-                ++idxAxis;
-              }
-            }
-          }
-
-          if (maskTmp)
-          {
-            size_t globalIndex = 0;
-            for (int k = 0; k < numElement_; ++k)
-            {
-              globalIndex += (currentGlobalIndex[k])*elementNGlobal_[k];
-            }
-            globalDataIndex_[globalIndex] = indexLocalDataOnClientCount;
-            localDataIndex_[indexLocalDataOnClientCount] = countLocalData;
-            globalLocalDataSendToServerMap_[globalIndex] = indexLocalDataOnClientCount;
-            localMaskIndex_[indexLocalDataOnClientCount] = gridMaskIndex;
-            localMaskedDataIndex_[indexLocalDataOnClientCount] = indexLocalDataOnClientCount;
-            ++indexLocalDataOnClientCount;
-          }
+
+          ++indexLocalDataOnClientCount;
+
         }
         ++countLocalData;
@@ -586,5 +494,5 @@
     }
     else countLocalData+=innerLoopSize ;
-    
+
     idxLoop[0] += innerLoopSize;
     idx += innerLoopSize;
@@ -614,17 +522,24 @@
                                         const int& dataDim, const int& ni, int& j)
 {
+  int i;
   int tempI = dataIIndex + dataIBegin,
       tempJ = (dataJIndex + dataJBegin);
   if (ni == 0)
   {
-    int i = 0;
-    j = 0;
+    i = -1;
+    j = -1;
     return i;
   }
-  int i = (dataDim == 1) ? (tempI) % ni
-                         : (tempI) ;
-  j = (dataDim == 1) ? (tempI) / ni
-                     : (tempJ) ;
-
+  if ((tempI < 0) || (tempJ < 0))
+  {
+    i = -1;
+    j = -1;
+    return i;
+  }
+  else
+  {
+    i = (dataDim == 1) ? (tempI) % ni : (tempI) ;
+    j = (dataDim == 1) ? (tempI) / ni : (tempJ) ;
+  }
   return i;
 }
@@ -643,5 +558,5 @@
     return -1;
   }
-  int tempI = dataIndex + dataBegin;
+  int tempI = dataIndex;
   if ((tempI < 0) || (tempI > ni))
     return -1;
@@ -677,5 +592,5 @@
   Return local mask index of client
 */
-const std::vector<int>& CDistributionClient::getLocalMaskIndexOnClient()
+const std::vector<bool>& CDistributionClient::getLocalMaskIndexOnClient()
 {
   if (!isComputed_) createGlobalIndexSendToServer();
Index: /XIOS/trunk/src/distribution_client.hpp
===================================================================
--- /XIOS/trunk/src/distribution_client.hpp	(revision 1636)
+++ /XIOS/trunk/src/distribution_client.hpp	(revision 1637)
@@ -33,5 +33,5 @@
 
   public:
-    /** Default constructor */        
+    /** Default constructor */
     CDistributionClient(int rank, CGrid* grid);
 
@@ -44,5 +44,5 @@
     GlobalLocalDataMap& getGlobalLocalDataSendToServer();
     GlobalLocalDataMap& getGlobalDataIndexOnClient();
-    const std::vector<int>& getLocalMaskIndexOnClient();
+    const std::vector<bool>& getLocalMaskIndexOnClient();
     const std::vector<int>& getLocalMaskedDataIndexOnClient();
 
@@ -83,6 +83,19 @@
     GlobalLocalDataMap globalLocalDataSendToServerMap_;
     GlobalLocalDataMap globalDataIndex_;
+
+    /*! Array holding masked data indexes.
+     * It includes:
+     *  masking on data (data_i/j_index or data_ni/nj and data_ibegin)
+     *  masking on grid elements (domains, axes or scalars)
+     * It DOES NOT include grid mask.
+     * The array size defines the data size entering the workflow. It is used by source filter of client or server1.
+    */
     std::vector<int> localDataIndex_;
-    std::vector<int> localMaskIndex_;
+
+    /*! Array holding grid mask. If grid mask is not defined, its size is zero.
+     * It is used by source filter of client for replacing unmasked data by NaN.
+    */
+    std::vector<bool> localMaskIndex_;
+
     std::vector<int> localMaskedDataIndex_;
 
@@ -104,7 +117,4 @@
     std::vector<CArray<int,1> > dataIndex_; //!< Data index
     std::vector<CArray<int,1> > infoIndex_; //!< i_index, j_index
-
-    std::vector<CArray<bool,1> > domainMasks_; //!< Domain mask
-    std::vector<CArray<bool,1> > axisMasks_; //!< Axis mask
 
     std::vector<int> indexMap_; //!< Mapping element index to dimension index
Index: /XIOS/trunk/src/filter/file_writer_filter.cpp
===================================================================
--- /XIOS/trunk/src/filter/file_writer_filter.cpp	(revision 1636)
+++ /XIOS/trunk/src/filter/file_writer_filter.cpp	(revision 1637)
@@ -17,7 +17,7 @@
   void CFileWriterFilter::onInputReady(std::vector<CDataPacketPtr> data)
   {
-    const bool detectMissingValue = (!field->detect_missing_value.isEmpty()
-                                      && !field->default_value.isEmpty()
-                                      && field->detect_missing_value == true);
+    const bool detectMissingValue = ( !field->default_value.isEmpty() &&
+                               ( (!field->detect_missing_value.isEmpty() || field->detect_missing_value == true)
+                                 || field->hasGridMask()) );
 
     CArray<double, 1> dataArray = (detectMissingValue) ? data[0]->data.copy() : data[0]->data;
Index: /XIOS/trunk/src/filter/source_filter.cpp
===================================================================
--- /XIOS/trunk/src/filter/source_filter.cpp	(revision 1636)
+++ /XIOS/trunk/src/filter/source_filter.cpp	(revision 1637)
@@ -7,5 +7,6 @@
 namespace xios
 {
-  CSourceFilter::CSourceFilter(CGarbageCollector& gc, CGrid* grid, bool compression, 
+  CSourceFilter::CSourceFilter(CGarbageCollector& gc, CGrid* grid,
+                               bool compression /*= true*/, bool mask /*= false*/,
                                const CDuration offset /*= NoneDu*/, bool manualTrigger /*= false*/,
                                bool hasMissingValue /*= false*/,
@@ -14,4 +15,5 @@
     , grid(grid)
     , compression(compression)
+    , mask(mask)
     , offset(offset)
     , hasMissingValue(hasMissingValue), defaultValue(defaultValue)
@@ -40,16 +42,10 @@
     }
     else
-      grid->inputField(data, packet->data);
-
-    
-    
-    // if (compression) grid->inputField(data, packet->data) ;
-    // else
-    // {
-    //   // just make a flat copy
-    //   CArray<double, N> data_tmp(data.copy()) ; // supress const attribute
-    //   CArray<double,1> dataTmp2(data_tmp.dataFirst(),shape(data.numElements()),neverDeleteData) ;
-    //   packet->data = dataTmp2 ;
-    // }
+    {
+      if (mask)
+        grid->maskField(data, packet->data);
+      else
+        grid->inputField(data, packet->data);
+    }
     // Convert missing values to NaN
     if (hasMissingValue)
Index: /XIOS/trunk/src/filter/source_filter.hpp
===================================================================
--- /XIOS/trunk/src/filter/source_filter.hpp	(revision 1636)
+++ /XIOS/trunk/src/filter/source_filter.hpp	(revision 1637)
@@ -21,4 +21,6 @@
        * \param gc the garbage collector associated with this filter
        * \param grid the grid to which the data is attached
+       * \param compression
+       * \param mask
        * \param offset the offset applied to the timestamp of all packets
        * \param manualTrigger whether the output should be triggered manually
@@ -27,5 +29,6 @@
        */
       CSourceFilter(CGarbageCollector& gc, CGrid* grid,
-                    bool compression=true,
+                    bool compression = true,
+                    bool mask = false,
                     const CDuration offset = NoneDu, bool manualTrigger = false,
                     bool hasMissingValue = false,
@@ -61,9 +64,10 @@
 
     private:
-      CGrid* grid; //!< The grid attached to the data the filter can accept
-      const CDuration offset; //!< The offset applied to the timestamp of all packets
+      CGrid* grid;             //!< The grid attached to the data the filter can accept
+      const CDuration offset;  //!< The offset applied to the timestamp of all packets
       const bool hasMissingValue;
       const double defaultValue;
-      const bool compression ; //!< indicate if the data need to be compressed : on client size : true, on server side : false
+      const bool compression ; //!< indicates if data need to be compressed : on client side : true, on server side : false
+      const bool mask ;        //!< indicates whether grid mask should be applied (true for clients, false for servers)
   }; // class CSourceFilter
 } // namespace xios
Index: /XIOS/trunk/src/filter/spatial_transform_filter.cpp
===================================================================
--- /XIOS/trunk/src/filter/spatial_transform_filter.cpp	(revision 1636)
+++ /XIOS/trunk/src/filter/spatial_transform_filter.cpp	(revision 1637)
@@ -68,8 +68,4 @@
       onOutputReady(outputPacket);
   }
-
-
-
-
 
   CSpatialTemporalFilter::CSpatialTemporalFilter(CGarbageCollector& gc, CSpatialTransformFilterEngine* engine, CGridTransformation* gridTransformation, double outputValue, size_t inputSlotsCount)
@@ -201,5 +197,4 @@
     const std::list<CGridTransformation::RecvIndexGridDestinationMap>& listLocalIndexToReceive = gridTransformation->getLocalIndexToReceiveOnGridDest();
     const std::list<size_t>& listNbLocalIndexToReceive = gridTransformation->getNbLocalIndexToReceiveOnGridDest();
-    const std::list<std::vector<bool> >& listLocalIndexMaskOnDest = gridTransformation->getLocalMaskIndexOnGridDest();
     const std::vector<CGenericAlgorithmTransformation*>& listAlgos = gridTransformation->getAlgos();
 
@@ -210,8 +205,7 @@
     std::list<CGridTransformation::RecvIndexGridDestinationMap>::const_iterator itListRecv = listLocalIndexToReceive.begin();
     std::list<size_t>::const_iterator itNbListRecv = listNbLocalIndexToReceive.begin();
-    std::list<std::vector<bool> >::const_iterator itLocalMaskIndexOnDest = listLocalIndexMaskOnDest.begin();
     std::vector<CGenericAlgorithmTransformation*>::const_iterator itAlgo = listAlgos.begin();
 
-    for (; itListSend != iteListSend; ++itListSend, ++itListRecv, ++itNbListRecv, ++itLocalMaskIndexOnDest, ++itAlgo)
+    for (; itListSend != iteListSend; ++itListSend, ++itListRecv, ++itNbListRecv, ++itAlgo)
     {
       CArray<double,1> dataCurrentSrc(dataCurrentDest);
@@ -266,8 +260,5 @@
 
       dataCurrentDest.resize(*itNbListRecv);
-      const std::vector<bool>& localMaskDest = *itLocalMaskIndexOnDest;
-      for (int i = 0; i < localMaskDest.size(); ++i)
-        if (localMaskDest[i]) dataCurrentDest(i) = 0.0;
-        else dataCurrentDest(i) = defaultValue;
+      dataCurrentDest = 0.0;
 
       std::vector<bool> localInitFlag(dataCurrentDest.numElements(), true);
Index: /XIOS/trunk/src/io/nc4_data_output.cpp
===================================================================
--- /XIOS/trunk/src/io/nc4_data_output.cpp	(revision 1636)
+++ /XIOS/trunk/src/io/nc4_data_output.cpp	(revision 1637)
@@ -155,5 +155,5 @@
 */
 
-         CArray<size_t, 1>& indexToWrite = domain->localIndexToWriteOnServer;
+         CArray<int, 1>& indexToWrite = domain->localIndexToWriteOnServer;
          int nbWritten = indexToWrite.numElements();
          CArray<double,1> writtenLat, writtenLon;
@@ -167,16 +167,15 @@
            for (int idx = 0; idx < nbWritten; ++idx)
            {
-        	  if (idx < domain->latvalue.numElements())
-        	  {
-                writtenLat(idx) = domain->latvalue(indexToWrite(idx));
-                writtenLon(idx) = domain->lonvalue(indexToWrite(idx));
-        	  }
-        	  else
-        	  {
-                writtenLat(idx) = 0.;
-                writtenLon(idx) = 0.;
-        	  }
+             if (indexToWrite(idx) < 0)
+             {
+               writtenLat(idx) = -1.;   // hole
+               writtenLon(idx) = -1.;
+             }
+             else
+             {
+               writtenLat(idx) = domain->latvalue(indexToWrite(idx));
+               writtenLon(idx) = domain->lonvalue(indexToWrite(idx));
+             }
            }
-         
 
            if (domain->hasBounds)
@@ -190,14 +189,14 @@
                for (int nv = 0; nv < nvertex; ++nv)
                {
-            	 if (idx < boundslat.columns())
-            	 {
+                 if (indexToWrite(idx) < 0)
+                 {
+                   writtenBndsLat(nv, idx) = -1.;  // hole
+                   writtenBndsLon(nv, idx) = -1.;
+                 }
+                 else
+                 {
                    writtenBndsLat(nv, idx) = boundslat(nv, int(indexToWrite(idx)));
                    writtenBndsLon(nv, idx) = boundslon(nv, int(indexToWrite(idx)));
-            	 }
-            	 else
-            	 {
-                   writtenBndsLat(nv, idx) = 0.;
-                   writtenBndsLon(nv, idx) = 0.;
-            	 }
+                 }
                }
            }
@@ -209,8 +208,8 @@
            for (int idx = 0; idx < nbWritten; ++idx)
            {
-        	  if (idx < domain->areavalue.numElements())
-                writtenArea(idx) = domain->areavalue(indexToWrite(idx));
+        	  if (indexToWrite(idx) < 0)
+              writtenArea(idx) = -1.;
         	  else
-                writtenArea(idx) = 0.;
+              writtenArea(idx) = domain->areavalue(indexToWrite(idx));
            }
          }
@@ -427,10 +426,11 @@
                      std::vector<StdSize> start(2) ;
                      std::vector<StdSize> count(2) ;
-                     if (domain->isEmpty())
-                     {
-                       start[0]=0 ; start[1]=0 ;
-                       count[0]=0 ; count[1]=0 ;
-                     }
-                     else
+// Comment out: it is not working for a hole
+//                     if (domain->isEmpty())
+//                     {
+//                       start[0]=0 ; start[1]=0 ;
+//                       count[0]=0 ; count[1]=0 ;
+//                     }
+//                     else
                      {
                        start[1]=domain->ibegin;
@@ -877,4 +877,7 @@
           case (MULTI_FILE) :
           {
+            ERROR("CNc4DataOutput::writeDomain(domain)",
+            << "[ type = multiple_file ]"
+            << " is not yet implemented for UGRID files !");
             break;
           }
@@ -942,5 +945,5 @@
          int nvertex = (domain->nvertex.isEmpty()) ? 0 : domain->nvertex;
 
-         CArray<size_t, 1>& indexToWrite = domain->localIndexToWriteOnServer;
+         CArray<int, 1>& indexToWrite = domain->localIndexToWriteOnServer;
          int nbWritten = indexToWrite.numElements();
          CArray<double,1> writtenLat, writtenLon;
@@ -954,14 +957,14 @@
            for (int idx = 0; idx < nbWritten; ++idx)
            {
-       	     if (idx < domain->latvalue.numElements())
-     	     {
-               writtenLat(idx) = domain->latvalue(indexToWrite(idx));
-               writtenLon(idx) = domain->lonvalue(indexToWrite(idx));
-     	     }
-     	     else
-     	     {
-               writtenLat(idx) = 0.;
-               writtenLon(idx) = 0.;
-     	     }
+       	     if (indexToWrite(idx) < 0)
+       	     {
+               writtenLat(idx) = -1.;
+               writtenLon(idx) = -1.;
+       	     }
+       	     else
+       	     {
+       	       writtenLat(idx) = domain->latvalue(indexToWrite(idx));
+       	       writtenLon(idx) = domain->lonvalue(indexToWrite(idx));
+       	     }
            }
          }
@@ -978,13 +981,13 @@
              for (int nv = 0; nv < nvertex; ++nv)
              {
-               if (idx < boundslat.columns())
+               if (indexToWrite(idx) < 0)
+               {
+                 writtenBndsLat(nv, idx) = -1.;
+                 writtenBndsLon(nv, idx) = -1.;
+               }
+               else
                {
                  writtenBndsLat(nv, idx) = boundslat(nv, int(indexToWrite(idx)));
                  writtenBndsLon(nv, idx) = boundslon(nv, int(indexToWrite(idx)));
-               }
-               else
-               {
-                 writtenBndsLat(nv, idx) = 0.;
-                 writtenBndsLon(nv, idx) = 0.;
                 }
              }
@@ -997,8 +1000,8 @@
            for (int idx = 0; idx < nbWritten; ++idx)
            {
-        	  if (idx < domain->areavalue.numElements())
-                writtenArea(idx) = domain->areavalue(indexToWrite(idx));
-        	  else
-                writtenArea(idx) = 0.;
+             if (indexToWrite(idx) < 0)
+               writtenArea(idx) = -1.;
+             else
+               writtenArea(idx) = domain->areavalue(indexToWrite(idx));
            }
          }
@@ -1277,5 +1280,5 @@
           SuperClassWriter::definition_end();
 
-          CArray<size_t, 1>& indexToWrite = axis->localIndexToWriteOnServer;
+          CArray<int, 1>& indexToWrite = axis->localIndexToWriteOnServer;
           int nbWritten = indexToWrite.numElements();
           CArray<double,1> axis_value(indexToWrite.numElements());
@@ -1284,8 +1287,8 @@
             for (int i = 0; i < nbWritten; i++)
             {
-              if (i < axis->value.numElements())
+              if (indexToWrite(i) < 0)
+                axis_value(i) = -1;   // Some value in case of a hole
+              else
                 axis_value(i) = axis->value(indexToWrite(i));
-              else
-                axis_value(i) = 0.;
             }
           }
@@ -1297,8 +1300,8 @@
             for (int i = 0; i < nbWritten; i++)
             {
-              if (i < axis->label.numElements())
+              if (indexToWrite(i) < 0)
+                axis_label(i) = boost::lexical_cast<string>(-1);  // Some value in case of a hole
+              else
                 axis_label(i) = axis->label(indexToWrite(i));
-              else
-                axis_label(i) = boost::lexical_cast<string>(0);  // Write 0 as a label
             }
           }
@@ -1318,14 +1321,13 @@
                   for (int i = 0; i < nbWritten; ++i)
                   {
-                    if (i < axis->bounds.columns())
+                    if (indexToWrite(i) < 0)
+                    {
+                      axis_bounds(0, i) = -1.; // Some value in case of a hole
+                      axis_bounds(1, i) = -1.;
+                    }
+                    else
                     {
                       axis_bounds(0, i) = axis->bounds(0, int(indexToWrite(i)));
                       axis_bounds(1, i) = axis->bounds(1, int(indexToWrite(i)));
-                    }
-                    else
-                    {
-                      axis_bounds(0, i) = 0.;
-                      axis_bounds(1, i) = 0.;
-
                     }
                   }
@@ -1358,13 +1360,13 @@
                   for (int i = 0; i < nbWritten; ++i)
                   {
-                    if (i < axis->bounds.columns())
+                    if (indexToWrite(i) < 0)
+                    {
+                      axis_bounds(0, i) = -1.;
+                      axis_bounds(1, i) = -1.;
+                    }
+                    else
                     {
                       axis_bounds(0, i) = axis->bounds(0, int(indexToWrite(i)));
                       axis_bounds(1, i) = axis->bounds(1, int(indexToWrite(i)));
-                    }
-                    else
-                    {
-                      axis_bounds(0, i) = 0.;
-                      axis_bounds(1, i) = 0.;
                     }
                   }
Index: /XIOS/trunk/src/node/axis.cpp
===================================================================
--- /XIOS/trunk/src/node/axis.cpp	(revision 1636)
+++ /XIOS/trunk/src/node/axis.cpp	(revision 1637)
@@ -274,5 +274,7 @@
    TRY
    {
-      if (this->n_glo.isEmpty())
+     CContext* context=CContext::getCurrent();
+
+     if (this->n_glo.isEmpty())
         ERROR("CAxis::checkAttributes(void)",
               << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] "
@@ -314,12 +316,16 @@
       }
 
-      // Remove this check because it doesn't make sense in case of a hole or overlapping axes
       if (!this->value.isEmpty())
       {
-//        StdSize true_size = value.numElements();
-//        if (this->n.getValue() != true_size)
-//          ERROR("CAxis::checkAttributes(void)",
-//                << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] "
-//                << "The axis is wrongly defined, attribute 'value' has a different size (" << true_size << ") than the one defined by the \'size\' attribute (" << n.getValue() << ").");
+        // Avoid this check at writing because it fails in case of a hole
+        if (context->hasClient)
+        {
+          StdSize true_size = value.numElements();
+          if (this->n.getValue() != true_size)
+            ERROR("CAxis::checkAttributes(void)",
+                << "[ id = '" << getId() << "' , context = '" << CObjectFactory::GetCurrentContextId() << "' ] "
+                << "The axis is wrongly defined, attribute 'value' has a different size (" << true_size
+                << ") than the one defined by the \'size\' attribute (" << n.getValue() << ").");
+        }
         this->hasValue = true;
       }
@@ -327,9 +333,8 @@
       this->checkBounds();
 
-      CContext* context=CContext::getCurrent();
       if (context->hasClient)
       {
+        this->checkMask();
         this->checkData();
-        this->checkMask();
         this->checkLabel();
       }
@@ -338,5 +343,5 @@
 
    /*!
-      Check the validity of data and fill in values if any.
+      Check the validity of data, fill in values if any, and apply mask.
    */
    void CAxis::checkData()
@@ -359,6 +364,32 @@
       {
         data_index.resize(data_n);
-        for (int i = 0; i < data_n; ++i) data_index(i) = i;
-      }
+        for (int i = 0; i < data_n; ++i)
+        {
+          if ((i+data_begin) >= 0 && (i+data_begin<n))
+          {
+            if (mask(i+data_begin))
+              data_index(i) = i+data_begin;
+            else
+              data_index(i) = -1;
+          }
+          else
+            data_index(i) = -1;
+        }
+      }
+      else
+      {
+        if (data_index.numElements() != data_n)
+        {
+          ERROR("CAxis::checkData(void)",
+                << "[ id = " << this->getId() << " , context = '" << CObjectFactory::GetCurrentContextId() << " ] "
+                << "The size of data_index = "<< data_index.numElements() << "is not equal to the data size data_n = " << data_n.getValue() << ").");
+        }
+        for (int i = 0; i < data_n; ++i)
+        {
+          if ((i+data_begin) >= 0 && (i+data_begin<n) && !mask(i+data_begin))
+            data_index(i) = -1;
+        }
+      }
+
    }
    CATCH_DUMP_ATTR
@@ -377,18 +408,17 @@
       if (!mask.isEmpty())
       {
-         if (mask.extent(0) != n)
-           ERROR("CAxis::checkMask(void)",
-                 << "[ id = " << this->getId() << " , context = '" << CObjectFactory::GetCurrentContextId() << " ] "
-                 << "The mask does not have the same size as the local domain." << std::endl
-                 << "Local size is " << n.getValue() << "." << std::endl
-                 << "Mask size is " << mask.extent(0) << ".");
-      }
-      else // (mask.isEmpty())
-      { // If no mask was defined, we create a default one without any masked point.
-         mask.resize(n);
-         for (int i = 0; i < n; ++i)
-         {
-           mask(i) = true;
-         }
+        if (mask.extent(0) != n)
+        {
+          ERROR("CAxis::checkMask(void)",
+              << "[ id = " << this->getId() << " , context = '" << CObjectFactory::GetCurrentContextId() << " ] "
+              << "The mask does not have the same size as the local domain." << std::endl
+              << "Local size is " << n.getValue() << "." << std::endl
+              << "Mask size is " << mask.extent(0) << ".");
+        }
+      }
+      else
+      {
+        mask.resize(n);
+        mask = true;
       }
    }
@@ -598,18 +628,18 @@
 
         // Calculate the compressed index if any
-        std::set<int> writtenInd;
-        if (isCompressible_)
-        {
-          for (int idx = 0; idx < data_index.numElements(); ++idx)
-          {
-            int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, ni);
-
-            if (ind >= 0 && ind < ni && mask(ind))
-            {
-              ind += ibegin;
-              writtenInd.insert(ind);
-            }
-          }
-        }
+//        std::set<int> writtenInd;
+//        if (isCompressible_)
+//        {
+//          for (int idx = 0; idx < data_index.numElements(); ++idx)
+//          {
+//            int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, ni);
+//
+//            if (ind >= 0 && ind < ni && mask(ind))
+//            {
+//              ind += ibegin;
+//              writtenInd.insert(ind);
+//            }
+//          }
+//        }
 
         // Compute the global index of the current client (process) hold
@@ -680,5 +710,5 @@
           connectedServerRank_[nbServer].push_back(client->clientRank % client->serverSize);
 
-         nbSenders[nbServer] = CClientServerMapping::computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_[nbServer]);
+        nbSenders[nbServer] = CClientServerMapping::computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_[nbServer]);
 
         delete clientServerMap;
@@ -718,4 +748,7 @@
     CArray<size_t,1>::const_iterator itSrvb = writtenGlobalIndex.begin(),
                                      itSrve = writtenGlobalIndex.end(), itSrv;  
+
+    localIndexToWriteOnServer.resize(writtenGlobalIndex.numElements());
+    nbWritten = 0;
     for (itSrv = itSrvb; itSrv != itSrve; ++itSrv)
     {
@@ -723,21 +756,13 @@
       if (ite != globalLocalIndexMap_.find(indGlo))
       {
-        ++nbWritten;
-      }
-    }
-
-    localIndexToWriteOnServer.resize(writtenGlobalIndex.numElements());
-//      localIndexToWriteOnServer.resize(nbWritten);
-
-    nbWritten = 0;
-    for (itSrv = itSrvb; itSrv != itSrve; ++itSrv)
-    {
-      indGlo = *itSrv;
-      if (ite != globalLocalIndexMap_.find(indGlo))
-      {
         localIndexToWriteOnServer(nbWritten) = globalLocalIndexMap_[indGlo];
-        ++nbWritten;
-      }
-    }
+      }
+      else
+      {
+        localIndexToWriteOnServer(nbWritten) = -1;
+      }
+      ++nbWritten;
+    }
+
   }
   CATCH_DUMP_ATTR
@@ -780,4 +805,24 @@
         }                 
       }
+//
+//      nbWritten = 0;
+//      for (int idx = 0; idx < data_index.numElements(); ++idx)
+//      {
+//        if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_index(idx)))
+//        {
+//          ++nbWritten;
+//        }
+//      }
+//
+//      compressedIndexToWriteOnServer[writtenCommSize].resize(nbWritten);
+//      nbWritten = 0;
+//      for (int idx = 0; idx < data_index.numElements(); ++idx)
+//      {
+//        if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_index(idx)))
+//        {
+//          compressedIndexToWriteOnServer[writtenCommSize](nbWritten) = localGlobalIndexMap[data_index(idx)];
+//          ++nbWritten;
+//        }
+//      }
 
       nbWritten = 0;
@@ -1027,12 +1072,12 @@
 
   /*
-    Send attributes of axis from a group of client to other group of clients/servers 
-    on supposing that these attributes are distributed among the clients of the sending group
-    In the future, if new attributes are added, they should also be processed in this function
+    Send axis attributes from a group of clients to another group of clients/servers
+    supposing that these attributes are distributed among the clients of the sending group
+    In future, if new attributes are added, they should also be processed in this function
   */
   void CAxis::sendDistributedAttributes(void)
   TRY
   {
-    int ns, n, i, j, ind, nv, idx;
+    int ind, idx;
     std::list<CContextClient*>::iterator it;
 
@@ -1046,9 +1091,9 @@
       list<CMessage> listData;
       list<CArray<int,1> > list_indi, list_dataInd;
-      list<CArray<bool,1> > list_mask;
       list<CArray<double,1> > list_val;
       list<CArray<double,2> > list_bounds;
       list<CArray<string,1> > list_label;
 
+      // Cut off the ghost points
       int nbIndex = index.numElements();
       CArray<int,1> dataIndex(nbIndex);
@@ -1057,5 +1102,5 @@
       {
         if (0 <= data_index(idx) && data_index(idx) < nbIndex)
-          dataIndex(idx) = 1;
+          dataIndex(data_index(idx)) = 1;
       }
 
@@ -1064,5 +1109,5 @@
       for (int k = 0; k < connectedServerRank_[nbServer].size(); ++k)
       {
-        int nbData = 0;
+        int nbData = 0, nbDataCount = 0;
         int rank = connectedServerRank_[nbServer][k];
         it = indSrv_[nbServer].find(rank);
@@ -1071,6 +1116,5 @@
 
         list_indi.push_back(CArray<int,1>(nbData));
-        list_dataInd.push_back(CArray<int,1>(nbData));        
-        list_mask.push_back(CArray<bool,1>(nbData));
+        list_dataInd.push_back(CArray<int,1>(nbData));
 
         if (hasValue)
@@ -1084,8 +1128,8 @@
 
         CArray<int,1>& indi = list_indi.back();
-        CArray<int,1>& dataIndi = list_dataInd.back();        
-        CArray<bool,1>& maskIndi = list_mask.back();
-
-        for (n = 0; n < nbData; ++n)
+        CArray<int,1>& dataIndi = list_dataInd.back();
+        dataIndi = -1;
+
+        for (int n = 0; n < nbData; ++n)
         {
           idx = static_cast<int>(it->second[n]);
@@ -1094,5 +1138,4 @@
           ind = globalLocalIndexMap_[idx];
           dataIndi(n) = dataIndex(ind);
-          maskIndi(n) = mask(ind);
 
           if (hasValue)
@@ -1118,5 +1161,5 @@
         listData.push_back(CMessage());
         listData.back() << this->getId()
-                        << list_indi.back() << list_dataInd.back() << list_mask.back();
+                        << list_indi.back() << list_dataInd.back();
 
         listData.back() << hasValue;
@@ -1173,5 +1216,4 @@
     int nbReceived = ranks.size(), idx, ind, gloInd, locInd;
     vector<CArray<int,1> > vec_indi(nbReceived), vec_dataInd(nbReceived);
-    vector<CArray<bool,1> > vec_mask(nbReceived);
     vector<CArray<double,1> > vec_val(nbReceived);
     vector<CArray<double,2> > vec_bounds(nbReceived);
@@ -1183,5 +1225,4 @@
       buffer >> vec_indi[idx];
       buffer >> vec_dataInd[idx];      
-      buffer >> vec_mask[idx];
 
       buffer >> hasValue;
@@ -1220,6 +1261,6 @@
          if (0 == globalLocalIndexMap_.count(gloInd))
          {
-           index(nbIndLoc) = gloInd % n_glo;
-           globalLocalIndexMap_[gloInd] = nbIndLoc;
+           index(nbIndexGlob) = gloInd % n_glo;
+           globalLocalIndexMap_[gloInd] = nbIndexGlob;
            ++nbIndexGlob;
          } 
@@ -1234,5 +1275,6 @@
     CArray<int,1> nonCompressedData(nbData);
     nonCompressedData = -1;   
-    mask.resize(nbData);
+    // Mask is incorporated into data_index and is not sent/received anymore
+    mask.resize(0);
     if (hasValue)
       value.resize(nbData);
@@ -1247,5 +1289,4 @@
       CArray<int,1>& indi = vec_indi[idx];
       CArray<int,1>& dataIndi = vec_dataInd[idx];
-      CArray<bool,1>& maskIndi = vec_mask[idx];
       int nb = indi.numElements();
       for (int n = 0; n < nb; ++n)
@@ -1255,7 +1296,4 @@
         nonCompressedData(locInd) = (-1 == nonCompressedData(locInd)) ? dataIndi(n) : nonCompressedData(locInd);
 
-        if (!mask(locInd)) // Only rewrite mask if it's not true
-          mask(locInd) = maskIndi(n);
-        
         if (hasValue)
           value(locInd) = vec_val[idx](n);
@@ -1272,9 +1310,9 @@
     }
     
-    int nbCompressedData = 0; 
+    int nbCompressedData = 0;
     for (idx = 0; idx < nonCompressedData.numElements(); ++idx)
     {
       if (0 <= nonCompressedData(idx))
-        ++nbCompressedData;        
+        ++nbCompressedData;
     }
 
@@ -1286,9 +1324,10 @@
       {
         data_index(nbCompressedData) = idx % n;
-        ++nbCompressedData;        
+        ++nbCompressedData;
       }
     }
 
     data_begin.setValue(0);
+    data_n.setValue(data_index.numElements());
   }
   CATCH_DUMP_ATTR
Index: /XIOS/trunk/src/node/axis.hpp
===================================================================
--- /XIOS/trunk/src/node/axis.hpp	(revision 1636)
+++ /XIOS/trunk/src/node/axis.hpp	(revision 1637)
@@ -126,5 +126,5 @@
         bool hasLabel;
 
-        CArray<size_t,1> localIndexToWriteOnServer;        
+        CArray<int,1> localIndexToWriteOnServer;
 
       private:
Index: /XIOS/trunk/src/node/domain.cpp
===================================================================
--- /XIOS/trunk/src/node/domain.cpp	(revision 1636)
+++ /XIOS/trunk/src/node/domain.cpp	(revision 1637)
@@ -179,10 +179,4 @@
        // size estimation for sendIndex (and sendArea which is always smaller or equal)
        size_t sizeIndexEvent = 2 * sizeof(size_t) + 2 * CArray<int,1>::size(idxCount);
-       // if (isCompressible_)
-       // {
-       //   std::map<int, std::vector<int> >::const_iterator itWritten = indWrittenSrv_.find(rank);
-       //   size_t writtenIdxCount = (itWritten != itWrittenIndexEnd) ? itWritten->second.size() : 0;
-       //   sizeIndexEvent += CArray<int,1>::size(writtenIdxCount);
-       // }
 
        // size estimation for sendLonLat
@@ -1139,4 +1133,5 @@
    TRY
    {
+     int i,j,ind;
       if (!data_i_index.isEmpty())
       {
@@ -1159,4 +1154,23 @@
                    << "'data_j_index' must be defined when 'data_i_index' is set and 'data_dim' is 2.");
           }
+          for (int k=0; k<data_i_index.numElements(); ++k)
+          {
+            i = data_i_index(k)+data_ibegin ;
+            j = data_j_index(k)+data_jbegin ;
+            if (i>=0 && i<ni && j>=0 && j<nj)
+            {
+              ind=j*ni+i ;
+              if (!domainMask(ind))
+              {
+                data_i_index(k) = -1;
+                data_j_index(k) = -1;
+              }
+            }
+            else
+            {
+              data_i_index(k) = -1;
+              data_j_index(k) = -1;
+            }
+          }
         }
         else // (1 == data_dim)
@@ -1165,5 +1179,17 @@
           {
             data_j_index.resize(data_ni);
-            for (int j = 0; j < data_ni; ++j) data_j_index(j) = 0;
+            data_j_index = 0;
+          }
+          for (int k=0; k<data_i_index.numElements(); ++k)
+          {
+            i=data_i_index(k)+data_ibegin ;
+            if (i>=0 && i < domainMask.size())
+            {
+              if (!domainMask(i)) data_i_index(k) = -1;
+            }
+            else
+              data_i_index(k) = -1;
+
+            if (!domainMask(i)) data_i_index(k) = -1;
           }
         }
@@ -1180,9 +1206,18 @@
           data_i_index.resize(data_ni);
           data_j_index.resize(data_ni);
-
-          for (int i = 0; i < data_ni; ++i)
+          data_j_index = 0;
+
+          for (int k = 0; k < data_ni; ++k)
           {
-            data_i_index(i) = i;
-            data_j_index(i) = 0;
+            i=k+data_ibegin ;
+            if (i>=0 && i < domainMask.size())
+            {
+              if (domainMask(i))
+                data_i_index(k) = k;
+              else
+                data_i_index(k) = -1;
+            }
+            else
+              data_i_index(k) = -1;
           }
         }
@@ -1193,10 +1228,29 @@
           data_j_index.resize(dsize);
 
-          for(int count = 0, j = 0; j < data_nj; ++j)
+          for(int count = 0, kj = 0; kj < data_nj; ++kj)
           {
-            for(int i = 0; i < data_ni; ++i, ++count)
+            for(int ki = 0; ki < data_ni; ++ki, ++count)
             {
-              data_i_index(count) = i;
-              data_j_index(count) = j;
+              i = ki + data_ibegin;
+              j = kj + data_jbegin;
+              ind=j*ni+i ;
+              if (i>=0 && i<ni && j>=0 && j<nj)
+              {
+                if (domainMask(ind))
+                {
+                  data_i_index(count) = ki;
+                  data_j_index(count) = kj;
+                }
+                else
+                {
+                  data_i_index(count) = -1;
+                  data_j_index(count) = -1;
+                }
+              }
+              else
+              {
+                data_i_index(count) = -1;
+                data_j_index(count) = -1;
+              }
             }
           }
@@ -1872,4 +1926,27 @@
             connectedServerRank_[nbServer].push_back(client->clientRank % client->serverSize);
 
+          // Now check if all servers have data to receive. If not, master client will send empty data.
+          // This ensures that all servers will participate in collective calls upon receiving even if they have no date to receive.
+          std::vector<int> counts (clientSize);
+          std::vector<int> displs (clientSize);
+          displs[0] = 0;
+          int localCount = connectedServerRank_[nbServer].size() ;
+          MPI_Gather(&localCount, 1, MPI_INT, &counts[0], 1, MPI_INT, 0, client->intraComm) ;
+          for (int i = 0; i < clientSize-1; ++i)
+          {
+            displs[i+1] = displs[i] + counts[i];
+          }
+          std::vector<int> allConnectedServers(displs[clientSize-1]+counts[clientSize-1]);
+          MPI_Gatherv(&(connectedServerRank_[nbServer])[0], localCount, MPI_INT, &allConnectedServers[0], &counts[0], &displs[0], MPI_INT, 0, client->intraComm);
+
+          if ((allConnectedServers.size() != nbServer) && (rank == 0))
+          {
+            std::vector<bool> isSrvConnected (nbServer, false);
+            for (int i = 0; i < allConnectedServers.size(); ++i) isSrvConnected[allConnectedServers[i]] = true;
+            for (int i = 0; i < nbServer; ++i)
+            {
+              if (!isSrvConnected[i]) connectedServerRank_[nbServer].push_back(i);
+            }
+          }
           nbSenders[nbServer] = clientServerMap->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_[nbServer]);
           delete clientServerMap;
@@ -1908,16 +1985,5 @@
                                        itSrve = writtenGlobalIndex.end(), itSrv;
 
-//      for (itSrv = itSrvb; itSrv != itSrve; ++itSrv)
-//      {
-//        indGlo = *itSrv;
-//        if (ite != globalLocalIndexMap_.find(indGlo))
-//        {
-//          ++nbWritten;
-//        }
-//      }
-
-//      localIndexToWriteOnServer.resize(nbWritten);
       localIndexToWriteOnServer.resize(writtenGlobalIndex.numElements());
-
       nbWritten = 0;
       for (itSrv = itSrvb; itSrv != itSrve; ++itSrv)
@@ -1927,57 +1993,11 @@
         {
           localIndexToWriteOnServer(nbWritten) = globalLocalIndexMap_[indGlo];
-          ++nbWritten;
         }
         else
         {
-          localIndexToWriteOnServer(nbWritten) = 0;
-          ++nbWritten;
-        }
-      }
-      
-      // if (isCompressible())
-      // {
-      //   nbWritten = 0;
-      //   std::unordered_map<size_t,size_t> localGlobalIndexMap;
-      //   for (itSrv = itSrvb; itSrv != itSrve; ++itSrv)
-      //   {
-      //     indGlo = *itSrv;
-      //     if (ite != globalLocalIndexMap_.find(indGlo))
-      //     {
-      //       localGlobalIndexMap[localIndexToWriteOnServer(nbWritten)] = indGlo;
-      //       ++nbWritten;
-      //     }                 
-      //   }
-
-      //   nbWritten = 0;
-      //   for (int idx = 0; idx < data_i_index.numElements(); ++idx)
-      //   {
-      //     if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_i_index(idx)))
-      //     {
-      //       ++nbWritten;
-      //     }
-      //   }
-
-      //   compressedIndexToWriteOnServer.resize(nbWritten);
-      //   nbWritten = 0;
-      //   for (int idx = 0; idx < data_i_index.numElements(); ++idx)
-      //   {
-      //     if (localGlobalIndexMap.end() != localGlobalIndexMap.find(data_i_index(idx)))
-      //     {
-      //       compressedIndexToWriteOnServer(nbWritten) = localGlobalIndexMap[data_i_index(idx)];
-      //       ++nbWritten;
-      //     }
-      //   }
-
-      //   numberWrittenIndexes_ = nbWritten;
-      //   if (isDistributed())
-      //   {            
-      //     MPI_Allreduce(&numberWrittenIndexes_, &totalNumberWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm);
-      //     MPI_Scan(&numberWrittenIndexes_, &offsetWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm);
-      //     offsetWrittenIndexes_ -= numberWrittenIndexes_;
-      //   }
-      //   else
-      //     totalNumberWrittenIndexes_ = numberWrittenIndexes_;
-      // }      
+          localIndexToWriteOnServer(nbWritten) = -1;
+        }
+        ++nbWritten;
+      }
    }
    CATCH_DUMP_ATTR
@@ -2063,5 +2083,4 @@
     sendDistributionAttributes();
     sendIndex();       
-    sendMask();
     sendLonLat();
     sendArea();    
@@ -2174,50 +2193,4 @@
 
   /*!
-    Send mask index from client to connected(s) clients    
-  */
-  void CDomain::sendMask()
-  TRY
-  {
-    int ns, n, i, j, ind, nv, idx;
-    std::list<CContextClient*>::iterator it;
-    for (it=clients.begin(); it!=clients.end(); ++it)
-    {
-      CContextClient* client = *it;
-      int serverSize = client->serverSize;
-
-      // send area for each connected server
-      CEventClient eventMask(getType(), EVENT_ID_MASK);
-
-      list<CMessage> list_msgsMask;
-      list<CArray<bool,1> > list_mask;
-
-      std::unordered_map<int, vector<size_t> >::const_iterator it, iteMap;
-      iteMap = indSrv_[serverSize].end();
-      for (int k = 0; k < connectedServerRank_[serverSize].size(); ++k)
-      {
-        int nbData = 0;
-        int rank = connectedServerRank_[serverSize][k];
-        it = indSrv_[serverSize].find(rank);
-        if (iteMap != it)
-          nbData = it->second.size();
-        list_mask.push_back(CArray<bool,1>(nbData));
-
-        const std::vector<size_t>& temp = it->second;
-        for (n = 0; n < nbData; ++n)
-        {
-          idx = static_cast<int>(it->second[n]);
-          list_mask.back()(n) = domainMask(globalLocalIndexMap_[idx]);
-        }
-
-        list_msgsMask.push_back(CMessage());
-        list_msgsMask.back() << this->getId() << list_mask.back();
-        eventMask.push(rank, nbSenders[serverSize][rank], list_msgsMask.back());
-      }
-      client->sendEvent(eventMask);
-    }
-  }
-  CATCH_DUMP_ATTR
-
-  /*!
     Send area from client to connected client(s)
   */
@@ -2458,8 +2431,4 @@
         case EVENT_ID_INDEX:
           recvIndex(event);
-          return true;
-          break;
-        case EVENT_ID_MASK:
-          recvMask(event);
           return true;
           break;
@@ -2555,15 +2524,8 @@
            jIndex = (jIndex < 0) ? 0 : jIndex;
            nbIndLoc = iIndex + ni * jIndex;
-           if (nbIndLoc < nbIndexGlobMax)
-           {
-             i_index(nbIndLoc) = index % ni_glo;
-             j_index(nbIndLoc) = index / ni_glo;
-             globalLocalIndexMap_[index] = nbIndLoc;  
-             ++nbIndGlob;
-           }
-           // i_index(nbIndGlob) = index % ni_glo;
-           // j_index(nbIndGlob) = index / ni_glo;
-           // globalLocalIndexMap_[index] = nbIndGlob;  
-           // ++nbIndGlob;
+           i_index(nbIndGlob) = index % ni_glo;
+           j_index(nbIndGlob) = index / ni_glo;
+           globalLocalIndexMap_[index] = nbIndGlob;
+           ++nbIndGlob;
          } 
       } 
@@ -2580,4 +2542,6 @@
       j_index.resizeAndPreserve(nbIndGlob);
     }
+
+    domainMask.resize(0); // Mask is not defined anymore on servers
   }
   CATCH
@@ -2619,78 +2583,5 @@
 
   }
-  CATCH_DUMP_ATTR
-
-  /*!
-    Receive area event from clients(s)
-    \param[in] event event contain info about rank and associated area
-  */
-  void CDomain::recvMask(CEventServer& event)
-  TRY
-  {
-    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)->recvMask(rankBuffers);
-  }
-  CATCH
-
-  /*!
-    Receive mask information from client(s)
-    \param[in] rankBuffers rank of sending client and the corresponding receive buffer  
-  */
-  void CDomain::recvMask(std::map<int, CBufferIn*>& rankBuffers)
-  TRY
-  {
-    int nbReceived = rankBuffers.size(), i, ind, index, lInd;
-    if (nbReceived != recvClientRanks_.size())
-      ERROR("void CDomain::recvMask(std::map<int, CBufferIn*>& rankBuffers)",
-           << "The number of sending clients is not correct."
-           << "Expected number: " << recvClientRanks_.size() << " but received " << nbReceived);
-
-    vector<CArray<bool,1> > recvMaskValue(nbReceived);      
-    for (i = 0; i < recvClientRanks_.size(); ++i)
-    {
-      int rank = recvClientRanks_[i];
-      CBufferIn& buffer = *(rankBuffers[rank]);      
-      buffer >> recvMaskValue[i];
-    }
-
-    int nbMaskInd = 0;
-    for (i = 0; i < nbReceived; ++i)
-    {
-      nbMaskInd += recvMaskValue[i].numElements();
-    }
-  
-    if (nbMaskInd != globalLocalIndexMap_.size())
-      info (0) << "If domain " << this->getDomainOutputName() <<" does not have overlapped regions between processes "
-               << "something must be wrong with mask index "<< std::endl;
-
-    nbMaskInd = globalLocalIndexMap_.size();
-    mask_1d.resize(nbMaskInd);
-    domainMask.resize(nbMaskInd);
-    mask_1d = false;
-    
-    for (i = 0; i < nbReceived; ++i)
-    {
-      CArray<int,1>& tmpInd = indGlob_[recvClientRanks_[i]];
-      CArray<bool,1>& tmp = recvMaskValue[i];
-      for (ind = 0; ind < tmp.numElements(); ++ind)
-      {
-        lInd = globalLocalIndexMap_[size_t(tmpInd(ind))];
-        if (!mask_1d(lInd)) // Only rewrite mask_1d if it's not true
-          mask_1d(lInd) = tmp(ind);
-      }
-    }
-    domainMask=mask_1d ;
-  }
-  CATCH_DUMP_ATTR
-
+ CATCH_DUMP_ATTR
   /*!
     Receive longitude event from clients(s)
@@ -3046,9 +2937,4 @@
          dataIIndex(lInd) = (-1 == dataIIndex(lInd)) ? tmpI(ind) : dataIIndex(lInd); // Only fill in dataIndex if there is no data
          dataJIndex(lInd) = (-1 == dataJIndex(lInd)) ? tmpJ(ind) : dataJIndex(lInd);  
-
-         if (!domainMask(lInd))   // Include mask info into data index on the RECEIVE getServerDimensionSizes
-         {
-           dataIIndex(lInd) = dataJIndex(lInd) = -1;
-         }
       } 
     }
Index: /XIOS/trunk/src/node/domain.hpp
===================================================================
--- /XIOS/trunk/src/node/domain.hpp	(revision 1636)
+++ /XIOS/trunk/src/node/domain.hpp	(revision 1637)
@@ -49,5 +49,5 @@
          {
            EVENT_ID_INDEX, EVENT_ID_LON, EVENT_ID_LAT, 
-           EVENT_ID_AREA, EVENT_ID_MASK,
+           EVENT_ID_AREA,
            EVENT_ID_DATA_INDEX, EVENT_ID_SERVER_ATTRIBUT
          } ;
@@ -142,5 +142,5 @@
          CArray<double, 1> areavalue;
 
-         CArray<size_t,1> localIndexToWriteOnServer;         
+         CArray<int,1> localIndexToWriteOnServer;
 
          CArray<bool, 1> domainMask; // mask_1d, mask_2d -> domainMask
@@ -175,5 +175,4 @@
          void sendIndex();
          void sendDistributionAttributes();
-         void sendMask();
          void sendArea();
          void sendLonLat();         
@@ -186,5 +185,4 @@
          static void recvDistributionAttributes(CEventServer& event);
          static void recvIndex(CEventServer& event);
-         static void recvMask(CEventServer& event);         
          static void recvLon(CEventServer& event);
          static void recvLat(CEventServer& event);
@@ -193,5 +191,4 @@
          void recvDistributionAttributes(CBufferIn& buffer);                  
          void recvIndex(std::map<int, CBufferIn*>& rankBuffers);         
-         void recvMask(std::map<int, CBufferIn*>& rankBuffers);
          void recvLon(std::map<int, CBufferIn*>& rankBuffers);
          void recvLat(std::map<int, CBufferIn*>& rankBuffers);
Index: /XIOS/trunk/src/node/field.cpp
===================================================================
--- /XIOS/trunk/src/node/field.cpp	(revision 1636)
+++ /XIOS/trunk/src/node/field.cpp	(revision 1637)
@@ -1122,5 +1122,5 @@
      {
         if (!instantDataFilter)
-          instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid,true));
+          instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, false));
 
 
@@ -1138,5 +1138,5 @@
      {
        if (!instantDataFilter)
-         instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true));
+         instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, false, false));
 
              // If the field data is to be read by the client or/and written to a file
@@ -1184,5 +1184,5 @@
          {
            checkTimeAttributes();
-           instantDataFilter = serverSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, freq_offset, true,
+           instantDataFilter = serverSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, false, freq_offset, true,
                                                                                                        detectMissingValues, defaultValue));
          }
@@ -1190,5 +1190,5 @@
          {
             if (check_if_active.isEmpty()) check_if_active = false; 
-            instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, false, NoneDu, false,
+            instantDataFilter = clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, false, true, NoneDu, false,
                                                                                                         detectMissingValues, defaultValue));
          }
@@ -1275,5 +1275,5 @@
          {
            checkTimeAttributes();
-           serverSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, freq_offset, true,
+           serverSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, false, freq_offset, true,
                                                                                    detectMissingValues, defaultValue));
          }
@@ -1292,5 +1292,5 @@
          {
            if (check_if_active.isEmpty()) check_if_active = false;
-           clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, NoneDu, false,
+           clientSourceFilter = std::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid, true, true, NoneDu, false,
                                                                                    detectMissingValues, defaultValue));
          }
@@ -1887,4 +1887,11 @@
    CATCH
 
+   bool CField::hasGridMask(void) const
+   TRY
+   {
+     return (this->grid->hasMask());
+   }
+   CATCH
+
    DEFINE_REF_FUNC(Field,field)
 } // namespace xios
Index: /XIOS/trunk/src/node/field.hpp
===================================================================
--- /XIOS/trunk/src/node/field.hpp	(revision 1636)
+++ /XIOS/trunk/src/node/field.hpp	(revision 1637)
@@ -209,4 +209,6 @@
         bool hasExpression(void) const;
 
+        bool hasGridMask(void) const;
+
       public:
          /// PropriÃ©tÃ©s privÃ©es ///
Index: /XIOS/trunk/src/node/grid.cpp
===================================================================
--- /XIOS/trunk/src/node/grid.cpp	(revision 1636)
+++ /XIOS/trunk/src/node/grid.cpp	(revision 1637)
@@ -364,4 +364,11 @@
    }
    CATCH_DUMP_ATTR
+   bool CGrid::hasMask() const
+   TRY
+   {
+     return (!mask_1d.isEmpty() || !mask_2d.isEmpty() || !mask_3d.isEmpty() ||
+             !mask_4d.isEmpty() || !mask_5d.isEmpty() || !mask_6d.isEmpty() || !mask_7d.isEmpty());
+   }
+   CATCH
 
    /*
@@ -453,50 +460,4 @@
    CATCH_DUMP_ATTR
 
-/*!
-  A grid can have multiple dimension, so can its mask in the form of multi-dimension array.
-It's not a good idea to store all multi-dimension arrays corresponding to each mask.
-One of the ways is to convert this array into 1-dimension one and every process is taken place on it.
-  \param [in] multi-dimension array grid mask
-*/
-
-  void CGrid::getLocalMask(CArray<bool,1>& localMask)
-  TRY
-  {
-      std::vector<CDomain*> domainP = this->getDomains();
-      std::vector<CAxis*> axisP = this->getAxis();
-      int dim = domainP.size() * 2 + axisP.size();
-
-      switch (dim)
-      {
-        case 0:
-          getLocalMask(mask_0d, localMask);
-          break;
-        case 1:
-          getLocalMask(mask_1d, localMask);
-          break;
-        case 2:
-          getLocalMask(mask_2d, localMask);
-          break;
-        case 3:
-          getLocalMask(mask_3d, localMask);
-          break;
-        case 4:
-          getLocalMask(mask_4d, localMask);
-          break;
-        case 5:
-          getLocalMask(mask_5d, localMask);
-          break;
-        case 6:
-          getLocalMask(mask_6d, localMask);
-          break;
-        case 7:
-          getLocalMask(mask_7d, localMask);
-          break;
-        default:
-          break;
-      }
-  }
-  CATCH_DUMP_ATTR
-      
    /*
      Modify value of mask in a certain index
@@ -736,12 +697,16 @@
      CContext* context = CContext::getCurrent();
 
-     CContextClient* client = context->client;  // Here it's not important which contextClient to recuperate
+     CContextClient* client = context->client;
      int rank = client->clientRank;
 
      clientDistribution_ = new CDistributionClient(rank, this);
      // Get local data index on client
-     storeIndex_client.resize(clientDistribution_->getLocalDataIndexOnClient().size());
-     int nbStoreIndex = storeIndex_client.numElements();
+     int nbStoreIndex = clientDistribution_->getLocalDataIndexOnClient().size();
+     int nbStoreGridMask = clientDistribution_->getLocalMaskIndexOnClient().size();
+     // nbStoreGridMask = nbStoreIndex if grid mask is defined, and 0 otherwise
+     storeIndex_client.resize(nbStoreIndex);
+     storeMask_client.resize(nbStoreGridMask);
      for (int idx = 0; idx < nbStoreIndex; ++idx) storeIndex_client(idx) = (clientDistribution_->getLocalDataIndexOnClient())[idx];
+     for (int idx = 0; idx < nbStoreGridMask; ++idx) storeMask_client(idx) = (clientDistribution_->getLocalMaskIndexOnClient())[idx];
 
      if (0 == serverDistribution_) isDataDistributed_= clientDistribution_->isDataDistributed();
@@ -884,4 +849,28 @@
          if (connectedServerRank_[receiverSize].empty())
           connectedServerRank_[receiverSize].push_back(client->clientRank % client->serverSize);
+
+         // Now check if all servers have data to receive. If not, master client will send empty data.
+         // This ensures that all servers will participate in collective calls upon receiving even if they have no date to receive.
+         std::vector<int> counts (client->clientSize);
+         std::vector<int> displs (client->clientSize);
+         displs[0] = 0;
+         int localCount = connectedServerRank_[receiverSize].size() ;
+         MPI_Gather(&localCount, 1, MPI_INT, &counts[0], 1, MPI_INT, 0, client->intraComm) ;
+         for (int i = 0; i < client->clientSize-1; ++i)
+         {
+           displs[i+1] = displs[i] + counts[i];
+         }
+         std::vector<int> allConnectedServers(displs[client->clientSize-1]+counts[client->clientSize-1]);
+         MPI_Gatherv(&(connectedServerRank_[receiverSize])[0], localCount, MPI_INT, &allConnectedServers[0], &counts[0], &displs[0], MPI_INT, 0, client->intraComm);
+
+         if ((allConnectedServers.size() != receiverSize) && (client->clientRank == 0))
+         {
+           std::vector<bool> isSrvConnected (receiverSize, false);
+           for (int i = 0; i < allConnectedServers.size(); ++i) isSrvConnected[allConnectedServers[i]] = true;
+           for (int i = 0; i < receiverSize; ++i)
+           {
+             if (!isSrvConnected[i]) connectedServerRank_[receiverSize].push_back(i);
+           }
+         }
 
          nbSenders[receiverSize] = clientServerMap_->computeConnectedClients(receiverSize, client->clientSize, client->intraComm, connectedServerRank_[receiverSize]);
@@ -1369,4 +1358,16 @@
    CATCH
 
+   void CGrid::maskField_arr(const double* const data, CArray<double, 1>& stored) const
+   {
+      const StdSize size = storeIndex_client.numElements();
+      stored.resize(size);
+      const double nanValue = std::numeric_limits<double>::quiet_NaN();
+
+      if (storeMask_client.numElements() != 0)
+        for(StdSize i = 0; i < size; i++) stored(i) = (storeMask_client(i)) ? data[storeIndex_client(i)] : nanValue;
+      else
+        for(StdSize i = 0; i < size; i++) stored(i) = data[storeIndex_client(i)];
+   }
+
    void CGrid::uncompressField_arr(const double* const data, CArray<double, 1>& out) const
    TRY
@@ -1836,40 +1837,4 @@
           nGlob.push_back(1);  
         }
-
-        modifyMaskSize(nSize, false);
-
-        // 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);
       }
 
Index: /XIOS/trunk/src/node/grid.hpp
===================================================================
--- /XIOS/trunk/src/node/grid.hpp	(revision 1636)
+++ /XIOS/trunk/src/node/grid.hpp	(revision 1637)
@@ -94,4 +94,6 @@
          template <int n>
          void inputField(const CArray<double,n>& field, CArray<double,1>& stored) const;
+         template <int n>
+         void maskField(const CArray<double,n>& field, CArray<double,1>& stored) const;
          template <int n>
          void outputField(const CArray<double,1>& stored, CArray<double,n>& field) const;  
@@ -203,9 +205,7 @@
          bool hasTransform();
          size_t getGlobalWrittenSize(void) ;
-         void getLocalMask(CArray<bool,1>& localMask) ;
-         template<int N>
-         void getLocalMask(const CArray<bool,N>& gridMask, CArray<bool,1>& localMask) ;
       public:
          CArray<int, 1> storeIndex_client;
+         CArray<bool, 1> storeMask_client;
 
 /** Map containing indexes that will be sent in sendIndex(). */
@@ -247,4 +247,5 @@
          CArray<size_t,1> indexFromClients;
 
+         bool hasMask(void) const;
          void checkMask(void);
          void createMask(void);
@@ -273,4 +274,5 @@
         void restoreField_arr(const CArray<double, 1>& stored, double* const data) const;
         void uncompressField_arr(const double* const data, CArray<double, 1>& outData) const;
+        void maskField_arr(const double* const data, CArray<double, 1>& stored) const;
 
         void setVirtualDomainGroup(CDomainGroup* newVDomainGroup);
@@ -387,4 +389,18 @@
 
    template <int n>
+   void CGrid::maskField(const CArray<double,n>& field, CArray<double,1>& stored) const
+   {
+//#ifdef __XIOS_DEBUG
+      if (this->getDataSize() != field.numElements())
+         ERROR("void CGrid::inputField(const  CArray<double,n>& field, CArray<double,1>& stored) const",
+                << "[ Awaiting data of size = " << this->getDataSize() << ", "
+                << "Received data size = "      << field.numElements() << " ] "
+                << "The data array does not have the right size! "
+                << "Grid = " << this->getId())
+//#endif
+      this->maskField_arr(field.dataFirst(), stored);
+   }
+
+   template <int n>
    void CGrid::outputField(const CArray<double,1>& stored, CArray<double,n>& field) const
    TRY
@@ -424,101 +440,97 @@
    TRY
    {
-     if (!gridMask.isEmpty() || createMask)
-     {
-       int idx = 0;
-       int numElement = axisDomainOrder.numElements();
-       int dim = domainMasks.size() * 2 + axisMasks.size();
-       std::vector<CDomain*> domainP = this->getDomains();
-       std::vector<CAxis*> axisP = this->getAxis();
-
-       std::vector<int> idxLoop(dim,0), indexMap(numElement), eachDimSize(dim);
-       std::vector<int> currentIndex(dim);
-       int idxDomain = 0, idxAxis = 0;
+     int idx = 0;
+     int numElement = axisDomainOrder.numElements();
+     int dim = domainMasks.size() * 2 + axisMasks.size();
+     std::vector<CDomain*> domainP = this->getDomains();
+     std::vector<CAxis*> axisP = this->getAxis();
+
+     std::vector<int> idxLoop(dim,0), indexMap(numElement), eachDimSize(dim);
+     std::vector<int> currentIndex(dim);
+     int idxDomain = 0, idxAxis = 0;
+    for (int i = 0; i < numElement; ++i)
+    {
+      indexMap[i] = idx;
+      if (2 == axisDomainOrder(i)) {
+          eachDimSize[indexMap[i]]   = domainP[idxDomain]->ni;
+          eachDimSize[indexMap[i]+1] = domainP[idxDomain]->nj;
+          idx += 2; ++idxDomain;
+      }
+      else if (1 == axisDomainOrder(i)) {
+//        eachDimSize[indexMap[i]] = axisMasks[idxAxis]->numElements();
+        eachDimSize[indexMap[i]] = axisP[idxAxis]->n;
+        ++idx; ++idxAxis;
+      }
+      else {};
+    }
+
+    if (!gridMask.isEmpty() && !createMask)
+    {
+      for (int i = 0; i < dim; ++i)
+      {
+        if (gridMask.extent(i) != eachDimSize[i])
+          ERROR("CGrid::checkMask(void)",
+                << "The mask has one dimension whose size is different from the one of the local grid." << std::endl
+                << "Local size of dimension " << i << " is " << eachDimSize[i] << "." << std::endl
+                << "Mask size for dimension " << i << " is " << gridMask.extent(i) << "." << std::endl
+                << "Grid = " << this->getId())
+      }
+    }
+    else {
+        CArrayBoolTraits<CArray<bool,N> >::resizeArray(gridMask,eachDimSize);
+        gridMask = true;
+    }
+
+    int ssize = gridMask.numElements();
+    idx = 0;
+    while (idx < ssize)
+    {
+      for (int i = 0; i < dim-1; ++i)
+      {
+        if (idxLoop[i] == eachDimSize[i])
+        {
+          idxLoop[i] = 0;
+          ++idxLoop[i+1];
+        }
+      }
+
+      // Find out outer index
+      idxDomain = idxAxis = 0;
+      bool maskValue = true;
       for (int i = 0; i < numElement; ++i)
       {
-        indexMap[i] = idx;
-        if (2 == axisDomainOrder(i)) {
-            eachDimSize[indexMap[i]]   = domainP[idxDomain]->ni;
-            eachDimSize[indexMap[i]+1] = domainP[idxDomain]->nj;
-            idx += 2; ++idxDomain;
+        if (2 == axisDomainOrder(i))
+        {
+          int idxTmp = idxLoop[indexMap[i]] + idxLoop[indexMap[i]+1] * eachDimSize[indexMap[i]];
+          if (idxTmp < (*domainMasks[idxDomain]).numElements())
+            maskValue = maskValue && (*domainMasks[idxDomain])(idxTmp);
+          else
+            maskValue = false;
+          ++idxDomain;
         }
-        else if (1 == axisDomainOrder(i)) {
-  //        eachDimSize[indexMap[i]] = axisMasks[idxAxis]->numElements();
-          eachDimSize[indexMap[i]] = axisP[idxAxis]->n;
-          ++idx; ++idxAxis;
+        else if (1 == axisDomainOrder(i))
+        {
+          int idxTmp = idxLoop[indexMap[i]];
+          if (idxTmp < (*axisMasks[idxAxis]).numElements())
+            maskValue = maskValue && (*axisMasks[idxAxis])(idxTmp);
+          else
+            maskValue = false;
+
+          ++idxAxis;
         }
-        else {};
-      }
-
-//      if (!gridMask.isEmpty() && !createMask)
-      if (!createMask)
+      }
+
+      int maskIndex = idxLoop[0];
+      int mulDim = 1;
+      for (int k = 1; k < dim; ++k)
       {
-        for (int i = 0; i < dim; ++i)
-        {
-          if (gridMask.extent(i) != eachDimSize[i])
-            ERROR("CGrid::checkMask(void)",
-                  << "The mask has one dimension whose size is different from the one of the local grid." << std::endl
-                  << "Local size of dimension " << i << " is " << eachDimSize[i] << "." << std::endl
-                  << "Mask size for dimension " << i << " is " << gridMask.extent(i) << "." << std::endl
-                  << "Grid = " << this->getId())
-        }
-      }
-      else {
-          CArrayBoolTraits<CArray<bool,N> >::resizeArray(gridMask,eachDimSize);
-          gridMask = true;
-      }
-
-      int ssize = gridMask.numElements();
-      idx = 0;
-      while (idx < ssize)
-      {
-        for (int i = 0; i < dim-1; ++i)
-        {
-          if (idxLoop[i] == eachDimSize[i])
-          {
-            idxLoop[i] = 0;
-            ++idxLoop[i+1];
-          }
-        }
-
-        // Find out outer index
-        idxDomain = idxAxis = 0;
-        bool maskValue = true;
-        for (int i = 0; i < numElement; ++i)
-        {
-          if (2 == axisDomainOrder(i))
-          {
-            int idxTmp = idxLoop[indexMap[i]] + idxLoop[indexMap[i]+1] * eachDimSize[indexMap[i]];
-            if (idxTmp < (*domainMasks[idxDomain]).numElements())
-              maskValue = maskValue && (*domainMasks[idxDomain])(idxTmp);
-            else
-              maskValue = false;
-            ++idxDomain;
-          }
-          else if (1 == axisDomainOrder(i))
-          {
-            int idxTmp = idxLoop[indexMap[i]];
-            if (idxTmp < (*axisMasks[idxAxis]).numElements())
-              maskValue = maskValue && (*axisMasks[idxAxis])(idxTmp);
-            else
-              maskValue = false;
-
-            ++idxAxis;
-          }
-        }
-
-        int maskIndex = idxLoop[0];
-        int mulDim = 1;
-        for (int k = 1; k < dim; ++k)
-        {
-          mulDim *= eachDimSize[k-1];
-          maskIndex += idxLoop[k]*mulDim;
-        }
-        *(gridMask.dataFirst()+maskIndex) &= maskValue;
-
-        ++idxLoop[0];
-        ++idx;
-      }
-     }
+        mulDim *= eachDimSize[k-1];
+        maskIndex += idxLoop[k]*mulDim;
+      }
+      *(gridMask.dataFirst()+maskIndex) &= maskValue;
+
+      ++idxLoop[0];
+      ++idx;
+    }
    }
    CATCH_DUMP_ATTR
@@ -565,47 +577,5 @@
    ///--------------------------------------------------------------
 
-  /*!
-    A grid can have multiple dimension, so can its mask in the form of multi-dimension array.
-  It's not a good idea to store all multi-dimension arrays corresponding to each mask.
-  One of the ways is to convert this array into 1-dimension one and every process is taken place on it.
-    \param [in] multi-dimension array grid mask
-  */
-  template<int N>
-  void CGrid::getLocalMask(const CArray<bool,N>& gridMask, CArray<bool,1>& localMask)
-  TRY
-  {
-    if (gridMask.isEmpty()) return ;
-    int dim = gridMask.dimensions();
-    std::vector<int> dimensionSizes(dim);
-    for (int i = 0; i < dim; ++i) dimensionSizes[i] = gridMask.extent(i);
-
-    std::vector<int> idxLoop(dim,0);
-    int ssize = gridMask.numElements(), idx = 0;
-    localMask.resize(ssize);
-    while (idx < ssize)
-    {
-      for (int i = 0; i < dim-1; ++i)
-      {
-        if (idxLoop[i] == dimensionSizes[i])
-        {
-          idxLoop[i] = 0;
-          ++idxLoop[i+1];
-        }
-      }
-
-      int maskIndex = idxLoop[0];
-      int mulDim = 1;
-      for (int k = 1; k < dim; ++k)
-      {
-        mulDim *= dimensionSizes[k-1];
-        maskIndex += idxLoop[k]*mulDim;
-      }
-      localMask(maskIndex) = *(gridMask.dataFirst()+maskIndex);
-
-      ++idxLoop[0];
-      ++idx;
-    }
-  }
-   CATCH_DUMP_ATTR
+
 
    // Declare/Define CGridGroup and CGridDefinition
Index: /XIOS/trunk/src/transformation/generic_algorithm_transformation.cpp
===================================================================
--- /XIOS/trunk/src/transformation/generic_algorithm_transformation.cpp	(revision 1636)
+++ /XIOS/trunk/src/transformation/generic_algorithm_transformation.cpp	(revision 1637)
@@ -856,5 +856,6 @@
 
 void CGenericAlgorithmTransformation::computeTransformationMappingNonDistributed(int elementPositionInGrid, CGrid* gridSrc, CGrid* gridDst,
-                                                                                 vector<int>& localSrc, vector<int>& localDst, vector<double>& weight, vector<bool>& localMaskOnGridDest)
+                                                                                 vector<int>& localSrc, vector<int>& localDst, vector<double>& weight,
+                                                                                 int& nlocalIndexDest)
 TRY
 {
@@ -883,5 +884,6 @@
     
   int nlocalIndexSrc=1 ;
-  int nlocalIndexDest=1 ;
+//  int nlocalIndexDest=1 ;
+  nlocalIndexDest=1 ;
   CArray<bool,1> maskScalar(1) ;
   maskScalar  = true ;
@@ -992,17 +994,4 @@
   }
 
-// just get the local src mask
-  CArray<bool,1> localMaskOnSrcGrid;
-  gridSrc->getLocalMask(localMaskOnSrcGrid) ;
-// intermediate grid, mask is not initialized => set up mask to true
-  if (localMaskOnSrcGrid.isEmpty())
-  {
-    localMaskOnSrcGrid.resize(nlocalIndexSrc) ;
-    localMaskOnSrcGrid=true ;
-  }
-  
-
-  localMaskOnGridDest.resize(nlocalIndexDest,false) ;
-
   vector<vector<vector<pair<int,double> > > > dstIndWeight(transformationMapping_.size()) ;
    
@@ -1031,11 +1020,15 @@
   
   nonDistributedrecursiveFunct(nElement-1,true,elementPositionInGrid,maskSrc,maskDst, srcInd, srcIndCompressed, nIndexSrc, t, dstIndWeight,  
-                               currentInd,localSrc,localDst,weight, localMaskOnSrcGrid, localMaskOnGridDest );
+                               currentInd,localSrc,localDst,weight);
                
 }
 CATCH
 
-void CGenericAlgorithmTransformation::nonDistributedrecursiveFunct(int currentPos, bool masked, int elementPositionInGrid, vector< CArray<bool,1>* >& maskSrc, vector< CArray<bool,1>* >& maskDst, int& srcInd, int& srcIndCompressed, vector<int>& nIndexSrc, int& t, vector<vector<vector<pair<int,double> > > >& dstIndWeight, int currentInd,
-                    vector<int>& localSrc, vector<int>& localDst, vector<double>& weight,  CArray<bool,1>& localMaskOnGridSrc, vector<bool>& localMaskOnGridDest )
+
+void CGenericAlgorithmTransformation::nonDistributedrecursiveFunct(int currentPos, bool masked, int elementPositionInGrid,
+                                                                   vector< CArray<bool,1>* >& maskSrc, vector< CArray<bool,1>* >& maskDst,
+                                                                   int& srcInd, int& srcIndCompressed, vector<int>& nIndexSrc,
+                                                                   int& t, vector<vector<vector<pair<int,double> > > >& dstIndWeight, int currentInd,
+                                                                   vector<int>& localSrc, vector<int>& localDst, vector<double>& weight)
 TRY
 {
@@ -1051,5 +1044,6 @@
         masked_=masked ;
         if (!mask(i)) masked_=false ;
-        nonDistributedrecursiveFunct(currentPos-1, masked_, elementPositionInGrid, maskSrc, maskDst, srcInd, srcIndCompressed, nIndexSrc, t, dstIndWeight, currentInd, localSrc, localDst, weight, localMaskOnGridSrc, localMaskOnGridDest) ;
+        nonDistributedrecursiveFunct(currentPos-1, masked_, elementPositionInGrid, maskSrc, maskDst, srcInd, srcIndCompressed, nIndexSrc, t,
+                                     dstIndWeight, currentInd, localSrc, localDst, weight);
       }
     }
@@ -1065,16 +1059,12 @@
             for(vector<pair<int,double> >::iterator it = dstIndWeight[t][currentInd].begin(); it!=dstIndWeight[t][currentInd].end(); ++it)
             {
-              if (localMaskOnGridSrc(srcInd))
-              {
-                localSrc.push_back(srcIndCompressed) ;
-                localDst.push_back(it->first) ;
-                weight.push_back(it->second) ;
-                localMaskOnGridDest[it->first]=true ;
-              }
+              localSrc.push_back(srcIndCompressed) ;
+              localDst.push_back(it->first) ;
+              weight.push_back(it->second) ;
               (it->first)++ ;
             }
           }
           if (t < dstIndWeight.size()-1) t++ ;
-          if (localMaskOnGridSrc(srcInd)) srcIndCompressed ++ ;
+            srcIndCompressed ++ ;
         }
         srcInd++ ;
@@ -1094,5 +1084,6 @@
         masked_=masked ;
         if (!mask(i)) masked_=false ; 
-        nonDistributedrecursiveFunct(currentPos-1, masked_, elementPositionInGrid, maskSrc, maskDst, srcInd, srcIndCompressed, nIndexSrc, t, dstIndWeight , i,  localSrc, localDst, weight, localMaskOnGridSrc, localMaskOnGridDest) ;
+        nonDistributedrecursiveFunct(currentPos-1, masked_, elementPositionInGrid, maskSrc, maskDst, srcInd,
+                                     srcIndCompressed, nIndexSrc, t, dstIndWeight , i,  localSrc, localDst, weight);
       }
     }
@@ -1108,16 +1099,12 @@
             for(vector<pair<int,double> >::iterator it = dstIndWeight[t][i].begin(); it!=dstIndWeight[t][i].end(); ++it)
             {
-              if (localMaskOnGridSrc(srcInd))
-              {
-                localSrc.push_back(srcIndCompressed) ;
-                localDst.push_back(it->first) ;
-                weight.push_back(it->second) ;
-                localMaskOnGridDest[it->first]=true ;
-              }
+              localSrc.push_back(srcIndCompressed) ;
+              localDst.push_back(it->first) ;
+              weight.push_back(it->second) ;
               (it->first)++ ;
             }
            }
           if (t < dstIndWeight.size()-1) t++ ;
-          if (localMaskOnGridSrc(srcInd)) srcIndCompressed ++ ;
+          srcIndCompressed ++ ;
         }
         srcInd++ ;
Index: /XIOS/trunk/src/transformation/generic_algorithm_transformation.hpp
===================================================================
--- /XIOS/trunk/src/transformation/generic_algorithm_transformation.hpp	(revision 1636)
+++ /XIOS/trunk/src/transformation/generic_algorithm_transformation.hpp	(revision 1637)
@@ -88,7 +88,9 @@
   void computeIndexSourceMapping(const std::vector<CArray<double,1>* >& dataAuxInputs = std::vector<CArray<double,1>* >());
   void computeTransformationMappingNonDistributed(int elementPositionInGrid, CGrid* gridSrc, CGrid* gridDst,
-                                                  vector<int>& localSrc, vector<int>& localDst, vector<double>& weight, vector<bool>& localMaskOnGridDest);
-  void nonDistributedrecursiveFunct(int currentPos, bool masked, int elementPositionInGrid,  vector< CArray<bool,1>* >& maskSrc, vector< CArray<bool,1>* >& maskDst, int& srcInd, int& srcIndCompressed, vector<int>& nIndexSrc, int& t, vector<vector<vector<pair<int,double> > > >& dstIndWeight, int currentInd,
-                                     vector<int>& localSrc, vector<int>& localDst, vector<double>& weight, CArray<bool,1>& localMaskOnGridSrc, vector<bool>& localMaskOnGridDest) ;
+                                                  vector<int>& localSrc, vector<int>& localDst, vector<double>& weight, int& nbLocalIndexOnGridDest);
+  void nonDistributedrecursiveFunct(int currentPos, bool masked, int elementPositionInGrid,  vector< CArray<bool,1>* >& maskSrc, vector< CArray<bool,1>* >& maskDst,
+                                    int& srcInd, int& srcIndCompressed, vector<int>& nIndexSrc,
+                                    int& t, vector<vector<vector<pair<int,double> > > >& dstIndWeight, int currentInd,
+                                    vector<int>& localSrc, vector<int>& localDst, vector<double>& weight) ;
 
 protected:
Index: /XIOS/trunk/src/transformation/grid_transformation.cpp
===================================================================
--- /XIOS/trunk/src/transformation/grid_transformation.cpp	(revision 1636)
+++ /XIOS/trunk/src/transformation/grid_transformation.cpp	(revision 1637)
@@ -359,5 +359,4 @@
       std::list<RecvIndexGridDestinationMap>().swap(localIndexToReceiveOnGridDest_);
       std::list<size_t>().swap(nbLocalIndexOnGridDest_);
-      std::list<std::vector<bool> >().swap(localMaskOnGridDest_);
     }
     else
@@ -412,12 +411,12 @@
         vector<int> localDst ;
         vector<double> weight ;
-        localMaskOnGridDest_.push_back(vector<bool>()) ;
+        int nbLocalIndexOnGridDest;
         CTimer::get("computeTransformationMappingNonDistributed").resume();  
         algo->computeTransformationMappingNonDistributed(elementPosition, gridSource_, tmpGridDestination_, 
-                                                         localSrc, localDst, weight, localMaskOnGridDest_.back()) ;
+                                                         localSrc, localDst, weight, nbLocalIndexOnGridDest) ;
         CTimer::get("computeTransformationMappingNonDistributed").suspend();  
 
         CTimer::get("computeTransformationMappingConvert").resume();  
-        nbLocalIndexOnGridDest_.push_back(localMaskOnGridDest_.back().size()) ;
+        nbLocalIndexOnGridDest_.push_back(nbLocalIndexOnGridDest) ;
         int clientRank=client->clientRank ;
         {
@@ -487,7 +486,7 @@
   size_t nbLocalIndex = globalLocalIndexGridDestSendToServer.size();
   nbLocalIndexOnGridDest_.push_back(nbLocalIndex);
-  localMaskOnGridDest_.push_back(std::vector<bool>());
-  std::vector<bool>& tmpMask = localMaskOnGridDest_.back();
-  tmpMask.resize(nbLocalIndex,false);
+//  localMaskOnGridDest_.push_back(std::vector<bool>());
+//  std::vector<bool>& tmpMask = localMaskOnGridDest_.back();
+//  tmpMask.resize(nbLocalIndex,false);
 
   // Find out number of index sent from grid source and number of index received on grid destination
@@ -672,5 +671,4 @@
         recvTmp[recvRank][realRecvSize].first = globalLocalIndexGridDestSendToServer[recvIndexDst(idx)];
         recvTmp[recvRank][realRecvSize].second = recvWeightDst(idx);
-        tmpMask[globalLocalIndexGridDestSendToServer[recvIndexDst(idx)]] = true;
          ++realRecvSize;
       }
@@ -732,14 +730,3 @@
 CATCH
 
-/*!
-  Local mask of data which will be received on the grid destination
-  \return local mask of data
-*/
-const std::list<std::vector<bool> >& CGridTransformation::getLocalMaskIndexOnGridDest() const
-TRY
-{
-  return localMaskOnGridDest_;
-}
-CATCH
-
-}
+}
Index: /XIOS/trunk/src/transformation/grid_transformation.hpp
===================================================================
--- /XIOS/trunk/src/transformation/grid_transformation.hpp	(revision 1636)
+++ /XIOS/trunk/src/transformation/grid_transformation.hpp	(revision 1637)
@@ -49,5 +49,4 @@
   const std::list<RecvIndexGridDestinationMap>& getLocalIndexToReceiveOnGridDest() const;
   const std::list<size_t>& getNbLocalIndexToReceiveOnGridDest() const;
-  const std::list<std::vector<bool> >& getLocalMaskIndexOnGridDest() const;
 
   CGrid* getGridSource() { return originalGridSource_; }
@@ -84,5 +83,4 @@
   //! Number of local index of data to receive on grid destination
   std::list<size_t> nbLocalIndexOnGridDest_;
-  std::list<std::vector<bool> > localMaskOnGridDest_;
 
   bool dynamicalTransformation_;
