Index: /XIOS/dev/dev_olga/inputs/iodef.xml
===================================================================
--- /XIOS/dev/dev_olga/inputs/iodef.xml	(revision 1024)
+++ /XIOS/dev/dev_olga/inputs/iodef.xml	(revision 1025)
@@ -8,4 +8,6 @@
    <field_definition level="1" enabled=".TRUE.">
      <field id="field_A"  operation="average" freq_op="3600s" grid_ref="grid_A"/>
+     <field id="field_Axis"  operation="average" freq_op="3600s" axis_ref="axis_A"/>
+     <field id="field_Domain"  operation="average" freq_op="3600s" domain_ref="domain_A"/>
      <field id="field_A_zoom"  operation="average" freq_op="3600s" field_ref="field_A" grid_ref="grid_A_zoom"/>
    </field_definition>
@@ -14,5 +16,5 @@
    <file_definition type="one_file" par_access="collective" output_freq="1h" output_level="10" enabled=".TRUE.">
      <file id="output" name="output">
-        <field field_ref="field_A" name="field_A" />
+        <field field_ref="field_Domain" name="field_A" />
      </file>
    </file_definition>
Index: /XIOS/dev/dev_olga/src/attribute.hpp
===================================================================
--- /XIOS/dev/dev_olga/src/attribute.hpp	(revision 1024)
+++ /XIOS/dev/dev_olga/src/attribute.hpp	(revision 1025)
@@ -55,4 +55,7 @@
             //! Returns true if and only if the attribute should be publicly exposed in the API
             virtual bool isPublic() const { return true; }
+            
+            //! Return true if the attribute should be sent to other clients or servers
+            virtual bool doSend() const { return true; }
 
             virtual void generateCInterface(ostream& oss, const string& className) = 0 ;
Index: /XIOS/dev/dev_olga/src/client_server_mapping.cpp
===================================================================
--- /XIOS/dev/dev_olga/src/client_server_mapping.cpp	(revision 1024)
+++ /XIOS/dev/dev_olga/src/client_server_mapping.cpp	(revision 1025)
@@ -97,3 +97,8 @@
 }
 
+CClientServerMapping::GlobalIndexMap& CClientServerMapping::getGlobalIndexOnServer()
+{
+  return indexGlobalOnServer_;
+}
+
 } //namespace xios
Index: /XIOS/dev/dev_olga/src/client_server_mapping.hpp
===================================================================
--- /XIOS/dev/dev_olga/src/client_server_mapping.hpp	(revision 1024)
+++ /XIOS/dev/dev_olga/src/client_server_mapping.hpp	(revision 1025)
@@ -42,4 +42,6 @@
     const GlobalIndexMap& getGlobalIndexOnServer() const;
 
+    GlobalIndexMap& getGlobalIndexOnServer();
+
   protected:
     //! Global index of data on SERVER, which are calculated by client(s)
Index: /XIOS/dev/dev_olga/src/config/axis_attribute.conf
===================================================================
--- /XIOS/dev/dev_olga/src/config/axis_attribute.conf	(revision 1024)
+++ /XIOS/dev/dev_olga/src/config/axis_attribute.conf	(revision 1025)
@@ -6,5 +6,5 @@
 
 DECLARE_ATTRIBUTE(int,       n_glo)
-DECLARE_ENUM2(positive, up, down)
+DECLARE_ENUM2(positive, up, down)		
 
 /* GLOBAL */
Index: /XIOS/dev/dev_olga/src/config/axis_attribute_private.conf
===================================================================
--- /XIOS/dev/dev_olga/src/config/axis_attribute_private.conf	(revision 1024)
+++ /XIOS/dev/dev_olga/src/config/axis_attribute_private.conf	(revision 1025)
@@ -1,2 +1,5 @@
 DECLARE_ATTRIBUTE_PRIVATE(int, global_zoom_begin)
 DECLARE_ATTRIBUTE_PRIVATE(int, global_zoom_n)
+
+/* LOCAL DATA*/
+DECLARE_ARRAY_PRIVATE(int    ,   1 , zoom_index)
Index: /XIOS/dev/dev_olga/src/config/domain_attribute.conf
===================================================================
--- /XIOS/dev/dev_olga/src/config/domain_attribute.conf	(revision 1024)
+++ /XIOS/dev/dev_olga/src/config/domain_attribute.conf	(revision 1025)
@@ -9,17 +9,17 @@
 
 /* LOCAL */
-DECLARE_ATTRIBUTE(int             , ibegin)
-DECLARE_ATTRIBUTE(int             , ni)
+DECLARE_ATTRIBUTE(int             , ibegin, false)
+DECLARE_ATTRIBUTE(int             , ni, false)
 
 /* LOCAL */
-DECLARE_ATTRIBUTE(int             , jbegin)
-DECLARE_ATTRIBUTE(int             , nj)
+DECLARE_ATTRIBUTE(int             , jbegin, false)
+DECLARE_ATTRIBUTE(int             , nj, false)
 
 
-DECLARE_ARRAY(int,1             , i_index)
-DECLARE_ARRAY(int,1             , j_index)
+DECLARE_ARRAY(int,1             , i_index, false)
+DECLARE_ARRAY(int,1             , j_index, false)
 
 /* LOCAL */
-DECLARE_ARRAY(bool, 1 , mask_1d)
+DECLARE_ARRAY(bool, 1 , mask_1d, false)
 DECLARE_ARRAY(bool, 2 , mask_2d)
 
@@ -28,24 +28,24 @@
 
 /* LOCAL */
-DECLARE_ATTRIBUTE(int             , data_ni)
-DECLARE_ATTRIBUTE(int             , data_nj)
-DECLARE_ATTRIBUTE(int             , data_ibegin)
-DECLARE_ATTRIBUTE(int             , data_jbegin)
+DECLARE_ATTRIBUTE(int             , data_ni, false)
+DECLARE_ATTRIBUTE(int             , data_nj, false)
+DECLARE_ATTRIBUTE(int             , data_ibegin, false)
+DECLARE_ATTRIBUTE(int             , data_jbegin, false)
 
 /* LOCAL */
-DECLARE_ARRAY(int, 1 , data_i_index)
-DECLARE_ARRAY(int, 1,  data_j_index)
+DECLARE_ARRAY(int, 1 , data_i_index, false)
+DECLARE_ARRAY(int, 1,  data_j_index, false)
 
 /* LOCAL */
-DECLARE_ARRAY(double, 1, lonvalue_1d)
-DECLARE_ARRAY(double, 1, latvalue_1d)
-DECLARE_ARRAY(double, 2, lonvalue_2d)
-DECLARE_ARRAY(double, 2, latvalue_2d)
+DECLARE_ARRAY(double, 1, lonvalue_1d, false)
+DECLARE_ARRAY(double, 1, latvalue_1d, false)
+DECLARE_ARRAY(double, 2, lonvalue_2d, false)
+DECLARE_ARRAY(double, 2, latvalue_2d, false)
 
 DECLARE_ATTRIBUTE(int, nvertex)
-DECLARE_ARRAY(double, 2, bounds_lon_1d)
-DECLARE_ARRAY(double, 2, bounds_lat_1d)
-DECLARE_ARRAY(double, 3, bounds_lon_2d)
-DECLARE_ARRAY(double, 3, bounds_lat_2d)
+DECLARE_ARRAY(double, 2, bounds_lon_1d, false)
+DECLARE_ARRAY(double, 2, bounds_lat_1d, false)
+DECLARE_ARRAY(double, 3, bounds_lon_2d, false)
+DECLARE_ARRAY(double, 3, bounds_lat_2d, false)
 
 DECLARE_ARRAY(double, 2, area)
Index: /XIOS/dev/dev_olga/src/config/domain_attribute_private.conf
===================================================================
--- /XIOS/dev/dev_olga/src/config/domain_attribute_private.conf	(revision 1024)
+++ /XIOS/dev/dev_olga/src/config/domain_attribute_private.conf	(revision 1025)
@@ -18,2 +18,11 @@
 DECLARE_ATTRIBUTE_PRIVATE(int,  global_zoom_jbegin)
 DECLARE_ATTRIBUTE_PRIVATE(int,  global_zoom_nj)
+
+DECLARE_ARRAY_PRIVATE(int    ,   1 , zoom_i_index, false)
+DECLARE_ARRAY_PRIVATE(int    ,   1 , zoom_j_index, false)
+//DECLARE_ARRAY_PRIVATE(double ,   1 , areavalue, false)
+//DECLARE_ARRAY_PRIVATE(int    ,   1 , lonvalue, false)
+//DECLARE_ARRAY_PRIVATE(int    ,   1 , latvalue, false)
+//DECLARE_ARRAY_PRIVATE(int    ,   2 , bounds_lonvalue, false)
+//DECLARE_ARRAY_PRIVATE(int    ,   2 , bounds_latvalue, false)
+
Index: /XIOS/dev/dev_olga/src/declare_attribute.hpp
===================================================================
--- /XIOS/dev/dev_olga/src/declare_attribute.hpp	(revision 1024)
+++ /XIOS/dev/dev_olga/src/declare_attribute.hpp	(revision 1025)
@@ -3,9 +3,9 @@
 
 /// ///////////////////////////// Macros ///////////////////////////// ///
