Index: XIOS/dev/dev_olga/src/attribute_map.cpp
===================================================================
--- XIOS/dev/dev_olga/src/attribute_map.cpp	(revision 992)
+++ XIOS/dev/dev_olga/src/attribute_map.cpp	(revision 1009)
@@ -28,9 +28,4 @@
 
       //---------------------------------------------------------------
-
-      bool CAttributeMap::hasAttribute(const StdString& key) const
-      {
-         return (this->find(key) != this->end());
-      }
 
       void CAttributeMap::clearAttribute(const StdString& key)
Index: XIOS/dev/dev_olga/src/attribute_map.hpp
===================================================================
--- XIOS/dev/dev_olga/src/attribute_map.hpp	(revision 992)
+++ XIOS/dev/dev_olga/src/attribute_map.hpp	(revision 1009)
@@ -20,5 +20,5 @@
 
             /// Tests ///
-            inline bool hasAttribute(const StdString & key) const;
+            bool hasAttribute(const StdString & key) const;
 
             /// Accesseurs ///
@@ -72,4 +72,9 @@
       };  // class CAttributeMap
 
+      inline bool CAttributeMap::hasAttribute(const StdString& key) const
+      {
+        return (this->find(key) != this->end());
+      }
+
 } // namespace xios
 
Index: XIOS/dev/dev_olga/src/client.cpp
===================================================================
--- XIOS/dev/dev_olga/src/client.cpp	(revision 992)
+++ XIOS/dev/dev_olga/src/client.cpp	(revision 1009)
@@ -18,5 +18,5 @@
     MPI_Comm CClient::interComm ;
     std::list<MPI_Comm> CClient::contextInterComms;
-    int CClient::serverLeader;
+    vector <int> CClient::serverLeader;
     bool CClient::is_MPI_Initialized ;
     int CClient::rank = INVALID_RANK;
@@ -103,11 +103,15 @@
           {
             int clientLeader=leaders[hashClient] ;
-            serverLeader=leaders[hashServer] ;
+//            serverLeader=leaders[hashServer] ;
+            serverLeader.push_back(leaders[hashServer]) ;
             int intraCommSize, intraCommRank ;
             MPI_Comm_size(intraComm,&intraCommSize) ;
             MPI_Comm_rank(intraComm,&intraCommRank) ;
             info(50)<<"intercommCreate::client "<<rank<<" intraCommSize : "<<intraCommSize
-                   <<" intraCommRank :"<<intraCommRank<<"  clientLeader "<< serverLeader<<endl ;
-             MPI_Intercomm_create(intraComm,0,CXios::globalComm,serverLeader,0,&interComm) ;
+                   <<" intraCommRank :"<<intraCommRank<<"  clientLeader "<< serverLeader.back()<<endl ;
+             MPI_Intercomm_create(intraComm, 0, CXios::globalComm, serverLeader.back(), 0, &interComm) ;
+//             info(50)<<"intercommCreate::client "<<rank<<" intraCommSize : "<<intraCommSize
+//                    <<" intraCommRank :"<<intraCommRank<<"  clientLeader "<< serverLeader<<endl ;
+//              MPI_Intercomm_create(intraComm,0,CXios::globalComm,serverLeader,0,&interComm) ;
           }
           else
@@ -161,15 +165,16 @@
     }
 
-    void CClient::initializeClientOnServer(const int rank, MPI_Comm& intraCommPrmSrv, const int srvSndLeader)
+    void CClient::initializeClientOnServer(const int rank, const MPI_Comm& intraCommPrmSrv, const int srvSndLeader)
     {
       MPI_Comm_dup(intraCommPrmSrv, &intraComm) ;
-      serverLeader = srvSndLeader;
+      serverLeader.push_back(srvSndLeader);
       int intraCommSize, intraCommRank ;
       MPI_Comm_size(intraComm,&intraCommSize) ;
       MPI_Comm_rank(intraComm,&intraCommRank) ;
       info(50)<<"intercommCreate::client "<<rank<<" intraCommSize : "<<intraCommSize
-          <<" intraCommRank :"<<intraCommRank<<"  clientLeader "<< serverLeader<<endl ;
-      MPI_Intercomm_create(intraComm, 0, CXios::globalComm, serverLeader, 0, &interComm) ;
-    }
+          <<" intraCommRank :"<<intraCommRank<<"  clientLeader "<< srvSndLeader<<endl ;
+      MPI_Intercomm_create(intraComm, 0, CXios::globalComm, srvSndLeader, 0, &interComm) ;
+    }
+
 
 ///---------------------------------------------------------------
@@ -226,20 +231,75 @@
         buffer<<msg ;
 
-        MPI_Send(buff, buffer.count(), MPI_CHAR, serverLeader, 1, CXios::globalComm) ;
+        for (int i = 0; i < serverLeader.size(); ++i)
+        {
+          MPI_Send(buff, buffer.count(), MPI_CHAR, serverLeader[i], 1, CXios::globalComm) ;
+          MPI_Intercomm_create(contextComm, 0, CXios::globalComm, serverLeader[i], 10+globalRank, &contextInterComm) ;
+          info(10)<<"Register new Context : "<<id<<endl ;
+          MPI_Comm inter ;
+          MPI_Intercomm_merge(contextInterComm,0,&inter) ;
+          MPI_Barrier(inter) ;
+
+          context->initClient(contextComm,contextInterComm) ;
+
+          contextInterComms.push_back(contextInterComm);
+          MPI_Comm_free(&inter);
+        }
         delete [] buff ;
 
-        MPI_Intercomm_create(contextComm, 0, CXios::globalComm, serverLeader, 10+globalRank, &contextInterComm) ;
-        info(10)<<"Register new Context : "<<id<<endl ;
-
-        MPI_Comm inter ;
-        MPI_Intercomm_merge(contextInterComm,0,&inter) ;
-        MPI_Barrier(inter) ;
-
-        context->initClient(contextComm,contextInterComm) ;
-
-        contextInterComms.push_back(contextInterComm);
-        MPI_Comm_free(&inter);
-      }
-    }
+      }
+    }
+
+    ///---------------------------------------------------------------
+    /*!
+     * \fn void CClient::registerContext(const string& id, const int poolNb, MPI_Comm contextComm)
+     * Function creates intraComm (CClient::intraComm) for client group with id=codeId and interComm (CClient::interComm) between client and server groups.
+     * \param [in] id id of context.
+     * \param [in] contextComm.
+     */
+        void CClient::registerContextOnSrvPools(const string& id, MPI_Comm contextComm)
+        {
+          CContext::setCurrent(id) ;
+          CContext* context=CContext::create(id);
+          StdString idServer(id);
+          idServer += "_server_";
+
+          int size,rank,globalRank ;
+          size_t message_size ;
+          int leaderRank ;
+          MPI_Comm contextInterComm ;
+
+          MPI_Comm_size(contextComm,&size) ;
+          MPI_Comm_rank(contextComm,&rank) ;
+          MPI_Comm_rank(CXios::globalComm,&globalRank) ;
+          if (rank!=0) globalRank=0 ;
+
+          CMessage msg ;
+
+          int messageSize ;
+          void * buff ;
+
+          for (int i = 0; i < serverLeader.size(); ++i)
+          {
+            StdString str = idServer + boost::lexical_cast<string>(i);
+            msg<<str<<size<<globalRank ;
+            messageSize = msg.size() ;
+            buff = new char[messageSize] ;
+            CBufferOut buffer(buff,messageSize) ;
+            buffer<<msg ;
+
+            MPI_Send(buff, buffer.count(), MPI_CHAR, serverLeader[i], 1, CXios::globalComm) ;
+            MPI_Intercomm_create(contextComm, 0, CXios::globalComm, serverLeader[i], 10+globalRank, &contextInterComm) ;
+            info(10)<<"Register new Context : "<<id<<endl ;
+            MPI_Comm inter ;
+            MPI_Intercomm_merge(contextInterComm,0,&inter) ;
+            MPI_Barrier(inter) ;
+
+            context->initClient(contextComm,contextInterComm) ;
+
+            contextInterComms.push_back(contextInterComm);
+            MPI_Comm_free(&inter);
+            delete [] buff ;
+          }
+        }
 
     void CClient::finalize(void)
Index: XIOS/dev/dev_olga/src/client.hpp
===================================================================
--- XIOS/dev/dev_olga/src/client.hpp	(revision 992)
+++ XIOS/dev/dev_olga/src/client.hpp	(revision 1009)
@@ -11,12 +11,14 @@
       public:
         static void initialize(const string& codeId, MPI_Comm& localComm, MPI_Comm& returnComm);
-        static void initializeClientOnServer(const int rank, MPI_Comm& localComm, const int srvSndLeader);
+        static void initializeClientOnServer(const int rank, const MPI_Comm& localComm, const int srvSndLeader);
+
         static void finalize(void);
         static void registerContext(const string& id, MPI_Comm contextComm);
+        static void registerContextOnSrvPools(const string& id, MPI_Comm contextComm);
 
         static MPI_Comm intraComm;
         static MPI_Comm interComm;
         static std::list<MPI_Comm> contextInterComms;
-        static int serverLeader;
+        static vector<int> serverLeader;
         static bool is_MPI_Initialized ;
 
Index: XIOS/dev/dev_olga/src/context_server.cpp
===================================================================
--- XIOS/dev/dev_olga/src/context_server.cpp	(revision 992)
+++ XIOS/dev/dev_olga/src/context_server.cpp	(revision 1009)
@@ -62,5 +62,4 @@
     boost::hash<string> hashString;
     StdString contextId = context->getId();
-    contextId += "_prim";                      // just to distinguish between server and serverPrimServer on server1
     hashId=hashString(contextId);
 
Index: XIOS/dev/dev_olga/src/declare_ref_func.hpp
===================================================================
--- XIOS/dev/dev_olga/src/declare_ref_func.hpp	(revision 992)
+++ XIOS/dev/dev_olga/src/declare_ref_func.hpp	(revision 1009)
@@ -51,4 +51,6 @@
     SuperClassAttribute::setAttributes(refer_ptr, apply);              \
   }                                                                    \
+  if (this->hasAttribute("name") && this->name.isEmpty())              \
+    this->name.setValue(this->get##type##OutputName());                \
 }                                                                      \
                                                                        \
@@ -95,5 +97,5 @@
     const C##type* refer_ptr = this, *tmp_ptr;                         \
     StdString nameRef = this->name_##_ref;                             \
-    std::set<const C##type*> tmpRefObjects;                                  \
+    std::set<const C##type*> tmpRefObjects;                            \
     while (refer_ptr->hasAutoGeneratedId() &&                          \
           (C##type::has(nameRef)))                                     \
@@ -102,12 +104,16 @@
       tmp_ptr = refer_ptr;                                             \
       refer_ptr = tmp_ptr->getDirect##type##Reference();               \
-      if (refer_ptr->hasDirect##type##Reference())                     \
-        nameRef = refer_ptr->name_##_ref;                              \
-      if (tmpRefObjects.end() != tmpRefObjects.find(refer_ptr))        \
-      {                                                                \
+      if (refer_ptr->hasAutoGeneratedId() &&                           \
+          refer_ptr->hasDirect##type##Reference())                     \
+          nameRef = refer_ptr->name_##_ref;                            \
+      else {                                                           \
+         nameRef = refer_ptr->getId(); break;                           \
+       }                                                                \
+       if (tmpRefObjects.end() != tmpRefObjects.find(refer_ptr))        \
+       {                                                                \
         ERROR("const StdString& C" #type "::get" #type "OutputName(void) const ",      \
-              << "Circular dependency stopped for " #name_ " object "  \
-              << "with id = \"" << refer_ptr->getId() << "\".");       \
-      }                                                                \
+               << "Circular dependency stopped for " #name_ " object "  \
+               << "with id = \"" << refer_ptr->getId() << "\".");       \
+       }                                                               \
     }                                                                  \
     return nameRef;                                                    \
Index: XIOS/dev/dev_olga/src/group_template.hpp
===================================================================
--- XIOS/dev/dev_olga/src/group_template.hpp	(revision 992)
+++ XIOS/dev/dev_olga/src/group_template.hpp	(revision 1009)
@@ -72,4 +72,5 @@
          static bool dispatchEvent(CEventServer& event) ;
          void sendCreateChild(const string& id="") ;
+         void sendCreateChild(const string& id, const int srvPool) ;
          void sendCreateChildGroup(const string& id="") ;
          static void recvCreateChild(CEventServer& event) ;
Index: XIOS/dev/dev_olga/src/group_template_impl.hpp
===================================================================
--- XIOS/dev/dev_olga/src/group_template_impl.hpp	(revision 992)
+++ XIOS/dev/dev_olga/src/group_template_impl.hpp	(revision 1009)
@@ -379,18 +379,23 @@
     {
       // Use correct context client to send message
-       CContextClient* contextClientTmp = (0 != context->clientPrimServer) ? context->clientPrimServer : context->client;
-
-       CEventClient event(this->getType(),EVENT_ID_CREATE_CHILD) ;   
-       if (contextClientTmp->isServerLeader())
-       {
-         CMessage msg ;
-         msg<<this->getId() ;
-         msg<<id ;
-         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) ;
+//      CContextClient* contextClientTmp = (0 != context->clientPrimServer) ? context->clientPrimServer : context->client;
+      int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
+      for (int i = 0; i < nbSrvPools; ++i)
+      {
+         CContextClient* contextClientTmp = (context->hasServer) ? context->clientPrimServer[i] : context->client;
+
+         CEventClient event(this->getType(),EVENT_ID_CREATE_CHILD) ;
+         if (contextClientTmp->isServerLeader())
+         {
+           CMessage msg ;
+           msg<<this->getId() ;
+           msg<<id ;
+           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) ;
+      }
     }
 
@@ -416,4 +421,24 @@
    
    template <class U, class V, class W>
+   void CGroupTemplate<U, V, W>::sendCreateChild(const string& id, const int srvPool)
+   {
+    CContext* context=CContext::getCurrent() ;
+    CContextClient* contextClientTmp = context->clientPrimServer[srvPool];
+
+    CEventClient event(this->getType(),EVENT_ID_CREATE_CHILD) ;
+    if (contextClientTmp->isServerLeader())
+    {
+      CMessage msg ;
+      msg<<this->getId() ;
+      msg<<id ;
+      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) ;
+   }
+
+   template <class U, class V, class W>
    void CGroupTemplate<U, V, W>::sendCreateChildGroup(const string& id)
    {
@@ -424,18 +449,22 @@
     {
         // Use correct context client to send message
-       CContextClient* contextClientTmp = (0 != context->clientPrimServer) ? context->clientPrimServer : context->client;
-
-       CEventClient event(this->getType(),EVENT_ID_CREATE_CHILD_GROUP) ;   
-       if (contextClientTmp->isServerLeader())
-       {
-         CMessage msg ;
-         msg<<this->getId() ;
-         msg<<id ;
-         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) ;
+//      CContextClient* contextClientTmp = (0 != context->clientPrimServer) ? context->clientPrimServer : context->client;
+      int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
+      for (int i = 0; i < nbSrvPools; ++i)
+      {
+        CContextClient* contextClientTmp = (context->hasServer) ? context->clientPrimServer[i] : context->client;
+        CEventClient event(this->getType(),EVENT_ID_CREATE_CHILD_GROUP) ;
+        if (contextClientTmp->isServerLeader())
+        {
+          CMessage msg ;
+          msg<<this->getId() ;
+          msg<<id ;
+          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) ;
+      }
     }
 
Index: XIOS/dev/dev_olga/src/node/axis.cpp
===================================================================
--- XIOS/dev/dev_olga/src/node/axis.cpp	(revision 992)
+++ XIOS/dev/dev_olga/src/node/axis.cpp	(revision 1009)
@@ -889,47 +889,48 @@
   {
     CContext* context = CContext::getCurrent();
-
-    CContextClient* contextClientTmp = (0 != context->clientPrimServer) ? context->clientPrimServer 
-                                                                        : 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);
+    int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
+    for (int i = 0; i < nbSrvPools; ++i)
+    {
+      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);
+    }
   }
 
Index: XIOS/dev/dev_olga/src/node/context.cpp
===================================================================
--- XIOS/dev/dev_olga/src/node/context.cpp	(revision 992)
+++ XIOS/dev/dev_olga/src/node/context.cpp	(revision 1009)
@@ -27,5 +27,6 @@
       , calendar(), hasClient(false), hasServer(false)
       , isPostProcessed(false), finalized(false)
-      , idServer_(), client(0), server(0), clientPrimServer(0), serverPrimServer(0)
+      , idServer_(), client(0), server(0)
+//	  , clientPrimServer(0), serverPrimServer(0)
    { /* Ne rien faire de plus */ }
 
@@ -34,5 +35,6 @@
       , calendar(), hasClient(false), hasServer(false)
       , isPostProcessed(false), finalized(false)
-      , idServer_(), client(0), server(0), clientPrimServer(0), serverPrimServer(0)
+      , idServer_(), client(0), server(0)
+//	  , clientPrimServer(0), serverPrimServer(0)
    { /* Ne rien faire de plus */ }
 
@@ -41,6 +43,6 @@
      delete client;
      delete server;
-     delete clientPrimServer;
-     delete serverPrimServer;
+//     delete clientPrimServer;
+//     delete serverPrimServer;
    }
 