-#define DECLARE_ATTRIBUTE(type, name)                             \
+#define DECLARE_ATTRIBUTE(type, name, ...)                        \
    class name##_attr : public CAttributeTemplate<type>            \
    {                                                              \
       public :                                                    \
-         name##_attr(void)                                          \
+         name##_attr(void)                                        \
             : CAttributeTemplate<type>                            \
             (#name, *CAttributeMap::Current)                      \
@@ -13,13 +13,15 @@
          type operator=(const type & value)                       \
          { return (CAttributeTemplate<type>::operator=(value)); } \
-         virtual ~name##_attr(void)                                 \
+         virtual bool doSend() const { return helper(## __VA_ARGS__); }   \
+         bool helper(bool returnTrue=true) const { return returnTrue; }   \
+         virtual ~name##_attr(void)                               \
          { /* Ne rien faire de plus */ }                          \
    } name;
 
-#define DECLARE_ATTRIBUTE_PRIVATE(type, name)                    \
-   class name##_attr : public CAttributeTemplate<type>           \
+#define DECLARE_ATTRIBUTE_PRIVATE(type, name, ...)                \
+   class name##_attr : public CAttributeTemplate<type>            \
    {                                                              \
       public :                                                    \
-         name##_attr(void)                                          \
+         name##_attr(void)                                        \
             : CAttributeTemplate<type>                            \
             (#name, *CAttributeMap::Current)                      \
@@ -29,9 +31,11 @@
          virtual bool isPublic() const                            \
          { return false; }                                        \
+         virtual bool doSend() const { return helper(## __VA_ARGS__); }   \
+         bool helper(bool returnTrue=true) const { return returnTrue; }   \
          virtual ~name##_attr(void)                               \
          { /* Ne rien faire de plus */ }                          \
    } name;
 
-#define DECLARE_ARRAY(T_num, T_rank, name)                        \
+#define DECLARE_ARRAY(T_num, T_rank, name, ...)                   \
    class name##_attr : public CAttributeArray<T_num, T_rank>      \
    {                                                              \
@@ -39,8 +43,10 @@
          using CAttributeArray<T_num, T_rank>::operator = ;       \
          name##_attr(void) : CAttributeArray<T_num, T_rank> (#name, *CAttributeMap::Current) {} \
+         virtual bool doSend() const { return helper(## __VA_ARGS__); }   \
+         bool helper(bool returnTrue=true) const { return returnTrue; }   \
          virtual ~name##_attr(void) {}                            \
    } name;
 
-#define DECLARE_ARRAY_PRIVATE(T_num, T_rank, name)                        \
+#define DECLARE_ARRAY_PRIVATE(T_num, T_rank, name, ...)           \
    class name##_attr : public CAttributeArray<T_num, T_rank>      \
    {                                                              \
@@ -50,13 +56,17 @@
          virtual bool isPublic() const                            \
          { return false; }                                        \
+         virtual bool doSend() const { return helper(## __VA_ARGS__); }   \
+         bool helper(bool returnTrue=true) const { return returnTrue; }   \
          virtual ~name##_attr(void) {}                            \
    } name;
 
-#define DECLARE_CLASS_ENUM(name)                                   \
-   class name##_attr : public CAttributeEnum<Enum_##name>          \
+#define DECLARE_CLASS_ENUM(name, ...)                             \
+   class name##_attr : public CAttributeEnum<Enum_##name>         \
    {                                                              \
       public :                                                    \
          name##_attr(void) : CAttributeEnum<Enum_##name>(#name, *CAttributeMap::Current) { } \
-         virtual ~name##_attr(void) {}                           \
+         virtual bool doSend() const { return helper(## __VA_ARGS__); }   \
+         bool helper(bool returnTrue=true) const { return returnTrue; }   \
+         virtual ~name##_attr(void) {}                            \
    } name;
 
@@ -71,9 +81,9 @@
    DECLARE_CLASS_ENUM(name)
 
-#define DECLARE_ENUM3(name,arg1,arg2,arg3)                             \
+#define DECLARE_ENUM3(name,arg1,arg2,arg3)                        \
    class Enum_##name                                              \
    {                                                              \
      public:                                                      \
-     enum t_enum { arg1=0, arg2, arg3} ;                                \
+     enum t_enum { arg1=0, arg2, arg3} ;                          \
      const char** getStr(void) const { static const char * enumStr[] = { #arg1, #arg2, #arg3 } ; return enumStr ; }   \
      int getSize(void) const { return 3 ; }                       \
@@ -81,9 +91,9 @@
    DECLARE_CLASS_ENUM(name)
 
-#define DECLARE_ENUM4(name,arg1,arg2,arg3,arg4)                             \
+#define DECLARE_ENUM4(name,arg1,arg2,arg3,arg4)                   \
    class Enum_##name                                              \
    {                                                              \
      public:                                                      \
-     enum t_enum { arg1=0, arg2, arg3,arg4} ;                                \
+     enum t_enum { arg1=0, arg2, arg3,arg4} ;                     \
      const char** getStr(void) const { static const char * enumStr[] = { #arg1, #arg2, #arg3,#arg4 } ; return enumStr ; }   \
      int getSize(void) const { return 4 ; }                       \
@@ -91,9 +101,9 @@
    DECLARE_CLASS_ENUM(name)
 
-#define DECLARE_ENUM5(name,arg1,arg2,arg3,arg4,arg5)                             \
+#define DECLARE_ENUM5(name,arg1,arg2,arg3,arg4,arg5)              \
    class Enum_##name                                              \
    {                                                              \
      public:                                                      \
-     enum t_enum { arg1=0, arg2, arg3,arg4,arg5} ;                                \
+     enum t_enum { arg1=0, arg2, arg3,arg4,arg5} ;                \
      const char** getStr(void) const { static const char * enumStr[] = { #arg1, #arg2, #arg3,#arg4,#arg5 } ; return enumStr ; }   \
      int getSize(void) const { return 5 ; }                       \
@@ -101,9 +111,9 @@
    DECLARE_CLASS_ENUM(name)
 
-#define DECLARE_ENUM6(name,arg1,arg2,arg3,arg4,arg5,arg6)                             \
+#define DECLARE_ENUM6(name,arg1,arg2,arg3,arg4,arg5,arg6)         \
    class Enum_##name                                              \
    {                                                              \
      public:                                                      \
-     enum t_enum { arg1=0, arg2, arg3,arg4,arg5,arg6} ;                                \
+     enum t_enum { arg1=0, arg2, arg3,arg4,arg5,arg6} ;           \
      const char** getStr(void) const { static const char * enumStr[] = { #arg1, #arg2, #arg3,#arg4,#arg5,#arg6 } ; return enumStr ; }   \
      int getSize(void) const { return 6 ; }                       \
@@ -111,9 +121,9 @@
    DECLARE_CLASS_ENUM(name)
 
-#define DECLARE_ENUM7(name,arg1,arg2,arg3,arg4,arg5,arg6,arg7)                             \
+#define DECLARE_ENUM7(name,arg1,arg2,arg3,arg4,arg5,arg6,arg7)    \
    class Enum_##name                                              \
    {                                                              \
      public:                                                      \
-     enum t_enum { arg1=0, arg2, arg3,arg4,arg5,arg6,arg7} ;                                \
+     enum t_enum { arg1=0, arg2, arg3,arg4,arg5,arg6,arg7} ;      \
      const char** getStr(void) const { static const char * enumStr[] = { #arg1, #arg2, #arg3,#arg4,#arg5,#arg6,#arg7 } ; return enumStr ; }   \
      int getSize(void) const { return 7 ; }                       \
@@ -125,5 +135,5 @@
    {                                                              \
      public:                                                      \
-     enum t_enum { arg1=0, arg2, arg3,arg4,arg5,arg6,arg7,arg8} ;                                \
+     enum t_enum { arg1=0, arg2, arg3,arg4,arg5,arg6,arg7,arg8} ; \
      const char** getStr(void) const { static const char * enumStr[] = { #arg1, #arg2, #arg3,#arg4,#arg5,#arg6,#arg7,#arg8 } ; return enumStr ; }   \
      int getSize(void) const { return 8 ; }                       \
Index: /XIOS/dev/dev_olga/src/distribution_client.cpp
===================================================================
--- /XIOS/dev/dev_olga/src/distribution_client.cpp	(revision 1024)
+++ /XIOS/dev/dev_olga/src/distribution_client.cpp	(revision 1025)
@@ -11,5 +11,5 @@
 namespace xios {
 
-CDistributionClient::CDistributionClient(int rank, const GlobalLocalDataMap& globalLocalIndex)
+CDistributionClient::CDistributionClient(int rank, CGrid* grid, const GlobalLocalDataMap& globalLocalIndex)
   : CDistribution(rank, 0)
    , axisDomainOrder_()
@@ -34,4 +34,70 @@
     ++idx;
   }
+
+  std::vector<CDomain*> domList = grid->getDomains();
+  std::vector<CAxis*> axisList = grid->getAxis();
+  std::vector<CScalar*> scalarList = grid->getScalars();
+  CArray<int,1> axisDomainOrder = grid->axis_domain_order;
+
+  int numElement = axisDomainOrder.numElements();
+  // Because domain and axis can be in any order (axis1, domain1, axis2, axis3, )
+  // their position should be specified. In axisDomainOrder, domain == true, axis == false
+  int dims = numElement;
+  idx = 0;
+  std::vector<int> indexMap(numElement);  
+  for (int i = 0; i < numElement; ++i)
+  {
+    indexMap[i] = idx;
+    if (2 == axisDomainOrder(i))
+    {
+      ++dims;
+      idx += 2;
+    }
+    else ++idx;
+  }
+
+  nGlob_.resize(dims);
+
+  // Data_n_index of domain or axis (For now, axis uses its size as data_n_index
+  dataNIndex_.resize(numElement);
+  dataDims_.resize(numElement);
+  isDataDistributed_ = false;
+  int domIndex = 0, axisIndex = 0, scalarIndex = 0;
+  for (idx = 0; idx < numElement; ++idx)
+  {
+    int eleDim = axisDomainOrder(idx);
+
+    // If this is a domain
+    if (2 == eleDim)
+    {
+      // On the j axis
+      nGlob_.at(indexMap[idx]+1)  = domList[domIndex]->nj_glo.getValue();
+      nGlob_.at(indexMap[idx]) = domList[domIndex]->ni_glo.getValue();
+      dataNIndex_.at(idx) = domList[domIndex]->data_i_index.numElements();
+      dataDims_.at(idx) = domList[domIndex]->data_dim.getValue();
+
+      isDataDistributed_ |= domList[domIndex]->isDistributed();
+      ++domIndex;
+    }
+    else if (1 == eleDim)// So it's an axis
+    {
+      nGlob_.at(indexMap[idx]) = axisList[axisIndex]->n_glo.getValue();
+      dataNIndex_.at(idx) = axisList[axisIndex]->data_index.numElements();
+      dataDims_.at(idx) = 1;
+
+      isDataDistributed_ |= axisList[axisIndex]->isDistributed();
+      ++axisIndex;
+    }
+    else // scalar
+    {
+      nGlob_.at(indexMap[idx]) = 1;
+      dataNIndex_.at(idx) = 1;
+      dataDims_.at(idx) = 1;
+
+      isDataDistributed_ |= false;
+      ++scalarIndex;
+    }
+  }
+
 }
 
@@ -192,8 +258,4 @@
   infoIndex_.resize(this->dims_);
 
-  // A trick to determine position of each domain in domainList
-  int domIndex = 0, axisIndex = 0, scalarIndex = 0;
-  idx = 0;
-
   elementLocalIndex_.resize(numElement_);
   elementGlobalIndex_.resize(numElement_);
@@ -202,9 +264,16 @@
   elementNLocal_.resize(numElement_);
   elementNGlobal_.resize(numElement_);
+
   elementNLocal_[0] = 1;
   elementNGlobal_[0] = 1;
+  isDataDistributed_ = false;
+
   size_t localSize = 1, globalSize = 1;
 
-  isDataDistributed_ = false;
+  // A trick to determine position of each domain in domainList
+  int domIndex = 0, axisIndex = 0, scalarIndex = 0;
+  idx = 0;
+
+  
   // Update all the vectors above
   for (idx = 0; idx < numElement_; ++idx)
Index: /XIOS/dev/dev_olga/src/distribution_client.hpp
===================================================================
--- /XIOS/dev/dev_olga/src/distribution_client.hpp	(revision 1024)
+++ /XIOS/dev/dev_olga/src/distribution_client.hpp	(revision 1025)
@@ -34,5 +34,5 @@
   public:
     /** Default constructor */
-    CDistributionClient(int rank, const GlobalLocalDataMap& globalLocalIndex);
+    CDistributionClient(int rank, CGrid* grid, const GlobalLocalDataMap& globalLocalIndex);
     CDistributionClient(int rank, int dims, const CArray<size_t,1>& globalIndex = CArray<size_t,1>());
     CDistributionClient(int rank, CGrid* grid);
Index: /XIOS/dev/dev_olga/src/distribution_server.cpp
===================================================================
--- /XIOS/dev/dev_olga/src/distribution_server.cpp	(revision 1024)
+++ /XIOS/dev/dev_olga/src/distribution_server.cpp	(revision 1025)
@@ -13,5 +13,6 @@
 
 CDistributionServer::CDistributionServer(int rank, int dims, const CArray<size_t,1>& globalIndex)
-  : CDistribution(rank, dims, globalIndex), nGlobal_(), nZoomSize_(), nZoomBegin_(), globalLocalIndexMap_()
+  : CDistribution(rank, dims, globalIndex), nGlobal_(), nZoomSize_(), nZoomBegin_(), globalLocalIndexMap_(),
+  globalIndexEachDimension_()
 {
 }
@@ -19,5 +20,6 @@
 CDistributionServer::CDistributionServer(int rank, const std::vector<int>& nZoomBegin,
                                          const std::vector<int>& nZoomSize, const std::vector<int>& nGlobal)
-  : CDistribution(rank, nGlobal.size()), nGlobal_(nGlobal), nZoomSize_(nZoomSize), nZoomBegin_(nZoomBegin), globalLocalIndexMap_()
+  : CDistribution(rank, nGlobal.size()), nGlobal_(nGlobal), nZoomSize_(nZoomSize), nZoomBegin_(nZoomBegin), globalLocalIndexMap_(),
+  globalIndexEachDimension_()
 {
   createGlobalIndex();
@@ -29,7 +31,18 @@
                                          const std::vector<int>& nGlobal)
   : CDistribution(rank, nGlobal.size()), nGlobal_(nGlobal), nZoomBeginGlobal_(nZoomBeginGlobal),
-    nZoomSize_(nZoomSize), nZoomBegin_(nZoomBegin), globalLocalIndexMap_()
+    nZoomSize_(nZoomSize), nZoomBegin_(nZoomBegin), globalLocalIndexMap_(),
+    globalIndexEachDimension_()
 {
   createGlobalIndex();
+}
+
+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);
 }
 
@@ -88,4 +101,52 @@
 }
 
+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 = 1; k < nbDim; ++k)
+      {
+        mulDim *= nbGlobal[k-1];
+        globalIndex += (currentIndex[k])*mulDim;
+      }
+      globalLocalIndexMap_[globalIndex] = idx;
+      this->globalIndex_(idx) = globalIndex;
+
+      ++idx;
+    }
+    idxLoop[0] += innerLoopSize;
+  }
+
+}
+
 /*!
   Compute local index for writing data on server
Index: /XIOS/dev/dev_olga/src/distribution_server.hpp
===================================================================
--- /XIOS/dev/dev_olga/src/distribution_server.hpp	(revision 1024)
+++ /XIOS/dev/dev_olga/src/distribution_server.hpp	(revision 1025)
@@ -30,4 +30,7 @@
                         const std::vector<int>& nZoomBeginGlobal,
                         const std::vector<int>& nGlobal);
+    CDistributionServer(int rank, 
+                        const std::vector<CArray<int,1> >& globalIndexEachDimension,
+                        const std::vector<int>& nGlobal);
 
     /** Default destructor */
@@ -38,4 +41,5 @@
     const std::vector<int>& getZoomSizeServer() const;
     const GlobalLocalMap& getGlobalLocalIndex() const { return globalLocalIndexMap_; }
+    const std::vector<CArray<int,1> >& getGlobalIndexEachDimension() const; 
 
     virtual CArray<size_t,1> computeLocalIndex(const CArray<size_t,1>& globalIndex);
@@ -45,4 +49,7 @@
   protected:
     virtual void createGlobalIndex();
+
+    void createGlobalIndexFromIndex(const std::vector<CArray<int,1> >& globalIndexOnEachDimension,
+                                    const std::vector<int>& nbGlobal);
 
   protected:
@@ -54,4 +61,5 @@
     std::vector<int> nZoomSize_;
     std::vector<int> nZoomBegin_;
+    std::vector<CArray<int, 1> > globalIndexEachDimension_;
 
 };
Index: /XIOS/dev/dev_olga/src/io/nc4_data_output.cpp
===================================================================
--- /XIOS/dev/dev_olga/src/io/nc4_data_output.cpp	(revision 1024)
+++ /XIOS/dev/dev_olga/src/io/nc4_data_output.cpp	(revision 1025)
@@ -74,4 +74,9 @@
          else setWrittenDomain(domid);
 
+        const std::vector<int>& local_size_write  = domain->getLocalWriteSize();
+        const std::vector<int>& global_size_write = domain->getGlobalWriteSize();
+        const std::vector<int>& start_write = domain->getStartWriteIndex();
+        const std::vector<int>& count_write = domain->getCountWriteIndex();
+        int nvertex = (domain->nvertex.isEmpty()) ? 0 : domain->nvertex;
 
          StdString dimXid, dimYid ;
@@ -135,6 +140,6 @@
                  bounds_latid = StdString("bounds_lat").append(appendDomid);
 
-                 SuperClassWriter::addDimension(dimXid, domain->zoom_ni_srv);
-                 SuperClassWriter::addDimension(dimYid, domain->zoom_nj_srv);
+                 SuperClassWriter::addDimension(dimXid, local_size_write[0]);
+                 SuperClassWriter::addDimension(dimYid, local_size_write[1]);
 
                  if (domain->hasBounds)
@@ -143,16 +148,12 @@
                  if (server->intraCommSize > 1)
                  {
-                   this->writeLocalAttributes(domain->zoom_ibegin_srv,
-                                              domain->zoom_ni_srv,
-                                              domain->zoom_jbegin_srv,
-                                              domain->zoom_nj_srv,
+                   this->writeLocalAttributes(0, count_write[0],
+                                              0, count_write[1],
                                               appendDomid);
 
                    if (singleDomain)
                     this->writeLocalAttributes_IOIPSL(dimXid, dimYid,
-                                                      domain->zoom_ibegin_srv,
-                                                      domain->zoom_ni_srv,
-                                                      domain->zoom_jbegin_srv,
-                                                      domain->zoom_nj_srv,
+                                                      0, count_write[0],
+                                                      0, count_write[1],
                                                       domain->ni_glo,domain->nj_glo,
                                                       server->intraCommRank,server->intraCommSize);
@@ -223,11 +224,11 @@
                    {
                      case CDomain::type_attr::curvilinear :
-                       SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0);
-                       SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0);
+                       SuperClassWriter::writeData(domain->latvalue, latid, isCollective, 0);
+                       SuperClassWriter::writeData(domain->lonvalue, lonid, isCollective, 0);
                        break;
                      case CDomain::type_attr::rectilinear :
-                       CArray<double,1> lat = domain->latvalue_srv(Range(fromStart,toEnd,domain->zoom_ni_srv)) ;
+                       CArray<double,1> lat = domain->latvalue(Range(fromStart,toEnd,local_size_write[0])) ;
                        SuperClassWriter::writeData(CArray<double,1>(lat.copy()), latid, isCollective, 0);
-                       CArray<double,1> lon=domain->lonvalue_srv(Range(0,domain->zoom_ni_srv-1)) ;
+                       CArray<double,1> lon = domain->lonvalue(Range(0,local_size_write[1])) ;
                        SuperClassWriter::writeData(CArray<double,1>(lon.copy()), lonid, isCollective, 0);
                        break;
@@ -236,11 +237,11 @@
                    if (domain->hasBounds)
                    {
-                     SuperClassWriter::writeData(domain->bounds_lon_srv, bounds_lonid, isCollective, 0);
-                     SuperClassWriter::writeData(domain->bounds_lat_srv, bounds_latid, isCollective, 0);
+                     SuperClassWriter::writeData(domain->bounds_lonvalue, bounds_lonid, isCollective, 0);
+                     SuperClassWriter::writeData(domain->bounds_latvalue, bounds_latid, isCollective, 0);
                    }
                  }
 
                  if (domain->hasArea)
-                   SuperClassWriter::writeData(domain->area_srv, areaId, isCollective, 0);
+                   SuperClassWriter::writeData(domain->areavalue, areaId, isCollective, 0);
 
                  SuperClassWriter::definition_start();
@@ -250,6 +251,6 @@
               case (ONE_FILE) :
               {
-                 SuperClassWriter::addDimension(dimXid, domain->global_zoom_ni);
-                 SuperClassWriter::addDimension(dimYid, domain->global_zoom_nj);
+                 SuperClassWriter::addDimension(dimXid, global_size_write[0]);
+                 SuperClassWriter::addDimension(dimYid, global_size_write[1]);
 
                  if (domain->hasBounds)
@@ -325,13 +326,17 @@
                      else
                      {
-                       start[1]=domain->zoom_ibegin_srv-domain->global_zoom_ibegin;
-                       start[0]=domain->zoom_jbegin_srv-domain->global_zoom_jbegin;
-                       count[1]=domain->zoom_ni_srv ; count[0]=domain->zoom_nj_srv ;
+                       // start[1]=domain->zoom_ibegin_srv-domain->global_zoom_ibegin;
+                       // start[0]=domain->zoom_jbegin_srv-domain->global_zoom_jbegin;
+                       // count[1]=domain->zoom_ni_srv ; count[0]=domain->zoom_nj_srv ;
+                       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_srv, latid, isCollective, 0,&start,&count);
-                       SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0,&start,&count);
+                       SuperClassWriter::writeData(domain->latvalue, latid, isCollective, 0,&start,&count);
+                       SuperClassWriter::writeData(domain->lonvalue, lonid, isCollective, 0,&start,&count);
                      }
                      break;
@@ -347,18 +352,18 @@
                          start[0]=0 ;
                          count[0]=0 ;
-                         SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0,&start,&count);
-                         SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0,&start,&count);
+                         SuperClassWriter::writeData(domain->latvalue, latid, isCollective, 0,&start,&count);
+                         SuperClassWriter::writeData(domain->lonvalue, lonid, isCollective, 0,&start,&count);
 
                        }
                        else
                        {
-                         start[0]=domain->zoom_jbegin_srv-domain->global_zoom_jbegin;
-                         count[0]=domain->zoom_nj_srv ;
-                         CArray<double,1> lat = domain->latvalue_srv(Range(fromStart,toEnd,domain->zoom_ni_srv)) ;
+                         start[0]= start_write[1];
+                         count[0]= count_write[1];
+                         CArray<double,1> lat = domain->latvalue(Range(fromStart,toEnd,count_write[0])) ;
                          SuperClassWriter::writeData(CArray<double,1>(lat.copy()), latid, isCollective, 0,&start,&count);
 
-                         start[0]=domain->zoom_ibegin_srv-domain->global_zoom_ibegin;
-                         count[0]=domain->zoom_ni_srv ;
-                         CArray<double,1> lon=domain->lonvalue_srv(Range(0,domain->zoom_ni_srv-1)) ;
+                         start[0]= start_write[0];
+                         count[0]= count_write[0];
+                         CArray<double,1> lon=domain->lonvalue(Range(0,count_write[1])) ;
                          SuperClassWriter::writeData(CArray<double,1>(lon.copy()), lonid, isCollective, 0,&start,&count);
                        }
@@ -380,13 +385,13 @@
                    {
                      start[2] = 0;
-                     start[1] = domain->zoom_ibegin_srv - domain->global_zoom_ibegin;
-                     start[0] = domain->zoom_jbegin_srv - domain->global_zoom_jbegin;
-                     count[2] = domain->nvertex;
-                     count[1] = domain->zoom_ni_srv;
-                     count[0] = domain->zoom_nj_srv;
+                     start[1] = start_write[0];
+                     start[0] = start_write[1];
+                     count[2] = nvertex;
+                     count[1] = count_write[0];
+                     count[0] = count_write[1];
                    }
 
-                 SuperClassWriter::writeData(domain->bounds_lon_srv, bounds_lonid, isCollective, 0, &start, &count);
-                 SuperClassWriter::writeData(domain->bounds_lat_srv, 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);
                  }
 
@@ -403,11 +408,16 @@
                    else
                    {
-                     start[1] = domain->zoom_ibegin_srv - domain->global_zoom_ibegin;
-                     start[0] = domain->zoom_jbegin_srv - domain->global_zoom_jbegin;
-                     count[1] = domain->zoom_ni_srv;
-                     count[0] = domain->zoom_nj_srv;
+                     // start[1] = domain->zoom_ibegin_srv - domain->global_zoom_ibegin;
+                     // start[0] = domain->zoom_jbegin_srv - domain->global_zoom_jbegin;
+                     // count[1] = domain->zoom_ni_srv;
+                     // count[0] = domain->zoom_nj_srv;
+
+                     start[1]= start_write[0];
+                     start[0]= start_write[1];
+                     count[1]= count_write[0];
+                     count[0]= count_write[1];
                    }
 
-                   SuperClassWriter::writeData(domain->area_srv, areaId, isCollective, 0, &start, &count);
+                   SuperClassWriter::writeData(domain->areavalue, areaId, isCollective, 0, &start, &count);
                  }
 
@@ -450,5 +460,5 @@
       StdString domainName = domain->name;
       domain->assignMesh(domainName, domain->nvertex);
-      domain->mesh->createMeshEpsilon(server->intraComm, domain->lonvalue_srv, domain->latvalue_srv, domain->bounds_lon_srv, domain->bounds_lat_srv);
+      domain->mesh->createMeshEpsilon(server->intraComm, domain->lonvalue, domain->latvalue, domain->bounds_lonvalue, domain->bounds_latvalue);
 
       StdString node_x = domainName + "_node_x";
@@ -471,4 +481,9 @@
       StdString dimVertex = "n" + domainName + "_vertex";
       StdString dimTwo = "Two";
+
+      const std::vector<int>& local_size_write  = domain->getLocalWriteSize();
+      const std::vector<int>& global_size_write = domain->getGlobalWriteSize();
+      const std::vector<int>& start_write = domain->getStartWriteIndex();
+      const std::vector<int>& count_write = domain->getCountWriteIndex();
 
       if (!SuperClassWriter::dimExist(dimTwo)) SuperClassWriter::addDimension(dimTwo, 2);
@@ -664,6 +679,6 @@
                  else
                  {
-                   startNodes[0] = domain->zoom_ibegin_srv-domain->global_zoom_ibegin;
-                   countNodes[0] = domain->zoom_ni_srv ;
+                   startNodes[0] = start_write[0]; //domain->zoom_ibegin_srv-domain->global_zoom_ibegin;
+                   countNodes[0] = count_write[0]; //domain->zoom_ni_srv ;
                  }
 
@@ -687,11 +702,11 @@
                  else
                  {
-                   startEdges[0] = domain->zoom_ibegin_srv-domain->global_zoom_ibegin;
-                   countEdges[0] = domain->zoom_ni_srv ;
+                   startEdges[0] = start_write[0]; //domain->zoom_ibegin_srv-domain->global_zoom_ibegin;
+                   countEdges[0] = count_write[0];
                    startNodes[0] = domain->mesh->node_start;
                    countNodes[0] = domain->mesh->node_count;
-                   startEdgeNodes[0] = domain->zoom_ibegin_srv-domain->global_zoom_ibegin;
+                   startEdgeNodes[0] = start_write[0]; //domain->zoom_ibegin_srv-domain->global_zoom_ibegin;
                    startEdgeNodes[1] = 0;
-                   countEdgeNodes[0] = domain->zoom_ni_srv;
+                   countEdgeNodes[0] = count_write[0]; //domain->zoom_ni_srv;
                    countEdgeNodes[1]= 2;
                  }
@@ -723,6 +738,6 @@
                  else
                  {
-                   startFaces[0] = domain->zoom_ibegin_srv-domain->global_zoom_ibegin;
-                   countFaces[0] = domain->zoom_ni_srv ;
+                   startFaces[0] = start_write[0]; //domain->zoom_ibegin_srv-domain->global_zoom_ibegin;
+                   countFaces[0] = count_write[0]; //domain->zoom_ni_srv ;
                    startNodes[0] = domain->mesh->node_start;
                    countNodes[0] = domain->mesh->node_count;
@@ -737,7 +752,7 @@
                    countEdgeFaces[0] = domain->mesh->edge_count;
                    countEdgeFaces[1]= 2;
-                   startFaceConctv[0] = domain->zoom_ibegin_srv-domain->global_zoom_ibegin;
-                   startFaceConctv[1] = 0;
-                   countFaceConctv[0] = domain->zoom_ni_srv;
+                   startFaceConctv[0] = start_write[0]; //domain->zoom_ibegin_srv-domain->global_zoom_ibegin;
+                   startFaceConctv[1] = 0; //0;
+                   countFaceConctv[0] = count_write[0]; //domain->zoom_ni_srv;
                    countFaceConctv[1] = domain->nvertex;
                  }
@@ -760,9 +775,9 @@
               if (domain->nvertex == 2)
               {
-                startEdges[0] = domain->zoom_ibegin_srv-domain->global_zoom_ibegin;
-                countEdges[0] = domain->zoom_ni_srv ;
-                startEdgeNodes[0] = domain->zoom_ibegin_srv-domain->global_zoom_ibegin;
-                startEdgeNodes[1] = 0;
-                countEdgeNodes[0] = domain->zoom_ni_srv;
+                startEdges[0] = start_write[0]; //domain->zoom_ibegin_srv-domain->global_zoom_ibegin;
+                countEdges[0] = count_write[0]; //domain->zoom_ni_srv ;
+                startEdgeNodes[0] = start_write[0]; //domain->zoom_ibegin_srv-domain->global_zoom_ibegin;
+                startEdgeNodes[1] = 0; //0;
+                countEdgeNodes[0] = count_write[0]; //domain->zoom_ni_srv;
                 countEdgeNodes[1]= 2;
                 SuperClassWriter::writeData(domain->mesh->edge_lat, edge_y, isCollective, 0, &startEdges, &countEdges);
@@ -785,13 +800,13 @@
                   SuperClassWriter::writeData(domain->mesh->edge_nodes, edge_nodes, isCollective, 0, &startEdgeNodes, &countEdgeNodes);
                 }
-                startFaces[0] = domain->zoom_ibegin_srv-domain->global_zoom_ibegin;
-                countFaces[0] = domain->zoom_ni_srv;
+                startFaces[0] = start_write[0]; //domain->zoom_ibegin_srv-domain->global_zoom_ibegin;
+                countFaces[0] = count_write[0]; //domain->zoom_ni_srv;
                 startEdgeFaces[0] = domain->mesh->edge_start;
                 startEdgeFaces[1]= 0;
                 countEdgeFaces[0] = domain->mesh->edge_count;
                 countEdgeFaces[1]= 2;
-                startFaceConctv[0] = domain->zoom_ibegin_srv-domain->global_zoom_ibegin;
-                startFaceConctv[1] = 0;
-                countFaceConctv[0] = domain->zoom_ni_srv;
+                startFaceConctv[0] = start_write[0]; //domain->zoom_ibegin_srv-domain->global_zoom_ibegin;
+                startFaceConctv[1] = 0; //0;
+                countFaceConctv[0] = count_write[0]; //domain->zoom_ni_srv;
                 countFaceConctv[1]= domain->nvertex;
                 SuperClassWriter::writeData(domain->mesh->face_lat, face_y, isCollective, 0, &startFaces, &countFaces);
@@ -860,4 +875,10 @@
          string areaId = "area" + appendDomid;
 
+        const std::vector<int>& local_size_write  = domain->getLocalWriteSize();
+        const std::vector<int>& global_size_write = domain->getGlobalWriteSize();
+        const std::vector<int>& start_write = domain->getStartWriteIndex();
+        const std::vector<int>& count_write = domain->getCountWriteIndex();
+        int nvertex = (domain->nvertex.isEmpty()) ? 0 : domain->nvertex;
+
          try
          {
@@ -867,5 +888,5 @@
               {
                  dim0.push_back(dimXid);
-                 SuperClassWriter::addDimension(dimXid, domain->zoom_ni_srv);
+                 SuperClassWriter::addDimension(dimXid, local_size_write[0]);
 
                  lonid = StdString("lon").append(appendDomid);
@@ -905,15 +926,15 @@
                  if (domain->hasLonLat)
                  {
-                   SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0);
-                   SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0);
+                   SuperClassWriter::writeData(domain->latvalue, latid, isCollective, 0);
+                   SuperClassWriter::writeData(domain->lonvalue, lonid, isCollective, 0);
                    if (domain->hasBounds)
                    {
-                     SuperClassWriter::writeData(domain->bounds_lon_srv, bounds_lonid, isCollective, 0);
-                     SuperClassWriter::writeData(domain->bounds_lat_srv, bounds_latid, isCollective, 0);
+                     SuperClassWriter::writeData(domain->bounds_lonvalue, bounds_lonid, isCollective, 0);
+                     SuperClassWriter::writeData(domain->bounds_latvalue, bounds_latid, isCollective, 0);
                    }
                  }
 
                  if (domain->hasArea)
-                   SuperClassWriter::writeData(domain->area_srv, areaId, isCollective, 0);
+                   SuperClassWriter::writeData(domain->areavalue, areaId, isCollective, 0);
 
                  SuperClassWriter::definition_start();
@@ -928,5 +949,5 @@
                  bounds_latid = StdString("bounds_lat").append(appendDomid);
                  dim0.push_back(dimXid);
-                 SuperClassWriter::addDimension(dimXid, domain->ni_glo);
+                 SuperClassWriter::addDimension(dimXid, global_size_write[0]);
                  if (domain->hasLonLat)
                  {
@@ -938,5 +959,5 @@
                    this->writeAxisAttributes(latid, "", "latitude", "Latitude", "degrees_north", domid);
                    if (domain->hasBounds) SuperClassWriter::addAttribute("bounds",bounds_latid, &latid);
-                   if (domain->hasBounds) SuperClassWriter::addDimension(dimVertId, domain->nvertex);
+                   if (domain->hasBounds) SuperClassWriter::addDimension(dimVertId, nvertex);
                  }
                  dim0.clear();
@@ -968,5 +989,5 @@
                    count[0]=0 ;
                    startBounds[1]=0 ;
-                   countBounds[1]=domain->nvertex ;
+                   countBounds[1]=nvertex ;
                    startBounds[0]=0 ;
                    countBounds[0]=0 ;
@@ -974,25 +995,25 @@
                  else
                  {
-                   start[0]=domain->zoom_ibegin_srv-domain->global_zoom_ibegin;
-                   count[0]=domain->zoom_ni_srv ;
-                   startBounds[0]=domain->zoom_ibegin_srv-domain->global_zoom_ibegin;
+                   start[0]=start_write[0];
+                   count[0]=count_write[0];
+                   startBounds[0]=start_write[0];
                    startBounds[1]=0 ;
-                   countBounds[0]=domain->zoom_ni_srv ;
-                   countBounds[1]=domain->nvertex ;
+                   countBounds[0]=count_write[0];
+                   countBounds[1]=nvertex ;
                  }
 
                  if (domain->hasLonLat)
                  {
-                   SuperClassWriter::writeData(domain->latvalue_srv, latid, isCollective, 0,&start,&count);
-                   SuperClassWriter::writeData(domain->lonvalue_srv, lonid, isCollective, 0,&start,&count);
+                   SuperClassWriter::writeData(domain->latvalue, latid, isCollective, 0,&start,&count);
+                   SuperClassWriter::writeData(domain->lonvalue, lonid, isCollective, 0,&start,&count);
                    if (domain->hasBounds)
                    {
-                     SuperClassWriter::writeData(domain->bounds_lon_srv, bounds_lonid, isCollective, 0,&startBounds,&countBounds);
-                     SuperClassWriter::writeData(domain->bounds_lat_srv, bounds_latid, isCollective, 0,&startBounds,&countBounds);
+                     SuperClassWriter::writeData(domain->bounds_lonvalue, bounds_lonid, isCollective, 0,&startBounds,&countBounds);
+                     SuperClassWriter::writeData(domain->bounds_latvalue, bounds_latid, isCollective, 0,&startBounds,&countBounds);
                    }
                  }
 
                  if (domain->hasArea)
-                   SuperClassWriter::writeData(domain->area_srv, areaId, isCollective, 0, &start, &count);
+                   SuperClassWriter::writeData(domain->areavalue, areaId, isCollective, 0, &start, &count);
 
                  SuperClassWriter::definition_start();
@@ -1021,14 +1042,16 @@
       void CNc4DataOutput::writeAxis_(CAxis* axis)
       {
+        CContext* context = CContext::getCurrent();
+        CContextServer* server = (context->hasServer) ? context->server : context->serverPrimServer;
+
         if (axis->IsWritten(this->filename)) return;
         axis->checkAttributes();
-        int zoom_size_srv  = axis->zoom_size_srv;
-        int zoom_begin_srv = axis->zoom_begin_srv;
-        int zoom_size  = (MULTI_FILE == SuperClass::type) ? zoom_size_srv
-                                                              : axis->global_zoom_n;
-        int zoom_begin = (MULTI_FILE == SuperClass::type) ? zoom_begin_srv
-                                                              : axis->global_zoom_begin;
-
-        if ((0 == zoom_size_srv) && (MULTI_FILE == SuperClass::type)) return;
+
+        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;
 
         std::vector<StdString> dims;
@@ -1039,5 +1062,5 @@
         try
         {
-          SuperClassWriter::addDimension(axisid, zoom_size);
+          SuperClassWriter::addDimension(axisid, global_size_write);
           if (axis->hasValue)
           {
@@ -1079,10 +1102,10 @@
               case MULTI_FILE:
               {
-                CArray<double,1> axis_value(zoom_size_srv);
-                for (int i = 0; i < zoom_size_srv; i++) axis_value(i) = axis->value_srv(i);
+                CArray<double,1> axis_value(local_size_write);
+                for (int i = 0; i < local_size_write; i++) axis_value(i) = axis->value(i);
                 SuperClassWriter::writeData(axis_value, axisid, isCollective, 0);
 
                 if (!axis->bounds.isEmpty())
-                  SuperClassWriter::writeData(axis->bound_srv, axisBoundsId, isCollective, 0);
+                  SuperClassWriter::writeData(axis->bounds, axisBoundsId, isCollective, 0);
 
                 SuperClassWriter::definition_start();
@@ -1092,11 +1115,11 @@
               case ONE_FILE:
               {
-                CArray<double,1> axis_value(zoom_size_srv);
-                axis_value = axis->value_srv;
+                CArray<double,1> axis_value(count_write);
+                axis_value = axis->value;
 
                 std::vector<StdSize> start(1), startBounds(2) ;
                 std::vector<StdSize> count(1), countBounds(2) ;
-                start[0] = startBounds[0] = zoom_begin_srv-axis->global_zoom_begin;
-                count[0] = countBounds[0] = zoom_size_srv;
+                start[0] = startBounds[0] = start_write;
+                count[0] = countBounds[0] = count_write;
                 startBounds[1] = 0;
                 countBounds[1] = 2;
@@ -1104,5 +1127,5 @@
 
                 if (!axis->bounds.isEmpty())
-                  SuperClassWriter::writeData(axis->bound_srv, axisBoundsId, isCollective, 0, &startBounds, &countBounds);
+                  SuperClassWriter::writeData(axis->bounds, axisBoundsId, isCollective, 0, &startBounds, &countBounds);
 
                 SuperClassWriter::definition_start();
@@ -2064,4 +2087,76 @@
               case (ONE_FILE) :
               {
+                // const std::vector<int>& nZoomBeginGlobal = grid->getDistributionServer()->getZoomBeginGlobal();
+                // const std::vector<int>& nZoomBeginServer = grid->getDistributionServer()->getZoomBeginServer();
+                // const std::vector<int>& nZoomSizeServer  = grid->getDistributionServer()->getZoomSizeServer();
+
+                // std::vector<StdSize> start, count;
+
+                // if (field->getUseCompressedOutput())
+                // {
+                //   if (grid->isCompressible())
+                //   {
+                //     start.push_back(grid->getOffsetWrittenIndexes());
+                //     count.push_back(grid->getNumberWrittenIndexes());
+                //   }
+                //   else
+                //   {
+                //     CArray<int,1> axisDomainOrder = grid->axis_domain_order;
+                //     std::vector<StdString> domainList = grid->getDomainList();
+                //     std::vector<StdString> axisList   = grid->getAxisList();
+                //     int numElement = axisDomainOrder.numElements();
+                //     int idxDomain = domainList.size() - 1, idxAxis = axisList.size() - 1;
+                //     int idx = nZoomBeginGlobal.size() - 1;
+
+                //     start.reserve(nZoomBeginGlobal.size());
+                //     count.reserve(nZoomBeginGlobal.size());
+
+
+                //     for (int i = numElement - 1; i >= 0; --i)
+                //     {
+                //       if (2 == axisDomainOrder(i))
+                //       {
+                //         CDomain* domain = CDomain::get(domainList[idxDomain]);
+
+                //         if (domain->isCompressible())
+                //         {
+                //           start.push_back(domain->getOffsetWrittenIndexes());
+                //           count.push_back(domain->getNumberWrittenIndexes());
+                //           idx -= 2;
+                //         }
+                //         else
+                //         {
+                //           if ((domain->type) != CDomain::type_attr::unstructured)
+                //           {
+                //             start.push_back(nZoomBeginServer[idx] - nZoomBeginGlobal[idx]);
+                //             count.push_back(nZoomSizeServer[idx]);
+                //           }
+                //           --idx;
+                //           start.push_back(nZoomBeginServer[idx] - nZoomBeginGlobal[idx]);
+                //           count.push_back(nZoomSizeServer[idx]);
+                //           --idx;
+                //         }
+                //         --idxDomain;
+                //       }
+                //       else if (1 == axisDomainOrder(i))
+                //       {
+                //         CAxis* axis = CAxis::get(axisList[idxAxis]);
+
+                //         if (axis->isCompressible())
+                //         {
+                //           start.push_back(axis->getOffsetWrittenIndexes());
+                //           count.push_back(axis->getNumberWrittenIndexes());
+                //         }
+                //         else
+                //         {
+                //           start.push_back(nZoomBeginServer[idx] - nZoomBeginGlobal[idx]);
+                //           count.push_back(nZoomSizeServer[idx]);
+                //         }
+
+                //         --idxAxis;
+                //         --idx;
+                //       }
+                //     }
+                //   }
                 const std::vector<int>& nZoomBeginGlobal = grid->getDistributionServer()->getZoomBeginGlobal();
                 const std::vector<int>& nZoomBeginServer = grid->getDistributionServer()->getZoomBeginServer();
@@ -2135,9 +2230,49 @@
                       }
                     }
-                  }
+                  }                
                 }
                 else
                 {
-
+                  // CArray<int,1> axisDomainOrder = grid->axis_domain_order;
+                  // std::vector<StdString> domainList = grid->getDomainList();
+                  // std::vector<StdString> axisList   = grid->getAxisList();
+                  // int numElement = axisDomainOrder.numElements();
+                  // int idxDomain = domainList.size() - 1, idxAxis = axisList.size() - 1;
+                  // int idx = nZoomBeginGlobal.size() - 1;
+
+                  // start.reserve(nZoomBeginGlobal.size());
+                  // count.reserve(nZoomBeginGlobal.size());
+
+                  // for (int i = numElement - 1; i >= 0; --i)
+                  // {
+                  //   if (2 == axisDomainOrder(i))
+                  //   {
+                  //     CDomain* domain = CDomain::get(domainList[idxDomain]);
+                  //     if ((domain->type) != CDomain::type_attr::unstructured)
+                  //     {
+                  //       start.push_back(nZoomBeginServer[idx] - nZoomBeginGlobal[idx]);
+                  //       count.push_back(nZoomSizeServer[idx]);
+                  //     }
+                  //     --idx ;
+                  //     start.push_back(nZoomBeginServer[idx] - nZoomBeginGlobal[idx]);
+                  //     count.push_back(nZoomSizeServer[idx]);
+                  //     --idx ;
+                  //     --idxDomain;
+                  //   }
+                  //   else if (1 == axisDomainOrder(i))
+                  //   {
+                  //     start.push_back(nZoomBeginServer[idx] - nZoomBeginGlobal[idx]);
+                  //     count.push_back(nZoomSizeServer[idx]);
+                  //     --idx;
+                  //   }
+                  //   else
+                  //   {
+                  //     if (1 == axisDomainOrder.numElements())
+                  //     {
+                  //       start.push_back(0);
+                  //       count.push_back(1);
+                  //     }
+                  //     --idx;
+                  //   }
                   CArray<int,1> axisDomainOrder = grid->axis_domain_order;
                   std::vector<StdString> domainList = grid->getDomainList();
@@ -2145,5 +2280,5 @@
                   int numElement = axisDomainOrder.numElements();
                   int idxDomain = domainList.size() - 1, idxAxis = axisList.size() - 1;
-                  int idx = nZoomBeginGlobal.size() - 1;
+                  int idx = domainList.size() * 2 + axisList.size() - 1;// nZoomBeginGlobal.size() - 1;
 
                   start.reserve(nZoomBeginGlobal.size());
@@ -2157,10 +2292,14 @@
                       if ((domain->type) != CDomain::type_attr::unstructured)
                       {
-                        start.push_back(nZoomBeginServer[idx] - nZoomBeginGlobal[idx]);
-                        count.push_back(nZoomSizeServer[idx]);
+                        // start.push_back(nZoomBeginServer[idx] - nZoomBeginGlobal[idx]);
+                        // count.push_back(nZoomSizeServer[idx]);
+                        start.push_back((domain->getStartWriteIndex())[idx]);
+                        count.push_back((domain->getCountWriteIndex())[idx]);
                       }
                       --idx ;
-                      start.push_back(nZoomBeginServer[idx] - nZoomBeginGlobal[idx]);
-                      count.push_back(nZoomSizeServer[idx]);
+                      // start.push_back(nZoomBeginServer[idx] - nZoomBeginGlobal[idx]);
+                      // count.push_back(nZoomSizeServer[idx]);
+                      start.push_back((domain->getStartWriteIndex())[idx]);
+                      count.push_back((domain->getCountWriteIndex())[idx]);
                       --idx ;
                       --idxDomain;
@@ -2168,7 +2307,9 @@
                     else if (1 == axisDomainOrder(i))
                     {
-                      start.push_back(nZoomBeginServer[idx] - nZoomBeginGlobal[idx]);
-                      count.push_back(nZoomSizeServer[idx]);
+                      CAxis* axis = CAxis::get(axisList[idxAxis]);
+                      start.push_back(axis->getStartWriteIndex());
+                      count.push_back(axis->getCountWriteIndex());
                       --idx;
+                      --idxAxis;
                     }
                     else
Index: /XIOS/dev/dev_olga/src/node/axis.cpp
===================================================================
--- /XIOS/dev/dev_olga/src/node/axis.cpp	(revision 1024)
+++ /XIOS/dev/dev_olga/src/node/axis.cpp	(revision 1025)
@@ -131,4 +131,38 @@
    }
 
+   /*!
+     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_;
+   }
+
    //----------------------------------------------------------------
 
@@ -166,5 +200,5 @@
      {
        // size estimation for sendDistributedValue
-       std::map<int, std::vector<size_t> >::const_iterator it, ite = indSrv_.end();
+       boost::unordered_map<int, vector<size_t> >::const_iterator it, ite = indSrv_.end();
        for (it = indSrv_.begin(); it != ite; ++it)
        {
@@ -292,4 +326,8 @@
      if (global_zoom_begin.isEmpty()) global_zoom_begin.setValue(0);
      if (global_zoom_n.isEmpty()) global_zoom_n.setValue(n_glo.getValue());
+     if (zoom_index.isEmpty())
+     {
+       zoom_index.setValue(index.getValue());
+     }
    }
 
@@ -342,18 +380,18 @@
         switch(event.type)
         {
-           case EVENT_ID_SERVER_ATTRIBUT :
-             recvServerAttribut(event);
-             return true;
-             break;
-           case EVENT_ID_INDEX:
-            recvIndex(event);
+           // case EVENT_ID_SERVER_ATTRIBUT :
+           //   recvServerAttribut(event);
+           //   return true;
+           //   break;
+          //  case EVENT_ID_INDEX:
+          //   recvIndex(event);
+          //   return true;
+          //   break;
+          case EVENT_ID_NON_DISTRIBUTED_ATTRIBUTES:
+            recvNonDistributedAttributes(event);
             return true;
             break;
-          case EVENT_ID_DISTRIBUTED_VALUE:
-            recvDistributedValue(event);
-            return true;
-            break;
-          case EVENT_ID_NON_DISTRIBUTED_VALUE:
-            recvNonDistributedValue(event);
+          case EVENT_ID_DISTRIBUTED_ATTRIBUTES:
+            recvDistributedAttributes(event);
             return true;
             break;
@@ -383,5 +421,5 @@
      if (context->hasClient)
      {
-       if (n.getValue() != n_glo.getValue()) computeConnectedServer(globalDim, orderPositionInGrid, distType);
+       if (index.numElements() != n_glo.getValue()) computeConnectedServer(globalDim, orderPositionInGrid, distType);
      }
 
@@ -398,19 +436,15 @@
 
      if (this->isChecked) return;
-     if (context->hasClient)
-     {
-       sendServerAttribut(globalDim, orderPositionInGrid, distType);
-       if (hasValue) sendValue();
-     }
+     if (context->hasClient) sendAttributes();    
 
      this->isChecked = true;
    }
 
-  void CAxis::sendValue()
-  {
-     if (n.getValue() == n_glo.getValue())
-       sendNonDistributedValue();
+  void CAxis::sendAttributes()
+  {
+     if (index.numElements() == n_glo.getValue())
+       sendNonDistributedAttributes();
      else
-       sendDistributedValue();
+       sendDistributedAttributes();
   }
 
@@ -419,51 +453,52 @@
   {
     CContext* context = CContext::getCurrent();
-    CContextClient* client = context->client;
+    CContextClient* client = (0 != context->clientPrimServer) ? context->clientPrimServer : context->client;
     int nbServer = client->serverSize;
     int range, clientSize = client->clientSize;
     int rank = client->clientRank;
 
-    size_t ni = this->n.getValue();
-    size_t ibegin = this->begin.getValue();
-    size_t zoom_end = global_zoom_begin+global_zoom_n-1;
-    size_t nZoomCount = 0;
+    // size_t ni = this->n.getValue();
+    // size_t ibegin = this->begin.getValue();
+    // size_t zoom_end = global_zoom_begin+global_zoom_n-1;
+    // size_t nZoomCount = 0;
     size_t nbIndex = index.numElements();
     for (size_t idx = 0; idx < nbIndex; ++idx)
     {
-      size_t globalIndex = index(idx);
-      if (globalIndex >= global_zoom_begin && globalIndex <= zoom_end) ++nZoomCount;
-    }
-
-    CArray<size_t,1> globalIndexAxis(nbIndex);
-    std::vector<size_t> globalAxisZoom(nZoomCount);
-    nZoomCount = 0;
-    for (size_t idx = 0; idx < nbIndex; ++idx)
-    {
-      size_t globalIndex = index(idx);
-      globalIndexAxis(idx) = globalIndex;
-      if (globalIndex >= global_zoom_begin && globalIndex <= zoom_end)
-      {
-        globalAxisZoom[nZoomCount] = globalIndex;
-        ++nZoomCount;
-      }
-    }
-
-    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;
-          if (ind >= global_zoom_begin && ind <= zoom_end)
-            writtenInd.insert(ind);
-        }
-      }
-    }
-
-    CServerDistributionDescription serverDescriptionGlobal(globalDim, nbServer);
+      globalLocalIndexMap_[index(idx)] = idx;
+      // size_t globalIndex = index(idx);
+      // if (globalIndex >= global_zoom_begin && globalIndex <= zoom_end) ++nZoomCount;
+    }
+
+    // CArray<size_t,1> globalIndexAxis(nbIndex);
+    // std::vector<size_t> globalAxisZoom(nZoomCount);
+    // nZoomCount = 0;
+    // for (size_t idx = 0; idx < nbIndex; ++idx)
+    // {
+    //   size_t globalIndex = index(idx);
+    //   globalIndexAxis(idx) = globalIndex;
+    //   if (globalIndex >= global_zoom_begin && globalIndex <= zoom_end)
+    //   {
+    //     globalAxisZoom[nZoomCount] = globalIndex;
+    //     ++nZoomCount;
+    //   }
+    // }
+
+    // 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;
+    //       if (ind >= global_zoom_begin && ind <= zoom_end)
+    //         writtenInd.insert(ind);
+    //     }
+    //   }
+    // }
+
+    CServerDistributionDescription serverDescriptionGlobal(globalDim, nbServer, distType);
     int distributedDimensionOnServer = serverDescriptionGlobal.getDimensionDistributed();
     CClientServerMapping::GlobalIndexMap globalIndexAxisOnServer;
@@ -493,8 +528,12 @@
       }
 
+      CArray<size_t,1> globalIndex(index.numElements());
+      for (size_t idx = 0; idx < globalIndex.numElements(); ++idx)
+        globalIndex(idx) = index(idx);
+
       CServerDistributionDescription serverDescription(nGlobAxis, nbServer);
       serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t,size_t>(indexBegin, indexEnd));
       CClientServerMapping* clientServerMap = new CClientServerMappingDistributed(serverDescription.getGlobalIndexRange(), client->intraComm);
-      clientServerMap->computeServerIndexMapping(globalIndexAxis);
+      clientServerMap->computeServerIndexMapping(globalIndex);
       globalIndexAxisOnServer = clientServerMap->getGlobalIndexOnServer();
       delete clientServerMap;
@@ -514,110 +553,221 @@
     }
 
-    CClientServerMapping::GlobalIndexMap::const_iterator it = globalIndexAxisOnServer.begin(),
-                                                         ite = globalIndexAxisOnServer.end();
-    std::vector<size_t>::const_iterator itbVec = (globalAxisZoom).begin(),
-                                        iteVec = (globalAxisZoom).end();
-    indSrv_.clear();
-    indWrittenSrv_.clear();
-    for (; it != ite; ++it)
-    {
-      int rank = it->first;
-      const std::vector<size_t>& globalIndexTmp = it->second;
-      int nb = globalIndexTmp.size();
-
-      for (int i = 0; i < nb; ++i)
-      {
-        if (std::binary_search(itbVec, iteVec, globalIndexTmp[i]))
-        {
-          indSrv_[rank].push_back(globalIndexTmp[i]);
-        }
-
-        if (writtenInd.count(globalIndexTmp[i]))
-        {
-          indWrittenSrv_[rank].push_back(globalIndexTmp[i]);
-        }
-      }
-    }
+    indSrv_.swap(globalIndexAxisOnServer);
+
+    // CClientServerMapping::GlobalIndexMap::const_iterator it = globalIndexAxisOnServer.begin(),
+    //                                                      ite = globalIndexAxisOnServer.end();
+    CClientServerMapping::GlobalIndexMap::const_iterator it = indSrv_.begin(),
+                                                         ite = indSrv_.end();
+    // std::vector<size_t>::const_iterator itbVec = (globalAxisZoom).begin(),
+    //                                     iteVec = (globalAxisZoom).end();
+    // indSrv_.clear();
+    // indWrittenSrv_.clear();
+    // for (; it != ite; ++it)
+    // {
+    //   int rank = it->first;
+    //   const std::vector<size_t>& globalIndexTmp = it->second;
+    //   int nb = globalIndexTmp.size();
+
+    //   for (int i = 0; i < nb; ++i)
+    //   {
+    //     if (std::binary_search(itbVec, iteVec, globalIndexTmp[i]))
+    //     {
+    //       indSrv_[rank].push_back(globalIndexTmp[i]);
+    //     }
+
+    //     if (writtenInd.count(globalIndexTmp[i]))
+    //     {
+    //       indWrittenSrv_[rank].push_back(globalIndexTmp[i]);
+    //     }
+    //   }
+    // }
 
     connectedServerRank_.clear();
-    for (it = globalIndexAxisOnServer.begin(); it != ite; ++it) {
+    for (it = indSrv_.begin(); it != ite; ++it) {
       connectedServerRank_.push_back(it->first);
     }
 
-    if (!indSrv_.empty())
-    {
-      std::map<int, vector<size_t> >::const_iterator itIndSrv  = indSrv_.begin(),
-                                                     iteIndSrv = indSrv_.end();
-      connectedServerRank_.clear();
-      for (; itIndSrv != iteIndSrv; ++itIndSrv)
-        connectedServerRank_.push_back(itIndSrv->first);
-    }
+    // if (!indSrv_.empty())
+    // {
+    //   std::map<int, vector<size_t> >::const_iterator itIndSrv  = indSrv_.begin(),
+    //                                                  iteIndSrv = indSrv_.end();
+    //   connectedServerRank_.clear();
+    //   for (; itIndSrv != iteIndSrv; ++itIndSrv)
+    //     connectedServerRank_.push_back(itIndSrv->first);
+    // }
     nbConnectedClients_ = CClientServerMapping::computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_);
   }
 
-  void CAxis::sendNonDistributedValue()
+
+  // void CAxis::computeConnectedServer(const std::vector<int>& globalDim, int orderPositionInGrid,
+  //                                    CServerDistributionDescription::ServerDistributionType distType)
+  // {
+  //   CContext* context = CContext::getCurrent();
+  //   CContextClient* client = (0 != context->clientPrimServer) ? context->clientPrimServer : context->client;
+  //   int nbServer = client->serverSize;
+  //   int range, clientSize = client->clientSize;
+  //   int rank = client->clientRank;
+
+  //   size_t ni = this->n.getValue();
+  //   size_t ibegin = this->begin.getValue();
+  //   size_t zoom_end = global_zoom_begin+global_zoom_n-1;
+  //   size_t nZoomCount = 0;
+  //   size_t nbIndex = index.numElements();
+  //   for (size_t idx = 0; idx < nbIndex; ++idx)
+  //   {
+  //     size_t globalIndex = index(idx);
+  //     if (globalIndex >= global_zoom_begin && globalIndex <= zoom_end) ++nZoomCount;
+  //   }
+
+  //   CArray<size_t,1> globalIndexAxis(nbIndex);
+  //   std::vector<size_t> globalAxisZoom(nZoomCount);
+  //   nZoomCount = 0;
+  //   for (size_t idx = 0; idx < nbIndex; ++idx)
+  //   {
+  //     size_t globalIndex = index(idx);
+  //     globalIndexAxis(idx) = globalIndex;
+  //     if (globalIndex >= global_zoom_begin && globalIndex <= zoom_end)
+  //     {
+  //       globalAxisZoom[nZoomCount] = globalIndex;
+  //       ++nZoomCount;
+  //     }
+  //   }
+
+  //   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;
+  //         if (ind >= global_zoom_begin && ind <= zoom_end)
+  //           writtenInd.insert(ind);
+  //       }
+  //     }
+  //   }
+
+  //   CServerDistributionDescription serverDescriptionGlobal(globalDim, nbServer);
+  //   int distributedDimensionOnServer = serverDescriptionGlobal.getDimensionDistributed();
+  //   CClientServerMapping::GlobalIndexMap globalIndexAxisOnServer;
+  //   if (distributedDimensionOnServer == orderPositionInGrid) // So we have distributed axis on client side and also on server side*
+  //   {
+  //     std::vector<int> nGlobAxis(1);
+  //     nGlobAxis[0] = n_glo.getValue();
+
+  //     size_t globalSizeIndex = 1, indexBegin, indexEnd;
+  //     for (int i = 0; i < nGlobAxis.size(); ++i) globalSizeIndex *= nGlobAxis[i];
+  //     indexBegin = 0;
+  //     if (globalSizeIndex <= clientSize)
+  //     {
+  //       indexBegin = rank%globalSizeIndex;
+  //       indexEnd = indexBegin;
+  //     }
+  //     else
+  //     {
+  //       for (int i = 0; i < clientSize; ++i)
+  //       {
+  //         range = globalSizeIndex / clientSize;
+  //         if (i < (globalSizeIndex%clientSize)) ++range;
+  //         if (i == client->clientRank) break;
+  //         indexBegin += range;
+  //       }
+  //       indexEnd = indexBegin + range - 1;
+  //     }
+
+  //     CServerDistributionDescription serverDescription(nGlobAxis, nbServer);
+  //     serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t,size_t>(indexBegin, indexEnd));
+  //     CClientServerMapping* clientServerMap = new CClientServerMappingDistributed(serverDescription.getGlobalIndexRange(), client->intraComm);
+  //     clientServerMap->computeServerIndexMapping(globalIndexAxis);
+  //     globalIndexAxisOnServer = clientServerMap->getGlobalIndexOnServer();
+  //     delete clientServerMap;
+  //   }
+  //   else
+  //   {
+  //     std::vector<size_t> globalIndexServer(n_glo.getValue());
+  //     for (size_t idx = 0; idx < n_glo.getValue(); ++idx)
+  //     {
+  //       globalIndexServer[idx] = idx;
+  //     }
+
+  //     for (int idx = 0; idx < nbServer; ++idx)
+  //     {
+  //       globalIndexAxisOnServer[idx] = globalIndexServer;
+  //     }
+  //   }
+
+  //   CClientServerMapping::GlobalIndexMap::const_iterator it = globalIndexAxisOnServer.begin(),
+  //                                                        ite = globalIndexAxisOnServer.end();
+  //   std::vector<size_t>::const_iterator itbVec = (globalAxisZoom).begin(),
+  //                                       iteVec = (globalAxisZoom).end();
+  //   indSrv_.clear();
+  //   indWrittenSrv_.clear();
+  //   for (; it != ite; ++it)
+  //   {
+  //     int rank = it->first;
+  //     const std::vector<size_t>& globalIndexTmp = it->second;
+  //     int nb = globalIndexTmp.size();
+
+  //     for (int i = 0; i < nb; ++i)
+  //     {
+  //       if (std::binary_search(itbVec, iteVec, globalIndexTmp[i]))
+  //       {
+  //         indSrv_[rank].push_back(globalIndexTmp[i]);
+  //       }
+
+  //       if (writtenInd.count(globalIndexTmp[i]))
+  //       {
+  //         indWrittenSrv_[rank].push_back(globalIndexTmp[i]);
+  //       }
+  //     }
+  //   }
+
+  //   connectedServerRank_.clear();
+  //   for (it = globalIndexAxisOnServer.begin(); it != ite; ++it) {
+  //     connectedServerRank_.push_back(it->first);
+  //   }
+
+  //   if (!indSrv_.empty())
+  //   {
+  //     std::map<int, vector<size_t> >::const_iterator itIndSrv  = indSrv_.begin(),
+  //                                                    iteIndSrv = indSrv_.end();
+  //     connectedServerRank_.clear();
+  //     for (; itIndSrv != iteIndSrv; ++itIndSrv)
+  //       connectedServerRank_.push_back(itIndSrv->first);
+  //   }
+  //   nbConnectedClients_ = CClientServerMapping::computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_);
+  // }
+
+  void CAxis::sendNonDistributedAttributes()
   {
     CContext* context = CContext::getCurrent();
-    CContextClient* client = context->client;
-    CEventClient event(getType(), EVENT_ID_NON_DISTRIBUTED_VALUE);
-
-    int zoom_end = global_zoom_begin + global_zoom_n - 1;
-    int nb = 0;
-    for (size_t idx = 0; idx < n; ++idx)
-    {
-      size_t globalIndex = begin + idx;
-      if (globalIndex >= global_zoom_begin && globalIndex <= zoom_end) ++nb;
-    }
-
-    int nbWritten = 0;
-    if (isCompressible_)
-    {
-      for (int idx = 0; idx < data_index.numElements(); ++idx)
-      {
-        int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, n);
-
-        if (ind >= 0 && ind < n && mask(ind))
-        {
-          ind += begin;
-          if (ind >= global_zoom_begin && ind <= zoom_end)
-            ++nbWritten;
-        }
-      }
-    }
-
-    CArray<double,1> val(nb);
-    nb = 0;
-    for (size_t idx = 0; idx < n; ++idx)
-    {
-      size_t globalIndex = begin + idx;
-      if (globalIndex >= global_zoom_begin && globalIndex <= zoom_end)
-      {
-        val(nb) = value(idx);
-        ++nb;
-      }
-    }
-
-    CArray<int, 1> writtenInd(nbWritten);
-    nbWritten = 0;
-    if (isCompressible_)
-    {
-      for (int idx = 0; idx < data_index.numElements(); ++idx)
-      {
-        int ind = CDistributionClient::getAxisIndex(data_index(idx), data_begin, n);
-
-        if (ind >= 0 && ind < n && mask(ind))
-        {
-          ind += begin;
-          if (ind >= global_zoom_begin && ind <= zoom_end)
-          {
-            writtenInd(nbWritten) = ind;
-            ++nbWritten;
-          }
-        }
-      }
+    CContextClient* client = (0 != context->clientPrimServer) ? context->clientPrimServer : context->client;
+    
+    CEventClient event(getType(), EVENT_ID_NON_DISTRIBUTED_ATTRIBUTES);
+    size_t nbIndex = index.numElements();
+    size_t nbDataIndex = 0;
+
+    for (int idx = 0; idx < data_index.numElements(); ++idx)
+    {      
+      int ind = data_index(idx);
+      if (ind >= 0 && ind < nbIndex) ++nbDataIndex;
+    }
+
+    CArray<int,1> dataIndex(nbDataIndex);
+    nbDataIndex = 0;
+    for (int idx = 0; idx < data_index.numElements(); ++idx)
+    {      
+      int ind = data_index(idx);
+      if (ind >= 0 && ind < nbIndex)
+      {
+        dataIndex(nbDataIndex) = ind;
+        ++nbDataIndex;
+      } 
     }
 
     if (client->isServerLeader())
-    {
+    { 
       std::list<CMessage> msgs;
 
@@ -628,7 +778,11 @@
         CMessage& msg = msgs.back();
         msg << this->getId();
-        msg << val;
-        if (isCompressible_)
-          msg << writtenInd;
+        msg << index.getValue() << dataIndex << zoom_index.getValue() << mask.getValue();
+        msg << hasValue;
+        if (hasValue) msg << value.getValue();
+
+        msg << hasBounds_;
+        if (hasBounds_) msg << bounds.getValue();
+        
         event.push(*itRank, 1, msg);
       }
@@ -638,21 +792,77 @@
   }
 
-  void CAxis::sendDistributedValue(void)
+  void CAxis::recvNonDistributedAttributes(CEventServer& event)
+  {
+    list<CEventServer::SSubEvent>::iterator it;
+    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
+    {
+      CBufferIn* buffer = it->buffer;
+      string axisId;
+      *buffer >> axisId;
+      get(axisId)->recvNonDistributedAttributes(it->rank, *buffer);
+    }
+  }
+
+  void CAxis::recvNonDistributedAttributes(int rank, CBufferIn& buffer)
+  { 
+    CArray<int,1> tmp_index, tmp_data_index, tmp_zoom_index;
+    CArray<bool,1> tmp_mask;
+    CArray<double,1> tmp_val;
+    CArray<double,2> tmp_bnds;
+
+    buffer >> tmp_index;
+    index.reference(tmp_index);
+    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 >> hasValue;
+    if (hasValue)
+    {
+      buffer >> tmp_val;
+      value.reference(tmp_val);
+    }
+
+    buffer >> hasBounds_;
+    if (hasBounds_)
+    {
+      buffer >> tmp_bnds;
+      bounds.reference(tmp_bnds);
+    }
+
+    {      
+      count_write_index_ = zoom_index.numElements();            
+      start_write_index_ = 0;
+      local_write_size_ = count_write_index_;
+      global_write_size_ = count_write_index_;
+    }
+  }
+
+  void CAxis::sendDistributedAttributes(void)
   {
     int ns, n, i, j, ind, nv, idx;
     CContext* context = CContext::getCurrent();
-    CContextClient* client=context->client;
-
-    // send value for each connected server
-    CEventClient eventIndex(getType(), EVENT_ID_INDEX);
-    CEventClient eventVal(getType(), EVENT_ID_DISTRIBUTED_VALUE);
-
-    list<CMessage> list_msgsIndex, list_msgsVal;
-    list<CArray<int,1> > list_indi;
-    list<CArray<int,1> > list_writtenInd;
+    CContextClient* client = (0 != context->clientPrimServer) ? context->clientPrimServer : context->client;
+
+    CEventClient eventData(getType(), EVENT_ID_DISTRIBUTED_ATTRIBUTES);
+    
+    list<CMessage> listData;
+    list<CArray<int,1> > list_indi, list_dataInd, list_zoomInd;    
+    list<CArray<bool,1> > list_mask;
     list<CArray<double,1> > list_val;
     list<CArray<double,2> > list_bounds;
 
-    std::map<int, std::vector<size_t> >::const_iterator it, iteMap;
+    int nbIndex = index.numElements();
+    CArray<int,1> dataIndex(nbIndex);
+    dataIndex = -1;
+    for (int idx = 0; idx < data_index.numElements(); ++idx)
+    {
+      if (0 <= data_index(idx) && data_index(idx) < nbIndex)
+        dataIndex(idx) = data_index(idx);
+    }
+
+    boost::unordered_map<int, std::vector<size_t> >::const_iterator it, iteMap;
     iteMap = indSrv_.end();
     for (int k = 0; k < connectedServerRank_.size(); ++k)
@@ -660,4 +870,5 @@
       int nbData = 0;
       int rank = connectedServerRank_[k];
+      int nbSendingClient = nbConnectedClients_[rank];
       it = indSrv_.find(rank);
       if (iteMap != it)
@@ -665,5 +876,11 @@
 
       list_indi.push_back(CArray<int,1>(nbData));
-      list_val.push_back(CArray<double,1>(nbData));
+      list_dataInd.push_back(CArray<int,1>(nbData));
+      list_zoomInd.push_back(CArray<int,1>(nbData));
+      list_mask.push_back(CArray<bool,1>(nbData));
+
+
+      if (hasValue)
+        list_val.push_back(CArray<double,1>(nbData));
 
       if (hasBounds_)
@@ -673,13 +890,23 @@
 
       CArray<int,1>& indi = list_indi.back();
-      CArray<double,1>& val = list_val.back();
+      CArray<int,1>& dataIndi = list_dataInd.back();
+      CArray<int,1>& zoomIndi = list_zoomInd.back();
+      CArray<bool,1>& maskIndi = list_mask.back();      
 
       for (n = 0; n < nbData; ++n)
       {
         idx = static_cast<int>(it->second[n]);
-        ind = idx - begin;
-
-        val(n) = value(ind);
         indi(n) = idx;
+
+        ind = globalLocalIndexMap_[idx];
+        dataIndi(n) = dataIndex(ind);
+        maskIndi(n) = mask(ind);
+        zoomIndi(n) = zoom_index(ind);        
+
+        if (hasValue)
+        {
+          CArray<double,1>& val = list_val.back();
+          val(n) = value(ind);
+        }
 
         if (hasBounds_)
@@ -691,155 +918,142 @@
       }
 
-      list_msgsIndex.push_back(CMessage());
-      list_msgsIndex.back() << this->getId() << list_indi.back();
-
-      if (isCompressible_)
-      {
-        std::vector<int>& writtenIndSrc = indWrittenSrv_[rank];
-        list_writtenInd.push_back(CArray<int,1>(writtenIndSrc.size()));
-        CArray<int,1>& writtenInd = list_writtenInd.back();
-
-        for (n = 0; n < writtenInd.numElements(); ++n)
-          writtenInd(n) = writtenIndSrc[n];
-
-        list_msgsIndex.back() << writtenInd;
-      }
-
-      list_msgsVal.push_back(CMessage());
-      list_msgsVal.back() << this->getId() << list_val.back();
-
+      listData.push_back(CMessage());
+      listData.back() << this->getId()  
+                      << list_indi.back() << list_dataInd.back() << list_zoomInd.back() << list_mask.back()
+                      << hasValue;
+      if (hasValue)
+        listData.back() << list_val.back();
+      listData.back() << hasBounds_;
       if (hasBounds_)
-      {
-        list_msgsVal.back() << list_bounds.back();
-      }
-
-      eventIndex.push(rank, nbConnectedClients_[rank], list_msgsIndex.back());
-      eventVal.push(rank, nbConnectedClients_[rank], list_msgsVal.back());
-    }
-
-    client->sendEvent(eventIndex);
-    client->sendEvent(eventVal);
-  }
-
-  void CAxis::recvIndex(CEventServer& event)
-  {
-    CAxis* axis;
+        listData.back() << list_bounds.back();
+
+      eventData.push(rank, nbConnectedClients_[rank], listData.back());
+    }
+
+    client->sendEvent(eventData);
+  }
+
+  void CAxis::recvDistributedAttributes(CEventServer& event)
+  {
+    string axisId;
+    vector<int> ranks;
+    vector<CBufferIn*> buffers;
 
     list<CEventServer::SSubEvent>::iterator it;
     for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
     {
+      ranks.push_back(it->rank);
       CBufferIn* buffer = it->buffer;
-      string axisId;
       *buffer >> axisId;
-      axis = get(axisId);
-      axis->recvIndex(it->rank, *buffer);
-    }
-
-    if (axis->isCompressible_)
-    {
-      std::sort(axis->indexesToWrite.begin(), axis->indexesToWrite.end());
-
+      buffers.push_back(buffer);
+    }
+    get(axisId)->recvDistributedAttributes(ranks, buffers);
+  }
+
+  void CAxis::recvDistributedAttributes(vector<int>& ranks, vector<CBufferIn*> buffers)
+  {
+    int nbReceived = ranks.size();
+    vector<CArray<int,1> > vec_indi(nbReceived), vec_dataInd(nbReceived), vec_zoomInd(nbReceived);    
+    vector<CArray<bool,1> > vec_mask(nbReceived);
+    vector<CArray<double,1> > vec_val(nbReceived);
+    vector<CArray<double,2> > vec_bounds(nbReceived);
+    
+    for (int idx = 0; idx < nbReceived; ++idx)
+    {      
+      CBufferIn& buffer = *buffers[idx];
+      buffer >> vec_indi[idx];
+      buffer >> vec_dataInd[idx];
+      buffer >> vec_zoomInd[idx];
+      buffer >> vec_mask[idx];
+
+      buffer >> hasValue;
+      if (hasValue)
+        buffer >> vec_val[idx];
+      buffer >> hasBounds_;
+      if (hasBounds_)
+        buffer >> vec_bounds[idx];
+    }
+
+    int nbData = 0;
+    for (int idx = 0; idx < nbReceived; ++idx)
+    {
+      nbData += vec_indi[idx].numElements();
+    }
+    
+    index.resize(nbData);
+    CArray<int,1> nonCompressedData(nbData);    
+    mask.resize(nbData);
+    if (hasValue)
+      value.resize(nbData);
+    if (hasBounds_)
+      bounds.resize(2,nbData);
+
+    nbData = 0;
+    for (int idx = 0; idx < nbReceived; ++idx)
+    {
+      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)
+      {
+        index(nbData) = indi(n);
+        nonCompressedData(nbData) = (0 <= dataIndi(n)) ? nbData : -1;
+        mask(nbData) = maskIndi(n);
+        if (hasValue)
+          value(nbData) = vec_val[idx](n);
+        if (hasBounds_)
+        {
+          bounds(0,nbData) = vec_bounds[idx](0,n);
+          bounds(1,nbData) = vec_bounds[idx](1,n);
+        }
+        ++nbData;
+      }
+    }
+
+    int nbIndex = index.numElements();
+    int nbCompressedData = 0; 
+    for (int idx = 0; idx < nonCompressedData.numElements(); ++idx)
+    {
+      if (0 <= nonCompressedData(idx) && nonCompressedData(idx) < nbIndex)
+        ++nbCompressedData;        
+    }
+
+    data_index.resize(nbCompressedData);
+    nbCompressedData = 0;
+    for (int idx = 0; idx < nonCompressedData.numElements(); ++idx)
+    {
+      if (0 <= nonCompressedData(idx) && nonCompressedData(idx) < nbIndex)
+      {
+        data_index(nbCompressedData) = nonCompressedData(idx);
+        ++nbCompressedData;        
+      }
+    }
+
+    int nbZoomIndex = 0;
+    for (int idx = 0; idx < nbReceived; ++idx)
+    {
+      nbZoomIndex += vec_zoomInd[idx].numElements();
+    }
+
+    zoom_index.resize(nbZoomIndex);
+    nbZoomIndex = 0;
+    CArray<int,1>& zoom_Index_Tmp = this->zoom_index;
+    for (int idx = 0; idx < nbReceived; ++idx)
+    {      
+      CArray<int,1> tmp = zoom_Index_Tmp(Range(nbZoomIndex, nbZoomIndex + vec_zoomInd[idx].numElements()-1));
+      tmp = vec_zoomInd[idx];
+
+      nbZoomIndex += vec_zoomInd[idx].numElements();
+    }
+
+
+    {
       CContextServer* server = CContext::getCurrent()->server;
-      axis->numberWrittenIndexes_ = axis->indexesToWrite.size();
-      MPI_Allreduce(&axis->numberWrittenIndexes_, &axis->totalNumberWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm);
-      MPI_Scan(&axis->numberWrittenIndexes_, &axis->offsetWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm);
-      axis->offsetWrittenIndexes_ -= axis->numberWrittenIndexes_;
-    }
-  }
-
-  void CAxis::recvIndex(int rank, CBufferIn& buffer)
-  {
-    buffer >> indiSrv_[rank];
-
-    if (isCompressible_)
-    {
-      CArray<int, 1> writtenIndexes;
-      buffer >> writtenIndexes;
-      indexesToWrite.reserve(indexesToWrite.size() + writtenIndexes.numElements());
-      for (int i = 0; i < writtenIndexes.numElements(); ++i)
-        indexesToWrite.push_back(writtenIndexes(i));
-    }
-  }
-
-  void CAxis::recvDistributedValue(CEventServer& event)
-  {
-    list<CEventServer::SSubEvent>::iterator it;
-    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
-    {
-      CBufferIn* buffer = it->buffer;
-      string axisId;
-      *buffer >> axisId;
-      get(axisId)->recvDistributedValue(it->rank, *buffer);
-    }
-  }
-
-  void CAxis::recvDistributedValue(int rank, CBufferIn& buffer)
-  {
-    CArray<int,1> &indi = indiSrv_[rank];
-    CArray<double,1> val;
-    CArray<double,2> boundsVal;
-
-    buffer >> val;
-    if (hasBounds_) buffer >> boundsVal;
-
-    int i, j, ind_srv;
-    for (int ind = 0; ind < indi.numElements(); ++ind)
-    {
-      i = indi(ind);
-      ind_srv = i - zoom_begin_srv;
-      value_srv(ind_srv) = val(ind);
-      if (hasBounds_)
-      {
-        bound_srv(0,ind_srv) = boundsVal(0, ind);
-        bound_srv(1,ind_srv) = boundsVal(1, ind);
-      }
-    }
-  }
-
-   void CAxis::recvNonDistributedValue(CEventServer& event)
-  {
-    CAxis* axis;
-
-    list<CEventServer::SSubEvent>::iterator it;
-    for (it = event.subEvents.begin(); it != event.subEvents.end(); ++it)
-    {
-      CBufferIn* buffer = it->buffer;
-      string axisId;
-      *buffer >> axisId;
-      axis = get(axisId);
-      axis->recvNonDistributedValue(it->rank, *buffer);
-    }
-
-    if (axis->isCompressible_)
-    {
-      std::sort(axis->indexesToWrite.begin(), axis->indexesToWrite.end());
-
-      axis->numberWrittenIndexes_ = axis->totalNumberWrittenIndexes_ = axis->indexesToWrite.size();
-      axis->offsetWrittenIndexes_ = 0;
-    }
-  }
-
-  void CAxis::recvNonDistributedValue(int rank, CBufferIn& buffer)
-  {
-    CArray<double,1> val;
-    buffer >> val;
-
-    for (int ind = 0; ind < val.numElements(); ++ind)
-    {
-      value_srv(ind) = val(ind);
-      if (hasBounds_)
-      {
-        bound_srv(0,ind) = bounds(0,ind);
-        bound_srv(1,ind) = bounds(1,ind);
-      }
-    }
-
-    if (isCompressible_)
-    {
-      CArray<int, 1> writtenIndexes;
-      buffer >> writtenIndexes;
-      indexesToWrite.reserve(indexesToWrite.size() + writtenIndexes.numElements());
-      for (int i = 0; i < writtenIndexes.numElements(); ++i)
-        indexesToWrite.push_back(writtenIndexes(i));
+      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_;      
     }
   }
@@ -849,6 +1063,10 @@
   // {
   //   CContext* context = CContext::getCurrent();
-  //   CContextClient* client = context->client;
-  //   int nbServer = client->serverSize;
+
+  //   CContextClient* contextClientTmp = (0 != context->clientPrimServer) ? context->clientPrimServer 
+  //                                                                       : context->client;
+
+    
+  //   int nbServer = contextClientTmp->serverSize;
 
   //   CServerDistributionDescription serverDescription(globalDim, nbServer);
@@ -858,10 +1076,13 @@
   //   std::vector<std::vector<int> > serverDimensionSizes = serverDescription.getServerDimensionSizes();
 
+  //   globalDimGrid.resize(globalDim.size());
+  //   for (int idx = 0; idx < globalDim.size(); ++idx) globalDimGrid(idx) = globalDim[idx];
+
   //   CEventClient event(getType(),EVENT_ID_SERVER_ATTRIBUT);
-  //   if (client->isServerLeader())
+  //   if (contextClientTmp->isServerLeader())
   //   {
   //     std::list<CMessage> msgs;
 
-  //     const std::list<int>& ranks = client->getRanksServerLeader();
+  //     const std::list<int>& ranks = contextClientTmp->getRanksServerLeader();
   //     for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
   //     {
@@ -877,114 +1098,69 @@
   //       msg << global_zoom_begin.getValue() << global_zoom_n.getValue();
   //       msg << isCompressible_;
+  //       msg << orderPositionInGrid;
+  //       msg << globalDimGrid;
 
   //       event.push(*itRank,1,msg);
   //     }
-  //     client->sendEvent(event);
+  //     contextClientTmp->sendEvent(event);
   //   }
-  //   else client->sendEvent(event);
+  //   else contextClientTmp->sendEvent(event);
   // }
 
-  void CAxis::sendServerAttribut(const std::vector<int>& globalDim, int orderPositionInGrid,
-                                 CServerDistributionDescription::ServerDistributionType distType)
-  {
-    CContext* context = CContext::getCurrent();
-    int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
-    for (int i = 0; i < nbSrvPools; ++i)
+  // void CAxis::recvServerAttribut(CEventServer& event)
+  // {
+  //   CBufferIn* buffer = event.subEvents.begin()->buffer;
+  //   string axisId;
+  //   *buffer >> axisId;
+  //   get(axisId)->recvServerAttribut(*buffer);
     {
       CContextClient* contextClientTmp = (context->hasServer) ? context->clientPrimServer[i]
-                                                                          : context->client;
-      int nbServer = contextClientTmp->serverSize;
-
-      CServerDistributionDescription serverDescription(globalDim, nbServer);
-      serverDescription.computeServerDistribution();
-
-      std::vector<std::vector<int> > serverIndexBegin = serverDescription.getServerIndexBegin();
-      std::vector<std::vector<int> > serverDimensionSizes = serverDescription.getServerDimensionSizes();
-
-      globalDimGrid.resize(globalDim.size());
-      for (int idx = 0; idx < globalDim.size(); ++idx) globalDimGrid(idx) = globalDim[idx];
-
-      CEventClient event(getType(),EVENT_ID_SERVER_ATTRIBUT);
-      if (contextClientTmp->isServerLeader())
-      {
-        std::list<CMessage> msgs;
-
-        const std::list<int>& ranks = contextClientTmp->getRanksServerLeader();
-        for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
-        {
-          // Use const int to ensure CMessage holds a copy of the value instead of just a reference
-          const int begin = serverIndexBegin[*itRank][orderPositionInGrid];
-          const int ni    = serverDimensionSizes[*itRank][orderPositionInGrid];
-          const int end   = begin + ni - 1;
-
-          msgs.push_back(CMessage());
-          CMessage& msg = msgs.back();
-          msg << this->getId();
-          msg << ni << begin << end;
-          msg << global_zoom_begin.getValue() << global_zoom_n.getValue();
-          msg << isCompressible_;
-          msg << orderPositionInGrid;
-          msg << globalDimGrid;
-
-          event.push(*itRank,1,msg);
-        }
-        contextClientTmp->sendEvent(event);
-      }
-      else contextClientTmp->sendEvent(event);
-    }
-  }
-
-  void CAxis::recvServerAttribut(CEventServer& event)
-  {
-    CBufferIn* buffer = event.subEvents.begin()->buffer;
-    string axisId;
-    *buffer >> axisId;
-    get(axisId)->recvServerAttribut(*buffer);
-
-    CContext* context = CContext::getCurrent();
-    if (context->hasClient && context->hasServer)
-    {
-      std::vector<int> globalDim(get(axisId)->globalDimGrid.numElements());
-      for (int idx = 0; idx < globalDim.size(); ++idx) globalDim[idx] = get(axisId)->globalDimGrid(idx);
-      get(axisId)->sendServerAttribut(globalDim, get(axisId)->orderPosInGrid, 
-                                      CServerDistributionDescription::BAND_DISTRIBUTION);
-    }
-  }
-
-  void CAxis::recvServerAttribut(CBufferIn& buffer)
-  {
-    int ni_srv, begin_srv, end_srv, global_zoom_begin_tmp, global_zoom_n_tmp;
-
-    buffer >> ni_srv >> begin_srv >> end_srv;
-    buffer >> global_zoom_begin_tmp >> global_zoom_n_tmp;
-    buffer >> isCompressible_;
-    buffer >> orderPosInGrid;
-    buffer >> globalDimGrid;
-
-    global_zoom_begin = global_zoom_begin_tmp;
-    global_zoom_n  = global_zoom_n_tmp;
-    int global_zoom_end = global_zoom_begin + global_zoom_n - 1;
-
-    zoom_begin_srv = global_zoom_begin > begin_srv ? global_zoom_begin : begin_srv ;
-    zoom_end_srv   = global_zoom_end < end_srv ? global_zoom_end : end_srv ;
-    zoom_size_srv  = zoom_end_srv - zoom_begin_srv + 1;
-
-    if (zoom_size_srv<=0)
-    {
-      zoom_begin_srv = 0; zoom_end_srv = 0; zoom_size_srv = 0;
-    }
-
-    if (n_glo == n)
-    {
-      zoom_begin_srv = global_zoom_begin;
-      zoom_end_srv   = global_zoom_end; //zoom_end;
-      zoom_size_srv  = zoom_end_srv - zoom_begin_srv + 1;
-    }
-    if (hasValue)
-    {
-      value_srv.resize(zoom_size_srv);
-      if (hasBounds_)  bound_srv.resize(2,zoom_size_srv);
-    }
-  }
+    }
+
+  //   CContext* context = CContext::getCurrent();
+  //   if (context->hasClient && context->hasServer)
+  //   {
+  //     std::vector<int> globalDim(get(axisId)->globalDimGrid.numElements());
+  //     for (int idx = 0; idx < globalDim.size(); ++idx) globalDim[idx] = get(axisId)->globalDimGrid(idx);
+  //     get(axisId)->sendServerAttribut(globalDim, get(axisId)->orderPosInGrid, 
+  //                                     CServerDistributionDescription::BAND_DISTRIBUTION);
+  //   }
+  // }
+
+  // void CAxis::recvServerAttribut(CBufferIn& buffer)
+  // {
+  //   int ni_srv, begin_srv, end_srv, global_zoom_begin_tmp, global_zoom_n_tmp;
+
+  //   buffer >> ni_srv >> begin_srv >> end_srv;
+  //   buffer >> global_zoom_begin_tmp >> global_zoom_n_tmp;
+  //   buffer >> isCompressible_;
+  //   buffer >> orderPosInGrid;
+  //   buffer >> globalDimGrid;
+
+  //   global_zoom_begin = global_zoom_begin_tmp;
+  //   global_zoom_n  = global_zoom_n_tmp;
+  //   int global_zoom_end = global_zoom_begin + global_zoom_n - 1;
+
+  //   zoom_begin_srv = global_zoom_begin > begin_srv ? global_zoom_begin : begin_srv ;
+  //   zoom_end_srv   = global_zoom_end < end_srv ? global_zoom_end : end_srv ;
+  //   zoom_size_srv  = zoom_end_srv - zoom_begin_srv + 1;
+
+  //   if (zoom_size_srv<=0)
+  //   {
+  //     zoom_begin_srv = 0; zoom_end_srv = 0; zoom_size_srv = 0;
+  //   }
+
+  //   if (n_glo == n)
+  //   {
+  //     zoom_begin_srv = global_zoom_begin;
+  //     zoom_end_srv   = global_zoom_end; //zoom_end;
+  //     zoom_size_srv  = zoom_end_srv - zoom_begin_srv + 1;
+  //   }
+  //   if (hasValue)
+  //   {
+  //     value_srv.resize(zoom_size_srv);
+  //     if (hasBounds_)  bound_srv.resize(2,zoom_size_srv);
+  //   }
+  // }
 
   CTransformation<CAxis>* CAxis::addTransformation(ETranformationType transType, const StdString& id)
@@ -1007,18 +1183,4 @@
   {
     return transformationMap_;
-  }
-
-  /*!
-    Check the validity of all transformations applied on axis
-  This functions is called AFTER all inherited attributes are solved
-  */
-  void CAxis::checkTransformations()
-  {
-    TransMapTypes::const_iterator itb = transformationMap_.begin(), it,
-                                  ite = transformationMap_.end();
-//    for (it = itb; it != ite; ++it)
-//    {
-//      (it->second)->checkValid(this);
-//    }
   }
 
Index: /XIOS/dev/dev_olga/src/node/axis.hpp
===================================================================
--- /XIOS/dev/dev_olga/src/node/axis.hpp	(revision 1024)
+++ /XIOS/dev/dev_olga/src/node/axis.hpp	(revision 1025)
@@ -48,5 +48,7 @@
            EVENT_ID_INDEX,
            EVENT_ID_DISTRIBUTED_VALUE,
-           EVENT_ID_NON_DISTRIBUTED_VALUE
+           EVENT_ID_NON_DISTRIBUTED_VALUE,
+           EVENT_ID_NON_DISTRIBUTED_ATTRIBUTES,
+           EVENT_ID_DISTRIBUTED_ATTRIBUTES
          } ;
 
@@ -76,4 +78,9 @@
          int getOffsetWrittenIndexes() const;
 
+         int getStartWriteIndex() const;
+         int getCountWriteIndex() const;
+         int getLocalWriteSize() const;
+         int getGlobalWriteSize() const;
+
          std::map<int, StdSize> getAttributesBufferSize();
 
@@ -101,9 +108,9 @@
          static ENodeType GetType(void);
 
-         void sendServerAttribut(const std::vector<int>& globalDim, int orderPositionInGrid,
-                                 CServerDistributionDescription::ServerDistributionType distType);
+         // void sendServerAttribut(const std::vector<int>& globalDim, int orderPositionInGrid,
+         //                         CServerDistributionDescription::ServerDistributionType distType);
          static bool dispatchEvent(CEventServer& event);
          static void recvServerAttribut(CEventServer& event);
-         void recvServerAttribut(CBufferIn& buffer) ;
+         // void recvServerAttribut(CBufferIn& buffer) ;
          void checkAttributesOnClient();
          void checkAttributesOnClientAfterTransformation(const std::vector<int>& globalDim, int orderPositionInGrid,
@@ -134,18 +141,16 @@
          void checkMask();
          void checkZoom();
-         void checkBounds();
-         void checkTransformations();
-         void sendValue();
+         void checkBounds();         
+         void sendAttributes();
          void computeConnectedServer(const std::vector<int>& globalDim, int orderPositionInGrid,
                                      CServerDistributionDescription::ServerDistributionType distType);
-         void sendDistributedValue();
-         void sendNonDistributedValue();
 
-         static void recvIndex(CEventServer& event);
-         static void recvDistributedValue(CEventServer& event);
-         static void recvNonDistributedValue(CEventServer& event);
-         void recvIndex(int rank, CBufferIn& buffer);
-         void recvDistributedValue(int rank, CBufferIn& buffer);
-         void recvNonDistributedValue(int rank, CBufferIn& buffer);
+         void sendNonDistributedAttributes(void);
+         void sendDistributedAttributes(void);
+
+         static void recvNonDistributedAttributes(CEventServer& event);
+         static void recvDistributedAttributes(CEventServer& event);
+         void recvNonDistributedAttributes(int rank, CBufferIn& buffer);
+         void recvDistributedAttributes(vector<int>& rank, vector<CBufferIn*> buffers);
 
          void setTransformations(const TransMapTypes&);
@@ -161,6 +166,7 @@
          bool isCompressible_;
          std::map<int,int> nbConnectedClients_; // Mapping of number of communicating client to a server
-         std::map<int, vector<size_t> > indSrv_; // Global index of each client sent to server
+         boost::unordered_map<int, vector<size_t> > indSrv_; // Global index of each client sent to server
          std::map<int, vector<int> > indWrittenSrv_; // Global written index of each client sent to server
+         boost::unordered_map<size_t,size_t> globalLocalIndexMap_;
          std::vector<int> indexesToWrite;
          int numberWrittenIndexes_, totalNumberWrittenIndexes_, offsetWrittenIndexes_;
@@ -168,4 +174,9 @@
          std::map<int, CArray<int,1> > indiSrv_;
          bool hasBounds_;
+
+         int start_write_index_;
+         int count_write_index_;
+         int local_write_size_;
+         int global_write_size_;
 
        private:
Index: /XIOS/dev/dev_olga/src/node/context.cpp
===================================================================
--- /XIOS/dev/dev_olga/src/node/context.cpp	(revision 1024)
+++ /XIOS/dev/dev_olga/src/node/context.cpp	(revision 1025)
@@ -29,4 +29,5 @@
       , idServer_(), client(0), server(0)
 //	  , clientPrimServer(0), serverPrimServer(0)
+      , allProcessed(false)
    { /* Ne rien faire de plus */ }
 
@@ -37,4 +38,5 @@
       , idServer_(), client(0), server(0)
 //	  , clientPrimServer(0), serverPrimServer(0)
+      , allProcessed(false)
    { /* Ne rien faire de plus */ }
 
@@ -475,4 +477,76 @@
    }
 
+
+   void CContext::postProcessingGlobalAttributes()
+   {
+     if (allProcessed) return;
+     
+     if (hasClient)
+     {
+       // After xml is parsed, there are some more works with post processing
+       postProcessing();
+     }
+
+     setClientServerBuffer();
+
+     if (hasClient)
+     {
+      // Send all attributes of current context to server
+      this->sendAllAttributesToServer();
+
+      // Send all attributes of current calendar
+      CCalendarWrapper::get(CCalendarWrapper::GetDefName())->sendAllAttributesToServer();
+
+      // We have enough information to send to server
+      // First of all, send all enabled files
+      sendEnabledFiles();
+
+      // Then, send all enabled fields
+      sendEnabledFields();
+
+      // At last, we have all info of domain and axis, then send them
+       sendRefDomainsAxis();
+
+       // After that, send all grid (if any)
+       sendRefGrid();
+
+       // We have a xml tree on the server side and now, it should be also processed
+       sendPostProcessing();
+     }
+     allProcessed = true;
+   }
+
+   void CContext::sendPostProcessingGlobalAttributes()
+   {
+         // Use correct context client to send message
+     CContextClient* contextClientTmp = (0 != clientPrimServer) ? clientPrimServer : client;
+     CEventClient event(getType(),EVENT_ID_POST_PROCESS_GLOBAL_ATTRIBUTES);
+
+     if (contextClientTmp->isServerLeader())
+     {
+       CMessage msg;
+       msg<<this->getIdServer();
+       const std::list<int>& ranks = contextClientTmp->getRanksServerLeader();
+       for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
+         event.push(*itRank,1,msg);
+       contextClientTmp->sendEvent(event);
+     }
+     else contextClientTmp->sendEvent(event);
+   }
+
+   void CContext::recvPostProcessingGlobalAttributes(CEventServer& event)
+   {
+      CBufferIn* buffer=event.subEvents.begin()->buffer;
+      string id;
+      *buffer>>id;
+      // get(id)->recvPostProcessingGlobalAttributes(*buffer);
+   }
+
+   void CContext::recvPostProcessingGlobalAttributes(CBufferIn& buffer)
+   {
+      // CCalendarWrapper::get(CCalendarWrapper::GetDefName())->createCalendar();
+      postProcessingGlobalAttributes();
+   }
+
    /*!
    \brief Close all the context defintion and do processing data
@@ -487,52 +561,65 @@
    {
      // There is nothing client need to send to server
-     if (hasClient)
-     {
-       // After xml is parsed, there are some more works with post processing
-       postProcessing();
-     }
-
-     setClientServerBuffer();
-
-     if (hasClient)
-     {
-      // Send all attributes of current context to server
-      this->sendAllAttributesToServer();
-
-      // Send all attributes of current calendar
-      CCalendarWrapper::get(CCalendarWrapper::GetDefName())->sendAllAttributesToServer();
-
-      // We have enough information to send to server
-      // First of all, send all enabled files
-      sendEnabledFiles();
-
-      // Then, send all enabled fields
-      sendEnabledFields();
-
-      // At last, we have all info of domain and axis, then send them
-       sendRefDomainsAxis();
-
-       // After that, send all grid (if any)
-       sendRefGrid();
-
-       // We have a xml tree on the server side and now, it should be also processed
-       sendPostProcessing();
-     }
+//      if (hasClient)
+//     if (hasClient && !hasServer)
+//      if (hasClient)
+//      {
+//        // After xml is parsed, there are some more works with post processing
+//        postProcessing();
+//      }
+
+//      setClientServerBuffer();
+
+// //     if (hasClient && !hasServer)
+//      if (hasClient)
+//      {
+//       // Send all attributes of current context to server
+//       this->sendAllAttributesToServer();
+
+//       // Send all attributes of current calendar
+//       CCalendarWrapper::get(CCalendarWrapper::GetDefName())->sendAllAttributesToServer();
+
+//       // We have enough information to send to server
+//       // First of all, send all enabled files
+//        sendEnabledFiles();
+
+//       // Then, send all enabled fields
+//        sendEnabledFields();
+
+//       // At last, we have all info of domain and axis, then send them
+//        sendRefDomainsAxis();
+
+//       // After that, send all grid (if any)
+//        sendRefGrid();
+
+//        // // We have a xml tree on the server side and now, it should be also processed
+//        sendPostProcessing();
+//      }
 
 
      // Now tell server that it can process all messages from client
-     if (hasClient) this->sendCloseDefinition();
+     // if (hasClient) this->sendCloseDefinition();
+    postProcessingGlobalAttributes();
+
+    if (hasClient) sendPostProcessingGlobalAttributes();
 
     // There are some processings that should be done after all of above. For example: check mask or index
+    this->buildFilterGraphOfEnabledFields();
+    
      if (hasClient && !hasServer)
     {
-      this->buildFilterGraphOfEnabledFields();  // references are resolved here (access xml file)
+      // this->buildFilterGraphOfEnabledFields();  // references are resolved here (access xml file)
       buildFilterGraphOfFieldsWithReadAccess();
-      this->solveAllRefOfEnabledFields(true);
+      // this->solveAllRefOfEnabledFields(true);
     }
 
+    // if (hasClient) this->solveAllRefOfEnabledFields(true);
+    this->processGridEnabledFields();
+    if (hasClient) this->sendProcessingGridOfEnabledFields();
+    // if (hasClient)        // We have a xml tree on the server side and now, it should be also processed
+    //    sendPostProcessing();
 //    // Now tell server that it can process all messages from client
 ////    if (hasClient && !hasServer) this->sendCloseDefinition();
-//    if (hasClient) this->sendCloseDefinition();
+   if (hasClient) this->sendCloseDefinition();
 
     // Nettoyage de l'arborescence
@@ -564,4 +651,30 @@
         (void)this->enabledReadModeFiles[i]->readAttributesOfEnabledFieldsInReadMode();
    }
+
+   void CContext::solveAllEnabledFields()
+   {
+     int size = this->enabledFiles.size();
+     for (int i = 0; i < size; ++i)
+     {
+       this->enabledFiles[i]->solveOnlyRefOfEnabledFields(false);
+     }
+
+     for (int i = 0; i < size; ++i)
+     {
+       this->enabledFiles[i]->generateNewTransformationGridDest();
+     }
+   }
+
+   void CContext::processGridEnabledFields()
+   {
+     int size = this->enabledFiles.size();
+     for (int i = 0; i < size; ++i)
+     {
+       this->enabledFiles[i]->checkGridOfEnabledFields();
+       this->enabledFiles[i]->sendGridOfEnabledFields();
+     }
+   }
+
+
 
    void CContext::solveOnlyRefOfEnabledFields(bool sendToServer)
@@ -754,6 +867,13 @@
              recvRegistry(event);
              return true;
-            break;
-
+             break;
+            case EVENT_ID_POST_PROCESS_GLOBAL_ATTRIBUTES:
+             recvPostProcessingGlobalAttributes(event);
+             return true;
+             break;
+            case EVENT_ID_PROCESS_GRID_ENABLED_FIELDS:
+             recvProcessingGridOfEnabledFields(event);
+             return true;
+             break;
            default :
              ERROR("bool CContext::dispatchEvent(CEventServer& event)",
@@ -802,8 +922,8 @@
       *buffer>>id;
       get(id)->closeDefinition();
-      if (get(id)->hasClient && get(id)->hasServer)
-      {        
-        get(id)->sendCloseDefinition();
-      }
+      // if (get(id)->hasClient && get(id)->hasServer)
+      // {        
+      //   get(id)->sendCloseDefinition();
+      // }
    }
 
@@ -833,31 +953,4 @@
          else contextClientTmp->sendEvent(event);
      }
-
-     // if (!hasServer)
-     // {
-     //   if (client->isServerLeader())
-     //   {
-     //     CMessage msg;
-     //     msg<<this->getIdServer()<<step;
-     //     const std::list<int>& ranks = client->getRanksServerLeader();
-     //     for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
-     //       event.push(*itRank,1,msg);
-     //     client->sendEvent(event);
-     //   }
-     //   else client->sendEvent(event);
-     // }
-     // else
-     // {
-     //   if (clientPrimServer->isServerLeader())
-     //   {
-     //     CMessage msg;
-     //     msg<<this->getIdServer()<<step;
-     //     const std::list<int>& ranks = clientPrimServer->getRanksServerLeader();
-     //     for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
-     //       event.push(*itRank,1,msg);
-     //     clientPrimServer->sendEvent(event);
-     //   }
-     //   else clientPrimServer->sendEvent(event);
-     // }
    }
 
@@ -907,30 +1000,4 @@
        else contextClientTmp->sendEvent(event);
      }
-     // if (!hasServer)
-     // {
-     //   if (client->isServerLeader())
-     //   {
-     //     CMessage msg;
-     //     msg<<this->getIdServer();
-     //     const std::list<int>& ranks = client->getRanksServerLeader();
-     //     for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
-     //       event.push(*itRank,1,msg) ;
-     //     client->sendEvent(event);
-     //   }
-     //   else client->sendEvent(event);
-     // }
-     // else
-     // {
-     //   if (clientPrimServer->isServerLeader())
-     //   {
-     //     CMessage msg;
-     //     msg<<this->getIdServer();
-     //     const std::list<int>& ranks = clientPrimServer->getRanksServerLeader();
-     //     for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
-     //       event.push(*itRank,1,msg) ;
-     //     clientPrimServer->sendEvent(event);
-     //   }
-     //   else clientPrimServer->sendEvent(event);
-     // }
    }
 
@@ -948,11 +1015,39 @@
    {
      // The creation of header file should be delegated to server2, for now
-      if (hasClient && hasServer)
-      {        
-        sendCreateFileHeader();
-      }
+      // if (hasClient && hasServer)
+      // {        
+      //   sendCreateFileHeader();
+      // }
       
       if (!hasClient && hasServer) 
         createFileHeader();
+   }
+
+   //! Client side: Send a message to do some post processing on server
+   void CContext::sendProcessingGridOfEnabledFields()
+   {
+      // Use correct context client to send message
+     CContextClient* contextClientTmp = (0 != clientPrimServer) ? clientPrimServer : client;
+     CEventClient event(getType(),EVENT_ID_PROCESS_GRID_ENABLED_FIELDS);
+
+     if (contextClientTmp->isServerLeader())
+     {
+       CMessage msg;
+       msg<<this->getIdServer();
+       const std::list<int>& ranks = contextClientTmp->getRanksServerLeader();
+       for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
+         event.push(*itRank,1,msg);
+       contextClientTmp->sendEvent(event);
+     }
+     else contextClientTmp->sendEvent(event);
+   }
+
+   //! Server side: Receive a message to do some post processing
+   void CContext::recvProcessingGridOfEnabledFields(CEventServer& event)
+   {
+      CBufferIn* buffer=event.subEvents.begin()->buffer;
+      string id;
+      *buffer>>id;
+      // get(id)->processGridEnabledFields();
    }
 
@@ -980,36 +1075,4 @@
        else contextClientTmp->sendEvent(event);
      }
-
-     // if (hasClient)
-     // {
-     //   if (!hasServer)
-     //   {
-     //     CEventClient event(getType(),EVENT_ID_POST_PROCESS);
-     //     if (client->isServerLeader())
-     //     {
-     //       CMessage msg;
-     //       msg<<this->getIdServer();
-     //       const std::list<int>& ranks = client->getRanksServerLeader();
-     //       for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
-     //         event.push(*itRank,1,msg);
-     //       client->sendEvent(event);
-     //     }
-     //     else client->sendEvent(event);
-     //   }
-     //   else
-     //   {
-     //     CEventClient event(getType(),EVENT_ID_POST_PROCESS);
-     //     if (clientPrimServer->isServerLeader())
-     //     {
-     //       CMessage msg;
-     //       msg<<this->getIdServer();
-     //       const std::list<int>& ranks = clientPrimServer->getRanksServerLeader();
-     //       for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
-     //         event.push(*itRank,1,msg);
-     //       clientPrimServer->sendEvent(event);
-     //     }
-     //     else clientPrimServer->sendEvent(event);
-     //   }
-     // }
    }
 
@@ -1075,18 +1138,25 @@
       // Check if some axis, domains or grids are eligible to for compressed indexed output.
       // Warning: This must be done after solving the inheritance and before the rest of post-processing
-      checkAxisDomainsGridsEligibilityForCompressedOutput();
+      checkAxisDomainsGridsEligibilityForCompressedOutput();      
 
       // Check if some automatic time series should be generated
       // Warning: This must be done after solving the inheritance and before the rest of post-processing
-      if (!hasServer)
-        prepareTimeseries();
+      // prepareTimeseries();
+
+      // The timeseries should only be prepared in client
+      if (hasClient && !hasServer) prepareTimeseries();
 
       //Initialisation du vecteur 'enabledFiles' contenant la liste des fichiers Ã  sortir.
       this->findEnabledFiles();
-      this->findEnabledReadModeFiles();
+      // this->findEnabledReadModeFiles();
+      // For now, only read files with client and only one level server
+      if (hasClient && !hasServer) this->findEnabledReadModeFiles();
+
 
       // Find all enabled fields of each file
       this->findAllEnabledFields();
-      this->findAllEnabledFieldsInReadModeFiles();
+      // this->findAllEnabledFieldsInReadModeFiles();
+      // For now, only read files with client and only one level server
+      if (hasClient && !hasServer) this->findAllEnabledFieldsInReadModeFiles();
 
 //     if (hasClient)
@@ -1097,14 +1167,25 @@
      }
 
+      // // Only search and rebuild all reference objects of enable fields, don't transform
+      // this->solveOnlyRefOfEnabledFields(false);
+
+      // // Search and rebuild all reference object of enabled fields
+      // this->solveAllRefOfEnabledFields(false);
+
+      // // Find all fields with read access from the public API
+      // findFieldsWithReadAccess();
+      // // and solve the all reference for them
+      // solveAllRefOfFieldsWithReadAccess();
+
       // Only search and rebuild all reference objects of enable fields, don't transform
-      this->solveOnlyRefOfEnabledFields(false);
+      if (hasClient) this->solveOnlyRefOfEnabledFields(false);
 
       // Search and rebuild all reference object of enabled fields
-      this->solveAllRefOfEnabledFields(false);
+      // if (hasClient) this->solveAllRefOfEnabledFields(false);
 
       // Find all fields with read access from the public API
-      findFieldsWithReadAccess();
+      if (hasClient && !hasServer) findFieldsWithReadAccess();
       // and solve the all reference for them
-      solveAllRefOfFieldsWithReadAccess();
+      if (hasClient && !hasServer) solveAllRefOfFieldsWithReadAccess();
 
       isPostProcessed = true;
Index: /XIOS/dev/dev_olga/src/node/context.hpp
===================================================================
--- /XIOS/dev/dev_olga/src/node/context.hpp	(revision 1024)
+++ /XIOS/dev/dev_olga/src/node/context.hpp	(revision 1025)
@@ -51,5 +51,7 @@
            EVENT_ID_CLOSE_DEFINITION,EVENT_ID_UPDATE_CALENDAR,
            EVENT_ID_CREATE_FILE_HEADER,EVENT_ID_CONTEXT_FINALIZE,
-           EVENT_ID_POST_PROCESS, EVENT_ID_SEND_REGISTRY
+           EVENT_ID_POST_PROCESS, EVENT_ID_SEND_REGISTRY,
+           EVENT_ID_POST_PROCESS_GLOBAL_ATTRIBUTES,
+           EVENT_ID_PROCESS_GRID_ENABLED_FIELDS
          };
 
@@ -122,4 +124,8 @@
          void buildFilterGraphOfFieldsWithReadAccess();
          void postProcessing();
+         void postProcessingGlobalAttributes();         
+
+         void solveAllEnabledFields();
+         void processGridEnabledFields();
 
          std::map<int, StdSize> getAttributesBufferSize(std::map<int, StdSize>& maxEventSize);
@@ -137,4 +143,6 @@
          void sendRefGrid();
          void sendPostProcessing();
+         void sendPostProcessingGlobalAttributes();
+         void sendProcessingGridOfEnabledFields();
          //!< after be gathered to the root process of the context, merged registry is sent to the root process of the servers
          void sendRegistry(void) ;
@@ -153,4 +161,7 @@
          static void recvPostProcessing(CEventServer& event);
          void recvPostProcessing(CBufferIn& buffer);
+         static void recvProcessingGridOfEnabledFields(CEventServer& event);
+         static void recvPostProcessingGlobalAttributes(CEventServer& event);
+         void recvPostProcessingGlobalAttributes(CBufferIn& buffer);
          static void recvRegistry(CEventServer& event) ;
          void recvRegistry(CBufferIn& buffer) ; //!< registry is received by the servers
@@ -235,4 +246,5 @@
       private:
          bool isPostProcessed;
+         bool allProcessed;
          bool finalized;
          StdString idServer_;
Index: /XIOS/dev/dev_olga/src/node/domain.cpp
===================================================================
--- /XIOS/dev/dev_olga/src/node/domain.cpp	(revision 1024)
+++ /XIOS/dev/dev_olga/src/node/domain.cpp	(revision 1025)
@@ -31,7 +31,6 @@
       : CObjectTemplate<CDomain>(), CDomainAttributes()
       , isChecked(false), relFiles(), isClientChecked(false), nbConnectedClients_(), indSrv_(), connectedServerRank_()
-      , hasBounds(false), hasArea(false), isDistributed_(false), nGlobDomain_(), isCompressible_(false), isUnstructed_(false)
+      , hasBounds(false), hasArea(false), isDistributed_(false), isCompressible_(false), isUnstructed_(false)
       , isClientAfterTransformationChecked(false), hasLonLat(false)
-      , lonvalue_client(), latvalue_client(), bounds_lon_client(), bounds_lat_client()
       , isRedistributed_(false), hasPole(false)
    {
@@ -41,7 +40,6 @@
       : CObjectTemplate<CDomain>(id), CDomainAttributes()
       , isChecked(false), relFiles(), isClientChecked(false), nbConnectedClients_(), indSrv_(), connectedServerRank_()
-      , hasBounds(false), hasArea(false), isDistributed_(false), nGlobDomain_(), isCompressible_(false), isUnstructed_(false)
+      , hasBounds(false), hasArea(false), isDistributed_(false), isCompressible_(false), isUnstructed_(false)
       , isClientAfterTransformationChecked(false), hasLonLat(false)
-      , lonvalue_client(), latvalue_client(), bounds_lon_client(), bounds_lat_client()
       , isRedistributed_(false), hasPole(false)
    {
@@ -113,4 +111,38 @@
    {
      return offsetWrittenIndexes_;
+   }
+
+   /*!
+     Returns the start of indexes written by each server.
+     \return the start of indexes written by each server
+   */
+   const std::vector<int>& CDomain::getStartWriteIndex() const
+   {
+     return start_write_index_;
+   }
+
+   /*!
+     Returns the count of indexes written by each server.
+     \return the count of indexes written by each server
+   */
+   const std::vector<int>& CDomain::getCountWriteIndex() const
+   {
+     return count_write_index_;
+   }
+
+   /*!
+     Returns the local data written by each server.     
+   */
+   const std::vector<int>& CDomain::getLocalWriteSize() const
+   {
+     return local_write_size_;
+   }
+
+   /*!
+     Returns the global data written by all server.     
+   */
+   const std::vector<int>& CDomain::getGlobalWriteSize() const
+   {
+     return global_write_size_;
    }
 
@@ -130,5 +162,5 @@
      if (client->isServerLeader())
      {
-       // size estimation for sendServerAttribut
+       // size estimation for sendDistributionAttribut
        size_t size = 11 * sizeof(size_t);
 
@@ -141,10 +173,10 @@
      }
 
-     std::map<int, std::vector<size_t> >::const_iterator itIndexEnd = indSrv_.end();
+     boost::unordered_map<int, vector<size_t> >::const_iterator itIndexEnd = indSrv_.end();
      std::map<int, std::vector<int> >::const_iterator itWrittenIndexEnd = indWrittenSrv_.end();
      for (size_t k = 0; k < connectedServerRank_.size(); ++k)
      {
        int rank = connectedServerRank_[k];
-       std::map<int, std::vector<size_t> >::const_iterator it = indSrv_.find(rank);
+       boost::unordered_map<int, std::vector<size_t> >::const_iterator it = indSrv_.find(rank);
        size_t idxCount = (it != itIndexEnd) ? it->second.size() : 0;
 
@@ -175,6 +207,7 @@
    bool CDomain::isEmpty(void) const
    {
-      return ((this->zoom_ni_srv == 0) ||
-              (this->zoom_nj_srv == 0));
+      return ((this->zoom_i_index.isEmpty()) || (0 == this->zoom_i_index.numElements()));
+      // return ((this->zoom_ni_srv == 0) ||
+      //         (this->zoom_nj_srv == 0));
    }
 
@@ -695,6 +728,5 @@
        for (int j = 0; j < nj; ++j)
          for (int i = 0; i < ni; ++i) j_index(i+j*ni) = j+jbegin;
-     }
-     computeNGlobDomain();
+     }     
      checkZoom();
 
@@ -715,4 +747,6 @@
      if (global_zoom_nj.isEmpty())
       global_zoom_nj.setValue(nj_glo);
+    if (zoom_i_index.isEmpty()) zoom_i_index.setValue(i_index.getValue());
+    if (zoom_j_index.isEmpty()) zoom_j_index.setValue(j_index.getValue());
    }
 
@@ -993,8 +1027,8 @@
      localMask.resize(ni*nj) ;
      localMask=false ;
-     size_t zoom_ibegin=global_zoom_ibegin ;
-     size_t zoom_iend=global_zoom_ibegin+global_zoom_ni-1 ;
-     size_t zoom_jbegin=global_zoom_jbegin ;
-     size_t zoom_jend=global_zoom_jbegin+global_zoom_nj-1 ;
+     size_t zoom_ibegin= global_zoom_ibegin ;
+     size_t zoom_iend= global_zoom_ibegin+global_zoom_ni-1 ;
+     size_t zoom_jbegin= global_zoom_jbegin ;
+     size_t zoom_jend= global_zoom_jbegin+global_zoom_nj-1 ;
 
 
@@ -1037,10 +1071,10 @@
      if (!lonvalue_2d.isEmpty())
      {
-       lonvalue_client.resize(ni * nj);
-       latvalue_client.resize(ni * nj);
+       lonvalue.resize(ni * nj);
+       latvalue.resize(ni * nj);
        if (hasBounds)
        {
-         bounds_lon_client.resize(nvertex, ni * nj);
-         bounds_lat_client.resize(nvertex, ni * nj);
+         bounds_lonvalue.resize(nvertex, ni * nj);
+         bounds_latvalue.resize(nvertex, ni * nj);
        }
 
@@ -1051,6 +1085,6 @@
            int k = j * ni + i;
 
-           lonvalue_client(k) = lonvalue_2d(i,j);
-           latvalue_client(k) = latvalue_2d(i,j);
+           lonvalue(k) = lonvalue_2d(i,j);
+           latvalue(k) = latvalue_2d(i,j);
 
            if (hasBounds)
@@ -1058,6 +1092,6 @@
              for (int n = 0; n < nvertex; ++n)
              {
-               bounds_lon_client(n,k) = bounds_lon_2d(n,i,j);
-               bounds_lat_client(n,k) = bounds_lat_2d(n,i,j);
+               bounds_lonvalue(n,k) = bounds_lon_2d(n,i,j);
+               bounds_latvalue(n,k) = bounds_lat_2d(n,i,j);
              }
            }
@@ -1071,10 +1105,10 @@
          if (ni == lonvalue_1d.numElements() && nj == latvalue_1d.numElements())
          {
-           lonvalue_client.resize(ni * nj);
-           latvalue_client.resize(ni * nj);
+           lonvalue.resize(ni * nj);
+           latvalue.resize(ni * nj);
            if (hasBounds)
            {
-             bounds_lon_client.resize(nvertex, ni * nj);
-             bounds_lat_client.resize(nvertex, ni * nj);
+             bounds_lonvalue.resize(nvertex, ni * nj);
+             bounds_latvalue.resize(nvertex, ni * nj);
            }
 
@@ -1085,6 +1119,6 @@
                int k = j * ni + i;
 
-               lonvalue_client(k) = lonvalue_1d(i);
-               latvalue_client(k) = latvalue_1d(j);
+               lonvalue(k) = lonvalue_1d(i);
+               latvalue(k) = latvalue_1d(j);
 
                if (hasBounds)
@@ -1092,6 +1126,6 @@
                  for (int n = 0; n < nvertex; ++n)
                  {
-                   bounds_lon_client(n,k) = bounds_lon_1d(n,i);
-                   bounds_lat_client(n,k) = bounds_lat_1d(n,j);
+                   bounds_lonvalue(n,k) = bounds_lon_1d(n,i);
+                   bounds_latvalue(n,k) = bounds_lat_1d(n,j);
                  }
                }
@@ -1101,10 +1135,10 @@
          else if (i_index.numElements() == lonvalue_1d.numElements() && j_index.numElements() == latvalue_1d.numElements())
          {
-           lonvalue_client.reference(lonvalue_1d);
-           latvalue_client.reference(latvalue_1d);
+           lonvalue.reference(lonvalue_1d);
+           latvalue.reference(latvalue_1d);
             if (hasBounds)
            {
-             bounds_lon_client.reference(bounds_lon_1d);
-             bounds_lat_client.reference(bounds_lat_1d);
+             bounds_lonvalue.reference(bounds_lon_1d);
+             bounds_latvalue.reference(bounds_lat_1d);
            }
          }
@@ -1120,10 +1154,10 @@
        else if (type == type_attr::curvilinear || type == type_attr::unstructured)
        {
-         lonvalue_client.reference(lonvalue_1d);
-         latvalue_client.reference(latvalue_1d);
+         lonvalue.reference(lonvalue_1d);
+         latvalue.reference(latvalue_1d);
          if (hasBounds)
          {
-           bounds_lon_client.reference(bounds_lon_1d);
-           bounds_lat_client.reference(bounds_lat_1d);
+           bounds_lonvalue.reference(bounds_lon_1d);
+           bounds_latvalue.reference(bounds_lat_1d);
          }
        }
@@ -1221,5 +1255,5 @@
    void CDomain::checkArea(void)
    {
-     hasArea = !area.isEmpty();
+     hasArea = !area.isEmpty() || !areavalue.isEmpty();
      if (hasArea)
      {
@@ -1231,4 +1265,16 @@
                << "Local size is " << ni.getValue() << " x " << nj.getValue() << "." << std::endl
                << "Area size is " << area.extent(0) << " x " << area.extent(1) << ".");
+       }
+       if (areavalue.isEmpty())
+       {
+          areavalue.resize(ni*nj);
+         for (int j = 0; j < nj; ++j)
+         {
+           for (int i = 0; i < ni; ++i)
+           {
+             int k = j * ni + i;
+             areavalue(k) = area(i,j);
+           }
+         }
        }
      }
@@ -1302,6 +1348,7 @@
      if (context->hasClient)
      {
-       this->checkMask();
-       if (hasLonLat || hasArea || isCompressible_) this->computeConnectedServer();
+       // this->checkMask();
+      this->computeConnectedClients();
+       // if (hasLonLat || hasArea || isCompressible_) this->computeConnectedClients();
        if (hasLonLat) this->completeLonLatClient();
      }
@@ -1318,8 +1365,50 @@
      CContext* context=CContext::getCurrent();
 
+      if (context->hasClient && !context->hasServer)
+      {
+        this->checkDomain();
+        this->checkBounds();
+        this->checkArea();
+        this->checkLonLat();
+      }
+
+      if (context->hasClient && !context->hasServer)
+      { // CÃŽtÃ© client uniquement
+         this->checkMask();
+         this->checkDomainData();
+         this->checkCompression();
+         this->computeLocalMask() ;
+      }
+      else
+      { // CÃŽtÃ© serveur uniquement
+      }
+
+      this->isClientChecked = true;
+   }
+
+   // Send all checked attributes to server
+   void CDomain::sendCheckedAttributes()
+   {
+     if (!this->isClientChecked) checkAttributesOnClient();
+     if (!this->isClientAfterTransformationChecked) checkAttributesOnClientAfterTransformation();
+     CContext* context=CContext::getCurrent() ;
+
+     if (this->isChecked) return;
+     if (context->hasClient)
+     {
+       sendAttributes();
+     }
+     this->isChecked = true;
+   }
+
+   void CDomain::checkAttributes(void)
+   {
+      if (this->isChecked) return;
+      CContext* context=CContext::getCurrent() ;
+
       this->checkDomain();
+      this->checkLonLat();
       this->checkBounds();
       this->checkArea();
-      this->checkLonLat();
 
       if (context->hasClient)
@@ -1329,4 +1418,5 @@
          this->checkCompression();
          this->computeLocalMask() ;
+
       }
       else
@@ -1334,51 +1424,8 @@
       }
 
-      this->isClientChecked = true;
-   }
-
-   // Send all checked attributes to server
-   void CDomain::sendCheckedAttributes()
-   {
-     if (!this->isClientChecked) checkAttributesOnClient();
-     if (!this->isClientAfterTransformationChecked) checkAttributesOnClientAfterTransformation();
-     CContext* context=CContext::getCurrent() ;
-
-     if (this->isChecked) return;
-     if (context->hasClient)
-     {
-       sendServerAttribut();
-       if (hasLonLat || hasArea || isCompressible_) sendLonLatArea();
-     }
-     this->isChecked = true;
-   }
-
-   void CDomain::checkAttributes(void)
-   {
-      if (this->isChecked) return;
-      CContext* context=CContext::getCurrent() ;
-
-      this->checkDomain();
-      this->checkLonLat();
-      this->checkBounds();
-      this->checkArea();
-
       if (context->hasClient)
-      { // CÃŽtÃ© client uniquement
-         this->checkMask();
-         this->checkDomainData();
-         this->checkCompression();
-         this->computeLocalMask() ;
-
-      }
-      else
-      { // CÃŽtÃ© serveur uniquement
-      }
-
-      if (context->hasClient)
-      {
-        this->computeConnectedServer();
+      {
+        this->computeConnectedClients();
         this->completeLonLatClient();
-        this->sendServerAttribut();
-        this->sendLonLatArea();
       }
 
@@ -1386,5 +1433,10 @@
    }
 
-  void CDomain::sendServerAttribut(void)
+  /*!
+    Send distribution from client to other clients
+    Because a client in a level knows correctly the grid distribution of client on the next level
+    it calculates this distribution then sends it to the corresponding clients on the next level
+  */
+  void CDomain::sendDistributionAttributes(void)
   {
     CContext* context = CContext::getCurrent();
@@ -1394,9 +1446,11 @@
     {
        CContextClient* contextClientTmp = (context->hasServer) ? context->clientPrimServer[i]
-                                                                           : context->client;
-      // CContextClient* client = context->client;
+                                                                         : context->client;    
       int nbServer = contextClientTmp->serverSize;
-
-      CServerDistributionDescription serverDescription(nGlobDomain_, nbServer);
+    std::vector<int> nGlobDomain(2);
+    nGlobDomain[0] = this->ni_glo;
+    nGlobDomain[1] = this->nj_glo;
+
+    CServerDistributionDescription serverDescription(nGlobDomain, nbServer);
       if (isUnstructed_) serverDescription.computeServerDistribution(false, 0);
       else serverDescription.computeServerDistribution(false, 1);
@@ -1418,12 +1472,9 @@
           const int ni_srv = serverDimensionSizes[*itRank][0];
           const int nj_srv = serverDimensionSizes[*itRank][1];
-          const int iend_srv = ibegin_srv + ni_srv - 1;
-          const int jend_srv = jbegin_srv + nj_srv - 1;
 
           msgs.push_back(CMessage());
           CMessage& msg = msgs.back();
           msg << this->getId() ;
-          msg << ni_srv << ibegin_srv << iend_srv << nj_srv << jbegin_srv << jend_srv;
-          msg << global_zoom_ni.getValue() << global_zoom_ibegin.getValue() << global_zoom_nj.getValue() << global_zoom_jbegin.getValue();
+        msg << ni_srv << ibegin_srv << nj_srv << jbegin_srv;        
           msg << isCompressible_;
 
@@ -1436,20 +1487,18 @@
   }
 
-  void CDomain::computeNGlobDomain()
-  {
-    nGlobDomain_.resize(2);
-    nGlobDomain_[0] = ni_glo.getValue();
-    nGlobDomain_[1] = nj_glo.getValue();
-  }
-
-  void CDomain::computeConnectedServer(void)
+  // void CDomain::computeConnectedClients(const std::vector<int>& globalDim, int orderPositionInGrid,
+  //                                     CServerDistributionDescription::ServerDistributionType distType)
+  /*!
+     Compute the connection of a client to other clients to determine which clients to send attributes to
+  */
+  void CDomain::computeConnectedClients()
   {
     CContext* context=CContext::getCurrent() ;
-    CContextClient* client=context->client ;
+    CContextClient* client = (0 != context->clientPrimServer) ? context->clientPrimServer : context->client;
     int nbServer=client->serverSize;
     int rank = client->clientRank;
     bool doComputeGlobalIndexServer = true;
 
-    int i,j,i_ind,j_ind, nbIndex;
+    int i,j,i_ind,j_ind, nbIndex, nbIndexZoom;
     int global_zoom_iend=global_zoom_ibegin+global_zoom_ni-1 ;
     int global_zoom_jend=global_zoom_jbegin+global_zoom_nj-1 ;
@@ -1458,40 +1507,40 @@
     int globalIndexCountZoom = 0;
     nbIndex = i_index.numElements();
-    for (i = 0; i < nbIndex; ++i)
-    {
-      i_ind=i_index(i);
-      j_ind=j_index(i);
-
-      if (i_ind >= global_zoom_ibegin && i_ind <= global_zoom_iend && j_ind >= global_zoom_jbegin && j_ind <= global_zoom_jend)
-      {
-        ++globalIndexCountZoom;
-      }
-    }
-
-    int globalIndexWrittenCount = 0;
-    if (isCompressible_)
-    {
-      for (i = 0; i < data_i_index.numElements(); ++i)
-      {
-        i_ind = CDistributionClient::getDomainIndex(data_i_index(i), data_j_index(i),
-                                                    data_ibegin, data_jbegin, data_dim, ni,
-                                                    j_ind);
-        if (i_ind >= 0 && i_ind < ni && j_ind >= 0 && j_ind < nj && mask_1d(i_ind + j_ind * ni))
-        {
-          i_ind += ibegin;
-          j_ind += jbegin;
-          if (i_ind >= global_zoom_ibegin && i_ind <= global_zoom_iend && j_ind >= global_zoom_jbegin && j_ind <= global_zoom_jend)
-            ++globalIndexWrittenCount;
-        }
-      }
-    }
+    // for (i = 0; i < nbIndex; ++i)
+    // {
+    //   i_ind=i_index(i);
+    //   j_ind=j_index(i);
+
+    //   if (i_ind >= global_zoom_ibegin && i_ind <= global_zoom_iend && j_ind >= global_zoom_jbegin && j_ind <= global_zoom_jend)
+    //   {
+    //     ++globalIndexCountZoom;
+    //   }
+    // }
+
+    // int globalIndexWrittenCount = 0;
+    // if (isCompressible_)
+    // {
+    //   for (i = 0; i < data_i_index.numElements(); ++i)
+    //   {
+    //     i_ind = CDistributionClient::getDomainIndex(data_i_index(i), data_j_index(i),
+    //                                                 data_ibegin, data_jbegin, data_dim, ni,
+    //                                                 j_ind);
+    //     if (i_ind >= 0 && i_ind < ni && j_ind >= 0 && j_ind < nj && mask_1d(i_ind + j_ind * ni))
+    //     {
+    //       i_ind += ibegin;
+    //       j_ind += jbegin;
+    //       if (i_ind >= global_zoom_ibegin && i_ind <= global_zoom_iend && j_ind >= global_zoom_jbegin && j_ind <= global_zoom_jend)
+    //         ++globalIndexWrittenCount;
+    //     }
+    //   }
+    // }
 
     // Fill in index
-    CArray<size_t,1> globalIndexDomainZoom(globalIndexCountZoom);
+    
     CArray<size_t,1> localIndexDomainZoom(globalIndexCountZoom);
     CArray<size_t,1> globalIndexDomain(nbIndex);
     size_t globalIndex;
     int globalIndexCount = 0;
-    globalIndexCountZoom = 0;
+    
 
     for (i = 0; i < nbIndex; ++i)
@@ -1501,38 +1550,55 @@
       globalIndex = i_ind + j_ind * ni_glo;
       globalIndexDomain(globalIndexCount) = globalIndex;
+      globalLocalIndexMap_[globalIndex] = i;
       ++globalIndexCount;
-      if (i_ind >= global_zoom_ibegin && i_ind <= global_zoom_iend && j_ind >= global_zoom_jbegin && j_ind <= global_zoom_jend)
-      {
-        globalIndexDomainZoom(globalIndexCountZoom) = globalIndex;
-        localIndexDomainZoom(globalIndexCountZoom) = i;
-        ++globalIndexCountZoom;
-      }
-    }
-
-    CArray<int,1> globalIndexWrittenDomain(globalIndexWrittenCount);
-    if (isCompressible_)
-    {
-      globalIndexWrittenCount = 0;
-      for (i = 0; i < data_i_index.numElements(); ++i)
-      {
-        i_ind = CDistributionClient::getDomainIndex(data_i_index(i), data_j_index(i),
-                                                    data_ibegin, data_jbegin, data_dim, ni,
-                                                    j_ind);
-        if (i_ind >= 0 && i_ind < ni && j_ind >= 0 && j_ind < nj && mask_1d(i_ind + j_ind * ni))
-        {
-          i_ind += ibegin;
-          j_ind += jbegin;
-          if (i_ind >= global_zoom_ibegin && i_ind <= global_zoom_iend && j_ind >= global_zoom_jbegin && j_ind <= global_zoom_jend)
-          {
-            globalIndexWrittenDomain(globalIndexWrittenCount) = i_ind + j_ind * ni_glo;
-            ++globalIndexWrittenCount;
-          }
-        }
-      }
-    }
+    }
+
+    nbIndexZoom = zoom_i_index.numElements();
+    CArray<size_t,1> globalIndexDomainZoom(nbIndexZoom);
+    globalIndexCountZoom = 0;
+    for (i = 0; i < nbIndexZoom; ++i)
+    {
+      i_ind=zoom_i_index(i);
+      j_ind=zoom_j_index(i);
+      globalIndex = i_ind + j_ind * ni_glo;
+      globalIndexDomainZoom(globalIndexCountZoom) = globalIndex;
+
+      ++globalIndexCountZoom;
+      // if (i_ind >= global_zoom_ibegin && i_ind <= global_zoom_iend && j_ind >= global_zoom_jbegin && j_ind <= global_zoom_jend)
+      // {
+      //   globalIndexDomainZoom(globalIndexCountZoom) = globalIndex;
+      //   localIndexDomainZoom(globalIndexCountZoom) = i;
+      //   ++globalIndexCountZoom;
+      // }
+    }
+
+    // CArray<int,1> globalIndexWrittenDomain(globalIndexWrittenCount);
+    // if (isCompressible_)
+    // {
+    //   globalIndexWrittenCount = 0;
+    //   for (i = 0; i < data_i_index.numElements(); ++i)
+    //   {
+    //     i_ind = CDistributionClient::getDomainIndex(data_i_index(i), data_j_index(i),
+    //                                                 data_ibegin, data_jbegin, data_dim, ni,
+    //                                                 j_ind);
+    //     if (i_ind >= 0 && i_ind < ni && j_ind >= 0 && j_ind < nj && mask_1d(i_ind + j_ind * ni))
+    //     {
+    //       i_ind += ibegin;
+    //       j_ind += jbegin;
+    //       if (i_ind >= global_zoom_ibegin && i_ind <= global_zoom_iend && j_ind >= global_zoom_jbegin && j_ind <= global_zoom_jend)
+    //       {
+    //         globalIndexWrittenDomain(globalIndexWrittenCount) = i_ind + j_ind * ni_glo;
+    //         ++globalIndexWrittenCount;
+    //       }
+    //     }
+    //   }
+    // }
 
     size_t globalSizeIndex = 1, indexBegin, indexEnd;
     int range, clientSize = client->clientSize;
-    for (int i = 0; i < nGlobDomain_.size(); ++i) globalSizeIndex *= nGlobDomain_[i];
+    std::vector<int> nGlobDomain(2);
+    nGlobDomain[0] = this->ni_glo;
+    nGlobDomain[1] = this->nj_glo;
+    for (int i = 0; i < nGlobDomain.size(); ++i) globalSizeIndex *= nGlobDomain[i];
     indexBegin = 0;
     if (globalSizeIndex <= clientSize)
@@ -1553,5 +1619,5 @@
     }
 
-    CServerDistributionDescription serverDescription(nGlobDomain_, nbServer);
+    CServerDistributionDescription serverDescription(nGlobDomain, nbServer);
     if (isUnstructed_) serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t,size_t>(indexBegin, indexEnd), 0);
     else serverDescription.computeServerGlobalIndexInRange(std::make_pair<size_t,size_t>(indexBegin, indexEnd), 1);
@@ -1560,37 +1626,37 @@
                                                                                 client->intraComm);
     clientServerMap->computeServerIndexMapping(globalIndexDomain);
-    const CClientServerMapping::GlobalIndexMap& globalIndexDomainOnServer = clientServerMap->getGlobalIndexOnServer();
+    CClientServerMapping::GlobalIndexMap& globalIndexDomainOnServer = clientServerMap->getGlobalIndexOnServer();
 
     CClientServerMapping::GlobalIndexMap::const_iterator it  = globalIndexDomainOnServer.begin(),
                                                          ite = globalIndexDomainOnServer.end();
-    typedef XIOSBinarySearchWithIndex<size_t> BinarySearch;
-    std::vector<int>::iterator itVec;
-
-    indSrv_.clear();
-    indWrittenSrv_.clear();
-    for (; it != ite; ++it)
-    {
-      int rank = it->first;
-      int indexSize = it->second.size();
-      std::vector<int> permutIndex(indexSize);
-      XIOSAlgorithms::fillInIndex(indexSize, permutIndex);
-      XIOSAlgorithms::sortWithIndex<size_t, CVectorStorage>(it->second, permutIndex);
-      BinarySearch binSearch(it->second);
-      int nb = globalIndexDomainZoom.numElements();
-      for (int i = 0; i < nb; ++i)
-      {
-        if (binSearch.search(permutIndex.begin(), permutIndex.end(), globalIndexDomainZoom(i), itVec))
-        {
-          indSrv_[rank].push_back(localIndexDomainZoom(i));
-        }
-      }
-      for (int i = 0; i < globalIndexWrittenDomain.numElements(); ++i)
-      {
-        if (binSearch.search(permutIndex.begin(), permutIndex.end(), globalIndexWrittenDomain(i), itVec))
-        {
-          indWrittenSrv_[rank].push_back(globalIndexWrittenDomain(i));
-        }
-      }
-    }
+    // typedef XIOSBinarySearchWithIndex<size_t> BinarySearch;
+    // std::vector<int>::iterator itVec;
+    
+    // indSrv_.clear();
+    // indWrittenSrv_.clear();
+    // for (; it != ite; ++it)
+    // {
+    //   int rank = it->first;
+    //   int indexSize = it->second.size();
+    //   std::vector<int> permutIndex(indexSize);
+    //   XIOSAlgorithms::fillInIndex(indexSize, permutIndex);
+    //   XIOSAlgorithms::sortWithIndex<size_t, CVectorStorage>(it->second, permutIndex);
+    //   BinarySearch binSearch(it->second);
+    //   int nb = globalIndexDomainZoom.numElements();
+    //   for (int i = 0; i < nb; ++i)
+    //   {
+    //     if (binSearch.search(permutIndex.begin(), permutIndex.end(), globalIndexDomainZoom(i), itVec))
+    //     {
+    //       indSrv_[rank].push_back(localIndexDomainZoom(i));
+    //     }
+    //   }
+    //   for (int i = 0; i < globalIndexWrittenDomain.numElements(); ++i)
+    //   {
+    //     if (binSearch.search(permutIndex.begin(), permutIndex.end(), globalIndexWrittenDomain(i), itVec))
+    //     {
+    //       indWrittenSrv_[rank].push_back(globalIndexWrittenDomain(i));
+    //     }
+    //   }
+    // }
 
     connectedServerRank_.clear();
@@ -1599,10 +1665,19 @@
     }
 
+    indSrv_.swap(globalIndexDomainOnServer);
     nbConnectedClients_ = clientServerMap->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_);
 
+    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);
+    nbConnectedClientsZoom_ = clientServerMap->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerZoomRank);       
+
     delete clientServerMap;
   }
 
-  const std::map<int, vector<size_t> >& CDomain::getIndexServer() const
+  const boost::unordered_map<int, vector<size_t> >& CDomain::getIndexServer() const
   {
     return indSrv_;
@@ -1610,5 +1685,20 @@
 
   /*!
-    Send index from client to server(s)
+    Send all attributes from client to connected clients
+    The attributes will be rebuilt on receiving side
+  */
+  void CDomain::sendAttributes()
+  {
+    sendIndex();
+    sendDistributionAttributes();
+    sendMask();
+    sendLonLat();
+    sendArea();    
+    sendDataIndex();
+  }
+
+  /*!
+    Send global index and zoom index from client to connected client(s)
+    zoom index can be smaller than global index
   */
   void CDomain::sendIndex()
@@ -1616,12 +1706,79 @@
     int ns, n, i, j, ind, nv, idx;
     CContext* context = CContext::getCurrent();
-    CContextClient* client=context->client;
+    CContextClient* client = (0 != context->clientPrimServer) ? context->clientPrimServer : context->client;
 
     CEventClient eventIndex(getType(), EVENT_ID_INDEX);
 
     list<CMessage> list_msgsIndex;
-    list<CArray<int,1> > list_indi, list_indj, list_writtenInd;
-
-    std::map<int, std::vector<size_t> >::const_iterator it, iteMap;
+    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();
+    for (int k = 0; k < connectedServerRank_.size(); ++k)
+    {
+      int nbIndGlob = 0;
+      int rank = connectedServerRank_[k];
+      itIndex = indSrv_.find(rank);
+      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();
+      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]);        
+      }
+
+      list_msgsIndex.push_back(CMessage());
+      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(); //list_indi.back() << list_indj.back();
+
+      // if (isCompressible_)
+      // {
+      //   std::vector<int>& writtenIndSrc = indWrittenSrv_[rank];
+      //   list_writtenInd.push_back(CArray<int,1>(writtenIndSrc.size()));
+      //   CArray<int,1>& writtenInd = list_writtenInd.back();
+
+      //   for (n = 0; n < writtenInd.numElements(); ++n)
+      //     writtenInd(n) = writtenIndSrc[n];
+
+      //   list_msgsIndex.back() << writtenInd;
+      // }
+
+      eventIndex.push(rank, nbConnectedClients_[rank], list_msgsIndex.back());
+    }
+
+    client->sendEvent(eventIndex);
+  }
+
+  /*!
+    Send mask index from client to connected(s)
+  */
+  void CDomain::sendMask()
+  {
+    int ns, n, i, j, ind, nv, idx;
+    CContext* context = CContext::getCurrent();
+    CContextClient* client = (0 != context->clientPrimServer) ? context->clientPrimServer : context->client;
+
+    // send area for each connected server
+    CEventClient eventMask(getType(), EVENT_ID_MASK);
+
+    list<CMessage> list_msgsMask;
+    list<CArray<bool,1> > list_mask;
+
+    boost::unordered_map<int, vector<size_t> >::const_iterator it, iteMap;
     iteMap = indSrv_.end();
     for (int k = 0; k < connectedServerRank_.size(); ++k)
@@ -1632,44 +1789,22 @@
       if (iteMap != it)
         nbData = it->second.size();
-
-      list_indi.push_back(CArray<int,1>(nbData));
-      list_indj.push_back(CArray<int,1>(nbData));
-
-      CArray<int,1>& indi = list_indi.back();
-      CArray<int,1>& indj = list_indj.back();
+      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]);
-        indi(n) = i_index(idx);
-        indj(n) = j_index(idx);
-      }
-
-      list_msgsIndex.push_back(CMessage());
-
-      list_msgsIndex.back() << this->getId() << (int)type; // enum ne fonctionne pour les message => ToFix
-      list_msgsIndex.back() << isCurvilinear;
-      list_msgsIndex.back() << list_indi.back() << list_indj.back();
-
-      if (isCompressible_)
-      {
-        std::vector<int>& writtenIndSrc = indWrittenSrv_[rank];
-        list_writtenInd.push_back(CArray<int,1>(writtenIndSrc.size()));
-        CArray<int,1>& writtenInd = list_writtenInd.back();
-
-        for (n = 0; n < writtenInd.numElements(); ++n)
-          writtenInd(n) = writtenIndSrc[n];
-
-        list_msgsIndex.back() << writtenInd;
-      }
-
-      eventIndex.push(rank, nbConnectedClients_[rank], list_msgsIndex.back());
-    }
-
-    client->sendEvent(eventIndex);
+        list_mask.back()(n) = mask_1d(globalLocalIndexMap_[idx]);          
+      }
+
+      list_msgsMask.push_back(CMessage());
+      list_msgsMask.back() << this->getId() << list_mask.back();
+      eventMask.push(rank, nbConnectedClients_[rank], list_msgsMask.back());
+    }
+    client->sendEvent(eventMask);
   }
 
   /*!
-    Send area from client to server(s)
+    Send area from client to connected client(s)
   */
   void CDomain::sendArea()
@@ -1679,5 +1814,5 @@
     int ns, n, i, j, ind, nv, idx;
     CContext* context = CContext::getCurrent();
-    CContextClient* client=context->client;
+    CContextClient* client = (0 != context->clientPrimServer) ? context->clientPrimServer : context->client;
 
     // send area for each connected server
@@ -1687,5 +1822,5 @@
     list<CArray<double,1> > list_area;
 
-    std::map<int, std::vector<size_t> >::const_iterator it, iteMap;
+    boost::unordered_map<int, vector<size_t> >::const_iterator it, iteMap;
     iteMap = indSrv_.end();
     for (int k = 0; k < connectedServerRank_.size(); ++k)
@@ -1702,12 +1837,10 @@
       {
         idx = static_cast<int>(it->second[n]);
-        i = i_index(idx);
-        j = j_index(idx);
-        if (hasArea)
-          list_area.back()(n) = area(i - ibegin, j - jbegin);
+        list_area.back()(n) = areavalue(globalLocalIndexMap_[idx]); 
       }
 
       list_msgsArea.push_back(CMessage());
-      list_msgsArea.back() << this->getId() << list_area.back();
+      list_msgsArea.back() << this->getId() << hasArea;
+      list_msgsArea.back() << list_area.back();
       eventArea.push(rank, nbConnectedClients_[rank], list_msgsArea.back());
     }