@@ -252,6 +254,8 @@
      else                         // initClient is called by primary server pool
      {
-       clientPrimServer = new CContextClient(this, intraComm, interComm);
-       serverPrimServer = new CContextServer(this, 1, intraComm, interComm);  // just some int parameter to distinguish server from serverPrimServer on server1
+//       clientPrimServer = new CContextClient(this, intraComm, interComm);
+//       serverPrimServer = new CContextServer(this, 1, intraComm, interComm);  // just some int parameter to distinguish server from serverPrimServer on server1
+       clientPrimServer.push_back(new CContextClient(this, intraComm, interComm));
+       serverPrimServer.push_back(new CContextServer(this, intraComm, interComm));
      }
 
@@ -320,13 +324,15 @@
      if (hasClient && hasServer)
      {
-       if (clientPrimServer->isServerLeader())
-       {
-         const std::list<int>& ranks = clientPrimServer->getRanksServerLeader();
-         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
-           if (!bufferSize.count(*itRank)) bufferSize[*itRank] = maxEventSize[*itRank] = minBufferSize;
-       }
-       clientPrimServer->setBufferSize(bufferSize, maxEventSize);
-     }
-
+       for (int i = 0; i < clientPrimServer.size(); ++i)
+       {
+         if (clientPrimServer[i]->isServerLeader())
+         {
+           const std::list<int>& ranks = clientPrimServer[i]->getRanksServerLeader();
+           for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
+             if (!bufferSize.count(*itRank)) bufferSize[*itRank] = maxEventSize[*itRank] = minBufferSize;
+         }
+         clientPrimServer[i]->setBufferSize(bufferSize, maxEventSize);
+       }
+     }
    }
 
@@ -377,5 +383,9 @@
      {
        bool serverFinished = server->eventLoop();
-       bool serverPrimFinished = serverPrimServer->eventLoop();
+       bool serverPrimFinished = true;
+       for (int i = 0; i < serverPrimServer.size(); ++i)
+       {
+         serverPrimFinished *= serverPrimServer[i]->eventLoop();
+       }
        return ( serverFinished && serverPrimFinished);
      }
@@ -397,7 +407,12 @@
      {
        client->checkBuffers();
-       clientPrimServer->checkBuffers();
+       for (int i = 0; i < clientPrimServer.size(); ++i)
+         clientPrimServer[i]->checkBuffers();
        bool serverFinished = server->eventLoop();
-       bool serverPrimFinished = serverPrimServer->eventLoop();
+       bool serverPrimFinished = true;
+       for (int i = 0; i < serverPrimServer.size(); ++i)
+       {
+         serverPrimFinished *= serverPrimServer[i]->eventLoop();
+       }
        return ( serverFinished && serverPrimFinished);
      }
@@ -412,66 +427,48 @@
    void CContext::finalize(void)
    {
-      if (!finalized)
-      {
-        finalized = true;
+     if (!finalized)
+     {
+       finalized = true;
 //        if (hasClient) sendRegistry() ;
 
-/*        if (CXios::serverLevel == 0)
-        {
-          client->finalize();
-          while (!server->hasFinished())
-          {
-            server->eventLoop();
-          }
-        }
-        else if (CXios::serverLevel == 1)
-        {
-          clientPrimServer->finalize();
-          while (!serverPrimServer->hasFinished())
-          {
-            serverPrimServer->eventLoop();
-          }
-          client->finalize();
-          while (!server->hasFinished())
-          {
-            server->eventLoop();
-          }
-        }
-        else if (CXios::serverLevel == 2)
-        {
-          client->finalize();
-          while (!server->hasFinished())
-          {
-            server->eventLoop();
-          }
-        }*/
-
-        if ((hasClient) && (hasServer))
-        {
-          clientPrimServer->finalize();
-          while (!serverPrimServer->hasFinished())
-          {
-            serverPrimServer->eventLoop();
-            CServer::eventScheduler->checkEvent() ;
-          }
-        }
-
-        client->finalize();
-        while (!server->hasFinished())
-        {
-          server->eventLoop();
-        }
-
-
-        if (hasServer)
-        {
-          closeAllFile();
-          registryOut->hierarchicalGatherRegistry() ;
-          if (server->intraCommRank==0) CXios::globalRegistry->mergeRegistry(*registryOut) ;
-        }
-
-        for (std::list<MPI_Comm>::iterator it = comms.begin(); it != comms.end(); ++it)
-          MPI_Comm_free(&(*it));
-        comms.clear();
+       if ((hasClient) && (hasServer))
+       {
+         for (int i = 0; i < clientPrimServer.size(); ++i)
+           clientPrimServer[i]->finalize();
+
+         for (int i = 0; i < serverPrimServer.size(); ++i)
+         {
+           while (!serverPrimServer[i]->hasFinished())
+           {
+             serverPrimServer[i]->eventLoop();
+             CServer::eventScheduler->checkEvent() ;
+           }
+         }
+       }
+
+       client->finalize();
+       while (!server->hasFinished())
+       {
+         server->eventLoop();
+       }
+
+       if (hasServer)
+       {
+         closeAllFile();
+         registryOut->hierarchicalGatherRegistry() ;
+         if (server->intraCommRank==0) CXios::globalRegistry->mergeRegistry(*registryOut) ;
+       }
+
+       for (std::vector<CContextClient*>::iterator it = clientPrimServer.begin(); it != clientPrimServer.end(); it++)
+         delete *it;
+
+       for (std::vector<CContextServer*>::iterator it = serverPrimServer.begin(); it != serverPrimServer.end(); it++)
+         delete *it;
+
+       for (std::list<MPI_Comm>::iterator it = comms.begin(); it != comms.end(); ++it)
+         MPI_Comm_free(&(*it));
+       comms.clear();
+
+
       }
    }
@@ -508,16 +505,21 @@
 
       // We have enough information to send to server
-      // First of all, send all enabled files
+      if (!hasServer)
+      {
+        // First of all, send all enabled files
        sendEnabledFiles();
-
-      // Then, send all enabled fields
+       // Then, send all enabled fields
        sendEnabledFields();
+      }
+      else
+      {
+        sendEnabledFiles(clientPrimServer.size());
+        sendEnabledFields(clientPrimServer.size());
+      }
 
       // 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();
@@ -539,6 +541,4 @@
       this->solveAllRefOfEnabledFields(true);
     }
-
-
 
 //    // Now tell server that it can process all messages from client
@@ -769,45 +769,24 @@
    {
      // Use correct context client to send message
-     CContextClient* contextClientTmp = (0 != clientPrimServer) ? clientPrimServer : client;
-     CEventClient event(getType(),EVENT_ID_CLOSE_DEFINITION);
-
-     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);
-
-     // 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);
-
-     // }
+//     CContextClient* contextClientTmp = (hasServer) ? clientPrimServer[0] : client;
+     int nbSrvPools = (hasServer) ? clientPrimServer.size() : 1;
+     for (int i = 0; i < nbSrvPools; ++i)
+     {
+       CContextClient* contextClientTmp = (hasServer) ? clientPrimServer[i] : client;
+       CEventClient event(getType(),EVENT_ID_CLOSE_DEFINITION);
+       if (contextClientTmp->isServerLeader())
+       {
+         CMessage msg;
+         if (hasServer)
+           msg<<this->getIdServer(i);
+         else
+           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);
+     }
    }
 
@@ -829,17 +808,25 @@
    {
      // Use correct context client to send message
-     CContextClient* contextClientTmp = (0 != clientPrimServer) ? clientPrimServer : client;
-     CEventClient event(getType(),EVENT_ID_UPDATE_CALENDAR);
-
-       if (contextClientTmp->isServerLeader())
-       {
-         CMessage msg;
-         msg<<this->getIdServer()<<step;
-         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);
+//     CContextClient* contextClientTmp = (0 != clientPrimServer) ? clientPrimServer : client;
+     int nbSrvPools = (hasServer) ? clientPrimServer.size() : 1;
+     for (int i = 0; i < nbSrvPools; ++i)
+     {
+       CContextClient* contextClientTmp = (hasServer) ? clientPrimServer[i] : client;
+       CEventClient event(getType(),EVENT_ID_UPDATE_CALENDAR);
+
+         if (contextClientTmp->isServerLeader())
+         {
+           CMessage msg;
+           if (hasServer)
+             msg<<this->getIdServer(i)<<step;
+           else
+             msg<<this->getIdServer()<<step;
+           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);
+     }
 
      // if (!hasServer)
@@ -896,18 +883,25 @@
    {
      // Use correct context client to send message
-     CContextClient* contextClientTmp = (0 != clientPrimServer) ? clientPrimServer : client;
-     CEventClient event(getType(),EVENT_ID_CREATE_FILE_HEADER);
-
-     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);
-
+//     CContextClient* contextClientTmp = (0 != clientPrimServer) ? clientPrimServer : client;
+     int nbSrvPools = (hasServer) ? clientPrimServer.size() : 1;
+     for (int i = 0; i < nbSrvPools; ++i)
+     {
+       CContextClient* contextClientTmp = (hasServer) ? clientPrimServer[i] : client;
+       CEventClient event(getType(),EVENT_ID_CREATE_FILE_HEADER);
+
+       if (contextClientTmp->isServerLeader())
+       {
+         CMessage msg;
+         if (hasServer)
+           msg<<this->getIdServer(i);
+         else
+           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);
+     }
      // if (!hasServer)
      // {
@@ -964,17 +958,24 @@
    {
       // Use correct context client to send message
-     CContextClient* contextClientTmp = (0 != clientPrimServer) ? clientPrimServer : client;
-     CEventClient event(getType(),EVENT_ID_POST_PROCESS);
-
-     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)
+//     CContextClient* contextClientTmp = (0 != clientPrimServer) ? clientPrimServer : client;
+     int nbSrvPools = (hasServer) ? clientPrimServer.size() : 1;
+     for (int i = 0; i < nbSrvPools; ++i)
+     {
+       CContextClient* contextClientTmp = (hasServer) ? clientPrimServer[i] : client;
+       CEventClient event(getType(),EVENT_ID_POST_PROCESS);
+       if (contextClientTmp->isServerLeader())
+       {
+         CMessage msg;
+         if (hasServer)
+           msg<<this->getIdServer(i);
+         else
+           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);
+         contextClientTmp->sendEvent(event);
+       }
+       else contextClientTmp->sendEvent(event);
+     }
 
      // if (hasClient)
@@ -1038,4 +1039,13 @@
    }
 