@@ -1726,5 +1859,5 @@
     int ns, n, i, j, ind, nv, idx;
     CContext* context = CContext::getCurrent();
-    CContextClient* client=context->client;
+    CContextClient* client = (0 != context->clientPrimServer) ? context->clientPrimServer : context->client;
 
     // send lon lat for each connected server
@@ -1736,5 +1869,5 @@
     list<CArray<double,2> > list_boundslon, list_boundslat;
 
-    std::map<int, std::vector<size_t> >::const_iterator it, iteMap;
+    boost::unordered_map<int, vector<size_t> >::const_iterator it, iteMap;
     iteMap = indSrv_.end();
     for (int k = 0; k < connectedServerRank_.size(); ++k)
@@ -1761,6 +1894,7 @@
       {
         idx = static_cast<int>(it->second[n]);
-        lon(n) = lonvalue_client(idx);
-        lat(n) = latvalue_client(idx);
+        int localInd = globalLocalIndexMap_[idx];
+        lon(n) = lonvalue(localInd);
+        lat(n) = latvalue(localInd);
 
         if (hasBounds)
@@ -1771,6 +1905,6 @@
           for (nv = 0; nv < nvertex; ++nv)
           {
-            boundslon(nv, n) = bounds_lon_client(nv, idx);
-            boundslat(nv, n) = bounds_lat_client(nv, idx);
+            boundslon(nv, n) = bounds_lonvalue(nv, localInd);
+            boundslat(nv, n) = bounds_latvalue(nv, localInd);
           }
         }
@@ -1780,6 +1914,6 @@
       list_msgsLat.push_back(CMessage());
 
-      list_msgsLon.back() << this->getId() << list_lon.back();
-      list_msgsLat.back() << this->getId() << list_lat.back();
+      list_msgsLon.back() << this->getId() << hasLonLat << list_lon.back() << hasBounds;
+      list_msgsLat.back() << this->getId() << hasLonLat << list_lat.back() << hasBounds;
 
       if (hasBounds)
@@ -1798,14 +1932,62 @@
 
   /*!
-    Send some optional information to server(s)
-    In the future, this function can be extended with more optional information to send
+    Send data index to corresponding connected clients.
+    Data index can be compressed however, we always send decompressed data index
+    and they will be compressed on receiving.
   */
-  void CDomain::sendLonLatArea(void)
-  {
-    sendIndex();
-    sendLonLat();
-    sendArea();
-  }
-
+  void CDomain::sendDataIndex()
+  {
+    int ns, n, i, j, ind, nv, idx;
+    CContext* context = CContext::getCurrent();
+    CContextClient* client = (0 != context->clientPrimServer) ? context->clientPrimServer : context->client;
+
+    // send area for each connected server
+    CEventClient eventDataIndex(getType(), EVENT_ID_DATA_INDEX);
+
+    list<CMessage> list_msgsDataIndex;
+    list<CArray<int,1> > list_data_i_index, list_data_j_index;
+
+    int nbIndex = i_index.numElements();
+    CArray<int,1> dataIIndex(nbIndex), dataJIndex(nbIndex);
+    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;
+      }
+    }
+
+    boost::unordered_map<int, vector<size_t> >::const_iterator it, iteMap;
+    iteMap = indSrv_.end();
+    for (int k = 0; k < connectedServerRank_.size(); ++k)
+    {
+      int nbData = 0;
+      int rank = connectedServerRank_[k];
+      it = indSrv_.find(rank);
+      if (iteMap != it)
+        nbData = it->second.size();
+      list_data_i_index.push_back(CArray<int,1>(nbData));
+      list_data_j_index.push_back(CArray<int,1>(nbData));
+
+      const std::vector<size_t>& temp = it->second;
+      for (n = 0; n < nbData; ++n)
+      {
+        idx = static_cast<int>(it->second[n]);
+        i = globalLocalIndexMap_[idx];
+        list_data_i_index.back()(n) = dataIIndex(i);
+        list_data_j_index.back()(n) = dataJIndex(i);          
+      }
+
+      list_msgsDataIndex.push_back(CMessage());
+      list_msgsDataIndex.back() << this->getId();
+      list_msgsDataIndex.back() << list_data_i_index.back() << list_data_j_index.back();
+      eventDataIndex.push(rank, nbConnectedClients_[rank], list_msgsDataIndex.back());
+    }
+    client->sendEvent(eventDataIndex);
+  }
+  
   bool CDomain::dispatchEvent(CEventServer& event)
   {
@@ -1816,9 +1998,13 @@
       {
         case EVENT_ID_SERVER_ATTRIBUT:
-          recvServerAttribut(event);
+          recvDistributionAttributes(event);
           return true;
           break;
         case EVENT_ID_INDEX:
           recvIndex(event);
+          return true;
+          break;
+        case EVENT_ID_MASK:
+          recvMask(event);
           return true;
           break;
@@ -1834,4 +2020,8 @@
           recvArea(event);
           return true;
+          break;  
+        case EVENT_ID_DATA_INDEX:
+          recvDataIndex(event);
+          return true;
           break;
         default:
@@ -1847,17 +2037,10 @@
     \param[in] event event contain info about rank and associated attributes
   */
-  void CDomain::recvServerAttribut(CEventServer& event)
+  void CDomain::recvDistributionAttributes(CEventServer& event)
   {
     CBufferIn* buffer=event.subEvents.begin()->buffer;
     string domainId ;
     *buffer>>domainId ;
-    get(domainId)->recvServerAttribut(*buffer) ;
-    
-    CContext* context = CContext::getCurrent();
-    if (context->hasClient && context->hasServer)
-    {
-      get(domainId)->sendServerAttribut();
-    }
-
+    get(domainId)->recvDistributionAttributes(*buffer) ;
   }
 
@@ -1867,50 +2050,13 @@
     \param[in] buffer message containing attributes info
   */
-  void CDomain::recvServerAttribut(CBufferIn& buffer)
-  {
-    int global_zoom_ni_tmp, global_zoom_ibegin_tmp, global_zoom_nj_tmp, global_zoom_jbegin_tmp;
-    buffer >> ni_srv >> ibegin_srv >> iend_srv >> nj_srv >> jbegin_srv >> jend_srv
-           >> global_zoom_ni_tmp >> global_zoom_ibegin_tmp >> global_zoom_nj_tmp >> global_zoom_jbegin_tmp
+  void CDomain::recvDistributionAttributes(CBufferIn& buffer)
+  {
+    int ni_tmp, ibegin_tmp, nj_tmp, jbegin_tmp;
+    buffer >> ni_tmp >> ibegin_tmp >> nj_tmp >> jbegin_tmp           
            >> isCompressible_;
-
-    global_zoom_ni.setValue(global_zoom_ni_tmp);
-    global_zoom_ibegin.setValue(global_zoom_ibegin_tmp);
-    global_zoom_nj.setValue(global_zoom_nj_tmp);
-    global_zoom_jbegin.setValue(global_zoom_jbegin_tmp);
-
-    int zoom_iend = global_zoom_ibegin + global_zoom_ni - 1;
-    int zoom_jend = global_zoom_jbegin + global_zoom_nj - 1;
-
-    zoom_ibegin_srv = global_zoom_ibegin > ibegin_srv ? global_zoom_ibegin : ibegin_srv ;
-    zoom_iend_srv = zoom_iend < iend_srv ? zoom_iend : iend_srv ;
-    zoom_ni_srv=zoom_iend_srv-zoom_ibegin_srv+1 ;
-
-    zoom_jbegin_srv = global_zoom_jbegin > jbegin_srv ? global_zoom_jbegin : jbegin_srv ;
-    zoom_jend_srv = zoom_jend < jend_srv ? zoom_jend : jend_srv ;
-    zoom_nj_srv=zoom_jend_srv-zoom_jbegin_srv+1 ;
-
-    if (zoom_ni_srv<=0 || zoom_nj_srv<=0)
-    {
-      zoom_ibegin_srv=0 ; zoom_iend_srv=0 ; zoom_ni_srv=0 ;
-      zoom_jbegin_srv=0 ; zoom_jend_srv=0 ; zoom_nj_srv=0 ;
-    }
-    lonvalue_srv.resize(zoom_ni_srv*zoom_nj_srv) ;
-    lonvalue_srv = 0. ;
-    latvalue_srv.resize(zoom_ni_srv*zoom_nj_srv) ;
-    latvalue_srv = 0. ;
-    if (hasBounds)
-    {
-      bounds_lon_srv.resize(nvertex,zoom_ni_srv*zoom_nj_srv) ;
-      bounds_lon_srv = 0. ;
-      bounds_lat_srv.resize(nvertex,zoom_ni_srv*zoom_nj_srv) ;
-      bounds_lat_srv = 0. ;
-    }
-
-    if (hasArea)
-    {
-      area_srv.resize(zoom_ni_srv * zoom_nj_srv);
-      area_srv = 0.;
-    }
-
+    ni.setValue(ni_tmp);
+    ibegin.setValue(ibegin_tmp);
+    nj.setValue(nj_tmp);
+    jbegin.setValue(jbegin_tmp);
   }
 
@@ -1921,47 +2067,198 @@
   void CDomain::recvIndex(CEventServer& event)
   {
-    CDomain* domain;
+    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;
-      string domainId;
       *buffer >> domainId;
-      domain = get(domainId);
-      domain->recvIndex(it->rank, *buffer);
-    }
-
-    if (domain->isCompressible_)
-    {
-      std::sort(domain->indexesToWrite.begin(), domain->indexesToWrite.end());
-
-      CContextServer* server = CContext::getCurrent()->server;
-      domain->numberWrittenIndexes_ = domain->indexesToWrite.size();
-      MPI_Allreduce(&domain->numberWrittenIndexes_, &domain->totalNumberWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm);
-      MPI_Scan(&domain->numberWrittenIndexes_, &domain->offsetWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm);
-      domain->offsetWrittenIndexes_ -= domain->numberWrittenIndexes_;
-    }
+      rankBuffers[it->rank] = buffer;        
+    }
+    get(domainId)->recvIndex(rankBuffers);
+
+    // if (domain->isCompressible_)
+    // {
+    //   std::sort(domain->indexesToWrite.begin(), domain->indexesToWrite.end());
+
+    //   CContextServer* server = CContext::getCurrent()->server;
+    //   domain->numberWrittenIndexes_ = domain->indexesToWrite.size();
+    //   MPI_Allreduce(&domain->numberWrittenIndexes_, &domain->totalNumberWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm);
+    //   MPI_Scan(&domain->numberWrittenIndexes_, &domain->offsetWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm);
+    //   domain->offsetWrittenIndexes_ -= domain->numberWrittenIndexes_;
+    // }
   }
 
   /*!
     Receive index information from client(s)
-    \param[in] rank rank of client source
-    \param[in] buffer message containing index info
+    \param[in] rankBuffers rank of sending client and the corresponding receive buffer  
   */
-  void CDomain::recvIndex(int rank, CBufferIn& buffer)
-  {
-    int type_int;
-    buffer >> type_int >> isCurvilinear >> indiSrv[rank] >> indjSrv[rank];
-    type.setValue((type_attr::t_enum)type_int); // probleme des type enum avec les buffers : ToFix
-
-    if (isCompressible_)
-    {
-      CArray<int, 1> writtenIndexes;
-      buffer >> writtenIndexes;
-      indexesToWrite.reserve(indexesToWrite.size() + writtenIndexes.numElements());
-      for (int i = 0; i < writtenIndexes.numElements(); ++i)
-        indexesToWrite.push_back(writtenIndexes(i));
-    }
+  void CDomain::recvIndex(std::map<int, CBufferIn*>& rankBuffers)
+  {
+    int nbReceived = rankBuffers.size(), i, ind, index, type_int;
+    recvClientRanks_.resize(nbReceived);
+    vector<CArray<int,1> > recvZoomInd(nbReceived);
+
+    std::map<int, CBufferIn*>::iterator it = rankBuffers.begin(), ite = rankBuffers.end();
+    ind = 0;
+    for (ind = 0; it != ite; ++it, ++ind)
+    {       
+       recvClientRanks_[ind] = it->first;
+       CBufferIn& buffer = *(it->second);
+       buffer >> type_int >> isCurvilinear >> indGlob_[it->first] >> recvZoomInd[ind]; //recvIndGlob[ind];
+       type.setValue((type_attr::t_enum)type_int); // probleme des type enum avec les buffers : ToFix
+    }
+    int nbIndGlob = 0;
+    for (i = 0; i < nbReceived; ++i)
+    {
+      nbIndGlob += indGlob_[recvClientRanks_[i]].numElements();
+    }
+    
+    i_index.resize(nbIndGlob);
+    j_index.resize(nbIndGlob);
+
+    nbIndGlob = 0;
+    for (i = 0; i < nbReceived; ++i)
+    {
+      CArray<int,1>& tmp = indGlob_[recvClientRanks_[i]];
+      for (ind = 0; ind < tmp.numElements(); ++ind)
+      {
+         index = tmp(ind);
+         i_index(nbIndGlob) = index / ni_glo;
+         j_index(nbIndGlob) = index % ni_glo;
+         ++nbIndGlob;
+      } 
+    }
+
+    int nbZoomInd = 0;
+    for (i = 0; i < nbReceived; ++i)
+    {
+      nbZoomInd += recvZoomInd[i].numElements();
+    }
+
+    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;
+      } 
+    }    
+
+    {
+      CContextServer* server = CContext::getCurrent()->server;
+      count_write_index_.resize(2);
+      start_write_index_.resize(2);
+      local_write_size_.resize(2);
+      global_write_size_.resize(2);
+      if ((this->type) == CDomain::type_attr::unstructured)
+      {
+        count_write_index_[0] = zoom_i_index.numElements();
+        count_write_index_[1] = 0;
+      }
+      else
+      {
+        int ni_zoom = zoom_i_index.numElements(), idx, nbIZoom = 0, nbJZoom = 0;
+        for (idx =0; idx < ni_zoom; ++idx)
+        {
+           if ((ibegin <= zoom_i_index(idx)) && (zoom_i_index(idx) < ibegin+ni) && (nbIZoom < ni))
+            ++nbIZoom;
+           if ((jbegin <= zoom_j_index(idx)) && (zoom_j_index(idx) < jbegin+nj) && (nbJZoom < nj))
+            ++nbJZoom;
+        }
+        count_write_index_[0] = nbIZoom;
+        count_write_index_[1] = nbJZoom;
+      }
+            
+      MPI_Scan(&count_write_index_[0], &start_write_index_[0], 2, MPI_INT, MPI_SUM, server->intraComm);      
+      start_write_index_[0] = 0; 
+      start_write_index_[1] -= count_write_index_[1];
+      local_write_size_[0] = count_write_index_[0];
+      local_write_size_[1] = count_write_index_[1];
+      MPI_Allreduce(&count_write_index_[0], &global_write_size_[0], 2, MPI_INT, MPI_SUM, server->intraComm);
+      global_write_size_[0] = count_write_index_[0];
+      global_write_size_[1] = (global_write_size_[1] > nj_glo) ? nj_glo : global_write_size_[1];
+         
+    }
+
+    // int type_int;
+    // buffer >> type_int >> isCurvilinear >> indiSrv[rank] >> indjSrv[rank];
+    // type.setValue((type_attr::t_enum)type_int); // probleme des type enum avec les buffers : ToFix
+
+    // if (isCompressible_)
+    // {
+    //   CArray<int, 1> writtenIndexes;
+    //   buffer >> writtenIndexes;
+    //   indexesToWrite.reserve(indexesToWrite.size() + writtenIndexes.numElements());
+    //   for (int i = 0; i < writtenIndexes.numElements(); ++i)
+    //     indexesToWrite.push_back(writtenIndexes(i));
+    // }
+  }
+
+  /*!
+    Receive area event from clients(s)
+    \param[in] event event contain info about rank and associated area
+  */
+  void CDomain::recvMask(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)->recvMask(rankBuffers);
+  }
+
+
+  /*!
+    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)
+  {
+    int nbReceived = rankBuffers.size(), i, ind, index;
+    if (nbReceived != recvClientRanks_.size())
+      ERROR("void CDomain::recvArea(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();
+    }
+  
+    mask_1d.resize(nbMaskInd);
+    nbMaskInd = 0;
+    for (i = 0; i < nbReceived; ++i)
+    {
+      CArray<bool,1>& tmp = recvMaskValue[i];
+      for (ind = 0; ind < tmp.numElements(); ++ind)
+      {
+        mask_1d(nbMaskInd) = tmp(ind);      
+        ++nbMaskInd;
+      }
+    }    
   }
 
@@ -1972,39 +2269,68 @@
   void CDomain::recvLon(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;
-      string domainId;
       *buffer >> domainId;
-      get(domainId)->recvLon(it->rank, *buffer);
-    }
+      rankBuffers[it->rank] = buffer;        
+    }
+    get(domainId)->recvLon(rankBuffers);
   }
 
   /*!
     Receive longitude information from client(s)
-    \param[in] rank rank of client source
-    \param[in] buffer message containing longitude info
+    \param[in] rankBuffers rank of sending client and the corresponding receive buffer  
   */