+   const StdString& CContext::getIdServer(const int i)
+   {
+     idServer_ = this->getId();
+     idServer_ += "_server_";
+     idServer_ += boost::lexical_cast<string>(i);
+     return idServer_;
+   }
+
+
    /*!
    \brief Do some simple post processings after parsing xml file
@@ -1192,5 +1202,4 @@
      StdString fileDefRoot("file_definition");
      CFileGroup* cfgrpPtr = CFileGroup::get(fileDefRoot);
-
      for (int i = 0; i < size; ++i)
      {
@@ -1201,4 +1210,26 @@
    }
 
+   //! Client side: Send infomation of active files (files are enabled to write out)
+   void CContext::sendEnabledFiles(const int nbPools)
+   {
+     int size = this->enabledFiles.size();
+
+     // In a context, each type has a root definition, e.g: axis, domain, field.
+     // Every object must be a child of one of these root definition. In this case
+     // all new file objects created on server must be children of the root "file_definition"
+     StdString fileDefRoot("file_definition");
+     CFileGroup* cfgrpPtr = CFileGroup::get(fileDefRoot);
+
+     {
+       for (int i = 0; i < size; ++i)
+       {
+         int srvId = i % nbPools;
+         cfgrpPtr->sendCreateChild(this->enabledFiles[i]->getId(), srvId);
+         this->enabledFiles[i]->sendAllAttributesToServer(srvId);
+         this->enabledFiles[i]->sendAddAllVariables(srvId);
+       }
+     }
+   }
+
    //! Client side: Send information of active fields (ones are written onto files)
    void CContext::sendEnabledFields()
@@ -1208,4 +1239,14 @@
      {
        this->enabledFiles[i]->sendEnabledFields();
+     }
+   }
+
+   void CContext::sendEnabledFields(const int nbPools)
+   {
+     int size = this->enabledFiles.size();
+     for (int i = 0; i < size; ++i)
+     {
+       int srvId = i % nbPools;
+       this->enabledFiles[i]->sendEnabledFields(srvId);
      }
    }
@@ -1320,4 +1361,65 @@
    //! Client side: Send information of reference domain and axis of active fields
    void CContext::sendRefDomainsAxis()
+   {
+     std::set<StdString> domainIds, axisIds, scalarIds;
+
+     // Find all reference domain and axis of all active fields
+     int numEnabledFiles = this->enabledFiles.size();
+     for (int i = 0; i < numEnabledFiles; ++i)
+     {
+       std::vector<CField*> enabledFields = this->enabledFiles[i]->getEnabledFields();
+       int numEnabledFields = enabledFields.size();
+       for (int j = 0; j < numEnabledFields; ++j)
+       {
+         const std::vector<StdString>& prDomAxisScalarId = enabledFields[j]->getRefDomainAxisIds();
+         if ("" != prDomAxisScalarId[0]) domainIds.insert(prDomAxisScalarId[0]);
+         if ("" != prDomAxisScalarId[1]) axisIds.insert(prDomAxisScalarId[1]);
+         if ("" != prDomAxisScalarId[2]) scalarIds.insert(prDomAxisScalarId[2]);
+       }
+     }
+
+     // Create all reference axis on server side
+     std::set<StdString>::iterator itDom, itAxis, itScalar;
+     std::set<StdString>::const_iterator itE;
+
+     StdString scalarDefRoot("scalar_definition");
+     CScalarGroup* scalarPtr = CScalarGroup::get(scalarDefRoot);
+     itE = scalarIds.end();
+     for (itScalar = scalarIds.begin(); itScalar != itE; ++itScalar)
+     {
+       if (!itScalar->empty())
+       {
+         scalarPtr->sendCreateChild(*itScalar);
+         CScalar::get(*itScalar)->sendAllAttributesToServer();
+       }
+     }
+
+     StdString axiDefRoot("axis_definition");
+     CAxisGroup* axisPtr = CAxisGroup::get(axiDefRoot);
+     itE = axisIds.end();
+     for (itAxis = axisIds.begin(); itAxis != itE; ++itAxis)
+     {
+       if (!itAxis->empty())
+       {
+         axisPtr->sendCreateChild(*itAxis);
+         CAxis::get(*itAxis)->sendAllAttributesToServer();
+       }
+     }
+
+     // Create all reference domains on server side
+     StdString domDefRoot("domain_definition");
+     CDomainGroup* domPtr = CDomainGroup::get(domDefRoot);
+     itE = domainIds.end();
+     for (itDom = domainIds.begin(); itDom != itE; ++itDom)
+     {
+       if (!itDom->empty()) {
+          domPtr->sendCreateChild(*itDom);
+          CDomain::get(*itDom)->sendAllAttributesToServer();
+       }
+     }
+   }
+
+   //! Client side: Send information of reference domain and axis of active fields
+   void CContext::sendRefDomainsAxis(const int nbPools)
    {
      std::set<StdString> domainIds, axisIds, scalarIds;
@@ -1466,18 +1568,26 @@
     registryOut->hierarchicalGatherRegistry() ;
 
-          // Use correct context client to send message
-     CContextClient* contextClientTmp = (0 != clientPrimServer) ? clientPrimServer : client;
-    CEventClient event(CContext::GetType(), CContext::EVENT_ID_SEND_REGISTRY);
-          if (contextClientTmp->isServerLeader())
-      {
-         CMessage msg ;
-         msg<<this->getIdServer();
-         if (contextClientTmp->clientRank==0) msg<<*registryOut ;
-         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);
-         contextClientTmp->sendEvent(event);
-       }
-       else contextClientTmp->sendEvent(event);
+    // Use correct context client to send message
+//    CContextClient* contextClientTmp = (0 != clientPrimServer) ? clientPrimServer : client;
+    int nbSrvPools = (hasServer) ? clientPrimServer.size() : 1;
+    for (int i = 0; i < nbSrvPools; ++i)
+    {
+      CContextClient* contextClientTmp = (hasServer) ? clientPrimServer[i] : client;
+      CEventClient event(CContext::GetType(), CContext::EVENT_ID_SEND_REGISTRY);
+            if (contextClientTmp->isServerLeader())
+        {
+           CMessage msg ;
+           if (hasServer)
+             msg<<this->getIdServer(i);
+           else
+             msg<<this->getIdServer();
+           if (contextClientTmp->clientRank==0) msg<<*registryOut ;
+           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);
+           contextClientTmp->sendEvent(event);
+         }
+         else contextClientTmp->sendEvent(event);
+    }
 
     // if (!hasServer)
Index: XIOS/dev/dev_olga/src/node/context.hpp
===================================================================
--- XIOS/dev/dev_olga/src/node/context.hpp	(revision 992)
+++ XIOS/dev/dev_olga/src/node/context.hpp	(revision 1009)
@@ -133,6 +133,9 @@
          void sendCreateFileHeader(void);
          void sendEnabledFiles();
+         void sendEnabledFiles(const int nbPools);
          void sendEnabledFields();
+         void sendEnabledFields(const int nbPools);
          void sendRefDomainsAxis();
+         void sendRefDomainsAxis(const int nbPools);
          void sendRefGrid();
          void sendPostProcessing();
@@ -141,4 +144,5 @@
 
          const StdString& getIdServer();
+         const StdString& getIdServer(const int srvPoolNb);
 
          // Client side: Receive and process messages
@@ -227,6 +231,8 @@
 
          // Client-server pair in case of secondary server pool
-         CContextClient* clientPrimServer;
-         CContextServer* serverPrimServer;
+//         CContextClient* clientPrimServer;
+//         CContextServer* serverPrimServer;
+         std::vector<CContextClient*> clientPrimServer;
+         std::vector<CContextServer*> serverPrimServer;
 
       private:
Index: XIOS/dev/dev_olga/src/node/domain.cpp
===================================================================
--- XIOS/dev/dev_olga/src/node/domain.cpp	(revision 992)
+++ XIOS/dev/dev_olga/src/node/domain.cpp	(revision 1009)
@@ -1024,10 +1024,4 @@
      }
    }
-
-
-
-
-
-
 
    void CDomain::checkEligibilityForCompressedOutput(void)
@@ -1396,45 +1390,48 @@
     CContext* context = CContext::getCurrent();
      // Use correct context client to send message
-     CContextClient* contextClientTmp = (0 != context->clientPrimServer) ? context->clientPrimServer 
-                                                                         : context->client;
-
-    // CContextClient* client = context->client;
-    int nbServer = contextClientTmp->serverSize;
-
-    CServerDistributionDescription serverDescription(nGlobDomain_, nbServer);
-    if (isUnstructed_) serverDescription.computeServerDistribution(false, 0);
-    else serverDescription.computeServerDistribution(false, 1);
-
-    std::vector<std::vector<int> > serverIndexBegin = serverDescription.getServerIndexBegin();
-    std::vector<std::vector<int> > serverDimensionSizes = serverDescription.getServerDimensionSizes();
-
-    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 ibegin_srv = serverIndexBegin[*itRank][0];
-        const int jbegin_srv = serverIndexBegin[*itRank][1];
-        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 << isCompressible_;
-
-        event.push(*itRank,1,msg);
-      }
-      contextClientTmp->sendEvent(event);
-    }
-    else contextClientTmp->sendEvent(event);
+    int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
+    for (int i = 0; i < nbSrvPools; ++i)
+    {
+       CContextClient* contextClientTmp = (context->hasServer) ? context->clientPrimServer[i]
+                                                                           : context->client;
+      // CContextClient* client = context->client;
+      int nbServer = contextClientTmp->serverSize;
+
+      CServerDistributionDescription serverDescription(nGlobDomain_, nbServer);
+      if (isUnstructed_) serverDescription.computeServerDistribution(false, 0);
+      else serverDescription.computeServerDistribution(false, 1);
+
+      std::vector<std::vector<int> > serverIndexBegin = serverDescription.getServerIndexBegin();
+      std::vector<std::vector<int> > serverDimensionSizes = serverDescription.getServerDimensionSizes();
+
+      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 ibegin_srv = serverIndexBegin[*itRank][0];
+          const int jbegin_srv = serverIndexBegin[*itRank][1];
+          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 << isCompressible_;
+
+          event.push(*itRank,1,msg);
+        }
+        contextClientTmp->sendEvent(event);
+      }
+      else contextClientTmp->sendEvent(event);
+    }
   }
 
Index: XIOS/dev/dev_olga/src/node/field.cpp
===================================================================
--- XIOS/dev/dev_olga/src/node/field.cpp	(revision 992)
+++ XIOS/dev/dev_olga/src/node/field.cpp	(revision 1009)
@@ -123,5 +123,66 @@
     CContext* context = CContext::getCurrent();
 //    CContextClient* client = context->client;
-    CContextClient* client = (!context->hasServer) ? context->client : context->clientPrimServer;
+    int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
+    for (int i = 0; i < nbSrvPools; ++i)
+    {
+      CContextClient* client = (!context->hasServer) ? context->client : context->clientPrimServer[i];
+
+      CEventClient event(getType(), EVENT_ID_UPDATE_DATA);
+
+      map<int, CArray<int,1> >::iterator it;
+      list<CMessage> list_msg;
+      list<CArray<double,1> > list_data;
+
+      if (!grid->doGridHaveDataDistributed())
+      {
+         if (client->isServerLeader())
+         {
+            for (it = grid->storeIndex_toSrv.begin(); it != grid->storeIndex_toSrv.end(); it++)
+            {
+              int rank = it->first;
+              CArray<int,1>& index = it->second;
+
+              list_msg.push_back(CMessage());
+              list_data.push_back(CArray<double,1>(index.numElements()));
+
+              CArray<double,1>& data_tmp = list_data.back();
+              for (int n = 0; n < data_tmp.numElements(); n++) data_tmp(n) = data(index(n));
+
+              list_msg.back() << getId() << data_tmp;
+              event.push(rank, 1, list_msg.back());
+            }
+            client->sendEvent(event);
+         }
+         else client->sendEvent(event);
+      }
+      else
+      {
+        for (it = grid->storeIndex_toSrv.begin(); it != grid->storeIndex_toSrv.end(); it++)
+        {
+          int rank = it->first;
+          CArray<int,1>& index = it->second;
+
+          list_msg.push_back(CMessage());
+          list_data.push_back(CArray<double,1>(index.numElements()));
+
+          CArray<double,1>& data_tmp = list_data.back();
+          for (int n = 0; n < data_tmp.numElements(); n++) data_tmp(n) = data(index(n));
+
+          list_msg.back() << getId() << data_tmp;
+          event.push(rank, grid->nbSenders[rank], list_msg.back());
+        }
+        client->sendEvent(event);
+      }
+    }
+
+    CTimer::get("XIOS Send Data").suspend();
+  }
+
+  void CField::sendUpdateData(const CArray<double,1>& data, const int srvPool)
+  {
+    CTimer::get("XIOS Send Data").resume();
+
+    CContext* context = CContext::getCurrent();
+    CContextClient* client = context->clientPrimServer[srvPool];
 
     CEventClient event(getType(), EVENT_ID_UPDATE_DATA);
@@ -150,5 +211,5 @@
           }
           client->sendEvent(event);
-       } 
+       }
        else client->sendEvent(event);
     }
@@ -171,5 +232,4 @@
       client->sendEvent(event);
     }
-
     CTimer::get("XIOS Send Data").suspend();
   }
@@ -248,8 +308,24 @@
 //      else
         this->outputField(fieldData);
-      sendUpdateData(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, 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();
     }
@@ -1249,4 +1325,18 @@
    }
 
+   void CField::sendAddAllVariables(const int srvPool)
+   {
+     std::vector<CVariable*> allVar = getAllVariables();
+     std::vector<CVariable*>::const_iterator it = allVar.begin();
+     std::vector<CVariable*>::const_iterator itE = allVar.end();
+
+     for (; it != itE; ++it)
+     {
+       this->sendAddVariable((*it)->getId());
+       (*it)->sendAllAttributesToServer(srvPool);
+       (*it)->sendValue(srvPool);
+     }
+   }
+
    void CField::sendAddVariable(const string& id)
    {
Index: XIOS/dev/dev_olga/src/node/field.hpp
===================================================================
--- XIOS/dev/dev_olga/src/node/field.hpp	(revision 992)
+++ XIOS/dev/dev_olga/src/node/field.hpp	(revision 1009)
@@ -139,4 +139,5 @@
         static bool dispatchEvent(CEventServer& event);
         void sendUpdateData(const CArray<double,1>& data);
+        void sendUpdateData(const CArray<double,1>& data, const int srvPool);
         static void recvUpdateData(CEventServer& event);
         void recvUpdateData(vector<int>& ranks, vector<CBufferIn*>& buffers);
@@ -168,4 +169,5 @@
         CVariableGroup* addVariableGroup(const string& id = "");
         void sendAddVariable(const string& id = "");
+        void sendAddVariable(const string& id, const int srvPool);
         void sendAddVariableGroup(const string& id = "");
         static void recvAddVariable(CEventServer& event);
@@ -174,4 +176,5 @@
         void recvAddVariableGroup(CBufferIn& buffer);
         void sendAddAllVariables();
+        void sendAddAllVariables(const int srvPool);
 
 
Index: XIOS/dev/dev_olga/src/node/file.cpp
===================================================================
--- XIOS/dev/dev_olga/src/node/file.cpp	(revision 992)
+++ XIOS/dev/dev_olga/src/node/file.cpp	(revision 1009)
@@ -235,6 +235,8 @@
       const int recordOffset = record_offset.isEmpty() ? 0 : record_offset;
 
-      set<CAxis*> setAxis;
-      set<CDomain*> setDomains;
+//      set<CAxis*> setAxis;
+//      set<CDomain*> setDomains;
+      set<StdString> setAxis;
+      set<StdString> setDomains;
 
       std::vector<CField*>::iterator it, end = this->enabledFields.end();
@@ -245,8 +247,10 @@
          std::vector<CAxis*> vecAxis = field->grid->getAxis();
          for (size_t i = 0; i < vecAxis.size(); ++i)
-            setAxis.insert(vecAxis[i]);
+           setAxis.insert(vecAxis[i]->getAxisOutputName());
+//            setAxis.insert(vecAxis[i]);
          std::vector<CDomain*> vecDomains = field->grid->getDomains();
          for (size_t i = 0; i < vecDomains.size(); ++i)
-            setDomains.insert(vecDomains[i]);
+           setDomains.insert(vecDomains[i]->getDomainOutputName());
+//            setDomains.insert(vecDomains[i]);
 
          field->resetNStep(recordOffset);
@@ -849,4 +853,29 @@
    }
 
+   void CFile::sendAddField(const string& id, const int srvPool)
+   {
+      sendAddItem(id, EVENT_ID_ADD_FIELD, srvPool);
+    // CContext* context = CContext::getCurrent();
+
+    // if (! context->hasServer )
+    // {
+    //    CContextClient* client = context->client;
+
+    //    CEventClient event(this->getType(),EVENT_ID_ADD_FIELD);
+    //    if (client->isServerLeader())
+    //    {
+    //      CMessage msg;
+    //      msg << this->getId();
+    //      msg << id;
+    //      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);
+    // }
+
+   }
+
    /*!
    \brief Send a message to create a field group on server side
@@ -945,4 +974,46 @@
    }
 
+   void CFile::sendAddAllVariables(const int srvPool)
+   {
+     std::vector<CVariable*> allVar = getAllVariables();
+     std::vector<CVariable*>::const_iterator it = allVar.begin();
+     std::vector<CVariable*>::const_iterator itE = allVar.end();
+
+     for (; it != itE; ++it)
+     {
+       this->sendAddVariable((*it)->getId(), srvPool);
+       (*it)->sendAllAttributesToServer(srvPool);
+       (*it)->sendValue(srvPool);
+     }
+   }
+
+   /*!
+   \brief Send a message to create a variable group on server side
+   \param[in] id String identity of variable group that will be created on server
+   */
+   void CFile::sendAddVariableGroup(const string& id)
+   {
+      sendAddItem(id, (int)EVENT_ID_ADD_VARIABLE_GROUP);
+    // CContext* context = CContext::getCurrent();
+    // if (! context->hasServer )
+    // {
+    //    CContextClient* client = context->client;
+
+    //    CEventClient event(this->getType(),EVENT_ID_ADD_VARIABLE_GROUP);
+    //    if (client->isServerLeader())
+    //    {
+    //      CMessage msg;
+    //      msg << this->getId();
+    //      msg << id;
+    //      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);
+    // }
+
+   }
+
    /*!
    \brief Send a message to create a variable on server side
@@ -975,17 +1046,14 @@
    }
 
-   /*!
-   \brief Send a message to create a variable group on server side
-   \param[in] id String identity of variable group that will be created on server
-   */
-   void CFile::sendAddVariableGroup(const string& id)
-   {
-      sendAddItem(id, (int)EVENT_ID_ADD_VARIABLE_GROUP);
+   void CFile::sendAddVariable(const string& id, const int srvPool)
+   {
+      sendAddItem(id, (int)EVENT_ID_ADD_VARIABLE, srvPool);
     // CContext* context = CContext::getCurrent();
+
     // if (! context->hasServer )
     // {
     //    CContextClient* client = context->client;
 
-    //    CEventClient event(this->getType(),EVENT_ID_ADD_VARIABLE_GROUP);
+    //    CEventClient event(this->getType(),EVENT_ID_ADD_VARIABLE);
     //    if (client->isServerLeader())
     //    {
@@ -1070,4 +1138,16 @@
    }
 
+   void CFile::sendEnabledFields(const int srvPool)
+   {
+     size_t size = this->enabledFields.size();
+     for (size_t i = 0; i < size; ++i)
+     {
+       CField* field = this->enabledFields[i];
+       this->sendAddField(field->getId(), srvPool);
+       field->sendAllAttributesToServer(srvPool);
+       field->sendAddAllVariables(srvPool);
+     }
+   }
+
    /*!
    \brief Dispatch event received from client
Index: XIOS/dev/dev_olga/src/node/file.hpp
===================================================================
--- XIOS/dev/dev_olga/src/node/file.hpp	(revision 992)
+++ XIOS/dev/dev_olga/src/node/file.hpp	(revision 1009)
@@ -117,8 +117,12 @@
          // Send info to server
          void sendEnabledFields();
+         void sendEnabledFields(const int srvPool);
          void sendAddField(const string& id = "");
+         void sendAddField(const string& id, const int srvPool);
          void sendAddFieldGroup(const string& id = "");
          void sendAddAllVariables();
+         void sendAddAllVariables(const int srvPool);
          void sendAddVariable(const string& id = "");
+         void sendAddVariable(const string& id, const int srvPool);
          void sendAddVariableGroup(const string& id = "");
 
Index: XIOS/dev/dev_olga/src/node/grid.cpp
===================================================================
--- XIOS/dev/dev_olga/src/node/grid.cpp	(revision 992)
+++ XIOS/dev/dev_olga/src/node/grid.cpp	(revision 1009)
@@ -273,37 +273,49 @@
    {
      CContext* context = CContext::getCurrent();
-     CContextClient* client= context->hasServer ? context->clientPrimServer : context->client;
-
-     if (isScalarGrid())
+     CContextClient* client;
+
+     int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
+     for (int i = 0; i < nbSrvPools; ++i)
      {
+       if (context->hasClient)
+       {
+         if (context->hasServer)
+           client = context->clientPrimServer[i];
+         else
+           client = context->client;
+       }
+
+       if (isScalarGrid())
+       {
+         if (context->hasClient && !context->hasServer)
+  //         if (context->hasClient)
+            if (this->isChecked && doSendingIndex && !isIndexSent) { sendIndexScalarGrid(); this->isIndexSent = true; }
+
+         if (this->isChecked) return;
+         if (context->hasClient && !context->hasServer)
+  //       if (context->hasClient)
+         {
+            this->computeIndexScalarGrid();
+         }
+
+         this->isChecked = true;
+         return;
+       }
+
        if (context->hasClient && !context->hasServer)
-//         if (context->hasClient)
-          if (this->isChecked && doSendingIndex && !isIndexSent) { sendIndexScalarGrid(); this->isIndexSent = true; }
+  //     if (context->hasClient)
+        if (this->isChecked && doSendingIndex && !isIndexSent) { sendIndex(); this->isIndexSent = true; }
 
        if (this->isChecked) return;
+
        if (context->hasClient && !context->hasServer)
-//       if (context->hasClient)
+  //     if (context->hasClient)
        {
-          this->computeIndexScalarGrid();
+          this->checkAttributesAfterTransformation();
+          this->checkMask();
+          this->computeIndex();
        }
-
        this->isChecked = true;
-       return;
      }
-
-     if (context->hasClient && !context->hasServer)
-//     if (context->hasClient)
-      if (this->isChecked && doSendingIndex && !isIndexSent) { sendIndex(); this->isIndexSent = true; }
-
-     if (this->isChecked) return;
-
-     if (context->hasClient && !context->hasServer)
-//     if (context->hasClient)
-     {
-        this->checkAttributesAfterTransformation();
-        this->checkMask();
-        this->computeIndex();
-     }
-     this->isChecked = true;
    }
 
@@ -502,76 +514,80 @@
      CContext* context = CContext::getCurrent();
 //     CContextClient* client = context->client;
-     CContextClient* client = (context->hasServer) ? context->clientPrimServer : context->client;
-
-
-     // First of all, compute distribution on client side
-     if (0 != serverDistribution_)
-       clientDistribution_ = new CDistributionClient(client->clientRank, serverDistribution_->getGlobalLocalIndex());
-     else
-       clientDistribution_ = new CDistributionClient(client->clientRank, this);
-
-     // Get local data index on client
-     int tmp = clientDistribution_->getLocalDataIndexOnClient().size();
-     storeIndex_client.resize(clientDistribution_->getLocalDataIndexOnClient().size());
-     int nbStoreIndex = storeIndex_client.numElements();
-     for (int idx = 0; idx < nbStoreIndex; ++idx) storeIndex_client(idx) = (clientDistribution_->getLocalDataIndexOnClient())[idx];
-     isDataDistributed_= clientDistribution_->isDataDistributed();
-
-     connectedServerRank_.clear();
-
-     if (!doGridHaveDataDistributed())
+     int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
+     for (int i = 0; i < nbSrvPools; ++i)
      {
-        if (client->isServerLeader())
-        {
-          size_t ssize = clientDistribution_->getLocalDataIndexOnClient().size();
-          const std::list<int>& ranks = client->getRanksServerLeader();
-          for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
+       CContextClient* client = (context->hasServer) ? context->clientPrimServer[i] : context->client;
+
+
+       // First of all, compute distribution on client side
+       if (0 != serverDistribution_)
+         clientDistribution_ = new CDistributionClient(client->clientRank, serverDistribution_->getGlobalLocalIndex());
+       else
+         clientDistribution_ = new CDistributionClient(client->clientRank, this);
+
+       // Get local data index on client
+       int tmp = clientDistribution_->getLocalDataIndexOnClient().size();
+       storeIndex_client.resize(clientDistribution_->getLocalDataIndexOnClient().size());
+       int nbStoreIndex = storeIndex_client.numElements();
+       for (int idx = 0; idx < nbStoreIndex; ++idx) storeIndex_client(idx) = (clientDistribution_->getLocalDataIndexOnClient())[idx];
+       isDataDistributed_= clientDistribution_->isDataDistributed();
+
+       connectedServerRank_.clear();
+
+       if (!doGridHaveDataDistributed())
+       {
+          if (client->isServerLeader())
           {
-            connectedServerRank_.push_back(*itRank);
-            connectedDataSize_[*itRank] = ssize;
+            size_t ssize = clientDistribution_->getLocalDataIndexOnClient().size();
+            const std::list<int>& ranks = client->getRanksServerLeader();
+            for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
+            {
+              connectedServerRank_.push_back(*itRank);
+              connectedDataSize_[*itRank] = ssize;
+            }
           }
-        }
-        return;
+          return;
+       }
+
+       // Compute mapping between client and server
+       std::vector<boost::unordered_map<size_t,std::vector<int> > > indexServerOnElement;
+       CServerDistributionDescription serverDistributionDescription(globalDim_, client->serverSize);
+       serverDistributionDescription.computeServerGlobalByElement(indexServerOnElement,
+                                                                  client->clientRank,
+                                                                  client->clientSize,
+                                                                  axis_domain_order,
+                                                                  positionDimensionDistributed_);
+       computeIndexByElement(indexServerOnElement, globalIndexOnServer_);
+
+       const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = clientDistribution_->getGlobalLocalDataSendToServer();
+       CDistributionClient::GlobalLocalDataMap::const_iterator iteGlobalLocalIndexMap = globalLocalIndexSendToServer.end(), itGlobalLocalIndexMap;
+       CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itbGlobalMap, itGlobalMap;
+       itGlobalMap  = itbGlobalMap = globalIndexOnServer_.begin();
+       iteGlobalMap = globalIndexOnServer_.end();
+
+       for (; itGlobalMap != iteGlobalMap; ++itGlobalMap)
+       {
+         int serverRank = itGlobalMap->first;
+         int indexSize = itGlobalMap->second.size();
+         const std::vector<size_t>& indexVec = itGlobalMap->second;
+         for (int idx = 0; idx < indexSize; ++idx)
+         {
+            itGlobalLocalIndexMap = globalLocalIndexSendToServer.find(indexVec[idx]);
+            if (iteGlobalLocalIndexMap != itGlobalLocalIndexMap)
+            {
+               if (connectedDataSize_.end() == connectedDataSize_.find(serverRank))
+                 connectedDataSize_[serverRank] = 1;
+               else
+                 ++connectedDataSize_[serverRank];
+            }
+         }
+       }
+
+       for (itGlobalMap = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap) {
+         connectedServerRank_.push_back(itGlobalMap->first);
+       }
+
+       nbSenders = clientServerMap_->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_);
      }
-
-     // Compute mapping between client and server
-     std::vector<boost::unordered_map<size_t,std::vector<int> > > indexServerOnElement;
-     CServerDistributionDescription serverDistributionDescription(globalDim_, client->serverSize);
-     serverDistributionDescription.computeServerGlobalByElement(indexServerOnElement,
-                                                                client->clientRank,
-                                                                client->clientSize,
-                                                                axis_domain_order,
-                                                                positionDimensionDistributed_);
-     computeIndexByElement(indexServerOnElement, globalIndexOnServer_);
-
-     const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = clientDistribution_->getGlobalLocalDataSendToServer();
-     CDistributionClient::GlobalLocalDataMap::const_iterator iteGlobalLocalIndexMap = globalLocalIndexSendToServer.end(), itGlobalLocalIndexMap;
-     CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itbGlobalMap, itGlobalMap;
-     itGlobalMap  = itbGlobalMap = globalIndexOnServer_.begin();
-     iteGlobalMap = globalIndexOnServer_.end();
-
-     for (; itGlobalMap != iteGlobalMap; ++itGlobalMap)
-     {
-       int serverRank = itGlobalMap->first;
-       int indexSize = itGlobalMap->second.size();
-       const std::vector<size_t>& indexVec = itGlobalMap->second;
-       for (int idx = 0; idx < indexSize; ++idx)
-       {
-          itGlobalLocalIndexMap = globalLocalIndexSendToServer.find(indexVec[idx]);
-          if (iteGlobalLocalIndexMap != itGlobalLocalIndexMap)
-          {
-             if (connectedDataSize_.end() == connectedDataSize_.find(serverRank))
-               connectedDataSize_[serverRank] = 1;
-             else
-               ++connectedDataSize_[serverRank];
-          }
-       }
-     }
-
-     for (itGlobalMap = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap) {
-       connectedServerRank_.push_back(itGlobalMap->first);
-     }
-
-     nbSenders = clientServerMap_->computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_);
    }
 
@@ -588,164 +604,168 @@
    {
      CContext* context = CContext::getCurrent();
-     CContextClient* client = context->hasServer ? context->clientPrimServer : context->client;
-     int serverSize = client->serverSize;
-     std::vector<CDomain*> domList = getDomains();
-     std::vector<CAxis*> axisList = getAxis();
-
-     // Some pre-calculations of global index on each element of current grid.
-     int nbElement = axis_domain_order.numElements();
-     std::vector<CArray<size_t,1> > globalIndexElement(nbElement);
-     int domainIdx = 0, axisIdx = 0, scalarIdx = 0;
-     std::vector<size_t> elementNGlobal(nbElement);
-     elementNGlobal[0] = 1;
-     size_t globalSize = 1;
-     for (int idx = 0; idx < nbElement; ++idx)
+     int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
+     for (int i = 0; i < nbSrvPools; ++i)
      {
-       elementNGlobal[idx] = globalSize;
-       size_t elementSize;
-       size_t elementGlobalSize = 1;
-       if (2 == axis_domain_order(idx)) // This is domain
+       CContextClient* client = context->hasServer ? context->clientPrimServer[i] : context->client;
+       int serverSize = client->serverSize;
+       std::vector<CDomain*> domList = getDomains();
+       std::vector<CAxis*> axisList = getAxis();
+
+       // Some pre-calculations of global index on each element of current grid.
+       int nbElement = axis_domain_order.numElements();
+       std::vector<CArray<size_t,1> > globalIndexElement(nbElement);
+       int domainIdx = 0, axisIdx = 0, scalarIdx = 0;
+       std::vector<size_t> elementNGlobal(nbElement);
+       elementNGlobal[0] = 1;
+       size_t globalSize = 1;
+       for (int idx = 0; idx < nbElement; ++idx)
        {
-         elementSize = domList[domainIdx]->i_index.numElements();
-         globalIndexElement[idx].resize(elementSize);
-         for (int jdx = 0; jdx < elementSize; ++jdx)
+         elementNGlobal[idx] = globalSize;
+         size_t elementSize;
+         size_t elementGlobalSize = 1;
+         if (2 == axis_domain_order(idx)) // This is domain
          {
-           globalIndexElement[idx](jdx) = (domList[domainIdx]->i_index)(jdx) + domList[domainIdx]->ni_glo * (domList[domainIdx]->j_index)(jdx);
+           elementSize = domList[domainIdx]->i_index.numElements();
+           globalIndexElement[idx].resize(elementSize);
+           for (int jdx = 0; jdx < elementSize; ++jdx)
+           {
+             globalIndexElement[idx](jdx) = (domList[domainIdx]->i_index)(jdx) + domList[domainIdx]->ni_glo * (domList[domainIdx]->j_index)(jdx);
+           }
+           elementGlobalSize = domList[domainIdx]->ni_glo.getValue() * domList[domainIdx]->nj_glo.getValue();
+           ++domainIdx;
          }
-         elementGlobalSize = domList[domainIdx]->ni_glo.getValue() * domList[domainIdx]->nj_glo.getValue();
-         ++domainIdx;
+         else if (1 == axis_domain_order(idx))  // This is axis
+         {
+           elementSize = axisList[axisIdx]->index.numElements();
+           globalIndexElement[idx].resize(elementSize);
+           for (int jdx = 0; jdx < elementSize; ++jdx)
+           {
+             globalIndexElement[idx](jdx) = (axisList[axisIdx]->index)(jdx);
+           }
+           elementGlobalSize = axisList[axisIdx]->n_glo.getValue();
+           ++axisIdx;
+         }
+         else  // Of course, this is scalar
+         {
+           globalIndexElement[idx].resize(1);
+           globalIndexElement[idx](0) = 0;
+           elementGlobalSize = 1;
+         }
+         globalSize *= elementGlobalSize;
        }
-       else if (1 == axis_domain_order(idx))  // This is axis
+
+       std::vector<std::vector<bool> > elementOnServer(nbElement, std::vector<bool>(serverSize, false));
+       std::vector<boost::unordered_map<int,std::vector<size_t> > > globalElementIndexOnServer(nbElement);
+       CArray<int,1> nbIndexOnServer(serverSize); // Number of distributed global index held by each client for each server
+       // Number of temporary distributed global index held by each client for each server
+       // We have this variable for the case of non-distributed element (often axis) to check the duplicate server rank
+       CArray<int,1> nbIndexOnServerTmp(serverSize);
+       for (int idx = 0; idx < nbElement; ++idx)
        {
-         elementSize = axisList[axisIdx]->index.numElements();
-         globalIndexElement[idx].resize(elementSize);
-         for (int jdx = 0; jdx < elementSize; ++jdx)
+         nbIndexOnServer = 0;
+         const boost::unordered_map<size_t,std::vector<int> >& indexServerElement = indexServerOnElement[idx];
+         const CArray<size_t,1>& globalIndexElementOnClient = globalIndexElement[idx];
+         CClientClientDHTInt clientClientDHT(indexServerElement, client->intraComm);
+         clientClientDHT.computeIndexInfoMapping(globalIndexElementOnClient);
+         const CClientClientDHTInt::Index2VectorInfoTypeMap& globalIndexElementOnServerMap = clientClientDHT.getInfoIndexMap();
+         CClientClientDHTInt::Index2VectorInfoTypeMap::const_iterator itb = globalIndexElementOnServerMap.begin(),
+                                                                      ite = globalIndexElementOnServerMap.end(), it;
+         for (it = itb; it != ite; ++it)
          {
-           globalIndexElement[idx](jdx) = (axisList[axisIdx]->index)(jdx);
+           const std::vector<int>& tmp = it->second;
+           nbIndexOnServerTmp = 0;
+           for (int i = 0; i < tmp.size(); ++i)
+           {
+             if (0 == nbIndexOnServerTmp(tmp[i])) ++nbIndexOnServerTmp(tmp[i]);
+           }
+           nbIndexOnServer += nbIndexOnServerTmp;
          }
-         elementGlobalSize = axisList[axisIdx]->n_glo.getValue();
-         ++axisIdx;
-       }
-       else  // Of course, this is scalar
-       {
-         globalIndexElement[idx].resize(1);
-         globalIndexElement[idx](0) = 0;
-         elementGlobalSize = 1;
-       }
-       globalSize *= elementGlobalSize;
-     }
-
-     std::vector<std::vector<bool> > elementOnServer(nbElement, std::vector<bool>(serverSize, false));
-     std::vector<boost::unordered_map<int,std::vector<size_t> > > globalElementIndexOnServer(nbElement);
-     CArray<int,1> nbIndexOnServer(serverSize); // Number of distributed global index held by each client for each server
-     // Number of temporary distributed global index held by each client for each server
-     // We have this variable for the case of non-distributed element (often axis) to check the duplicate server rank
-     CArray<int,1> nbIndexOnServerTmp(serverSize);
-     for (int idx = 0; idx < nbElement; ++idx)
-     {
-       nbIndexOnServer = 0;
-       const boost::unordered_map<size_t,std::vector<int> >& indexServerElement = indexServerOnElement[idx];
-       const CArray<size_t,1>& globalIndexElementOnClient = globalIndexElement[idx];
-       CClientClientDHTInt clientClientDHT(indexServerElement, client->intraComm);
-       clientClientDHT.computeIndexInfoMapping(globalIndexElementOnClient);
-       const CClientClientDHTInt::Index2VectorInfoTypeMap& globalIndexElementOnServerMap = clientClientDHT.getInfoIndexMap();
-       CClientClientDHTInt::Index2VectorInfoTypeMap::const_iterator itb = globalIndexElementOnServerMap.begin(),
-                                                                    ite = globalIndexElementOnServerMap.end(), it;
-       for (it = itb; it != ite; ++it)
-       {
-         const std::vector<int>& tmp = it->second;
-         nbIndexOnServerTmp = 0;
-         for (int i = 0; i < tmp.size(); ++i)
+
+         for (int i = 0; i < serverSize; ++i)
          {
-           if (0 == nbIndexOnServerTmp(tmp[i])) ++nbIndexOnServerTmp(tmp[i]);
+           if (0 != nbIndexOnServer(i))
+           {
+             globalElementIndexOnServer[idx][i].resize(nbIndexOnServer(i));
+             elementOnServer[idx][i] = true;
+           }
          }
-         nbIndexOnServer += nbIndexOnServerTmp;
-       }
-
-       for (int i = 0; i < serverSize; ++i)
-       {
-         if (0 != nbIndexOnServer(i))
+
+         nbIndexOnServer = 0;
+         for (it = itb; it != ite; ++it)
          {
-           globalElementIndexOnServer[idx][i].resize(nbIndexOnServer(i));
-           elementOnServer[idx][i] = true;
+           const std::vector<int>& tmp = it->second;
+           nbIndexOnServerTmp = 0;
+           for (int i = 0; i < tmp.size(); ++i)
+           {
+             if (0 == nbIndexOnServerTmp(tmp[i]))
+             {
+               globalElementIndexOnServer[idx][tmp[i]][nbIndexOnServer(tmp[i])] = it->first;
+               ++nbIndexOnServerTmp(tmp[i]);
+             }
+           }
+           nbIndexOnServer += nbIndexOnServerTmp;
          }
        }
 
-       nbIndexOnServer = 0;
-       for (it = itb; it != ite; ++it)
-       {
-         const std::vector<int>& tmp = it->second;
-         nbIndexOnServerTmp = 0;
-         for (int i = 0; i < tmp.size(); ++i)
-         {
-           if (0 == nbIndexOnServerTmp(tmp[i]))
-           {
-             globalElementIndexOnServer[idx][tmp[i]][nbIndexOnServer(tmp[i])] = it->first;
-             ++nbIndexOnServerTmp(tmp[i]);
-           }
-         }
-         nbIndexOnServer += nbIndexOnServerTmp;
-       }
+      // Determine server which contain global source index
+      std::vector<bool> intersectedProc(serverSize, true);
+      for (int idx = 0; idx < nbElement; ++idx)
+      {
+        std::transform(elementOnServer[idx].begin(), elementOnServer[idx].end(),
+                       intersectedProc.begin(), intersectedProc.begin(),
+                       std::logical_and<bool>());
+      }
+
+      std::vector<int> srcRank;
+      for (int idx = 0; idx < serverSize; ++idx)
+      {
+        if (intersectedProc[idx]) srcRank.push_back(idx);
+      }
+
+      // Compute the global index of grid from global index of each element.
+      for (int i = 0; i < srcRank.size(); ++i)
+      {
+        size_t ssize = 1;
+        int rankSrc = srcRank[i];
+        std::vector<std::vector<size_t>* > globalIndexOfElementTmp(nbElement);
+        std::vector<size_t> currentIndex(nbElement,0);
+        for (int idx = 0; idx < nbElement; ++idx)
+        {
+          ssize *= (globalElementIndexOnServer[idx][rankSrc]).size();
+          globalIndexOfElementTmp[idx] = &(globalElementIndexOnServer[idx][rankSrc]);
+        }
+        globalIndexOnServer[rankSrc].resize(ssize);
+
+        std::vector<int> idxLoop(nbElement,0);
+        int innnerLoopSize = (globalIndexOfElementTmp[0])->size();
+        size_t idx = 0;
+        while (idx < ssize)
+        {
+          for (int ind = 0; ind < nbElement; ++ind)
+          {
+            if (idxLoop[ind] == (globalIndexOfElementTmp[ind])->size())
+            {
+              idxLoop[ind] = 0;
+              ++idxLoop[ind+1];
+            }
+
+            currentIndex[ind] = (*(globalIndexOfElementTmp[ind]))[idxLoop[ind]];
+          }
+
+          for (int ind = 0; ind < innnerLoopSize; ++ind)
+          {
+            currentIndex[0] = (*globalIndexOfElementTmp[0])[ind];
+            size_t globalSrcIndex = 0;
+            for (int idxElement = 0; idxElement < nbElement; ++idxElement)
+            {
+              globalSrcIndex += currentIndex[idxElement] * elementNGlobal[idxElement];
+            }
+            globalIndexOnServer[rankSrc][idx] = globalSrcIndex;
+            ++idx;
+            ++idxLoop[0];
+          }
+        }
+      }
      }
-
-    // Determine server which contain global source index
-    std::vector<bool> intersectedProc(serverSize, true);
-    for (int idx = 0; idx < nbElement; ++idx)
-    {
-      std::transform(elementOnServer[idx].begin(), elementOnServer[idx].end(),
-                     intersectedProc.begin(), intersectedProc.begin(),
-                     std::logical_and<bool>());
-    }
-
-    std::vector<int> srcRank;
-    for (int idx = 0; idx < serverSize; ++idx)
-    {
-      if (intersectedProc[idx]) srcRank.push_back(idx);
-    }
-
-    // Compute the global index of grid from global index of each element.
-    for (int i = 0; i < srcRank.size(); ++i)
-    {
-      size_t ssize = 1;
-      int rankSrc = srcRank[i];
-      std::vector<std::vector<size_t>* > globalIndexOfElementTmp(nbElement);
-      std::vector<size_t> currentIndex(nbElement,0);
-      for (int idx = 0; idx < nbElement; ++idx)
-      {
-        ssize *= (globalElementIndexOnServer[idx][rankSrc]).size();
-        globalIndexOfElementTmp[idx] = &(globalElementIndexOnServer[idx][rankSrc]);
-      }
-      globalIndexOnServer[rankSrc].resize(ssize);
-
-      std::vector<int> idxLoop(nbElement,0);
-      int innnerLoopSize = (globalIndexOfElementTmp[0])->size();
-      size_t idx = 0;
-      while (idx < ssize)
-      {
-        for (int ind = 0; ind < nbElement; ++ind)
-        {
-          if (idxLoop[ind] == (globalIndexOfElementTmp[ind])->size())
-          {
-            idxLoop[ind] = 0;
-            ++idxLoop[ind+1];
-          }
-
-          currentIndex[ind] = (*(globalIndexOfElementTmp[ind]))[idxLoop[ind]];
-        }
-
-        for (int ind = 0; ind < innnerLoopSize; ++ind)
-        {
-          currentIndex[0] = (*globalIndexOfElementTmp[0])[ind];
-          size_t globalSrcIndex = 0;
-          for (int idxElement = 0; idxElement < nbElement; ++idxElement)
-          {
-            globalSrcIndex += currentIndex[idxElement] * elementNGlobal[idxElement];
-          }
-          globalIndexOnServer[rankSrc][idx] = globalSrcIndex;
-          ++idx;
-          ++idxLoop[0];
-        }
-      }
-    }
    }
    //----------------------------------------------------------------
@@ -986,21 +1006,25 @@
   {
     CContext* context = CContext::getCurrent();
-    CContextClient* client = context->hasServer ? context->clientPrimServer : context->client;
-
-    storeIndex_client.resize(1);
-    storeIndex_client(0) = 0;
-
-    connectedServerRank_.clear();
-
-    if (0 == client->clientRank)
-    {
-      for (int rank = 0; rank < client->serverSize; ++rank)
-      {
-        connectedServerRank_.push_back(rank);
-        connectedDataSize_[rank] = 1;
-        nbSenders[rank] = 1;
-      }
-    }
-    isDataDistributed_ = false;
+    int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
+    for (int i = 0; i < nbSrvPools; ++i)
+    {
+      CContextClient* client = context->hasServer ? context->clientPrimServer[i] : context->client;
+
+      storeIndex_client.resize(1);
+      storeIndex_client(0) = 0;
+
+      connectedServerRank_.clear();
+
+      if (0 == client->clientRank)
+      {
+        for (int rank = 0; rank < client->serverSize; ++rank)
+        {
+          connectedServerRank_.push_back(rank);
+          connectedDataSize_[rank] = 1;
+          nbSenders[rank] = 1;
+        }
+      }
+      isDataDistributed_ = false;
+    }
   }
 
@@ -1042,134 +1066,143 @@
   {
     CContext* context = CContext::getCurrent();
-    CContextClient* client = context->hasServer ? context->clientPrimServer : context->client;
-
-    CEventClient event(getType(), EVENT_ID_INDEX);
-    list<CMessage> listMsg;
-    list<CArray<size_t,1> > listOutIndex;
-
-    if (client->isServerLeader())
-    {
-      const std::list<int>& ranks = client->getRanksServerLeader();
-      for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
-      {
-        int rank = *itRank;
-        int nb = 1;
-        storeIndex_toSrv.insert(std::make_pair(rank, CArray<int,1>(nb)));
-        listOutIndex.push_back(CArray<size_t,1>(nb));
-
-        CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv[rank];
-        CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back();
-
-        for (int k = 0; k < nb; ++k)
-        {
-          outGlobalIndexOnServer(k) = 0;
-          outLocalIndexToServer(k)  = 0;
-        }
-
-        listMsg.push_back(CMessage());
-        listMsg.back() << getId( )<< isDataDistributed_ << isCompressible_ << listOutIndex.back();
-
-        event.push(rank, 1, listMsg.back());
-      }
-      client->sendEvent(event);
-    }
-    else
-      client->sendEvent(event);
-  }
-
-  void CGrid::sendIndex(void)
-  {
-    CContext* context = CContext::getCurrent();
-//    CContextClient* client = context->client;
-    CContextClient* client = context->hasServer ? context->clientPrimServer : context->client ;
-
-    CEventClient event(getType(), EVENT_ID_INDEX);
-    int rank;
-    list<CMessage> listMsg;
-    list<CArray<size_t,1> > listOutIndex;
-    const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = clientDistribution_->getGlobalLocalDataSendToServer();
-    CDistributionClient::GlobalLocalDataMap::const_iterator itIndex = globalLocalIndexSendToServer.begin(),
-                                                           iteIndex = globalLocalIndexSendToServer.end();
-
-    if (!doGridHaveDataDistributed())
-    {
+    int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
+    for (int i = 0; i < nbSrvPools; ++i)
+    {
+      CContextClient* client = context->hasServer ? context->clientPrimServer[i] : context->client;
+
+      CEventClient event(getType(), EVENT_ID_INDEX);
+      list<CMessage> listMsg;
+      list<CArray<size_t,1> > listOutIndex;
+
       if (client->isServerLeader())
       {
-        int indexSize = globalLocalIndexSendToServer.size();
-        CArray<size_t,1> outGlobalIndexOnServer(indexSize);
-        CArray<int,1> outLocalIndexToServer(indexSize);
-        for (int idx = 0; itIndex != iteIndex; ++itIndex, ++idx)
-        {
-          outGlobalIndexOnServer(idx) = itIndex->first;
-          outLocalIndexToServer(idx) = itIndex->second;
-        }
-
-        //int nbClient = client->clientSize; // This stupid variable signals the servers the number of client connect to them
         const std::list<int>& ranks = client->getRanksServerLeader();
         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
         {
-          storeIndex_toSrv.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer)));
-          listOutIndex.push_back(CArray<size_t,1>(outGlobalIndexOnServer));
+          int rank = *itRank;
+          int nb = 1;
+          storeIndex_toSrv.insert(std::make_pair(rank, CArray<int,1>(nb)));
+          listOutIndex.push_back(CArray<size_t,1>(nb));
+
+          CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv[rank];
+          CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back();
+
+          for (int k = 0; k < nb; ++k)
+          {
+            outGlobalIndexOnServer(k) = 0;
+            outLocalIndexToServer(k)  = 0;
+          }
+
+          listMsg.push_back(CMessage());
+          listMsg.back() << getId( )<< isDataDistributed_ << isCompressible_ << listOutIndex.back();
+
+          event.push(rank, 1, listMsg.back());
+        }
+        client->sendEvent(event);
+      }
+      else
+        client->sendEvent(event);
+    }
+  }
+
+  void CGrid::sendIndex(void)
+  {
+    CContext* context = CContext::getCurrent();
+//    CContextClient* client = context->client;
+    int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
+    for (int i = 0; i < nbSrvPools; ++i)
+    {
+      CContextClient* client = context->hasServer ? context->clientPrimServer[i] : context->client ;
+
+      CEventClient event(getType(), EVENT_ID_INDEX);
+      int rank;
+      list<CMessage> listMsg;
+      list<CArray<size_t,1> > listOutIndex;
+      const CDistributionClient::GlobalLocalDataMap& globalLocalIndexSendToServer = clientDistribution_->getGlobalLocalDataSendToServer();
+      CDistributionClient::GlobalLocalDataMap::const_iterator itIndex = globalLocalIndexSendToServer.begin(),
+                                                             iteIndex = globalLocalIndexSendToServer.end();
+
+      if (!doGridHaveDataDistributed())
+      {
+        if (client->isServerLeader())
+        {
+          int indexSize = globalLocalIndexSendToServer.size();
+          CArray<size_t,1> outGlobalIndexOnServer(indexSize);
+          CArray<int,1> outLocalIndexToServer(indexSize);
+          for (int idx = 0; itIndex != iteIndex; ++itIndex, ++idx)
+          {
+            outGlobalIndexOnServer(idx) = itIndex->first;
+            outLocalIndexToServer(idx) = itIndex->second;
+          }
+
+          //int nbClient = client->clientSize; // This stupid variable signals the servers the number of client connect to them
+          const std::list<int>& ranks = client->getRanksServerLeader();
+          for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
+          {
+            storeIndex_toSrv.insert(std::make_pair(*itRank, CArray<int,1>(outLocalIndexToServer)));
+            listOutIndex.push_back(CArray<size_t,1>(outGlobalIndexOnServer));
+
+            listMsg.push_back(CMessage());
+            listMsg.back() << getId() << isDataDistributed_ << isCompressible_ << listOutIndex.back();
+
+            event.push(*itRank, 1, listMsg.back());
+          }
+          client->sendEvent(event);
+        }
+        else
+          client->sendEvent(event);
+      }
+      else
+      {
+        CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itGlobalMap;
+        itGlobalMap = globalIndexOnServer_.begin();
+        iteGlobalMap = globalIndexOnServer_.end();
+
+        std::map<int,std::vector<int> >localIndexTmp;
+        std::map<int,std::vector<size_t> > globalIndexTmp;
+        for (; itGlobalMap != iteGlobalMap; ++itGlobalMap)
+        {
+          int serverRank = itGlobalMap->first;
+          int indexSize = itGlobalMap->second.size();
+          const std::vector<size_t>& indexVec = itGlobalMap->second;
+          for (int idx = 0; idx < indexSize; ++idx)
+          {
+            itIndex = globalLocalIndexSendToServer.find(indexVec[idx]);
+            if (iteIndex != itIndex)
+            {
+              globalIndexTmp[serverRank].push_back(itIndex->first);
+              localIndexTmp[serverRank].push_back(itIndex->second);
+            }
+          }
+        }
+
+//        for (int ns = 0; ns < connectedServerRank_.size(); ++ns)
+        for (int ns = 0; ns < client->serverSize; ++ns)
+        {
+          rank = connectedServerRank_[ns];
+          int nb = 0;
+          if (globalIndexTmp.end() != globalIndexTmp.find(rank))
+            nb = globalIndexTmp[rank].size();
+
+          storeIndex_toSrv.insert(make_pair(rank, CArray<int,1>(nb)));
+          listOutIndex.push_back(CArray<size_t,1>(nb));
+
+          CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv[rank];
+          CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back();
+
+          for (int k = 0; k < nb; ++k)
+          {
+            outGlobalIndexOnServer(k) = globalIndexTmp[rank].at(k);
+            outLocalIndexToServer(k)  = localIndexTmp[rank].at(k);
+          }
 
           listMsg.push_back(CMessage());
           listMsg.back() << getId() << isDataDistributed_ << isCompressible_ << listOutIndex.back();
 
-          event.push(*itRank, 1, listMsg.back());
-        }
+          event.push(rank, nbSenders[rank], listMsg.back());
+        }
+
         client->sendEvent(event);
       }
-      else
-        client->sendEvent(event);
-    }
-    else
-    {
-      CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itGlobalMap;
-      itGlobalMap = globalIndexOnServer_.begin();
-      iteGlobalMap = globalIndexOnServer_.end();
-
-      std::map<int,std::vector<int> >localIndexTmp;
-      std::map<int,std::vector<size_t> > globalIndexTmp;
-      for (; itGlobalMap != iteGlobalMap; ++itGlobalMap)
-      {
-        int serverRank = itGlobalMap->first;
-        int indexSize = itGlobalMap->second.size();
-        const std::vector<size_t>& indexVec = itGlobalMap->second;
-        for (int idx = 0; idx < indexSize; ++idx)
-        {
-          itIndex = globalLocalIndexSendToServer.find(indexVec[idx]);
-          if (iteIndex != itIndex)
-          {
-            globalIndexTmp[serverRank].push_back(itIndex->first);
-            localIndexTmp[serverRank].push_back(itIndex->second);
-          }
-        }
-      }
-
-      for (int ns = 0; ns < connectedServerRank_.size(); ++ns)
-      {
-        rank = connectedServerRank_[ns];
-        int nb = 0;
-        if (globalIndexTmp.end() != globalIndexTmp.find(rank))
-          nb = globalIndexTmp[rank].size();
-
-        storeIndex_toSrv.insert(make_pair(rank, CArray<int,1>(nb)));
-        listOutIndex.push_back(CArray<size_t,1>(nb));
-
-        CArray<int, 1>& outLocalIndexToServer = storeIndex_toSrv[rank];
-        CArray<size_t, 1>& outGlobalIndexOnServer = listOutIndex.back();
-
-        for (int k = 0; k < nb; ++k)
-        {
-          outGlobalIndexOnServer(k) = globalIndexTmp[rank].at(k);
-          outLocalIndexToServer(k)  = localIndexTmp[rank].at(k);
-        }
-
-        listMsg.push_back(CMessage());
-        listMsg.back() << getId() << isDataDistributed_ << isCompressible_ << listOutIndex.back();
-
-        event.push(rank, nbSenders[rank], listMsg.back());
-      }
-
-      client->sendEvent(event);
     }
   }
@@ -1202,6 +1235,8 @@
   {
     CContext* context = CContext::getCurrent();
-    CContextServer* server = (context->hasServer) ? context->server : context->serverPrimServer;
-    CContextClient* client = (context->hasServer) ? context->client : context->clientPrimServer;
+//    CContextServer* server = (context->hasServer) ? context->server : context->serverPrimServer;
+//    CContextClient* client = (context->hasServer) ? context->client : context->clientPrimServer;
+    CContextServer* server = context->server;
+    CContextClient* client = context->client;
     numberWrittenIndexes_ = totalNumberWrittenIndexes_ = offsetWrittenIndexes_ = 0;
     connectedServerRank_ = ranks;
Index: XIOS/dev/dev_olga/src/node/variable.cpp
===================================================================
--- XIOS/dev/dev_olga/src/node/variable.cpp	(revision 992)
+++ XIOS/dev/dev_olga/src/node/variable.cpp	(revision 1009)
@@ -85,22 +85,26 @@
      if (context->hasClient)
      {
-           // Use correct context client to send message
-       CContextClient* contextClientTmp = (0 != context->clientPrimServer) ? context->clientPrimServer 
-                                                                           : context->client;
-
-       CEventClient event(this->getType(),EVENT_ID_VARIABLE_VALUE) ;
-       if (contextClientTmp->isServerLeader())
+       // Use correct context client to send message
+       int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
+       for (int i = 0; i < nbSrvPools; ++i)
        {
-         CMessage msg ;
-         msg<<this->getId() ;
-         msg<<content ;
-         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) ;
-    }
-
+//       CContextClient* contextClientTmp = (0 != context->clientPrimServer) ? context->clientPrimServer
+         CContextClient* contextClientTmp = (context->hasServer) ? context->clientPrimServer[i]
+                                                                             : context->client;
+
+         CEventClient event(this->getType(),EVENT_ID_VARIABLE_VALUE) ;
+         if (contextClientTmp->isServerLeader())
+         {
+           CMessage msg ;
+           msg<<this->getId() ;
+           msg<<content ;
+           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) ;
+      }
+     }
 
     //  if (!context->hasServer)
@@ -123,4 +127,22 @@
    }
 
+   void CVariable::sendValue(const int srvPool)
+   {
+     CContext* context=CContext::getCurrent() ;
+     CContextClient* contextClientTmp = context->clientPrimServer[srvPool];
+     CEventClient event(this->getType(),EVENT_ID_VARIABLE_VALUE) ;
+     if (contextClientTmp->isServerLeader())
+     {
+       CMessage msg ;
+       msg<<this->getId() ;
+       msg<<content ;
+       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) ;
+   }
+
    /*
    *\brief Receive value of a variable with its id from client to server
Index: XIOS/dev/dev_olga/src/node/variable.hpp
===================================================================
--- XIOS/dev/dev_olga/src/node/variable.hpp	(revision 992)
+++ XIOS/dev/dev_olga/src/node/variable.hpp	(revision 1009)
@@ -79,4 +79,5 @@
             //! Sending a request to set up variable data
             void sendValue();
+            void sendValue(const int srvPool);
 
             static void recvValue(CEventServer& event) ;
Index: XIOS/dev/dev_olga/src/object_template.hpp
===================================================================
--- XIOS/dev/dev_olga/src/object_template.hpp	(revision 992)
+++ XIOS/dev/dev_olga/src/object_template.hpp	(revision 1009)
@@ -56,7 +56,11 @@
          std::map<int, size_t> getMinimumBufferSizeForAttributes();
          void sendAttributToServer(const string& id);
+         void sendAttributToServer(const string& id, const int srvPool);
          void sendAttributToServer(CAttribute& attr) ;
+         void sendAttributToServer(CAttribute& attr, const int srvPool) ;
          void sendAllAttributesToServer();
+         void sendAllAttributesToServer(const int srvPool);
          void sendAddItem(const string& id, int itemType);
+         void sendAddItem(const string& id, int itemType, const int srvPool);
          static void recvAttributFromClient(CEventServer& event) ;
          static bool dispatchEvent(CEventServer& event) ;
Index: XIOS/dev/dev_olga/src/object_template_impl.hpp
===================================================================
--- XIOS/dev/dev_olga/src/object_template_impl.hpp	(revision 992)
+++ XIOS/dev/dev_olga/src/object_template_impl.hpp	(revision 1009)
@@ -168,33 +168,37 @@
 
           // Use correct context client to send message
-     CContextClient* contextClientTmp = (0 != context->clientPrimServer) ? context->clientPrimServer : context->client;
-
-     std::map<int, size_t> minimumSizes;
-
-     if (contextClientTmp->isServerLeader())
+//     CContextClient* contextClientTmp = (0 != context->clientPrimServer) ? context->clientPrimServer : context->client;
+     int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
+     for (int i = 0; i < nbSrvPools; ++i)
      {
-       size_t minimumSize = 0;
-       CAttributeMap& attrMap = *this;
-       CAttributeMap::const_iterator it = attrMap.begin(), itE = attrMap.end();
-       for (; it != itE; ++it)
+       CContextClient* contextClientTmp = (context->hasServer) ? context->clientPrimServer[i] : context->client;
+
+       std::map<int, size_t> minimumSizes;
+
+       if (contextClientTmp->isServerLeader())
        {
-         if (!it->second->isEmpty())
+         size_t minimumSize = 0;
+         CAttributeMap& attrMap = *this;
+         CAttributeMap::const_iterator it = attrMap.begin(), itE = attrMap.end();
+         for (; it != itE; ++it)
          {
-           size_t size = it->second->getName().size() + sizeof(size_t) + it->second->size();
-           if (size > minimumSize)
-             minimumSize = size;
+           if (!it->second->isEmpty())
+           {
+             size_t size = it->second->getName().size() + sizeof(size_t) + it->second->size();
+             if (size > minimumSize)
+               minimumSize = size;
+           }
+         }
+
+         if (minimumSize)
+         {
+           // Account for extra header info
+           minimumSize += CEventClient::headerSize + getIdServer().size() + sizeof(size_t);
+
+           const std::list<int>& ranks = contextClientTmp->getRanksServerLeader();
+           for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
+             minimumSizes.insert(std::make_pair(*itRank, minimumSize));
          }
        }
-
-       if (minimumSize)
-       {
-         // Account for extra header info
-         minimumSize += CEventClient::headerSize + getIdServer().size() + sizeof(size_t);
-
-         const std::list<int>& ranks = contextClientTmp->getRanksServerLeader();
-         for (std::list<int>::const_iterator itRank = ranks.begin(), itRankEnd = ranks.end(); itRank != itRankEnd; ++itRank)
-           minimumSizes.insert(std::make_pair(*itRank, minimumSize));
-       }
-     }
 
      // if (client->isServerLeader())
@@ -224,5 +228,6 @@
      // }
 
-     return minimumSizes;
+       return minimumSizes;
+     }
    }
 
@@ -238,4 +243,15 @@
    }
 
+   template<typename T>
+   void CObjectTemplate<T>::sendAllAttributesToServer(const int srvPool)
+   {
+     CAttributeMap& attrMap = *this;
+     CAttributeMap::const_iterator it = attrMap.begin(), itE = attrMap.end();
+     for (; it != itE; ++it)
+     {
+       if (!(it->second)->isEmpty()) sendAttributToServer(*(it->second), srvPool);
+     }
+   }
+
    template <class T>
    void CObjectTemplate<T>::sendAttributToServer(const string& id)
@@ -244,4 +260,12 @@
       CAttribute* attr=attrMap[id];
       sendAttributToServer(*attr);
+   }
+
+   template <class T>
+   void CObjectTemplate<T>::sendAttributToServer(const string& id, const int srvPool)
+   {
+      CAttributeMap & attrMap = *this;
+      CAttribute* attr=attrMap[id];
+      sendAttributToServer(*attr, srvPool);
    }
 
@@ -252,27 +276,35 @@
 
      // Use correct context client to send message
-     CContextClient* contextClientTmp = (0 != context->clientPrimServer) ? context->clientPrimServer : context->client;
-
-    // if (!context->hasServer)
+//    CContextClient* contextClientTmp = (0 != context->clientPrimServer) ? context->clientPrimServer : context->client;
     if (context->hasClient)
     {
-       // CContextClient* contextClientTmp=context->contextClientTmp;
-
-       CEventClient event(getType(),EVENT_ID_SEND_ATTRIBUTE);
-       if (contextClientTmp->isServerLeader())
-       {
-         CMessage msg;
-//       msg << this->getId();
-         msg << this->getIdServer();
-         msg << attr.getName();
-         msg << attr;
-         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);
+      int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
+      for (int i = 0; i < nbSrvPools; ++i)
+      {
+        CContextClient* contextClientTmp = (context->hasServer) ? context->clientPrimServer[i] : context->client;
+        // CContextClient* contextClientTmp=context->contextClientTmp;
+
+        CEventClient event(getType(),EVENT_ID_SEND_ATTRIBUTE);
+        if (contextClientTmp->isServerLeader())
+        {
+          CMessage msg;
+//          if (context->hasServer)
+//          {
+//            StdString tmp = this->getIdServer() + "_" +boost::lexical_cast<string>(i);
+//            msg<<tmp;
+//          }
+//          else
+            msg<<this->getIdServer();
+
+          msg << attr.getName();
+          msg << attr;
+          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);
+      }
     }
-
 //     // if (!context->hasServer)
 //     if (context->hasClient)
@@ -298,4 +330,25 @@
   }
 
+  template <class T>
+  void CObjectTemplate<T>::sendAttributToServer(CAttribute& attr, const int srvPool)
+  {
+    CContext* context=CContext::getCurrent();
+    CContextClient* contextClientTmp = context->clientPrimServer[srvPool];
+    CEventClient event(getType(),EVENT_ID_SEND_ATTRIBUTE);
+    if (contextClientTmp->isServerLeader())
+    {
+      CMessage msg;
+      msg<<this->getIdServer();
+      msg << attr.getName();
+      msg << attr;
+      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);
+  }
+
+
   /*!
     This generic funtion only provides instance for sending, for receving, each 
@@ -312,18 +365,43 @@
     {
        // Use correct context client to send message
-       CContextClient* contextClientTmp = (0 != context->clientPrimServer) ? context->clientPrimServer : context->client;
-       CEventClient event(this->getType(),ItemType(itemType));
-       if (contextClientTmp->isServerLeader())
-       {
-         CMessage msg;
-         msg << this->getId();
-         msg << id;
-         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);
+//      CContextClient* contextClientTmp = (0 != context->clientPrimServer) ? context->clientPrimServer : context->client;
+      int nbSrvPools = (context->hasServer) ? context->clientPrimServer.size() : 1;
+      for (int i = 0; i < nbSrvPools; ++i)
+      {
+         CContextClient* contextClientTmp = (context->hasServer) ? context->clientPrimServer[i] : context->client;
+         CEventClient event(this->getType(),ItemType(itemType));
+         if (contextClientTmp->isServerLeader())
+         {
+           CMessage msg;
+           msg << this->getId();
+           msg << id;
+           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);
+      }
     }
+  }
+
+  template<class T>
+  void CObjectTemplate<T>::sendAddItem(const StdString& id, int itemType, const int srvPool)
+  {
+    CContext* context = CContext::getCurrent();
+    typedef typename T::EEventId ItemType;
+     CContextClient* contextClientTmp = context->clientPrimServer[srvPool];
+     CEventClient event(this->getType(),ItemType(itemType));
+     if (contextClientTmp->isServerLeader())
+     {
+       CMessage msg;
+       msg << this->getId();
+       msg << id;
+       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);
   }
 
Index: XIOS/dev/dev_olga/src/server.cpp
===================================================================
--- XIOS/dev/dev_olga/src/server.cpp	(revision 992)
+++ XIOS/dev/dev_olga/src/server.cpp	(revision 1009)
@@ -22,6 +22,9 @@
     list<MPI_Comm> CServer::interComm ;
     std::list<MPI_Comm> CServer::contextInterComms;
+    int CServer::nbSndSrvPools = (CXios::serverLevel == 0) ? 0 : 1;
+    int CServer::poolNb = 0;
     bool CServer::isRoot = false ;
     int CServer::rank = INVALID_RANK;
+    int CServer::rankSndServers = 0;
     StdOFStream CServer::m_infoStream;
     StdOFStream CServer::m_errorStream;
@@ -43,4 +46,5 @@
       else is_MPI_Initialized=false ;
 
+
       // Not using OASIS
       if (!CXios::usingOasis)
@@ -52,6 +56,4 @@
         }
         CTimer::get("XIOS").resume() ;
-
-        int nbSrvLevels = 2;
 
         boost::hash<string> hashString ;
@@ -61,4 +63,5 @@
 
         unsigned long* hashAll ;
+        unsigned long* hashAllServers ;
 
 //        int rank ;
@@ -66,14 +69,17 @@
         int myColor ;
         int i,c ;
-        MPI_Comm newComm ;
+        MPI_Comm newComm, serversInterComm;
 
         MPI_Comm_size(CXios::globalComm, &size) ;
         MPI_Comm_rank(CXios::globalComm, &rank);
+
         hashAll=new unsigned long[size] ;
         MPI_Allgather(&hashServer, 1, MPI_LONG, hashAll, 1, MPI_LONG, CXios::globalComm) ;
 
-        map<unsigned long, int> colors ;
+        map<unsigned long, int> colors, colorsServers ;
         map<unsigned long, int> leaders ;
         map<unsigned long, int>::iterator it ;
+//        map<unsigned long, int> leadersServers ;
+        vector<int> leadersServers;
 
         for(i=0,c=0;i<size;i++)
@@ -87,6 +93,73 @@
         }
 
-        myColor=colors[hashServer] ;
-        MPI_Comm_split(MPI_COMM_WORLD, myColor, rank, &intraComm) ;
+        nbSndSrvPools = size - leaders[hashServer2];    // one proc per secondary-server pool
+
+        // Taking into account multiple pools on secondary server
+        if (nbSndSrvPools > 1)
+        {
+          if (CXios::serverLevel > 1)
+          {
+            int nbProcs = size - leaders[hashServer2];
+            int remain = nbProcs % nbSndSrvPools;
+            int procsPerPool = nbProcs / nbSndSrvPools;
+            rankSndServers = rank - leaders[hashServer2];
+            StdString strTmp = CXios::xiosCodeIdSnd;
+
+            if (remain == 0)
+            {
+              poolNb = rankSndServers/procsPerPool;
+            }
+            else
+            {
+              if (rankSndServers <= (procsPerPool + 1) * remain)
+                poolNb = rankSndServers/(procsPerPool+1);
+              else
+              {
+                poolNb = remain + 1;
+                rankSndServers -= (procsPerPool + 1) * remain;
+                rankSndServers -= procsPerPool;
+                poolNb += rankSndServers/procsPerPool;
+              }
+            }
+            strTmp += boost::lexical_cast<string>(poolNb+1);  // add 1 to avoid hashing zero
+            hashServer = hashString(strTmp);
+            hashServer2 = hashString(strTmp);
+          }
+        }
+
+        if (nbSndSrvPools > 1)
+        {
+          myColor = size;
+          MPI_Comm_split(MPI_COMM_WORLD, myColor, rank, &serversInterComm) ;
+        }
+        else
+        {
+          myColor=colors[hashServer] ;
+          MPI_Comm_split(MPI_COMM_WORLD, myColor, rank, &intraComm) ;
+        }
+
+        if (nbSndSrvPools > 1)
+        {
+          int sizeServers;
+//          int rankServers;
+//          MPI_Comm_rank(serversInterComm, &rankServers) ;
+          MPI_Comm_size(serversInterComm, &sizeServers) ;
+          hashAllServers=new unsigned long[sizeServers] ;
+          MPI_Allgather(&hashServer, 1, MPI_LONG, hashAllServers, 1, MPI_LONG, serversInterComm) ;
+
+          for(i=0, c=0; i<sizeServers; i++)
+          {
+            if (colorsServers.find(hashAllServers[i])==colorsServers.end())
+            {
+              colorsServers[hashAllServers[i]]=c ;
+//              leadersServers[hashAllServers[i]]= leaders[hashServer1] + i ;
+              leadersServers.push_back( leaders[hashServer1] + i );
+              c++ ;
+            }
+          }
+          myColor=colorsServers[hashServer] ;
+          MPI_Comm_split(serversInterComm, myColor, rank, &intraComm) ;
+        }
+
 
         if (CXios::serverLevel == 0)
@@ -104,5 +177,5 @@
                        <<" intraCommRank :"<<intraCommRank<<"  clientLeader "<< clientLeader<<endl ;
 
-               MPI_Intercomm_create(intraComm, 0, CXios::globalComm, clientLeader, 0, &newComm) ;
+              MPI_Intercomm_create(intraComm, 0, CXios::globalComm, clientLeader, 0, &newComm) ;
                interCommLeft.push_back(newComm) ;
                interComm.push_back(newComm) ;
@@ -110,61 +183,114 @@
           }
         }
-
-        else if ((CXios::serverLevel == 1))
-        {
-          int clientLeader;
-          int srvSndLeader;
-          for(it=leaders.begin();it!=leaders.end();it++)
+        else
+        {
+          if ((CXios::serverLevel == 1))
           {
-            if (it->first != hashServer2)
-            {
-              if (it->first != hashServer1)
+            // Creating interComm with client (interCommLeft)
+            int clientLeader;
+            int srvSndLeader;
+            for(it=leaders.begin();it!=leaders.end();it++)
+            {
+              if (it->first != hashServer2)
               {
-                clientLeader=it->second ;
-                int intraCommSize, intraCommRank ;
-                MPI_Comm_size(intraComm,&intraCommSize) ;
-                MPI_Comm_rank(intraComm,&intraCommRank) ;
-                info(50)<<"intercommCreate::server "<<rank<<" intraCommSize : "<<intraCommSize
-                         <<" intraCommRank :"<<intraCommRank<<"  clientLeader "<< clientLeader<<endl ;
-                MPI_Intercomm_create(intraComm, 0, CXios::globalComm, clientLeader, 0, &newComm) ;
-                interCommLeft.push_back(newComm) ;
-                interComm.push_back(newComm) ;
+                if (it->first != hashServer1)
+                {
+                  clientLeader=it->second ;
+                  int intraCommSize, intraCommRank ;
+                  MPI_Comm_size(intraComm, &intraCommSize) ;
+                  MPI_Comm_rank(intraComm, &intraCommRank) ;
+                  info(50)<<"intercommCreate::server "<<rank<<" intraCommSize : "<<intraCommSize
+                           <<" intraCommRank :"<<intraCommRank<<"  clientLeader "<< clientLeader<<endl ;
+                  MPI_Intercomm_create(intraComm, 0, CXios::globalComm, clientLeader, 0, &newComm) ;
+                  interCommLeft.push_back(newComm) ;
+                  interComm.push_back(newComm) ;
+                }
               }
+              else
+              {
+                srvSndLeader = it->second;
+              }
+            }
+
+            // Creating interComm with secondary server pool(s) (interCommRight)
+//            if (nbSndSrvPools < 1)
+            if (nbSndSrvPools < 2)
+            {
+              CClient::initializeClientOnServer(rank, intraComm, srvSndLeader);
+              interCommRight.push_back(CClient::getInterComm());
+              interComm.push_back(CClient::getInterComm());
             }
             else
             {
-              srvSndLeader = it->second;
-            }
-          }
-
-          CClient::initializeClientOnServer(rank, intraComm, srvSndLeader);
-          interCommRight.push_back(CClient::getInterComm());
-          interComm.push_back(CClient::getInterComm());
-
-        }
-
-        else // secondary server pool
-        {
-          int clientLeader;
-          for(it=leaders.begin();it!=leaders.end();it++)
+//              for(it=leadersServers.begin();it!=leadersServers.end();it++)
+//              {
+//                if (it->first != hashServer)
+//                {
+//                  srvSndLeader = it->second;
+//                  CClient::initializeClientOnServer(rank, intraComm, srvSndLeader);
+//                  interCommRight.push_back(CClient::getInterComm());
+//                  interComm.push_back(CClient::getInterComm());
+//                }
+//              }
+
+              for(int i = 1; i < leadersServers.size(); ++i)
+              {
+                srvSndLeader = leadersServers[i];
+                CClient::initializeClientOnServer(rank, intraComm, srvSndLeader);
+                interCommRight.push_back(CClient::getInterComm());
+                interComm.push_back(CClient::getInterComm());
+              }
+            }
+          } // primary server
+
+          else // secondary server pool(s)
           {
-            if (it->first == hashServer1)
-            {
-              clientLeader=it->second ;
-              int intraCommSize, intraCommRank ;
-              MPI_Comm_size(intraComm,&intraCommSize) ;
-              MPI_Comm_rank(intraComm,&intraCommRank) ;
-              info(50)<<"intercommCreate::server "<<rank<<" intraCommSize : "<<intraCommSize
-                       <<" intraCommRank :"<<intraCommRank<<"  clientLeader "<< clientLeader<<endl ;
-
-              MPI_Intercomm_create(intraComm, 0, CXios::globalComm, clientLeader, 0, &newComm) ;
-              interCommLeft.push_back(newComm) ;
-              interComm.push_back(newComm) ;
-
-              break;
-            }
-          }
-        }
-
+            int clientLeader;
+            if (nbSndSrvPools < 2)
+//            if (nbSndSrvPools < 1)
+            {
+              for(it=leaders.begin();it!=leaders.end();it++)
+              {
+                if (it->first == hashServer1)
+                {
+                  clientLeader=it->second ;
+                  int intraCommSize, intraCommRank ;
+                  MPI_Comm_size(intraComm, &intraCommSize) ;
+                  MPI_Comm_rank(intraComm, &intraCommRank) ;
+                  info(50)<<"intercommCreate::server "<<rank<<" intraCommSize : "<<intraCommSize
+                           <<" intraCommRank :"<<intraCommRank<<"  clientLeader "<< clientLeader<<endl ;
+
+                  MPI_Intercomm_create(intraComm, 0, CXios::globalComm, clientLeader, 0, &newComm) ;
+                  interCommLeft.push_back(newComm) ;
+                  interComm.push_back(newComm) ;
+
+                  break;
+                }
+              }
+            }
+            else
+            {
+//              for(it=leadersServers.begin();it!=leadersServers.end();it++)
+              {
+ //               if (it->first == hashServer1)
+                {
+//                  clientLeader=it->second ;
+                  clientLeader = leadersServers[0];
+                  int intraCommSize, intraCommRank ;
+                  MPI_Comm_size(intraComm, &intraCommSize) ;
+                  MPI_Comm_rank(intraComm, &intraCommRank) ;
+                  info(50)<<"intercommCreate::server "<<rank<<" intraCommSize : "<<intraCommSize
+                           <<" intraCommRank :"<<intraCommRank<<"  clientLeader "<< clientLeader<<endl ;
+
+                  MPI_Intercomm_create(intraComm, 0, CXios::globalComm, clientLeader, 0, &newComm) ;
+                  interCommLeft.push_back(newComm) ;
+                  interComm.push_back(newComm) ;
+                }
+              }
+            }
+          } // secondary server
+        } // CXios::serverLevel != 0
+
+        if (nbSndSrvPools > 1) delete [] hashAllServers;
         delete [] hashAll ;
 
@@ -204,6 +330,5 @@
       }
 
-//      int rank;
-      MPI_Comm_rank(intraComm,&rank) ;
+      MPI_Comm_rank(intraComm, &rank) ;
       if (rank==0) isRoot=true;
       else isRoot=false;
@@ -489,5 +614,6 @@
        if (CXios::serverLevel == 1)
        {
-         CClient::registerContext(contextId, intraComm);
+//         CClient::registerContext(contextId, intraComm);
+         CClient::registerContextOnSrvPools(contextId, intraComm);
        }
 
@@ -531,4 +657,5 @@
       int numDigit = 0;
       int size = 0;
+      int mpiRank;
       MPI_Comm_size(CXios::globalComm, &size);
       while (size)
@@ -538,5 +665,9 @@
       }
 
-      fileNameClient << fileName << "_" << std::setfill('0') << std::setw(numDigit) << getRank() << ext;
+      if (nbSndSrvPools < 2)
+        mpiRank = getRank();
+      else
+        mpiRank = rankSndServers;
+      fileNameClient << fileName << "_" << std::setfill('0') << std::setw(numDigit) << mpiRank << ext;
       fb->open(fileNameClient.str().c_str(), std::ios::out);
       if (!fb->is_open())
Index: XIOS/dev/dev_olga/src/server.hpp
===================================================================
--- XIOS/dev/dev_olga/src/server.hpp	(revision 992)
+++ XIOS/dev/dev_olga/src/server.hpp	(revision 1009)
@@ -27,9 +27,12 @@
         // Communicators for the primary group of servers
         static MPI_Comm intraComm;
-        static list<MPI_Comm> interCommLeft;   // interComm between server and its client (client or primary server)
+        static list<MPI_Comm> interCommLeft;   // interComm between server (primary or secondary) and its client (client or primary server)
         static list<MPI_Comm> interCommRight;  // interComm between primary server and secondary server (non-empty only for primary server pool)
         static list<MPI_Comm> interComm;       // interCommLeft + interCommRight
         static std::list<MPI_Comm> contextInterComms;
         static CEventScheduler* eventScheduler;
+
+        static int nbSndSrvPools;   // number of secondary server pools
+        static int poolNb;          // for secondary servers; stores the pool number
 
         struct contextMessage
@@ -65,4 +68,5 @@
       private:
         static int rank;
+        static int rankSndServers;
         static StdOFStream m_infoStream;
         static StdOFStream m_errorStream;
Index: XIOS/dev/dev_olga/src/test/test_regular.f90
===================================================================
--- XIOS/dev/dev_olga/src/test/test_regular.f90	(revision 992)
+++ XIOS/dev/dev_olga/src/test/test_regular.f90	(revision 1009)
@@ -20,6 +20,6 @@
   INTEGER :: size, rank
 
-  INTEGER :: nlon = 100 
-  INTEGER :: nlat = 100
+  INTEGER :: nlon = 5 !100 
+  INTEGER :: nlat = 5 !100
   INTEGER :: ncell 
   INTEGER :: ilat, ilon, ind
@@ -37,4 +37,6 @@
   DOUBLE PRECISION,ALLOCATABLE :: bounds_lat(:,:)
   DOUBLE PRECISION,ALLOCATABLE :: field_temp(:,:)
+  DOUBLE PRECISION,ALLOCATABLE :: field_temp1(:,:)
+  DOUBLE PRECISION,ALLOCATABLE :: field_temp2(:,:)
 
 !!! MPI Initialization
@@ -118,9 +120,14 @@
   ALLOCATE(bounds_lat(4,ni))
   ALLOCATE(field_temp(ni,ntime)) 
-  lon = lon_glo(1+ibegin:1+ibegin+ni)
-  lat = lat_glo(1+ibegin:1+ibegin+ni)
-  bounds_lon(:,:) = bounds_lon_glo(:,1+ibegin:1+ibegin+ni)
-  bounds_lat(:,:) = bounds_lat_glo(:,1+ibegin:1+ibegin+ni)
+  ALLOCATE(field_temp1(ni,ntime))
+  ALLOCATE(field_temp2(ni,ntime))
+  lon = lon_glo(ibegin:1+ibegin+ni)
+  lat = lat_glo(ibegin:1+ibegin+ni)
+  bounds_lon(:,:) = bounds_lon_glo(:,ibegin:1+ibegin+ni)
+  bounds_lat(:,:) = bounds_lat_glo(:,ibegin:1+ibegin+ni)
+
   field_temp(:,:) = rank
+  field_temp1(:,:) = rank
+  field_temp2(:,:) = rank + 10
 
 
@@ -135,8 +142,11 @@
                             time_origin=xios_date(1999, 01, 01, 15, 00, 00))
 
-  CALL xios_set_domain_attr("face", ni_glo=ncell, ibegin=ibegin, ni=ni, type='unstructured')
-  CALL xios_set_domain_attr("face", lonvalue_1d=lon, latvalue_1d=lat)
-  CALL xios_set_domain_attr("face", bounds_lon_1d=bounds_lon, bounds_lat_1d=bounds_lat)
-
+  CALL xios_set_domain_attr("face1", ni_glo=ncell, ibegin=ibegin, ni=ni, type='unstructured')
+  CALL xios_set_domain_attr("face1", lonvalue_1d=lon, latvalue_1d=lat)
+  CALL xios_set_domain_attr("face1", bounds_lon_1d=bounds_lon, bounds_lat_1d=bounds_lat)
+
+  CALL xios_set_domain_attr("face2", ni_glo=ncell, ibegin=ibegin, ni=ni, type='unstructured')
+  CALL xios_set_domain_attr("face2", lonvalue_1d=lon, latvalue_1d=lat)
+  CALL xios_set_domain_attr("face2", bounds_lon_1d=bounds_lon, bounds_lat_1d=bounds_lat)
    
 !!! Definition du timestep
@@ -160,5 +170,6 @@
 
 !!! On donne la valeur du champ atm
-     CALL xios_send_field("temp",field_temp(:,1))
+     CALL xios_send_field("temp1",field_temp1(:,1))
+     CALL xios_send_field("temp2",field_temp2(:,1))
 
     ENDDO
@@ -178,4 +189,5 @@
     DEALLOCATE(bounds_lon, bounds_lat)
     DEALLOCATE(field_temp)
+    DEALLOCATE(field_temp1, field_temp2)
 
 !!! Fin de XIOS
Index: XIOS/dev/dev_olga/src/type/message.cpp
===================================================================
--- XIOS/dev/dev_olga/src/type/message.cpp	(revision 992)
+++ XIOS/dev/dev_olga/src/type/message.cpp	(revision 1009)
@@ -27,5 +27,6 @@
      size_t retSize=0 ;
      
-     for(it=typeList.begin();it!=typeList.end();it++) retSize+=(*it)->size() ;
+     for(it=typeList.begin();it!=typeList.end();it++)
+    	 retSize+=(*it)->size() ;
      return retSize ;
    }