-  void CDomain::recvLon(int rank, CBufferIn& buffer)
-  {
-    CArray<int,1> &indi = indiSrv[rank], &indj = indjSrv[rank];
-    CArray<double,1> lon;
-    CArray<double,2> boundslon;
-
-    buffer >> lon;
-
-    if (hasBounds) buffer >> boundslon;
-
-    int i, j, ind_srv;
-    for (int ind = 0; ind < indi.numElements(); ind++)
-    {
-      i = indi(ind); j = indj(ind);
-      ind_srv = (i - zoom_ibegin_srv) + (j - zoom_jbegin_srv) * zoom_ni_srv;
-      lonvalue_srv(ind_srv) = lon(ind);
+  void CDomain::recvLon(std::map<int, CBufferIn*>& rankBuffers)
+  {
+    int nbReceived = rankBuffers.size(), i, ind, index;
+    if (nbReceived != recvClientRanks_.size())
+      ERROR("void CDomain::recvLon(std::map<int, CBufferIn*>& rankBuffers)",
+           << "The number of sending clients is not correct."
+           << "Expected number: " << recvClientRanks_.size() << " but received " << nbReceived);
+
+    vector<CArray<double,1> > recvLonValue(nbReceived);
+    vector<CArray<double,2> > recvBoundsLonValue(nbReceived);    
+    for (i = 0; i < recvClientRanks_.size(); ++i)
+    {
+      int rank = recvClientRanks_[i];
+      CBufferIn& buffer = *(rankBuffers[rank]);
+      buffer >> hasLonLat;
+      buffer >> recvLonValue[i];
+      buffer >> hasBounds;
       if (hasBounds)
-      {
-        for (int nv = 0; nv < nvertex; ++nv)
-          bounds_lon_srv(nv, ind_srv) = boundslon(nv, ind);
+        buffer >> recvBoundsLonValue[i];
+    }
+
+    int nbLonInd = 0;
+    for (i = 0; i < nbReceived; ++i)
+    {
+      nbLonInd += recvLonValue[i].numElements();
+    }
+
+    lonvalue.resize(nbLonInd);
+    if (hasBounds)
+    {
+      bounds_lonvalue.resize(nvertex, nbLonInd);
+    }
+
+    nbLonInd = 0;
+    for (i = 0; i < nbReceived; ++i)
+    {
+      CArray<double,1>& tmp = recvLonValue[i];
+      for (ind = 0; ind < tmp.numElements(); ++ind)
+      {
+         lonvalue(nbLonInd) = tmp(ind);
+         if (hasBounds)
+         {
+          CArray<double,2>& tmpBnds = recvBoundsLonValue[i];
+          for (int nv = 0; nv < nvertex; ++nv)
+            bounds_lonvalue(nv, nbLonInd) = tmpBnds(nv, ind);
+         }       
+         ++nbLonInd;
       }
     }
@@ -2017,38 +2343,68 @@
   void CDomain::recvLat(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;
-      string domainId;
       *buffer >> domainId;
-      get(domainId)->recvLat(it->rank, *buffer);
-    }
+      rankBuffers[it->rank] = buffer;    
+    }
+    get(domainId)->recvLat(rankBuffers);
   }
 
   /*!
     Receive latitude information from client(s)
-    \param[in] rank rank of client source
-    \param[in] buffer message containing latitude info
+    \param[in] rankBuffers rank of sending client and the corresponding receive buffer  
   */
-  void CDomain::recvLat(int rank, CBufferIn& buffer)
-  {
-    CArray<int,1> &indi = indiSrv[rank], &indj = indjSrv[rank];
-    CArray<double,1> lat;
-    CArray<double,2> boundslat;
-
-    buffer >> lat;
-    if (hasBounds) buffer >> boundslat;
-
-    int i, j, ind_srv;
-    for (int ind = 0; ind < indi.numElements(); ind++)
-    {
-      i = indi(ind); j = indj(ind);
-      ind_srv = (i - zoom_ibegin_srv) + (j - zoom_jbegin_srv) * zoom_ni_srv;
-      latvalue_srv(ind_srv) = lat(ind);
+  void CDomain::recvLat(std::map<int, CBufferIn*>& rankBuffers)
+  {
+    int nbReceived = rankBuffers.size(), i, ind, index;
+    if (nbReceived != recvClientRanks_.size())
+      ERROR("void CDomain::recvLat(std::map<int, CBufferIn*>& rankBuffers)",
+           << "The number of sending clients is not correct."
+           << "Expected number: " << recvClientRanks_.size() << " but received " << nbReceived);
+
+    vector<CArray<double,1> > recvLatValue(nbReceived);
+    vector<CArray<double,2> > recvBoundsLatValue(nbReceived);    
+    for (i = 0; i < recvClientRanks_.size(); ++i)
+    {
+      int rank = recvClientRanks_[i];
+      CBufferIn& buffer = *(rankBuffers[rank]);
+      buffer >> hasLonLat;
+      buffer >> recvLatValue[i];
+      buffer >> hasBounds;
       if (hasBounds)
-      {
-        for (int nv = 0; nv < nvertex; nv++)
-          bounds_lat_srv(nv, ind_srv) = boundslat(nv, ind);
+        buffer >> recvBoundsLatValue[i];
+    }
+
+    int nbLatInd = 0;
+    for (i = 0; i < nbReceived; ++i)
+    {
+      nbLatInd += recvLatValue[i].numElements();
+    }
+
+    latvalue.resize(nbLatInd);
+    if (hasBounds)
+    {
+      bounds_latvalue.resize(nvertex, nbLatInd);
+    }
+    
+    nbLatInd = 0;
+    for (i = 0; i < nbReceived; ++i)
+    {
+      CArray<double,1>& tmp = recvLatValue[i];
+      for (ind = 0; ind < tmp.numElements(); ++ind)
+      {         
+         latvalue(nbLatInd) = tmp(ind);
+         if (hasBounds)
+         {
+          CArray<double,2>& tmpBnds = recvBoundsLatValue[i];
+          for (int nv = 0; nv < nvertex; ++nv)
+            bounds_latvalue(nv, nbLatInd) = tmpBnds(nv, ind);
+         }       
+         ++nbLatInd;
       }
     }
@@ -2061,32 +2417,147 @@
   void CDomain::recvArea(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;
-      string domainId;
       *buffer >> domainId;
-      get(domainId)->recvArea(it->rank, *buffer);
-    }
-  }
+      rankBuffers[it->rank] = buffer;     
+    }
+    get(domainId)->recvArea(rankBuffers);
+  }
+
 
   /*!
     Receive area information from client(s)
-    \param[in] rank rank of client source
-    \param[in] buffer message containing area info
+    \param[in] rankBuffers rank of sending client and the corresponding receive buffer     
   */
-  void CDomain::recvArea(int rank, CBufferIn& buffer)
-  {
-    CArray<int,1> &indi = indiSrv[rank], &indj = indjSrv[rank];
-    CArray<double,1> clientArea;
-
-    buffer >> clientArea;
-
-    int i, j, ind_srv;
-    for (int ind = 0; ind < indi.numElements(); ind++)
-    {
-      i = indi(ind); j = indj(ind);
-      ind_srv = (i - zoom_ibegin_srv) + (j - zoom_jbegin_srv) * zoom_ni_srv;
-      area_srv(ind_srv) = clientArea(ind);
+  void CDomain::recvArea(std::map<int, CBufferIn*>& rankBuffers)
+  {
+    int nbReceived = rankBuffers.size(), i, ind, index;
+    if (nbReceived != recvClientRanks_.size())
+      ERROR("void CDomain::recvArea(std::map<int, CBufferIn*>& rankBuffers)",
+           << "The number of sending clients is not correct."
+           << "Expected number: " << recvClientRanks_.size() << " but received " << nbReceived);
+
+    vector<CArray<double,1> > recvAreaValue(nbReceived);      
+    for (i = 0; i < recvClientRanks_.size(); ++i)
+    {
+      int rank = recvClientRanks_[i];
+      CBufferIn& buffer = *(rankBuffers[rank]);      
+      buffer >> hasArea;
+      if (hasArea)
+        buffer >> recvAreaValue[i];
+    }
+
+    int nbAreaInd = 0;
+    for (i = 0; i < nbReceived; ++i)
+    {
+      if (hasArea)
+        nbAreaInd += recvAreaValue[i].numElements();
+    }
+  
+    areavalue.resize(nbAreaInd);
+    nbAreaInd = 0;
+    if (hasArea)
+    {
+      for (i = 0; i < nbReceived; ++i)
+      {
+        CArray<double,1>& tmp = recvAreaValue[i];
+        for (ind = 0; ind < tmp.numElements(); ++ind)
+        {
+          area(nbAreaInd) = tmp(ind);      
+          ++nbAreaInd;
+        }
+      }
+    }
+  }
+
+  /*!
+    Receive data index event from clients(s)
+    \param[in] event event contain info about rank and associated index
+  */
+  void CDomain::recvDataIndex(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)->recvDataIndex(rankBuffers);
+
+    // if (domain->isCompressible_)
+    // {
+    //   std::sort(domain->indexesToWrite.begin(), domain->indexesToWrite.end());
+
+    //   CContextServer* server = CContext::getCurrent()->server;
+    //   domain->numberWrittenIndexes_ = domain->indexesToWrite.size();
+    //   MPI_Allreduce(&domain->numberWrittenIndexes_, &domain->totalNumberWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm);
+    //   MPI_Scan(&domain->numberWrittenIndexes_, &domain->offsetWrittenIndexes_, 1, MPI_INT, MPI_SUM, server->intraComm);
+    //   domain->offsetWrittenIndexes_ -= domain->numberWrittenIndexes_;
+    // }
+  }
+
+  /*!
+    Receive data index information from client(s)
+    A client receives data index from different clients to rebuild its own data index.
+    Because the data index is local, to rebuild data index of received client, we should use global index along with. 
+    \param[in] rankBuffers rank of sending client and the corresponding receive buffer     
+  */
+  void CDomain::recvDataIndex(std::map<int, CBufferIn*>& rankBuffers)
+  {
+    int nbReceived = rankBuffers.size(), i, ind, index, indexI, type_int;    
+    if (nbReceived != recvClientRanks_.size())
+      ERROR("void CDomain::recvLat(std::map<int, CBufferIn*>& rankBuffers)",
+           << "The number of sending clients is not correct."
+           << "Expected number: " << recvClientRanks_.size() << " but received " << nbReceived);
+
+    vector<CArray<int,1> > recvDataIIndex(nbReceived),recvDataJIndex(nbReceived);     
+    for (i = 0; i < recvClientRanks_.size(); ++i)
+    {
+      int rank = recvClientRanks_[i];
+      CBufferIn& buffer = *(rankBuffers[rank]);
+      buffer >> recvDataIIndex[i];
+      buffer >> recvDataJIndex[i];
+    }
+   
+    int nbCompressedData = 0; 
+    for (i = 0; i < nbReceived; ++i)
+    {
+      CArray<int,1>& tmp = recvDataIIndex[i];
+      for (ind = 0; ind < tmp.numElements(); ++ind)
+      {
+         index = tmp(ind);
+         if (0 <= index)
+           ++nbCompressedData;
+      }        
+    }
+
+    data_i_index.resize(nbCompressedData);
+    data_j_index.resize(nbCompressedData);
+
+    nbCompressedData = 0;
+    for (i = 0; i < nbReceived; ++i)
+    {
+      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;
+         }         
+      } 
     }
   }
@@ -2123,18 +2594,4 @@
   {
     return transformationMap_;
-  }
-
-  /*!
-    Check the validity of all transformations applied on domain
-  This functions is called AFTER all inherited attributes are solved
-  */
-  void CDomain::checkTransformations()
-  {
-    TransMapTypes::const_iterator itb = transformationMap_.begin(), it,
-                                  ite = transformationMap_.end();
-//    for (it = itb; it != ite; ++it)
-//    {
-//      (it->second)->checkValid(this);
-//    }
   }
 
Index: /XIOS/dev/dev_olga/src/node/domain.hpp
===================================================================
--- /XIOS/dev/dev_olga/src/node/domain.hpp	(revision 1024)
+++ /XIOS/dev/dev_olga/src/node/domain.hpp	(revision 1025)
@@ -16,5 +16,5 @@
 #include "transformation.hpp"
 #include "transformation_enum.hpp"
-
+#include "server_distribution_description.hpp"
 #include "mesh.hpp"
 
@@ -49,5 +49,7 @@
          enum EEventId
          {
-           EVENT_ID_SERVER_ATTRIBUT, EVENT_ID_INDEX, EVENT_ID_LON, EVENT_ID_LAT, EVENT_ID_AREA
+           EVENT_ID_INDEX, EVENT_ID_LON, EVENT_ID_LAT, 
+           EVENT_ID_AREA, EVENT_ID_MASK,
+           EVENT_ID_DATA_INDEX, EVENT_ID_SERVER_ATTRIBUT
          } ;
 
@@ -75,8 +77,6 @@
          /// VÃ©rifications ///
          void checkAttributes(void);
-
          void checkAttributesOnClient();
          void checkAttributesOnClientAfterTransformation();
-
          void checkEligibilityForCompressedOutput(void);
 
@@ -100,27 +100,24 @@
          int getOffsetWrittenIndexes() const;
 
+         const std::vector<int>& getStartWriteIndex() const;
+         const std::vector<int>& getCountWriteIndex() const;
+         const std::vector<int>& getLocalWriteSize() const;
+         const std::vector<int>& getGlobalWriteSize() const;
+
          std::map<int, StdSize> getAttributesBufferSize();
 
          bool isEmpty(void) const;
          bool isDistributed(void) const;
-         bool isCompressible(void) const;
-
-         int ni_srv,ibegin_srv,iend_srv ;
-         int zoom_ni_srv,zoom_ibegin_srv,zoom_iend_srv ;
-
-         int nj_srv,jbegin_srv,jend_srv ;
-         int zoom_nj_srv,zoom_jbegin_srv,zoom_jend_srv ;
-
-         CArray<double, 1> lonvalue_srv, latvalue_srv ;
-         CArray<double, 2> bounds_lon_srv, bounds_lat_srv ;
-         CArray<double, 1> lonvalue_client, latvalue_client;
-         CArray<double, 2> bounds_lon_client, bounds_lat_client;
-         CArray<double, 1> area_srv;
-
-        vector<int> connectedServer ; // list of connected server
-        vector<int> nbSenders ; // for each communication with a server, number of communicating client
-        vector<int> nbDataSrv ; // size of data to send to each server
-        vector< vector<int> > i_indSrv ; // for each server, i global index to send
-        vector< vector<int> > j_indSrv ; // for each server, j global index to send
+         bool isCompressible(void) const; 
+ 
+         CArray<double, 1> lonvalue, latvalue;
+         CArray<double, 2> bounds_lonvalue, bounds_latvalue;
+         CArray<double, 1> areavalue;
+
+         vector<int> connectedServer ; // list of connected server
+         vector<int> nbSenders ; // for each communication with a server, number of communicating client
+         vector<int> nbDataSrv ; // size of data to send to each server
+         vector< vector<int> > i_indSrv ; // for each server, i global index to send
+         vector< vector<int> > j_indSrv ; // for each server, j global index to send
 
       public:
@@ -128,8 +125,6 @@
          void addRelFile(const StdString & filename);
          void addRelFileCompressed(const StdString& filename);
-         void completeLonLatClient(void);
-         void sendServerAttribut(void) ;
-         void sendLonLatArea(void);
-         void computeConnectedServer(void) ;
+         void completeLonLatClient(void);         
+         void computeConnectedClients();
 
          void AllgatherRectilinearLonLat(CArray<double,1>& lon, CArray<double,1>& lat,
@@ -141,14 +136,20 @@
 
          static bool dispatchEvent(CEventServer& event);
-         static void recvServerAttribut(CEventServer& event);
+         static void recvDistributionAttributes(CEventServer& event);
          static void recvIndex(CEventServer& event);
+         static void recvMask(CEventServer& event);
+         static void recvZoom(CEventServer& event);
          static void recvLon(CEventServer& event);
          static void recvLat(CEventServer& event);
          static void recvArea(CEventServer& event);
-         void recvServerAttribut(CBufferIn& buffer);
-         void recvIndex(int rank, CBufferIn& buffer);
-         void recvLon(int rank, CBufferIn& buffer);
-         void recvLat(int rank, CBufferIn& buffer);
-         void recvArea(int rank, CBufferIn& buffer);
+         static void recvDataIndex(CEventServer& event);
+         void recvDistributionAttributes(CBufferIn& buffer);         
+         void recvZoom(std::vector<int>& rank, std::vector<CBufferIn*>& buffers);
+         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);
+         void recvArea(std::map<int, CBufferIn*>& rankBuffers);         
+         void recvDataIndex(std::map<int, CBufferIn*>& rankBuffers);
 
          /// Destructeur ///
@@ -160,5 +161,5 @@
 
          static ENodeType GetType(void);
-         const std::map<int, vector<size_t> >& getIndexServer() const;
+         const boost::unordered_map<int, vector<size_t> >& getIndexServer() const;
          CArray<bool, 1> localMask;
          bool isCurvilinear ;
@@ -183,22 +184,33 @@
          void computeLocalMask(void) ;
 
-         void checkTransformations();
-         void setTransformations(const TransMapTypes&);
-         void computeNGlobDomain();
-
+         void setTransformations(const TransMapTypes&);         
+
+         void sendAttributes();
          void sendIndex();
+         void sendDistributionAttributes();
+         void sendMask();
          void sendArea();
          void sendLonLat();
-
-       private:
+         void sendZoom();
+         void sendDataIndex();
+
+       private:         
+         std::vector<int> start_write_index_;
+         std::vector<int> count_write_index_;
+         std::vector<int> local_write_size_;
+         std::vector<int> global_write_size_;
+
          bool isChecked;
          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;
-         std::map<int,int> nbConnectedClients_; // Mapping of number of communicating client to a server
-         std::map<int, vector<size_t> > indSrv_; // Global index of each client sent to server
+         std::map<int, CArray<int,1> > indiSrv, indjSrv, indGlob_;
+         std::map<int,int> nbConnectedClients_, nbConnectedClientsZoom_; // Mapping of number of communicating client to a server
+
+         boost::unordered_map<int, vector<size_t> > indSrv_; // Global index of each client sent to server
+         boost::unordered_map<int, vector<size_t> > indZoomSrv_; // Global index of each client sent to server
          std::map<int, vector<int> > indWrittenSrv_; // Global written index of each client sent to server
          std::vector<int> indexesToWrite;
+         std::vector<int> recvClientRanks_;
          int numberWrittenIndexes_, totalNumberWrittenIndexes_, offsetWrittenIndexes_;
          std::vector<int> connectedServerRank_;
@@ -207,7 +219,7 @@
          bool isCompressible_;
          bool isRedistributed_;
-         TransMapTypes transformationMap_;
-         std::vector<int> nGlobDomain_;
+         TransMapTypes transformationMap_;         
          bool isUnstructed_;
+         boost::unordered_map<size_t,size_t> globalLocalIndexMap_;
        
        private:
Index: /XIOS/dev/dev_olga/src/node/field.cpp
===================================================================
--- /XIOS/dev/dev_olga/src/node/field.cpp	(revision 1024)
+++ /XIOS/dev/dev_olga/src/node/field.cpp	(revision 1025)
@@ -23,4 +23,5 @@
 #include "temporal_filter.hpp"
 #include "spatial_transform_filter.hpp"
+#include "file_server_writer_filter.hpp"
 
 namespace xios{
@@ -234,6 +235,5 @@
   void CField::recvUpdateData(CEventServer& event)
   {
-    vector<int> ranks;
-    vector<CBufferIn*> buffers;
+    std::map<int,CBufferIn*> rankBuffers;
 
     list<CEventServer::SSubEvent>::iterator it;
@@ -245,23 +245,48 @@
       CBufferIn* buffer = it->buffer;
       *buffer >> fieldId;
-      ranks.push_back(rank);
-      buffers.push_back(buffer);
-    }
-    get(fieldId)->recvUpdateData(ranks,buffers);
+      rankBuffers[rank] = buffer;
+    }
+    get(fieldId)->recvUpdateData(rankBuffers);
   }
 
-  void  CField::recvUpdateData(vector<int>& ranks, vector<CBufferIn*>& buffers)
+  void  CField::recvUpdateData(std::map<int,CBufferIn*>& rankBuffers)
   {
     CContext* context = CContext::getCurrent();
 
-    if (data_srv.empty())
+    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();
+      }
+
+      // Gather all data from different clients
+      recvDataSrv.resize(sizeData);
+      recvFoperationSrv = boost::shared_ptr<func::CFunctor>(new func::CInstant(recvDataSrv));
+    }
+
+    CArray<double,1> recv_data_tmp(recvDataSrv.numElements());
+    sizeData = 0;
+    const CDate& currDate = context->getCalendar()->getCurrentDate();
+    const CDate opeDate      = last_operation_srv +freq_op + freq_operation_srv - freq_op;
+
+    if (opeDate <= currDate)
     {
       for (map<int, CArray<size_t, 1> >::iterator it = grid->outIndexFromClient.begin(); it != grid->outIndexFromClient.end(); ++it)
-      {
-        int rank = it->first;
-        data_srv.insert(std::make_pair(rank, CArray<double,1>(it->second.numElements())));
-        foperation_srv.insert(pair<int,boost::shared_ptr<func::CFunctor> >(rank,boost::shared_ptr<func::CFunctor>(new func::CInstant(data_srv[rank]))));
-      }
-    }
+      {        
+        CArray<double,1> tmp;       
+        *(rankBuffers[it->first]) >> tmp;
+        recv_data_tmp(Range(sizeData,sizeData+it->second.numElements()-1)) = tmp;  
+        sizeData += it->second.numElements();      
+      }
+    }
+
+    this->setData(recv_data_tmp);
+  }
+
+  void CField::writeUpdateData(const CArray<double,1>& data)
+  {
+    CContext* context = CContext::getCurrent();
 
     const CDate& currDate = context->getCalendar()->getCurrentDate();
@@ -271,64 +296,86 @@
     if (opeDate <= currDate)
     {
-      for (int n = 0; n < ranks.size(); n++)
-      {
-        CArray<double,1> data_tmp;
-        *buffers[n] >> data_tmp;
-        (*foperation_srv[ranks[n]])(data_tmp);
-      }
+      (*recvFoperationSrv)(data);
       last_operation_srv = currDate;
+//        sendUpdateData(fieldData);
+        // Redirecting data to the correct secondary server
+        //int fileIdx = std::find(context->enabledFiles.begin(), context->enabledFiles.end(), this->file) - context->enabledFiles.begin();
+        //int srvId = fileIdx % context->clientPrimServer.size();
+        //sendUpdateData(fieldData, context->clientPrimServer[srvId]);
     }
 
     if (writeDate < (currDate + freq_operation_srv))
     {
-      for (int n = 0; n < ranks.size(); n++)
-      {
-        this->foperation_srv[ranks[n]]->final();
-      }
-
+      recvFoperationSrv->final();
       last_Write_srv = writeDate;
-    }
-
-    if (context->hasClient && context->hasServer)
-    {
-      size_t writtenSize;
-//      if (field->getUseCompressedOutput())
-//        writtenSize = grid->getNumberWrittenIndexes();
-//      else
-        writtenSize = grid->getWrittenDataSize();
-
-      CArray<double,1> fieldData(writtenSize);
-//      if (!field->default_value.isEmpty()) fieldData = field->default_value;
-
-//      if (field->getUseCompressedOutput())
-//        field->outputCompressedField(fieldData);
-//      else
-        this->outputField(fieldData);
-//        sendUpdateData(fieldData);
-        // Redirecting data to the correct secondary server
-        int fileIdx = std::find(context->enabledFiles.begin(), context->enabledFiles.end(), this->file) - context->enabledFiles.begin();
-        int srvId = fileIdx % context->clientPrimServer.size();
-        sendUpdateData(fieldData, context->clientPrimServer[srvId]);
-    }
-    if (!context->hasClient && context->hasServer)
-    {
-//      size_t writtenSize;
-//      if (this->getUseCompressedOutput())
-//        writtenSize = grid->getNumberWrittenIndexes();
-//      else
-//        writtenSize = grid->getWrittenDataSize();
-//
-//      CArray<double,1> fieldData(writtenSize);
-
-//      if (this->getUseCompressedOutput())
-//        this->outputCompressedField(fieldData);
-//      else
-//        this->outputField(fieldData);
       writeField();
-    }
-
-    lastlast_Write_srv = last_Write_srv;
-
+      lastlast_Write_srv = last_Write_srv;
+    }
   }
+  
+//   void  CField::recvUpdateData(vector<int>& ranks, vector<CBufferIn*>& buffers)
+//   {
+//     CContext* context = CContext::getCurrent();
+
+//     if (data_srv.empty())
+//     {
+//       for (map<int, CArray<size_t, 1> >::iterator it = grid->outIndexFromClient.begin(); it != grid->outIndexFromClient.end(); ++it)
+//       {
+//         int rank = it->first;
+//         data_srv.insert(std::make_pair(rank, CArray<double,1>(it->second.numElements())));
+//         foperation_srv.insert(pair<int,boost::shared_ptr<func::CFunctor> >(rank,boost::shared_ptr<func::CFunctor>(new func::CInstant(data_srv[rank]))));
+//       }
+//     }
+
+//     const CDate& currDate = context->getCalendar()->getCurrentDate();
+//     const CDate opeDate      = last_operation_srv +freq_op + freq_operation_srv - freq_op;
+//     const CDate writeDate    = last_Write_srv     + freq_write_srv;
+
+//     if (opeDate <= currDate)
+//     {
+//       for (int n = 0; n < ranks.size(); n++)
+//       {
+//         CArray<double,1> data_tmp;
+//         *buffers[n] >> data_tmp;
+//         (*foperation_srv[ranks[n]])(data_tmp);
+//       }
+//       last_operation_srv = currDate;
+//     }
+
+//     if (writeDate < (currDate + freq_operation_srv))
+//     {
+//       for (int n = 0; n < ranks.size(); n++)
+//       {
+//         this->foperation_srv[ranks[n]]->final();
+//       }
+
+//       last_Write_srv = writeDate;
+//     }
+
+//     if (context->hasClient && context->hasServer)
+//     {
+//       size_t writtenSize;
+// //      if (field->getUseCompressedOutput())
+// //        writtenSize = grid->getNumberWrittenIndexes();
+// //      else
+//         writtenSize = grid->getWrittenDataSize();
+
+//       CArray<double,1> fieldData(writtenSize);
+// //      if (!field->default_value.isEmpty()) fieldData = field->default_value;
+
+// //      if (field->getUseCompressedOutput())
+// //        field->outputCompressedField(fieldData);
+// //      else
+//         this->outputField(fieldData);
+//       sendUpdateData(fieldData);
+//     }
+//     if (!context->hasClient && context->hasServer)
+//     {
+//       writeField();
+//     }
+
+//     lastlast_Write_srv = last_Write_srv;
+
+//   }
 
   void CField::writeField(void)
@@ -656,32 +703,4 @@
 
    //----------------------------------------------------------------
-
-   void CField::solveOnlyReferenceEnabledField(bool doSending2Server)
-   {
-     CContext* context = CContext::getCurrent();
-     if (!isReferenceSolved)
-     {
-        isReferenceSolved = true;
-
-        if (context->hasClient && !context->hasServer)
-//        if (context->hasClient)
-        {
-          solveRefInheritance(true);
-          if (hasDirectFieldReference()) getDirectFieldReference()->solveOnlyReferenceEnabledField(false);
-        }
-//        else if (context->hasServer)
-        if (context->hasServer)
-          solveServerOperation();
-
-        solveGridReference();
-
-        if (context->hasClient && !context->hasServer)
-//       if (context->hasClient)
-       {
-         solveGenerateGrid();
-         buildGridTransformationGraph();
-       }
-     }
-   }
 
    /*!
@@ -784,5 +803,83 @@
      }
    }
-
+   
+   void CField::solveAllEnabledFields()
+   {
+     CContext* context = CContext::getCurrent();
+     bool hasClient = context->hasClient;
+     bool hasServer = context->hasServer;
+
+     if (!isReferenceSolved)
+     {
+        isReferenceSolved = true;
+
+        if (hasClient && !hasServer)
+        {
+          solveRefInheritance(true);
+          if (hasDirectFieldReference()) getDirectFieldReference()->solveAllEnabledFields();
+        }
+
+        if (hasServer)
+          solveServerOperation();
+
+        solveGridReference();
+
+        if (hasClient && !hasServer)
+       {
+         solveGenerateGrid();
+         buildGridTransformationGraph();
+       }
+
+       solveGridDomainAxisRef(false);
+
+       if (hasClient && !hasServer)
+       {
+         solveTransformedGrid();
+       }
+
+       solveGridDomainAxisRef(false);
+     }
+   }
+
+   void CField::checkGridOfEnabledFields()
+   {
+      solveCheckMaskIndex(false);
+   }
+
+   void CField::sendGridOfEnabledFields()
+   {
+      solveGridDomainAxisRef(true);
+      solveCheckMaskIndex(true);
+   }
+
+
+    void CField::solveOnlyReferenceEnabledField(bool doSending2Server)
+   {
+     CContext* context = CContext::getCurrent();
+     if (!isReferenceSolved)
+     {
+        isReferenceSolved = true;
+
+        if (context->hasClient && !context->hasServer)
+//        if (context->hasClient)
+        {
+          solveRefInheritance(true);
+          if (hasDirectFieldReference()) getDirectFieldReference()->solveOnlyReferenceEnabledField(false);
+        }
+//        else if (context->hasServer)
+        if (context->hasServer)
+          solveServerOperation();
+
+        solveGridReference();
+
+        if (context->hasClient && !context->hasServer)
+//       if (context->hasClient)
+       {
+         solveGenerateGrid();
+         buildGridTransformationGraph();
+       }
+     }
+   }
+     
    void CField::solveAllReferenceEnabledField(bool doSending2Server)
    {
@@ -794,5 +891,5 @@
         areAllReferenceSolved = true;
 
-//        if (context->hasClient)
+       // if (context->hasClient)
         if (context->hasClient && !context->hasServer)
         {
@@ -800,6 +897,6 @@
           if (hasDirectFieldReference()) getDirectFieldReference()->solveAllReferenceEnabledField(false);
         }
-//        else if (context->hasServer)
-        if (context->hasServer && !context->hasClient)
+       else if (context->hasServer)
+        // if (context->hasServer && !context->hasClient)
           solveServerOperation();
 
@@ -885,12 +982,48 @@
    void CField::buildFilterGraph(CGarbageCollector& gc, bool enableOutput)
    {
-     if (!areAllReferenceSolved) solveAllReferenceEnabledField(false);
-
-     // Start by building a filter which can provide the field's instant data
-     if (!instantDataFilter)
-     {
-       // Check if we have an expression to parse
+     // if (!areAllReferenceSolved) solveAllReferenceEnabledField(false);
+    if (!isReferenceSolved) solveAllEnabledFields();
+     CContext* context = CContext::getCurrent();
+     bool hasWriterServer = context->hasServer && !context->hasClient;
+     bool hasIntermediateServer = context->hasServer && context->hasClient;
+
+     if (hasWriterServer)
+     {
+        if (!instantDataFilter)
+          instantDataFilter = clientSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(grid));
+
+             // If the field data is to be read by the client or/and written to a file
+       if (enableOutput && !storeFilter && !fileWriterFilter)
+       {
+         if (file && (file->mode.isEmpty() || file->mode == CFile::mode_attr::write))
+         {
+           fileServerWriterFilter = boost::shared_ptr<CFileServerWriterFilter>(new CFileServerWriterFilter(gc, this));
+           instantDataFilter->connectOutput(fileServerWriterFilter, 0);
+         }
+       }
+     }
+     else if (hasIntermediateServer)
+     {
+       if (!instantDataFilter)
+          instantDataFilter = clientSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(grid));
+
+             // If the field data is to be read by the client or/and written to a file
+       if (enableOutput && !storeFilter && !fileWriterFilter)
+       {
+         if (file && (file->mode.isEmpty() || file->mode == CFile::mode_attr::write))
+         {
+           fileWriterFilter = boost::shared_ptr<CFileWriterFilter>(new CFileWriterFilter(gc, this));
+           instantDataFilter->connectOutput(fileWriterFilter, 0);
+         }
+       }
+     }
+     else
+     {
+       // Start by building a filter which can provide the field's instant data
+       if (!instantDataFilter)
+       {
+         // Check if we have an expression to parse
        if (hasExpression())
-       {
+         {
          boost::scoped_ptr<IFilterExprNode> expr(parseExpr(getExpression() + '\0'));
          boost::shared_ptr<COutputPin> filter = expr->reduce(gc, *this);
@@ -912,30 +1045,31 @@
 
          instantDataFilter = filter;
-       }
-       // Check if we have a reference on another field
-       else if (!field_ref.isEmpty())
-         instantDataFilter = getFieldReference(gc);
-       // Check if the data is to be read from a file
-       else if (file && !file->mode.isEmpty() && file->mode == CFile::mode_attr::read)
+         }
+         // Check if we have a reference on another field
+         else if (!field_ref.isEmpty())
+           instantDataFilter = getFieldReference(gc);
+         // Check if the data is to be read from a file
+         else if (file && !file->mode.isEmpty() && file->mode == CFile::mode_attr::read)
          instantDataFilter = serverSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid,
                                                                                                      freq_offset.isEmpty() ? NoneDu : freq_offset,
                                                                                                      true));
-       else // The data might be passed from the model
+         else // The data might be passed from the model
          instantDataFilter = clientSourceFilter = boost::shared_ptr<CSourceFilter>(new CSourceFilter(gc, grid));
-     }
-
-     // If the field data is to be read by the client or/and written to a file
-     if (enableOutput && !storeFilter && !fileWriterFilter)
-     {
-       if (!read_access.isEmpty() && read_access)
-       {
-         storeFilter = boost::shared_ptr<CStoreFilter>(new CStoreFilter(gc, CContext::getCurrent(), grid));
-         instantDataFilter->connectOutput(storeFilter, 0);
-       }
-
-       if (file && (file->mode.isEmpty() || file->mode == CFile::mode_attr::write))
-       {
-         fileWriterFilter = boost::shared_ptr<CFileWriterFilter>(new CFileWriterFilter(gc, this));
-         getTemporalDataFilter(gc, file->output_freq)->connectOutput(fileWriterFilter, 0);
+       }
+
+       // If the field data is to be read by the client or/and written to a file
+       if (enableOutput && !storeFilter && !fileWriterFilter)
+       {
+         if (!read_access.isEmpty() && read_access)
+         {
+           storeFilter = boost::shared_ptr<CStoreFilter>(new CStoreFilter(gc, CContext::getCurrent(), grid));
+           instantDataFilter->connectOutput(storeFilter, 0);
+         }
+
+         if (file && (file->mode.isEmpty() || file->mode == CFile::mode_attr::write))
+         {
+           fileWriterFilter = boost::shared_ptr<CFileWriterFilter>(new CFileWriterFilter(gc, this));
+           getTemporalDataFilter(gc, file->output_freq)->connectOutput(fileWriterFilter, 0);
+         }
        }
      }
@@ -1285,10 +1419,11 @@
    void CField::outputField(CArray<double,1>& fieldOut)
    {
-      map<int, CArray<double,1> >::iterator it;
-
-      for (it = data_srv.begin(); it != data_srv.end(); it++)
-      {
-         grid->outputField(it->first, it->second, fieldOut.dataFirst());
-      }
+      // map<int, CArray<double,1> >::iterator it;
+
+      // for (it = data_srv.begin(); it != data_srv.end(); it++)
+      // {
+      //    grid->outputField(it->first, it->second, fieldOut.dataFirst());
+      // }
+    grid->outputField(recvDataSrv, fieldOut);
    }
 
Index: /XIOS/dev/dev_olga/src/node/file.cpp
===================================================================
--- /XIOS/dev/dev_olga/src/node/file.cpp	(revision 1024)
+++ /XIOS/dev/dev_olga/src/node/file.cpp	(revision 1025)
@@ -689,6 +689,25 @@
      for (int i = 0; i < size; ++i)
      {
-       this->enabledFields[i]->solveOnlyReferenceEnabledField(sendToServer);
+       // this->enabledFields[i]->solveOnlyReferenceEnabledField(sendToServer);
+       this->enabledFields[i]->solveAllEnabledFields();
 //       this->enabledFields[i]->buildGridTransformationGraph();
+     }
+   }
+
+   void CFile::checkGridOfEnabledFields()
+   { 
+     int size = this->enabledFields.size();
+     for (int i = 0; i < size; ++i)
+     {
+       this->enabledFields[i]->checkGridOfEnabledFields();
+     }
+   }
+
+   void CFile::sendGridOfEnabledFields()
+   { 
+     int size = this->enabledFields.size();
+     for (int i = 0; i < size; ++i)
+     {
+       this->enabledFields[i]->sendGridOfEnabledFields();
      }
    }
Index: /XIOS/dev/dev_olga/src/node/file.hpp
===================================================================
--- /XIOS/dev/dev_olga/src/node/file.hpp	(revision 1024)
+++ /XIOS/dev/dev_olga/src/node/file.hpp	(revision 1025)
@@ -110,4 +110,7 @@
          void prefetchEnabledReadModeFieldsIfNeeded();
 
+         void checkGridOfEnabledFields();
+         void sendGridOfEnabledFields();
+
          // Add component into file
          CField* addField(const string& id = "");
Index: /XIOS/dev/dev_olga/src/node/grid.hpp
===================================================================
--- /XIOS/dev/dev_olga/src/node/grid.hpp	(revision 1024)
+++ /XIOS/dev/dev_olga/src/node/grid.hpp	(revision 1025)
@@ -225,4 +225,5 @@
 
          map<int, CArray<size_t, 1> > outIndexFromClient, compressedOutIndexFromClient;
+         CArray<size_t,1> indexFromClients;
          void checkMask(void);
          void createMask(void);
@@ -260,4 +261,7 @@
         void computeIndexByElement(const std::vector<boost::unordered_map<size_t,std::vector<int> > >& indexServerOnElement,
                                    CClientServerMapping::GlobalIndexMap& globalIndexOnServer);
+
+        void computeClientIndex();
+        void computeConnectedClients();
 
       private:
Index: /XIOS/dev/dev_olga/src/object_template_impl.hpp
===================================================================
--- /XIOS/dev/dev_olga/src/object_template_impl.hpp	(revision 1024)
+++ /XIOS/dev/dev_olga/src/object_template_impl.hpp	(revision 1025)
@@ -256,5 +256,6 @@
       CAttributeMap & attrMap = *this;
       CAttribute* attr=attrMap[id];
-      sendAttributToServer(*attr);
+      if (attr->doSend()) 
+        sendAttributToServer(*attr);
    }
 
Index: /XIOS/dev/dev_olga/src/test/test_client.f90
===================================================================
--- /XIOS/dev/dev_olga/src/test/test_client.f90	(revision 1024)
+++ /XIOS/dev/dev_olga/src/test/test_client.f90	(revision 1025)
@@ -17,7 +17,7 @@
   CHARACTER(len=15) :: calendar_type
   TYPE(xios_context) :: ctx_hdl
-  INTEGER,PARAMETER :: ni_glo=2
-  INTEGER,PARAMETER :: nj_glo=2
-  INTEGER,PARAMETER :: llm=1
+  INTEGER,PARAMETER :: ni_glo=4
+  INTEGER,PARAMETER :: nj_glo=4
+  INTEGER,PARAMETER :: llm=5
   DOUBLE PRECISION  :: lval(llm)=1
   TYPE(xios_field) :: field_hdl
@@ -28,5 +28,5 @@
   DOUBLE PRECISION,DIMENSION(ni_glo,nj_glo) :: lon_glo,lat_glo
   DOUBLE PRECISION :: field_A_glo(ni_glo,nj_glo,llm)
-  DOUBLE PRECISION,ALLOCATABLE :: lon(:,:),lat(:,:),field_A(:,:,:), lonvalue(:,:) ;
+  DOUBLE PRECISION,ALLOCATABLE :: lon(:,:),lat(:,:),field_A(:,:,:), lonvalue(:,:), axisValue(:), field_domain(:,:) ;
   INTEGER :: ni,ibegin,iend,nj,jbegin,jend
   INTEGER :: i,j,l,ts,n
@@ -66,8 +66,10 @@
   iend=ibegin+ni-1 ; jend=jbegin+nj-1
 
-  ALLOCATE(lon(ni,nj),lat(ni,nj),field_A(0:ni+1,-1:nj+2,llm),lonvalue(ni,nj))
+  ALLOCATE(lon(ni,nj),lat(ni,nj),field_A(0:ni+1,-1:nj+2,llm),lonvalue(ni,nj), axisValue(nj), field_domain(0:ni+1,-1:nj+2))
   lon(:,:)=lon_glo(ibegin+1:iend+1,jbegin+1:jend+1)
   lat(:,:)=lat_glo(ibegin+1:iend+1,jbegin+1:jend+1)
   field_A(1:ni,1:nj,:)=field_A_glo(ibegin+1:iend+1,jbegin+1:jend+1,:)
+  field_domain(1:ni,1:nj) = field_A_glo(ibegin+1:iend+1,jbegin+1:jend+1,1)
+  axisValue(1:nj)=field_A(1,1:nj,1);
 
   CALL xios_context_initialize("test",comm)
@@ -78,4 +80,5 @@
   PRINT *, "calendar_type = ", calendar_type
 
+  ! CALL xios_set_axis_attr("axis_A",n_glo=nj_glo ,value=axisValue, n=nj, begin=jbegin) ;
   CALL xios_set_axis_attr("axis_A",n_glo=llm ,value=lval) ;
   CALL xios_set_domain_attr("domain_A",ni_glo=ni_glo, nj_glo=nj_glo, ibegin=ibegin, ni=ni,jbegin=jbegin,nj=nj,type='curvilinear')
@@ -128,7 +131,10 @@
 
   PRINT*,"field field_A is active ? ",xios_field_is_active("field_A")
-  DO ts=1,24
+  DO ts=1,40
     CALL xios_update_calendar(ts)
-    CALL xios_send_field("field_A",field_A)
+    ! CALL xios_send_field("field_A",field_A)
+    ! CALL xios_send_field("field_Axis",axisValue)
+    ! CALL xios_send_field("field_Axis",lval)
+    CALL xios_send_field("field_Domain",field_domain)
     CALL wait_us(5000) ;
   ENDDO
Index: /XIOS/dev/dev_olga/src/test/test_remap.f90
===================================================================
--- /XIOS/dev/dev_olga/src/test/test_remap.f90	(revision 1024)
+++ /XIOS/dev/dev_olga/src/test/test_remap.f90	(revision 1025)
@@ -166,6 +166,6 @@
 
   CALL xios_close_context_definition()
-  ! CALL xios_get_domain_attr("src_domain_regular_read", ni=src_tmp_ni, nj=src_tmp_nj)
-  ! ALLOCATE(tmp_field_0(src_tmp_ni*src_tmp_nj))
+  CALL xios_get_domain_attr("src_domain_regular_read", ni=src_tmp_ni, nj=src_tmp_nj)
+  ALLOCATE(tmp_field_0(src_tmp_ni*src_tmp_nj))
 
   ! CALL xios_get_axis_attr("src_axis_curvilinear_read", n=src_tmp_n)
@@ -177,5 +177,5 @@
 
   DO ts=1,5
-    ! CALL xios_recv_field("src_field_regular", tmp_field_0)
+    CALL xios_recv_field("src_field_regular", tmp_field_0)
     ! CALL xios_recv_field("src_field_curvilinear", tmp_field_1)
     ! CALL xios_recv_field("src_field_unstructured", tmp_field_2)
@@ -186,5 +186,5 @@
     CALL xios_send_field("src_field_4D",src_field_4D)
     CALL xios_send_field("src_field_3D_pression",src_field_pression)
-    ! CALL xios_send_field("tmp_field_0",tmp_field_0)
+    CALL xios_send_field("tmp_field_0",tmp_field_0)
     ! CALL xios_send_field("tmp_field_1",tmp_field_1)
     ! CALL xios_send_field("tmp_field_2",tmp_field_2)
