Index: XIOS/trunk/src/client_client_dht_decl.cpp
===================================================================
--- XIOS/trunk/src/client_client_dht_decl.cpp	(revision 828)
+++ XIOS/trunk/src/client_client_dht_decl.cpp	(revision 829)
@@ -13,4 +13,5 @@
 
 template class CClientClientDHTTemplate<int>;
+template class CClientClientDHTTemplate<PairIntInt>;
 
 }
Index: XIOS/trunk/src/client_client_dht_template.hpp
===================================================================
--- XIOS/trunk/src/client_client_dht_template.hpp	(revision 828)
+++ XIOS/trunk/src/client_client_dht_template.hpp	(revision 829)
@@ -16,4 +16,6 @@
 #include "policy.hpp"
 #include <boost/unordered_map.hpp>
+//#include "utils.hpp"
+#include "dht_data_types.hpp"
 
 namespace xios
@@ -33,8 +35,10 @@
     typedef T InfoType;
     static const int infoTypeSize = sizeof(InfoType);
+    typedef typename boost::unordered_map<InfoType, std::vector<size_t> > InfoType2IndexMap;
+    typedef typename boost::unordered_map<size_t,InfoType> Index2InfoTypeMap;
 
   public:
     /** Default constructor */
-    CClientClientDHTTemplate(const boost::unordered_map<size_t,T>& indexInfoInitMap,
+    CClientClientDHTTemplate(const Index2InfoTypeMap& indexInfoInitMap,
                              const MPI_Comm& clientIntraComm,
                              int hierarLvl = 2);
@@ -42,5 +46,5 @@
     void computeIndexInfoMapping(const CArray<size_t,1>& indices);
 
-    const std::map<T, std::vector<size_t> >& getInfoIndexMap() const {return indexGlobalOnServer_; }
+    const Index2InfoTypeMap& getInfoIndexMap() const {return infoIndexMapping_; }
 
     /** Default destructor */
@@ -49,5 +53,5 @@
   protected:
     // Redistribute index and info among clients
-    void computeDistributedIndex(const boost::unordered_map<size_t,T>& indexInfoInitMap,
+    void computeDistributedIndex(const Index2InfoTypeMap& indexInfoInitMap,
                                  const MPI_Comm& intraCommLevel,
                                  int level);
@@ -67,8 +71,8 @@
                                       const MPI_Comm& intraComm);
 
-    void probeInfoMessageFromClients(InfoType* recvIndexServerBuff,
+    void probeInfoMessageFromClients(unsigned char* recvIndexServerBuff,
                                      const int recvNbIndexCount,
                                      int& countIndexServer,
-                                     std::map<int, InfoType*>& indexServerBuffBegin,
+                                     std::map<int, unsigned char*>& indexServerBuffBegin,
                                      std::map<int, MPI_Request>& requestRecvIndexServer,
                                      const MPI_Comm& intraComm);
@@ -93,11 +97,11 @@
   protected:
     //! Mapping of global index to the corresponding client
-    boost::unordered_map<size_t,InfoType> index2InfoMapping_;
+    Index2InfoTypeMap index2InfoMapping_;
 
     //! A temporary mapping of index to the corresponding information in each level of hierarchy
-    boost::unordered_map<size_t,InfoType> indexToInfoMappingLevel_;
+    Index2InfoTypeMap indexToInfoMappingLevel_;
 
-    //! Global index of data on SERVER, which are calculated by client(s)
-    std::map<int, std::vector<size_t> > indexGlobalOnServer_;
+    //! Data (information) corresponding to global index
+    Index2InfoTypeMap infoIndexMapping_;
 
     //! intracommuntion of clients
@@ -109,4 +113,5 @@
 
 typedef CClientClientDHTTemplate<int> CClientClientDHTInt;
+typedef CClientClientDHTTemplate<PairIntInt> CClientClientDHTPairIntInt;
 
 } // namespace xios
Index: XIOS/trunk/src/client_client_dht_template_impl.hpp
===================================================================
--- XIOS/trunk/src/client_client_dht_template_impl.hpp	(revision 828)
+++ XIOS/trunk/src/client_client_dht_template_impl.hpp	(revision 829)
@@ -49,6 +49,7 @@
   for (size_t idx = 0; idx < size; ++idx)
   {
-    int serverIdx = indexToInfoMappingLevel_[indices(idx)];
-    indexGlobalOnServer_[serverIdx].push_back(indices(idx));
+    T& info = indexToInfoMappingLevel_[indices(idx)];
+//    infoIndexMapping_[info].push_back(indices(idx));
+    infoIndexMapping_[indices(idx)] = info;
   }
 }
@@ -125,8 +126,9 @@
 
   // Buffer to receive respond from other clients, it can be allocated or not depending whether it demands other clients
-  InfoType* recvBuffInfo = 0;
+//  InfoType* recvBuffInfo = 0;
+  unsigned char* recvBuffInfo = 0;
   int nbIndexReceivedFromOthers = nbIndexToSend;
   if (0 != nbIndexReceivedFromOthers)
-    recvBuffInfo = new InfoType[nbIndexReceivedFromOthers];
+    recvBuffInfo = new unsigned char[nbIndexReceivedFromOthers*infoTypeSize];
 
   std::map<int, MPI_Request>::iterator itRequest;
@@ -212,5 +214,5 @@
 
   // Mapping client rank and the begining position of receiving buffer for message of server index from this client
-  std::map<int, InfoType*> infoBuffBegin;
+  std::map<int, unsigned char*> infoBuffBegin;
 
   while ((!sendInfoRequest.empty()) || (nbSendBuffInfoReceived < nbIndexReceivedFromOthers))
@@ -233,13 +235,17 @@
       if (true == flagInfo)
       {
-        MPI_Get_count(&statusInfo, MPI_INT, &count);
+        MPI_Get_count(&statusInfo, MPI_CHAR, &count);
+        int actualCountInfo = count/infoTypeSize;
         int clientSourceRank = statusInfo.MPI_SOURCE;
-        InfoType* beginBuff = infoBuffBegin[clientSourceRank];
+        unsigned char* beginBuff = infoBuffBegin[clientSourceRank];
         std::vector<size_t>& indexTmp = client2ClientIndex[clientSourceRank];
-        for (int i = 0; i < count; ++i)
+        TypeToBytes<InfoType> u;
+        for (int i = 0; i < actualCountInfo; ++i)
         {
-          indexToInfoMapping[indexTmp[i]] = *(beginBuff+i);
+          unsigned char* tmpBeginBuff = beginBuff+i*infoTypeSize;
+          for (size_t idx = 0; idx < infoTypeSize; ++idx) u.bytes[idx] = *(tmpBeginBuff+idx);
+          indexToInfoMapping[indexTmp[i]] = u.value;
         }
-        nbSendBuffInfoReceived += count;
+        nbSendBuffInfoReceived += actualCountInfo;
         repondAlreadyReceived.push_back(clientSourceRank);
       }
@@ -251,5 +257,5 @@
   }
 
-  indexToInfoMappingLevel_ = indexToInfoMapping;
+  indexToInfoMappingLevel_.swap(indexToInfoMapping);
   if (0 != maxNbIndexDemandedFromOthers) delete [] recvBuffIndex;
   if (0 != nbIndexReceivedFromOthers) delete [] recvBuffInfo;
@@ -289,6 +295,6 @@
 template<typename T, typename H>
 void CClientClientDHTTemplate<T,H>::computeDistributedIndex(const boost::unordered_map<size_t,T>& indexInfoMap,
-                                                          const MPI_Comm& commLevel,
-                                                          int level)
+                                                            const MPI_Comm& commLevel,
+                                                            int level)
 {
   int nbClient, clientRank;
@@ -340,5 +346,5 @@
   int recvNbIndexCount = recvNbIndexBuff[clientRank];
   unsigned long* recvIndexBuff = new unsigned long[recvNbIndexCount];
-  InfoType* recvInfoBuff = new InfoType[recvNbIndexCount];
+  unsigned char* recvInfoBuff = new unsigned char[recvNbIndexCount*infoTypeSize];
 
   // If a client holds information about index and the corresponding which don't belong to it,
@@ -374,5 +380,5 @@
 
   // Mapping client rank and the begining position of receiving buffer for message of server index from this client
-  std::map<int, int*> infoBuffBegin;
+  std::map<int, unsigned char*> infoBuffBegin;
 
   boost::unordered_map<size_t,InfoType> indexToInfoMapping;
@@ -418,6 +424,12 @@
       {
         int count = it->second;
+        TypeToBytes<InfoType> u;
         for (int i = 0; i < count; ++i)
-           indexToInfoMapping.insert(std::make_pair<size_t,InfoType>(*(indexBuffBegin[rank]+i),*(infoBuffBegin[rank]+i)));
+        {
+          unsigned char* tmpBeginBuff = infoBuffBegin[rank]+i*infoTypeSize;
+          for (size_t idx = 0; idx < infoTypeSize; ++idx) u.bytes[idx] = *(tmpBeginBuff+idx);
+          indexToInfoMapping.insert(std::make_pair<size_t,InfoType>(*(indexBuffBegin[rank]+i),u.value));
+        }
+
         processedList.push_back(rank);
         --recvNbClient;
@@ -466,9 +478,9 @@
 template<typename T, typename H>
 void CClientClientDHTTemplate<T,H>::probeIndexMessageFromClients(unsigned long* recvIndexBuff,
-                                                    const int recvNbIndexCount,
-                                                    int& countIndex,
-                                                    std::map<int, unsigned long*>& indexBuffBegin,
-                                                    std::map<int, MPI_Request>& requestRecvIndex,
-                                                    const MPI_Comm& intraComm)
+                                                                 const int recvNbIndexCount,
+                                                                 int& countIndex,
+                                                                 std::map<int, unsigned long*>& indexBuffBegin,
+                                                                 std::map<int, MPI_Request>& requestRecvIndex,
+                                                                 const MPI_Comm& intraComm)
 {
   MPI_Status statusIndexGlobal;
@@ -500,10 +512,10 @@
 */
 template<typename T, typename H>
-void CClientClientDHTTemplate<T,H>::probeInfoMessageFromClients(T* recvInfoBuff,
-                                                   const int recvNbIndexCount,
-                                                   int& countInfo,
-                                                   std::map<int, T*>& infoBuffBegin,
-                                                   std::map<int, MPI_Request>& requestRecvInfo,
-                                                   const MPI_Comm& intraComm)
+void CClientClientDHTTemplate<T,H>::probeInfoMessageFromClients(unsigned char* recvInfoBuff,
+                                                                const int recvNbIndexCount,
+                                                                int& countInfo,
+                                                                std::map<int, unsigned char*>& infoBuffBegin,
+                                                                std::map<int, MPI_Request>& requestRecvInfo,
+                                                                const MPI_Comm& intraComm)
 {
   MPI_Status statusInfo;
@@ -515,6 +527,7 @@
   {
     MPI_Get_count(&statusInfo, MPI_CHAR, &count);
-    infoBuffBegin.insert(std::make_pair<int, T*>(statusInfo.MPI_SOURCE, recvInfoBuff+countInfo));
-    MPI_Irecv(recvInfoBuff+countInfo, count, MPI_CHAR,
+    unsigned char* beginInfoBuff = recvInfoBuff+countInfo*infoTypeSize;
+    infoBuffBegin.insert(std::make_pair<int, unsigned char*>(statusInfo.MPI_SOURCE, beginInfoBuff));
+    MPI_Irecv(beginInfoBuff, count, MPI_CHAR,
               statusInfo.MPI_SOURCE, MPI_DHT_INFO, intraComm,
               &requestRecvInfo[statusInfo.MPI_SOURCE]);
@@ -533,6 +546,6 @@
 template<typename T, typename H>
 void CClientClientDHTTemplate<T,H>::sendIndexToClients(int clientDestRank, std::vector<size_t>& indices,
-                                          const MPI_Comm& clientIntraComm,
-                                          std::list<MPI_Request>& requestSendIndex)
+                                                       const MPI_Comm& clientIntraComm,
+                                                       std::list<MPI_Request>& requestSendIndex)
 {
   MPI_Request request;
@@ -551,6 +564,6 @@
 template<typename T, typename H>
 void CClientClientDHTTemplate<T,H>::sendInfoToClients(int clientDestRank, std::vector<T>& info,
-                                         const MPI_Comm& clientIntraComm,
-                                         std::list<MPI_Request>& requestSendInfo)
+                                                      const MPI_Comm& clientIntraComm,
+                                                      std::list<MPI_Request>& requestSendInfo)
 {
   MPI_Request request;
Index: XIOS/trunk/src/client_server_mapping.cpp
===================================================================
--- XIOS/trunk/src/client_server_mapping.cpp	(revision 828)
+++ XIOS/trunk/src/client_server_mapping.cpp	(revision 829)
@@ -12,5 +12,5 @@
 
 CClientServerMapping::CClientServerMapping()
-  : indexGlobalOnServer_(), localIndexSend2Server_(), connectedClients_()
+  : indexGlobalOnServer_(), connectedClients_() //, localIndexSend2Server_()
 {
 }
@@ -20,51 +20,51 @@
 }
 
-/*!
-  Compute mapping global index of server which client sends to.
-  \param [in] globalIndexOnClient global index on client
-  \param [in] globalIndexServer global index of servers
-*/
-void CClientServerMapping::computeServerIndexMapping(const CArray<size_t,1>& globalIndexOnClient,
-                                                     const std::vector<CArray<size_t,1>* >& globalIndexServer)
-{
-  defaultComputeServerIndexMapping(globalIndexOnClient, globalIndexServer);
-}
+///*!
+//  Compute mapping global index of server which client sends to.
+//  \param [in] globalIndexOnClient global index on client
+//  \param [in] globalIndexServer global index of servers
+//*/
+//void CClientServerMapping::computeServerIndexMapping(const CArray<size_t,1>& globalIndexOnClient,
+//                                                     const std::vector<CArray<size_t,1>* >& globalIndexServer)
+//{
+//  defaultComputeServerIndexMapping(globalIndexOnClient, globalIndexServer);
+//}
 
-/*!
-   Compute index of data which are sent to server and index global on server side
-   \param [in] globalIndexOnClient global index of data on client
-   \param [in] globalIndexServer global index of server(s)
-   \param [in] localIndexOnClient local index of data on client which are sent to server
-*/
-void CClientServerMapping::defaultComputeServerIndexMapping(const CArray<size_t,1>& globalIndexOnClient,
-                                                            const std::vector<CArray<size_t,1>* >& globalIndexServer,
-                                                            const CArray<int,1>* localIndexOnClient)
-{
-  int nServer = globalIndexServer.size();
-  std::vector<CArray<size_t,1>::const_iterator> itBegin(nServer), itEnd(nServer), it(nServer);
-  for (int i = 0; i < nServer; ++i)
-  {
-    itBegin[i] = it[i] = globalIndexServer[i]->begin();
-    itEnd[i]   = globalIndexServer[i]->end();
-  }
-
-  size_t ssize = globalIndexOnClient.numElements();
-  for (int i = 0; i < ssize; ++i)
-  {
-    for (int j = 0; j < nServer; ++j)
-    {
-      // Just temporarily, it's bad.
-      if (std::binary_search(itBegin[j], itEnd[j], globalIndexOnClient(i)))
-      {
-        // Just try to calculate local index server on client side
-        (indexGlobalOnServer_[j]).push_back((globalIndexOnClient)(i));
-        if (0 != localIndexOnClient) (localIndexSend2Server_[j]).push_back((*localIndexOnClient)(i));
-        else
-          (localIndexSend2Server_[j]).push_back(i);
-        continue;
-      }
-    }
-  }
-}
+///*!
+//   Compute index of data which are sent to server and index global on server side
+//   \param [in] globalIndexOnClient global index of data on client
+//   \param [in] globalIndexServer global index of server(s)
+//   \param [in] localIndexOnClient local index of data on client which are sent to server
+//*/
+//void CClientServerMapping::defaultComputeServerIndexMapping(const CArray<size_t,1>& globalIndexOnClient,
+//                                                            const std::vector<CArray<size_t,1>* >& globalIndexServer,
+//                                                            const CArray<int,1>* localIndexOnClient)
+//{
+//  int nServer = globalIndexServer.size();
+//  std::vector<CArray<size_t,1>::const_iterator> itBegin(nServer), itEnd(nServer), it(nServer);
+//  for (int i = 0; i < nServer; ++i)
+//  {
+//    itBegin[i] = it[i] = globalIndexServer[i]->begin();
+//    itEnd[i]   = globalIndexServer[i]->end();
+//  }
+//
+//  size_t ssize = globalIndexOnClient.numElements();
+//  for (int i = 0; i < ssize; ++i)
+//  {
+//    for (int j = 0; j < nServer; ++j)
+//    {
+//      // Just temporarily, it's bad.
+//      if (std::binary_search(itBegin[j], itEnd[j], globalIndexOnClient(i)))
+//      {
+//        // Just try to calculate local index server on client side
+//        (indexGlobalOnServer_[j]).push_back((globalIndexOnClient)(i));
+//        if (0 != localIndexOnClient) (localIndexSend2Server_[j]).push_back((*localIndexOnClient)(i));
+//        else
+//          (localIndexSend2Server_[j]).push_back(i);
+//        continue;
+//      }
+//    }
+//  }
+//}
 
 /*!
@@ -134,12 +134,12 @@
 }
 
-/*!
-  Return local index of data that is send to server
-  \return mapping of server rank and local index of sending data on the client
-*/
-const std::map<int, std::vector<int> >& CClientServerMapping::getLocalIndexSendToServer() const
-{
-  return localIndexSend2Server_;
-}
+///*!
+//  Return local index of data that is send to server
+//  \return mapping of server rank and local index of sending data on the client
+//*/
+//const CClientServerMapping::LocalIndexMap& CClientServerMapping::getLocalIndexSendToServer() const
+//{
+//  return localIndexSend2Server_;
+//}
 
 /*!
@@ -149,5 +149,5 @@
   \return mapping of server rank and its global index.
 */
-const std::map<int, std::vector<size_t> >& CClientServerMapping::getGlobalIndexOnServer() const
+const CClientServerMapping::GlobalIndexMap& CClientServerMapping::getGlobalIndexOnServer() const
 {
   return indexGlobalOnServer_;
Index: XIOS/trunk/src/client_server_mapping.hpp
===================================================================
--- XIOS/trunk/src/client_server_mapping.hpp	(revision 828)
+++ XIOS/trunk/src/client_server_mapping.hpp	(revision 829)
@@ -13,4 +13,5 @@
 #include "array_new.hpp"
 #include "mpi.hpp"
+#include <boost/unordered_map.hpp>
 
 namespace xios {
@@ -23,4 +24,7 @@
 class CClientServerMapping
 {
+public:
+  typedef boost::unordered_map<int, std::vector<size_t> > GlobalIndexMap;
+  typedef std::map<int, std::vector<int> > LocalIndexMap;
   public:
     /** Default constructor */
@@ -33,11 +37,7 @@
     virtual void computeServerIndexMapping(const CArray<size_t,1>& globalIndexOnClient) = 0;
 
-//    // In case of computing local index on client sent to server
+//    // Simple case, global index on client and index on servers
 //    virtual void computeServerIndexMapping(const CArray<size_t,1>& globalIndexOnClient,
-//                                           const CArray<int,1>& localIndexOnClient) = 0;
-
-    // Simple case, global index on client and index on servers
-    virtual void computeServerIndexMapping(const CArray<size_t,1>& globalIndexOnClient,
-                                           const std::vector<CArray<size_t,1>* >& globalIndexOnServer);
+//                                           const std::vector<CArray<size_t,1>* >& globalIndexOnServer);
 
     static std::map<int,int> computeConnectedClients(int nbServer, int nbClient,
@@ -45,18 +45,18 @@
                                                      const std::vector<int>& connectedServerRank);
 
-    const std::map<int, std::vector<size_t> >& getGlobalIndexOnServer() const;
-    const std::map<int, std::vector<int> >& getLocalIndexSendToServer() const;
+    const GlobalIndexMap& getGlobalIndexOnServer() const;
+//    const LocalIndexMap& getLocalIndexSendToServer() const;
 
   protected:
-    void defaultComputeServerIndexMapping(const CArray<size_t,1>& globalIndexOnClient,
-                                          const std::vector<CArray<size_t,1>* >& globalIndexOnServer,
-                                          const CArray<int,1>* localIndexOnClient = 0);
+//    void defaultComputeServerIndexMapping(const CArray<size_t,1>& globalIndexOnClient,
+//                                          const std::vector<CArray<size_t,1>* >& globalIndexOnServer,
+//                                          const CArray<int,1>* localIndexOnClient = 0);
 
   protected:
     //! Global index of data on SERVER, which are calculated by client(s)
-    std::map<int, std::vector<size_t> > indexGlobalOnServer_;
+    GlobalIndexMap indexGlobalOnServer_;
 
     //! Index of the local data which will be sent to the corresponding server(s)
-    std::map<int, std::vector<int> >  localIndexSend2Server_;
+//    LocalIndexMap  localIndexSend2Server_;
 
     //!< Number of clients connected to a server
Index: XIOS/trunk/src/client_server_mapping_distributed.cpp
===================================================================
--- XIOS/trunk/src/client_server_mapping_distributed.cpp	(revision 828)
+++ XIOS/trunk/src/client_server_mapping_distributed.cpp	(revision 829)
@@ -3,5 +3,5 @@
    \author Ha NGUYEN
    \since 27 Feb 2015
-   \date 06 Oct 2015
+   \date 16 Mars 2016
 
    \brief Mapping between index client and server.
@@ -19,18 +19,9 @@
 CClientServerMappingDistributed::CClientServerMappingDistributed(const boost::unordered_map<size_t,int>& globalIndexOfServer,
                                                                  const MPI_Comm& clientIntraComm, bool isDataDistributed)
-  : CClientServerMapping(), indexClientHash_(), countIndexGlobal_(0), countIndexServer_(0),
-    indexGlobalBuffBegin_(), indexServerBuffBegin_(), requestRecvIndexServer_(), isDataDistributed_(isDataDistributed),
-    ccDHT_(0)
+  : CClientServerMapping(), ccDHT_(0)
 {
-  clientIntraComm_ = clientIntraComm;
-  MPI_Comm_size(clientIntraComm,&(nbClient_));
-  MPI_Comm_rank(clientIntraComm,&clientRank_);
-  computeHashIndex();
-
   ccDHT_ = new CClientClientDHTInt(globalIndexOfServer,
                                    clientIntraComm,
                                    isDataDistributed);
-
-//  computeDistributedServerIndex(globalIndexOfServer, clientIntraComm);
 }
 
@@ -47,477 +38,12 @@
 {
   ccDHT_->computeIndexInfoMapping(globalIndexOnClient);
-  indexGlobalOnServer_ = (ccDHT_->getInfoIndexMap());
-
-/*
-  size_t ssize = globalIndexOnClient.numElements(), hashedIndex;
-
-  std::vector<size_t>::const_iterator itbClientHash = indexClientHash_.begin(), itClientHash,
-                                      iteClientHash = indexClientHash_.end();
-  std::map<int, std::vector<size_t> > client2ClientIndexGlobal;
-  std::map<int, std::vector<int> > client2ClientIndexServer;
-
-  // Number of global index whose mapping server can be found out thanks to index-server mapping
-  int nbIndexAlreadyOnClient = 0;
-
-  // Number of global index whose mapping server are on other clients
-  int nbIndexSendToOthers = 0;
-  HashXIOS<size_t> hashGlobalIndex;
-  for (int i = 0; i < ssize; ++i)
-  {
-    size_t globalIndexClient = globalIndexOnClient(i);
-    hashedIndex  = hashGlobalIndex(globalIndexClient);
-    itClientHash = std::upper_bound(itbClientHash, iteClientHash, hashedIndex);
-    if (iteClientHash != itClientHash)
-    {
-      int indexClient = std::distance(itbClientHash, itClientHash)-1;
-      {
-        client2ClientIndexGlobal[indexClient].push_back(globalIndexClient);
-        ++nbIndexSendToOthers;
-      }
-    }
-  }
-
-  int* sendBuff = new int[nbClient_];
-  for (int i = 0; i < nbClient_; ++i) sendBuff[i] = 0;
-  std::map<int, std::vector<size_t> >::iterator itb  = client2ClientIndexGlobal.begin(), it,
-                                                ite  = client2ClientIndexGlobal.end();
-  for (it = itb; it != ite; ++it) sendBuff[it->first] = 1;
-  int* recvBuff = new int[nbClient_];
-  MPI_Allreduce(sendBuff, recvBuff, nbClient_, MPI_INT, MPI_SUM, clientIntraComm_);
-
-  std::list<MPI_Request> sendRequest;
-  if (0 != nbIndexSendToOthers)
-      for (it = itb; it != ite; ++it)
-         sendIndexGlobalToClients(it->first, it->second, clientIntraComm_, sendRequest);
-
-  int nbDemandingClient = recvBuff[clientRank_], nbIndexServerReceived = 0;
-
-  // Receiving demand as well as the responds from other clients
-  // The demand message contains global index; meanwhile the responds have server index information
-  // Buffer to receive demand from other clients, it can be allocated or not depending whether it has demand(s)
-    // There are some cases we demand duplicate index so need to determine maxium size of demanding buffer
-  for (it = itb; it != ite; ++it) sendBuff[it->first] = (it->second).size();
-  MPI_Allreduce(sendBuff, recvBuff, nbClient_, MPI_INT, MPI_SUM, clientIntraComm_);
-
-  unsigned long* recvBuffIndexGlobal = 0;
-  int maxNbIndexDemandedFromOthers = recvBuff[clientRank_];
-  if (!isDataDistributed_) maxNbIndexDemandedFromOthers = nbDemandingClient * nbIndexSendToOthers; //globalIndexToServerMapping_.size(); // Not very optimal but it's general
-
-  if (0 != maxNbIndexDemandedFromOthers)
-    recvBuffIndexGlobal = new unsigned long[maxNbIndexDemandedFromOthers];
-
-  // Buffer to receive respond from other clients, it can be allocated or not depending whether it demands other clients
-  int* recvBuffIndexServer = 0;
-  int nbIndexReceivedFromOthers = nbIndexSendToOthers;
-  if (0 != nbIndexReceivedFromOthers)
-    recvBuffIndexServer = new int[nbIndexReceivedFromOthers];
-
-  std::map<int, MPI_Request>::iterator itRequest;
-  std::vector<int> demandAlreadyReceived, repondAlreadyReceived;
-
-
-  resetReceivingRequestAndCount();
-  while ((0 < nbDemandingClient) || (!sendRequest.empty()) ||
-         (nbIndexServerReceived < nbIndexReceivedFromOthers))
-  {
-    // Just check whether a client has any demand from other clients.
-    // If it has, then it should send responds to these client(s)
-    probeIndexGlobalMessageFromClients(recvBuffIndexGlobal, maxNbIndexDemandedFromOthers);
-    if (0 < nbDemandingClient)
-    {
-      for (itRequest = requestRecvIndexGlobal_.begin();
-           itRequest != requestRecvIndexGlobal_.end(); ++itRequest)
-      {
-        int flagIndexGlobal, count;
-        MPI_Status statusIndexGlobal;
-
-        MPI_Test(&(itRequest->second), &flagIndexGlobal, &statusIndexGlobal);
-        if (true == flagIndexGlobal)
-        {
-          MPI_Get_count(&statusIndexGlobal, MPI_UNSIGNED_LONG, &count);
-          int clientSourceRank = statusIndexGlobal.MPI_SOURCE;
-          unsigned long* beginBuff = indexGlobalBuffBegin_[clientSourceRank];
-          for (int i = 0; i < count; ++i)
-          {
-            client2ClientIndexServer[clientSourceRank].push_back(globalIndexToServerMapping_[*(beginBuff+i)]);
-          }
-          sendIndexServerToClients(clientSourceRank, client2ClientIndexServer[clientSourceRank], clientIntraComm_, sendRequest);
-          --nbDemandingClient;
-
-          demandAlreadyReceived.push_back(clientSourceRank);
-        }
-      }
-      for (int i = 0; i< demandAlreadyReceived.size(); ++i)
-        requestRecvIndexGlobal_.erase(demandAlreadyReceived[i]);
-    }
-
-    testSendRequest(sendRequest);
-
-    // In some cases, a client need to listen respond from other clients about server information
-    // Ok, with the information, a client can fill in its server-global index map.
-    probeIndexServerMessageFromClients(recvBuffIndexServer, nbIndexReceivedFromOthers);
-    for (itRequest = requestRecvIndexServer_.begin();
-         itRequest != requestRecvIndexServer_.end();
-         ++itRequest)
-    {
-      int flagIndexServer, count;
-      MPI_Status statusIndexServer;
-
-      MPI_Test(&(itRequest->second), &flagIndexServer, &statusIndexServer);
-      if (true == flagIndexServer)
-      {
-        MPI_Get_count(&statusIndexServer, MPI_INT, &count);
-        int clientSourceRank = statusIndexServer.MPI_SOURCE;
-        int* beginBuff = indexServerBuffBegin_[clientSourceRank];
-        std::vector<size_t>& globalIndexTmp = client2ClientIndexGlobal[clientSourceRank];
-        for (int i = 0; i < count; ++i)
-        {
-          (indexGlobalOnServer_[*(beginBuff+i)]).push_back(globalIndexTmp[i]);
-        }
-        nbIndexServerReceived += count;
-        repondAlreadyReceived.push_back(clientSourceRank);
-      }
-    }
-
-    for (int i = 0; i< repondAlreadyReceived.size(); ++i)
-      requestRecvIndexServer_.erase(repondAlreadyReceived[i]);
-    repondAlreadyReceived.resize(0);
-  }
-
-  if (0 != maxNbIndexDemandedFromOthers) delete [] recvBuffIndexGlobal;
-  if (0 != nbIndexReceivedFromOthers) delete [] recvBuffIndexServer;
-  delete [] sendBuff;
-  delete [] recvBuff;
-*/
-}
-
-/*!
-  Compute the hash index distribution of whole size_t space then each client will have a range of this distribution
-*/
-void CClientServerMappingDistributed::computeHashIndex()
-{
-  // Compute range of hash index for each client
-  indexClientHash_.resize(nbClient_+1);
-  size_t nbHashIndexMax = std::numeric_limits<size_t>::max();
-  size_t nbHashIndex;
-  indexClientHash_[0] = 0;
-  for (int i = 1; i < nbClient_; ++i)
-  {
-    nbHashIndex = nbHashIndexMax / nbClient_;
-    if (i < (nbHashIndexMax%nbClient_)) ++nbHashIndex;
-    indexClientHash_[i] = indexClientHash_[i-1] + nbHashIndex;
-  }
-  indexClientHash_[nbClient_] = nbHashIndexMax;
-}
-
-/*!
-  Compute distribution of global index for servers
-  Each client already holds a piece of information about global index and the corresponding server.
-This information is redistributed into size_t space in which each client possesses a specific range of index.
-After the redistribution, each client as well as its range of index contains all necessary information about server.
-  \param [in] globalIndexOfServer global index and the corresponding server
-  \param [in] clientIntraComm client joining distribution process.
-*/
-void CClientServerMappingDistributed::computeDistributedServerIndex(const boost::unordered_map<size_t,int>& globalIndexOfServer,
-                                                                    const MPI_Comm& clientIntraComm)
-{
-  int* sendBuff = new int[nbClient_];
-  int* sendNbIndexBuff = new int[nbClient_];
-  for (int i = 0; i < nbClient_; ++i)
-  {
-    sendBuff[i] = 0; sendNbIndexBuff[i] = 0;
-  }
-
-  // Compute size of sending and receving buffer
-  std::map<int, std::vector<size_t> > client2ClientIndexGlobal;
-  std::map<int, std::vector<int> > client2ClientIndexServer;
-
-  std::vector<size_t>::const_iterator itbClientHash = indexClientHash_.begin(), itClientHash,
-                                      iteClientHash = indexClientHash_.end();
-  boost::unordered_map<size_t,int>::const_iterator it  = globalIndexOfServer.begin(),
-                                                   ite = globalIndexOfServer.end();
-  HashXIOS<size_t> hashGlobalIndex;
+  const boost::unordered_map<size_t,int>& infoIndexMap = (ccDHT_->getInfoIndexMap());
+//  indexGlobalOnServer_ = (ccDHT_->getInfoIndexMap());
+  boost::unordered_map<size_t,int>::const_iterator it = infoIndexMap.begin(), ite = infoIndexMap.end();
   for (; it != ite; ++it)
   {
-    size_t hashIndex = hashGlobalIndex(it->first);
-    itClientHash = std::upper_bound(itbClientHash, iteClientHash, hashIndex);
-    if (itClientHash != iteClientHash)
-    {
-      int indexClient = std::distance(itbClientHash, itClientHash)-1;
-      {
-        sendBuff[indexClient] = 1;
-        ++sendNbIndexBuff[indexClient];
-        client2ClientIndexGlobal[indexClient].push_back(it->first);
-        client2ClientIndexServer[indexClient].push_back(it->second);
-      }
-    }
-  }
-
-  // Calculate from how many clients each client receive message.
-  int* recvBuff = new int[nbClient_];
-  MPI_Allreduce(sendBuff, recvBuff, nbClient_, MPI_INT, MPI_SUM, clientIntraComm);
-  int recvNbClient = recvBuff[clientRank_];
-
-  // Calculate size of buffer for receiving message
-  int* recvNbIndexBuff = new int[nbClient_];
-  MPI_Allreduce(sendNbIndexBuff, recvNbIndexBuff, nbClient_, MPI_INT, MPI_SUM, clientIntraComm);
-  int recvNbIndexCount = recvNbIndexBuff[clientRank_];
-  unsigned long* recvIndexGlobalBuff = new unsigned long[recvNbIndexCount];
-  int* recvIndexServerBuff = new int[recvNbIndexCount];
-
-  // If a client holds information about global index and servers which don't belong to it,
-  // it will send a message to the correct clients.
-  // Contents of the message are global index and its corresponding server index
-  std::list<MPI_Request> sendRequest;
-  std::map<int, std::vector<size_t> >::iterator itGlobal  = client2ClientIndexGlobal.begin(),
-                                                iteGlobal = client2ClientIndexGlobal.end();
-  for ( ;itGlobal != iteGlobal; ++itGlobal)
-    sendIndexGlobalToClients(itGlobal->first, itGlobal->second, clientIntraComm, sendRequest);
-  std::map<int, std::vector<int> >::iterator itServer  = client2ClientIndexServer.begin(),
-                                             iteServer = client2ClientIndexServer.end();
-  for (; itServer != iteServer; ++itServer)
-    sendIndexServerToClients(itServer->first, itServer->second, clientIntraComm, sendRequest);
-
-  std::map<int, MPI_Request>::iterator itRequestIndexGlobal, itRequestIndexServer;
-  std::map<int, int> countBuffIndexServer, countBuffIndexGlobal;
-  std::vector<int> processedList;
-
-  bool isFinished = (0 == recvNbClient) ? true : false;
-
-  // Just to make sure before listening message, all counting index and receiving request have already beeen reset
-  resetReceivingRequestAndCount();
-
-  // Now each client trys to listen to demand from others.
-  // If they have message, it processes: pushing global index and corresponding server to its map
-  while (!isFinished || (!sendRequest.empty()))
-  {
-    testSendRequest(sendRequest);
-    probeIndexGlobalMessageFromClients(recvIndexGlobalBuff, recvNbIndexCount);
-
-    // Processing complete request
-    for (itRequestIndexGlobal = requestRecvIndexGlobal_.begin();
-         itRequestIndexGlobal != requestRecvIndexGlobal_.end();
-         ++itRequestIndexGlobal)
-    {
-      int rank = itRequestIndexGlobal->first;
-      int countIndexGlobal = computeBuffCountIndexGlobal(itRequestIndexGlobal->second);
-      if (0 != countIndexGlobal)
-        countBuffIndexGlobal[rank] = countIndexGlobal;
-    }
-
-    probeIndexServerMessageFromClients(recvIndexServerBuff, recvNbIndexCount);
-    for (itRequestIndexServer = requestRecvIndexServer_.begin();
-         itRequestIndexServer != requestRecvIndexServer_.end();
-         ++itRequestIndexServer)
-    {
-      int rank = itRequestIndexServer->first;
-      int countIndexServer = computeBuffCountIndexServer(itRequestIndexServer->second);
-      if (0 != countIndexServer)
-        countBuffIndexServer[rank] = countIndexServer;
-    }
-
-    for (std::map<int, int>::iterator it = countBuffIndexGlobal.begin();
-                                      it != countBuffIndexGlobal.end(); ++it)
-    {
-      int rank = it->first;
-      if (countBuffIndexServer.end() != countBuffIndexServer.find(rank))
-      {
-        processReceivedRequest(indexGlobalBuffBegin_[rank], indexServerBuffBegin_[rank], it->second);
-        processedList.push_back(rank);
-        --recvNbClient;
-      }
-    }
-
-    for (int i = 0; i < processedList.size(); ++i)
-    {
-      requestRecvIndexServer_.erase(processedList[i]);
-      requestRecvIndexGlobal_.erase(processedList[i]);
-      countBuffIndexGlobal.erase(processedList[i]);
-      countBuffIndexServer.erase(processedList[i]);
-    }
-
-    if (0 == recvNbClient) isFinished = true;
-  }
-
-  delete [] sendBuff;
-  delete [] sendNbIndexBuff;
-  delete [] recvBuff;
-  delete [] recvNbIndexBuff;
-  delete [] recvIndexGlobalBuff;
-  delete [] recvIndexServerBuff;
-}
-
-/*!
-  Probe and receive message containg global index from other clients.
-  Each client can send a message of global index to other clients to fulfill their maps.
-Each client probes message from its queue then if the message is ready, it will be put into the receiving buffer
-  \param [in] recvIndexGlobalBuff buffer dedicated for receiving global index
-  \param [in] recvNbIndexCount size of the buffer
-*/
-void CClientServerMappingDistributed::probeIndexGlobalMessageFromClients(unsigned long* recvIndexGlobalBuff, int recvNbIndexCount)
-{
-  MPI_Status statusIndexGlobal;
-  int flagIndexGlobal, count;
-
-  // Probing for global index
-  MPI_Iprobe(MPI_ANY_SOURCE, MPI_DHT_INDEX_0, clientIntraComm_, &flagIndexGlobal, &statusIndexGlobal);
-  if ((true == flagIndexGlobal) && (countIndexGlobal_ < recvNbIndexCount))
-  {
-    MPI_Get_count(&statusIndexGlobal, MPI_UNSIGNED_LONG, &count);
-    indexGlobalBuffBegin_.insert(std::make_pair<int, unsigned long*>(statusIndexGlobal.MPI_SOURCE, recvIndexGlobalBuff+countIndexGlobal_));
-    MPI_Irecv(recvIndexGlobalBuff+countIndexGlobal_, count, MPI_UNSIGNED_LONG,
-              statusIndexGlobal.MPI_SOURCE, MPI_DHT_INDEX_0, clientIntraComm_,
-              &requestRecvIndexGlobal_[statusIndexGlobal.MPI_SOURCE]);
-    countIndexGlobal_ += count;
+    indexGlobalOnServer_[it->second].push_back(it->first);
   }
 }
 
-/*!
-  Probe and receive message containg server index from other clients.
-  Each client can send a message of server index to other clients to fulfill their maps.
-Each client probes message from its queue then if the message is ready, it will be put into the receiving buffer
-  \param [in] recvIndexServerBuff buffer dedicated for receiving server index
-  \param [in] recvNbIndexCount size of the buffer
-*/
-void CClientServerMappingDistributed::probeIndexServerMessageFromClients(int* recvIndexServerBuff, int recvNbIndexCount)
-{
-  MPI_Status statusIndexServer;
-  int flagIndexServer, count;
-
-  // Probing for server index
-  MPI_Iprobe(MPI_ANY_SOURCE, MPI_DHT_INFO_0, clientIntraComm_, &flagIndexServer, &statusIndexServer);
-  if ((true == flagIndexServer) && (countIndexServer_ < recvNbIndexCount))
-  {
-    MPI_Get_count(&statusIndexServer, MPI_INT, &count);
-    indexServerBuffBegin_.insert(std::make_pair<int, int*>(statusIndexServer.MPI_SOURCE, recvIndexServerBuff+countIndexServer_));
-    MPI_Irecv(recvIndexServerBuff+countIndexServer_, count, MPI_INT,
-              statusIndexServer.MPI_SOURCE, MPI_DHT_INFO_0, clientIntraComm_,
-              &requestRecvIndexServer_[statusIndexServer.MPI_SOURCE]);
-
-    countIndexServer_ += count;
-  }
 }
-
-/*!
-  Send message containing global index to clients
-  \param [in] clientDestRank rank of destination client
-  \param [in] indexGlobal global index to send
-  \param [in] clientIntraComm communication group of client
-  \param [in] requestSendIndexGlobal list of sending request
-*/
-void CClientServerMappingDistributed::sendIndexGlobalToClients(int clientDestRank, std::vector<size_t>& indexGlobal,
-                                                               const MPI_Comm& clientIntraComm,
-                                                               std::list<MPI_Request>& requestSendIndexGlobal)
-{
-  MPI_Request request;
-  requestSendIndexGlobal.push_back(request);
-  MPI_Isend(&(indexGlobal)[0], (indexGlobal).size(), MPI_UNSIGNED_LONG,
-            clientDestRank, MPI_DHT_INDEX_0, clientIntraComm, &(requestSendIndexGlobal.back()));
-}
-
-/*!
-  Send message containing server index to clients
-  \param [in] clientDestRank rank of destination client
-  \param [in] indexServer server index to send
-  \param [in] clientIntraComm communication group of client
-  \param [in] requestSendIndexServer list of sending request
-*/
-void CClientServerMappingDistributed::sendIndexServerToClients(int clientDestRank, std::vector<int>& indexServer,
-                                                               const MPI_Comm& clientIntraComm,
-                                                               std::list<MPI_Request>& requestSendIndexServer)
-{
-  MPI_Request request;
-  requestSendIndexServer.push_back(request);
-  MPI_Isend(&(indexServer)[0], (indexServer).size(), MPI_INT,
-            clientDestRank, MPI_DHT_INFO_0, clientIntraComm, &(requestSendIndexServer.back()));
-}
-
-/*!
-  Verify status of sending request
-  \param [in] sendRequest sending request to verify
-*/
-void CClientServerMappingDistributed::testSendRequest(std::list<MPI_Request>& sendRequest)
-{
-  int flag = 0;
-  MPI_Status status;
-  std::list<MPI_Request>::iterator itRequest;
-  int sizeListRequest = sendRequest.size();
-  int idx = 0;
-  while (idx < sizeListRequest)
-  {
-    bool isErased = false;
-    for (itRequest = sendRequest.begin(); itRequest != sendRequest.end(); ++itRequest)
-    {
-      MPI_Test(&(*itRequest), &flag, &status);
-      if (true == flag)
-      {
-        isErased = true;
-        break;
-      }
-    }
-    if (true == isErased) sendRequest.erase(itRequest);
-    ++idx;
-  }
-}
-
-/*!
-  Process the received request. Pushing global index and server index into map
-  \param[in] buffIndexGlobal pointer to the begining of buffer containing global index
-  \param[in] buffIndexServer pointer to the begining of buffer containing server index
-  \param[in] count size of received message
-*/
-void CClientServerMappingDistributed::processReceivedRequest(unsigned long* buffIndexGlobal, int* buffIndexServer, int count)
-{
-  for (int i = 0; i < count; ++i)
-    globalIndexToServerMapping_.insert(std::make_pair<size_t,int>(*(buffIndexGlobal+i),*(buffIndexServer+i)));
-}
-
-/*!
-  Compute size of message containing global index
-  \param[in] requestRecv request of message
-*/
-int CClientServerMappingDistributed::computeBuffCountIndexGlobal(MPI_Request& requestRecv)
-{
-  int flag, count = 0;
-  MPI_Status status;
-
-  MPI_Test(&requestRecv, &flag, &status);
-  if (true == flag)
-  {
-    MPI_Get_count(&status, MPI_UNSIGNED_LONG, &count);
-  }
-
-  return count;
-}
-
-/*!
-  Compute size of message containing server index
-  \param[in] requestRecv request of message
-*/
-int CClientServerMappingDistributed::computeBuffCountIndexServer(MPI_Request& requestRecv)
-{
-  int flag, count = 0;
-  MPI_Status status;
-
-  MPI_Test(&requestRecv, &flag, &status);
-  if (true == flag)
-  {
-    MPI_Get_count(&status, MPI_INT, &count);
-  }
-
-  return count;
-}
-
-/*!
-  Reset all receiving request map and counter
-*/
-void CClientServerMappingDistributed::resetReceivingRequestAndCount()
-{
-  countIndexGlobal_ = countIndexServer_ = 0;
-  requestRecvIndexGlobal_.clear();
-  requestRecvIndexServer_.clear();
-  indexGlobalBuffBegin_.clear();
-  indexServerBuffBegin_.clear();
-}
-
-}
Index: XIOS/trunk/src/client_server_mapping_distributed.hpp
===================================================================
--- XIOS/trunk/src/client_server_mapping_distributed.hpp	(revision 828)
+++ XIOS/trunk/src/client_server_mapping_distributed.hpp	(revision 829)
@@ -42,81 +42,5 @@
     virtual ~CClientServerMappingDistributed();
 
-
-
   protected:
-    // Redistribute global index and server index among clients
-    void computeDistributedServerIndex(const boost::unordered_map<size_t,int>& globalIndexOfServer,
-                                       const MPI_Comm& clientIntraComm);
-
-    // Send server index to clients
-    void sendIndexServerToClients(int clientDestRank, std::vector<int>& indexServer,
-                                  const MPI_Comm& clientIntraComm, std::list<MPI_Request>& requestSendIndexServer);
-
-    // Send global index to clients
-    void sendIndexGlobalToClients(int clientDestRank, std::vector<size_t>& indexGlobal,
-                                  const MPI_Comm& clientIntraComm, std::list<MPI_Request>& requestSendIndexGlobal);
-
-    // Verify sending request
-    void testSendRequest(std::list<MPI_Request>& sendRequest);
-
-    // Process request
-    void processReceivedRequest(unsigned long* buffIndexGlobal, int* buffIndexServer, int count);
-
-    // Probe and receive message of global index
-    void probeIndexGlobalMessageFromClients(unsigned long* recvIndexGlobalBuff, int recvNbIndexCount);
-
-    // Probe and receive message of server index
-    void probeIndexServerMessageFromClients(int* recvIndexServerBuff, int recvNbIndexCount);
-
-    // Compute range of hashing
-    void computeHashIndex();
-
-    // Compute size of receiving buffer for global index
-    int computeBuffCountIndexGlobal(MPI_Request& requestRecv);
-
-    // Compute size of receiving buffer for server index
-    int computeBuffCountIndexServer(MPI_Request& requestRecv);
-
-    // Reset request map
-    void resetReceivingRequestAndCount();
-
-  protected:
-    //! Mapping of global index to the corresponding server
-    boost::unordered_map<size_t,int> globalIndexToServerMapping_;
-
-    //! Bounds of hash index
-    std::vector<size_t> indexClientHash_;
-
-    //! Number of client
-    int nbClient_;
-
-    //! Rank of client
-    int clientRank_;
-
-    //! Counting of buffer for receiving global index
-    int countIndexGlobal_;
-
-    //! Counting of buffer for receiving server index
-    int countIndexServer_;
-
-    //! intracommuntion of clients
-    MPI_Comm clientIntraComm_;
-
-    //! Request returned by MPI_IRecv function about global index
-    std::map<int, MPI_Request> requestRecvIndexGlobal_;
-
-    //! Request returned by MPI_IRecv function about index of server
-    std::map<int, MPI_Request> requestRecvIndexServer_;
-
-    //! Mapping client rank and the beginning position of receiving buffer for message of global index from this client
-    std::map<int, unsigned long*> indexGlobalBuffBegin_;
-
-    //! Mapping client rank and the begining position of receiving buffer for message of server index from this client
-    std::map<int, int*> indexServerBuffBegin_;
-
-    //! Flag to specify whether data is distributed or not
-    bool isDataDistributed_;
-
-//    CClientClientDHTTemplate<int>* ccDHT_;
     CClientClientDHTInt* ccDHT_;
 };
Index: XIOS/trunk/src/mpi_tag.hpp
===================================================================
--- XIOS/trunk/src/mpi_tag.hpp	(revision 828)
+++ XIOS/trunk/src/mpi_tag.hpp	(revision 829)
@@ -18,8 +18,14 @@
 
 /* Tag for mpi communication to send and receive info of current grid source in grid transformation*/
-#define MPI_GRID_TRANSFORMATION_ORIGINAL_GRID_INDEX 32
+#define MPI_GRID_TRANSFORMATION_ORIGINAL_GRID_GLOBAL_INDEX 32
 
 /* Tag for mpi communication to send and receive info of current grid source in grid transformation*/
-#define MPI_GRID_TRANSFORMATION_ORIGINAL_GRID_WEIGHT 33
+#define MPI_GRID_TRANSFORMATION_ORIGINAL_GRID_LOCAL_INDEX 33
+
+/* Tag for mpi communication to send and receive info of current grid source in grid transformation*/
+#define MPI_GRID_TRANSFORMATION_ORIGINAL_GRID_WEIGHT 34
+
+/* Tag for mpi communication to send and receive info grid source and grid destination in transformation mapping*/
+#define MPI_TRANSFORMATION_MAPPING_INDEX 35
 
 /* Tag for mpi communication to send and receive info of DOMAIN in domain interpolation*/
@@ -32,3 +38,5 @@
 #define MPI_DOMAIN_INTERPOLATION_WEIGHT 9
 
+
+
 #endif
Index: XIOS/trunk/src/node/axis.cpp
===================================================================
--- XIOS/trunk/src/node/axis.cpp	(revision 828)
+++ XIOS/trunk/src/node/axis.cpp	(revision 829)
@@ -433,5 +433,5 @@
     CServerDistributionDescription serverDescriptionGlobal(globalDim, nbServer);
     int distributedDimensionOnServer = serverDescriptionGlobal.getDimensionDistributed();
-    std::map<int, std::vector<size_t> > globalIndexAxisOnServer;
+    CClientServerMapping::GlobalIndexMap globalIndexAxisOnServer;
     if (distributedDimensionOnServer == orderPositionInGrid) // So we have distributed axis on client side and also on server side*
     {
@@ -472,6 +472,6 @@
     }
 
-    std::map<int, std::vector<size_t> >::const_iterator it = globalIndexAxisOnServer.begin(),
-                                                       ite = globalIndexAxisOnServer.end();
+    CClientServerMapping::GlobalIndexMap::const_iterator it = globalIndexAxisOnServer.begin(),
+                                                         ite = globalIndexAxisOnServer.end();
     std::vector<size_t>::const_iterator itbVec = (globalAxisZoom).begin(),
                                         iteVec = (globalAxisZoom).end();
@@ -505,7 +505,9 @@
     if (!indSrv_.empty())
     {
+      std::map<int, vector<size_t> >::const_iterator itIndSrv  = indSrv_.begin(),
+                                                     iteIndSrv = indSrv_.end();
       connectedServerRank_.clear();
-      for (it = indSrv_.begin(); it != indSrv_.end(); ++it)
-        connectedServerRank_.push_back(it->first);
+      for (; itIndSrv != iteIndSrv; ++itIndSrv)
+        connectedServerRank_.push_back(itIndSrv->first);
     }
     nbConnectedClients_ = CClientServerMapping::computeConnectedClients(client->serverSize, client->clientSize, client->intraComm, connectedServerRank_);
Index: XIOS/trunk/src/node/domain.cpp
===================================================================
--- XIOS/trunk/src/node/domain.cpp	(revision 828)
+++ XIOS/trunk/src/node/domain.cpp	(revision 829)
@@ -1386,8 +1386,8 @@
                                                                                 client->intraComm);
     clientServerMap->computeServerIndexMapping(globalIndexDomain);
-    const std::map<int, std::vector<size_t> >& globalIndexDomainOnServer = clientServerMap->getGlobalIndexOnServer();
-
-    std::map<int, std::vector<size_t> >::const_iterator it = globalIndexDomainOnServer.begin(),
-                                                       ite = globalIndexDomainOnServer.end();
+    const CClientServerMapping::GlobalIndexMap& globalIndexDomainOnServer = clientServerMap->getGlobalIndexOnServer();
+
+    CClientServerMapping::GlobalIndexMap::const_iterator it  = globalIndexDomainOnServer.begin(),
+                                                         ite = globalIndexDomainOnServer.end();
     typedef XIOSBinarySearchWithIndex<size_t> BinarySearch;
     std::vector<int>::iterator itVec;
Index: XIOS/trunk/src/node/grid.cpp
===================================================================
--- XIOS/trunk/src/node/grid.cpp	(revision 828)
+++ XIOS/trunk/src/node/grid.cpp	(revision 829)
@@ -457,9 +457,9 @@
 
      clientServerMap_->computeServerIndexMapping(clientDistribution_->getGlobalIndex());
-     const std::map<int, std::vector<size_t> >& globalIndexOnServer = clientServerMap_->getGlobalIndexOnServer();
+     const CClientServerMapping::GlobalIndexMap& globalIndexOnServer = clientServerMap_->getGlobalIndexOnServer();
 
      const std::vector<size_t>& globalIndexSendToServer = clientDistribution_->getGlobalDataIndexSendToServer();
-     std::map<int, std::vector<size_t> >::const_iterator iteGlobalMap, itbGlobalMap, itGlobalMap;
-     itbGlobalMap = itGlobalMap = globalIndexOnServer.begin();
+     CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itbGlobalMap, itGlobalMap;
+     itGlobalMap  = itbGlobalMap = globalIndexOnServer.begin();
      iteGlobalMap = globalIndexOnServer.end();
 
@@ -488,6 +488,6 @@
 
      connectedServerRank_.clear();
-     for (std::map<int, std::vector<size_t> >::const_iterator it = globalIndexOnServer.begin(); it != globalIndexOnServer.end(); ++it) {
-       connectedServerRank_.push_back(it->first);
+     for (itGlobalMap = itbGlobalMap; itGlobalMap != iteGlobalMap; ++itGlobalMap) {
+       connectedServerRank_.push_back(itGlobalMap->first);
      }
 
@@ -787,5 +787,5 @@
     list<CMessage> listMsg;
     list<CArray<size_t,1> > listOutIndex;
-    const std::map<int, std::vector<size_t> >& globalIndexOnServer = clientServerMap_->getGlobalIndexOnServer();
+    const CClientServerMapping::GlobalIndexMap& globalIndexOnServer = clientServerMap_->getGlobalIndexOnServer();
     const std::vector<int>& localIndexSendToServer = clientDistribution_->getLocalDataIndexSendToServer();
     const std::vector<size_t>& globalIndexSendToServer = clientDistribution_->getGlobalDataIndexSendToServer();
@@ -821,5 +821,5 @@
     else
     {
-      std::map<int, std::vector<size_t> >::const_iterator iteGlobalMap, itbGlobalMap, itGlobalMap;
+      CClientServerMapping::GlobalIndexMap::const_iterator iteGlobalMap, itbGlobalMap, itGlobalMap;
       itbGlobalMap = itGlobalMap = globalIndexOnServer.begin();
       iteGlobalMap = globalIndexOnServer.end();
Index: XIOS/trunk/src/transformation/axis_algorithm_inverse.cpp
===================================================================
--- XIOS/trunk/src/transformation/axis_algorithm_inverse.cpp	(revision 828)
+++ XIOS/trunk/src/transformation/axis_algorithm_inverse.cpp	(revision 829)
@@ -72,19 +72,21 @@
   std::map<int, std::vector<double> >& transWeight = this->transformationWeight_[0];
 
-  std::map<size_t, std::vector<std::pair<size_t,double> > > globaIndexMapFromDestToSource;
+  CTransformationMapping::DestinationIndexMap globaIndexMapFromDestToSource;
   std::map<int, std::vector<int> >::const_iterator it = transMap.begin(), ite = transMap.end();
+  int localIndex = 0;
   for (; it != ite; ++it)
   {
-    globaIndexMapFromDestToSource[it->first].push_back(make_pair((it->second)[0], (transWeight[it->first])[0]));
+    globaIndexMapFromDestToSource[it->first].push_back(make_pair(localIndex,make_pair((it->second)[0], (transWeight[it->first])[0])));
+    ++localIndex;
   }
 
   transformationMap.computeTransformationMapping(globaIndexMapFromDestToSource);
 
-  const std::map<int,std::vector<std::vector<std::pair<size_t,double> > > >& globalIndexToReceive = transformationMap.getGlobalIndexReceivedOnGridDestMapping();
-  const std::map<int,std::vector<size_t> >& globalIndexToSend = transformationMap.getGlobalIndexSendToGridDestMapping();
+  const CTransformationMapping::ReceivedIndexMap& globalIndexToReceive = transformationMap.getGlobalIndexReceivedOnGridDestMapping();
+  const CTransformationMapping::SentIndexMap& globalIndexToSend = transformationMap.getGlobalIndexSendToGridDestMapping();
 
  // Sending global index of original grid source
-  std::map<int,std::vector<size_t> >::const_iterator itbSend = globalIndexToSend.begin(), itSend,
-                                                     iteSend = globalIndexToSend.end();
+  CTransformationMapping::SentIndexMap::const_iterator itbSend = globalIndexToSend.begin(), itSend,
+                                                       iteSend = globalIndexToSend.end();
  int sendBuffSize = 0;
  for (itSend = itbSend; itSend != iteSend; ++itSend) sendBuffSize += (itSend->second).size();
@@ -99,9 +101,9 @@
  {
    int destRank = itSend->first;
-   const std::vector<size_t>& globalIndexOfCurrentGridSourceToSend = itSend->second;
+   const std::vector<std::pair<int,size_t> >& globalIndexOfCurrentGridSourceToSend = itSend->second;
    int countSize = globalIndexOfCurrentGridSourceToSend.size();
    for (int idx = 0; idx < (countSize); ++idx)
    {
-     int index = globalIndexOfCurrentGridSourceToSend[idx] - ibeginSrc;
+     int index = globalIndexOfCurrentGridSourceToSend[idx].first;
      sendBuff[idx+currentBuffPosition] = (axisSrc_->value)(index);
    }
@@ -112,6 +114,6 @@
 
  // Receiving global index of grid source sending from current grid source
- std::map<int,std::vector<std::vector<std::pair<size_t,double> > > >::const_iterator itbRecv = globalIndexToReceive.begin(), itRecv,
-                                                                                     iteRecv = globalIndexToReceive.end();
+ CTransformationMapping::ReceivedIndexMap::const_iterator itbRecv = globalIndexToReceive.begin(), itRecv,
+                                                          iteRecv = globalIndexToReceive.end();
  int recvBuffSize = 0;
  for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv) recvBuffSize += (itRecv->second).size();
Index: XIOS/trunk/src/transformation/axis_algorithm_transformation.cpp
===================================================================
--- XIOS/trunk/src/transformation/axis_algorithm_transformation.cpp	(revision 828)
+++ XIOS/trunk/src/transformation/axis_algorithm_transformation.cpp	(revision 829)
@@ -49,6 +49,6 @@
                                                                           const std::vector<int>& gridDestGlobalDim,
                                                                           const std::vector<int>& gridSrcGlobalDim,
-                                                                          const std::vector<size_t>& globalIndexGridDestSendToServer,
-                                                                          CArray<size_t,1>& globalIndexDestGrid,
+                                                                          const GlobalLocalMap& globalLocalIndexDestSendToServerMap,
+                                                                          std::vector<std::pair<size_t,int> >& globalLocalIndexDestMap,
                                                                           std::vector<std::vector<size_t> >& globalIndexSrcGrid)
 {
@@ -72,6 +72,5 @@
   }
 
-  std::vector<size_t>::const_iterator itbArr = globalIndexGridDestSendToServer.begin(), itArr,
-                                      iteArr = globalIndexGridDestSendToServer.end();
+  GlobalLocalMap::const_iterator iteArr = globalLocalIndexDestSendToServerMap.end(), it;
 
   while (idx < ssize)
@@ -111,11 +110,11 @@
     }
 
-    if (std::binary_search(itbArr, iteArr, globIndex)) ++realGlobalIndexSize;
+    if (iteArr != globalLocalIndexDestSendToServerMap.find(globIndex)) ++realGlobalIndexSize;
     ++idxLoop[0];
     ++idx;
   }
 
-  if (globalIndexDestGrid.numElements() != realGlobalIndexSize)
-    globalIndexDestGrid.resize(realGlobalIndexSize);
+  if (globalLocalIndexDestMap.size() != realGlobalIndexSize)
+    globalLocalIndexDestMap.resize(realGlobalIndexSize);
 
   if (realGlobalIndexSize != globalIndexSrcGrid.size()) globalIndexSrcGrid.resize(realGlobalIndexSize);
@@ -162,7 +161,8 @@
     }
 
-    if (std::binary_search(itbArr, iteArr, globIndex))
+    it = globalLocalIndexDestSendToServerMap.find(globIndex);
+    if (iteArr != it)
     {
-      globalIndexDestGrid(realGlobalIndex) = globIndex;
+      globalLocalIndexDestMap[realGlobalIndex] = (std::make_pair(it->first,it->second));
       for (int i = 0; i < globalIndexSrcGrid[realGlobalIndex].size(); ++i)
       {
@@ -183,105 +183,4 @@
     ++idx;
   }
-
-
-
-//  int globalDim = gridDestGlobalDim.size();
-//
-//  std::vector<size_t> currentIndex(globalDim);
-//  std::vector<int> gridAxisGlobalDim(globalDim);
-//  std::vector<int> idxLoop(globalDim, 0);
-//
-//  size_t ssize = 1, idx = 0, realGlobalIndexSize = 0;
-//  for (int i = 0; i< globalDim; ++i)
-//  {
-//    if (axisPositionInGrid == i) gridAxisGlobalDim[i] = 1;
-//    else gridAxisGlobalDim[i] = gridDestGlobalDim[i];
-//    ssize *= gridAxisGlobalDim[i];
-//  }
-//
-//  std::vector<size_t>::const_iterator itbArr = globalIndexGridDestSendToServer.begin(), itArr,
-//                                      iteArr = globalIndexGridDestSendToServer.end();
-//
-//  while (idx < ssize)
-//  {
-//    for (int i = 0; i < globalDim-1; ++i)
-//    {
-//      if (idxLoop[i] == gridAxisGlobalDim[i])
-//      {
-//        idxLoop[i] = 0;
-//        ++idxLoop[i+1];
-//      }
-//    }
-//
-//    for (int i = 0; i < globalDim; ++i) currentIndex[i] = idxLoop[i];
-//    currentIndex[axisPositionInGrid] = axisDestGlobalIndex;
-//
-//    size_t globIndex = currentIndex[0];
-//    size_t mulDim = 1;
-//    for (int k = 1; k < globalDim; ++k)
-//    {
-//      mulDim *= gridDestGlobalDim[k-1];
-//      globIndex += (currentIndex[k])*mulDim;
-//    }
-//
-//    if (std::binary_search(itbArr, iteArr, globIndex)) ++realGlobalIndexSize;
-//    ++idxLoop[0];
-//    ++idx;
-//  }
-//
-//  if (globalIndexDestGrid.numElements() != realGlobalIndexSize)
-//    globalIndexDestGrid.resize(realGlobalIndexSize);
-//
-//  if (realGlobalIndexSize != globalIndexSrcGrid.size()) globalIndexSrcGrid.resize(realGlobalIndexSize);
-//  for (int i = 0; i < globalIndexSrcGrid.size(); ++i)
-//    if (globalIndexSrcGrid[i].size() != axisSrcGlobalIndex.size())
-//      globalIndexSrcGrid[i].resize(axisSrcGlobalIndex.size());
-//
-//  size_t realGlobalIndex = 0;
-//  idx = 0;
-//  idxLoop.assign(globalDim, 0);
-//  while (idx < ssize)
-//  {
-//    for (int i = 0; i < globalDim-1; ++i)
-//    {
-//      if (idxLoop[i] == gridAxisGlobalDim[i])
-//      {
-//        idxLoop[i] = 0;
-//        ++idxLoop[i+1];
-//      }
-//    }
-//
-//    for (int i = 0; i < globalDim; ++i) currentIndex[i] = idxLoop[i];
-//    currentIndex[axisPositionInGrid] = axisDestGlobalIndex;
-//
-//    size_t globIndex = currentIndex[0];
-//    size_t mulDim = 1;
-//    for (int k = 1; k < globalDim; ++k)
-//    {
-//      mulDim *= gridDestGlobalDim[k-1];
-//      globIndex += (currentIndex[k])*mulDim;
-//    }
-//
-//    if (std::binary_search(itbArr, iteArr, globIndex))
-//    {
-//      globalIndexDestGrid(realGlobalIndex) = globIndex;
-//      for (int i = 0; i < globalIndexSrcGrid[realGlobalIndex].size(); ++i)
-//      {
-//        currentIndex[axisPositionInGrid] = axisSrcGlobalIndex[i];
-//        globIndex = currentIndex[0];
-//        mulDim = 1;
-//        for (int k = 1; k < globalDim; ++k)
-//        {
-//          mulDim *= gridDestGlobalDim[k-1];
-//          globIndex += (currentIndex[k])*mulDim;
-//        }
-//        (globalIndexSrcGrid[realGlobalIndex])[i] = globIndex;
-//      }
-//      ++realGlobalIndex;
-//    }
-//
-//    ++idxLoop[0];
-//    ++idx;
-//  }
 }
 }
Index: XIOS/trunk/src/transformation/axis_algorithm_transformation.hpp
===================================================================
--- XIOS/trunk/src/transformation/axis_algorithm_transformation.hpp	(revision 828)
+++ XIOS/trunk/src/transformation/axis_algorithm_transformation.hpp	(revision 829)
@@ -33,6 +33,6 @@
                                                         const std::vector<int>& gridDestGlobalDim,
                                                         const std::vector<int>& gridSrcGlobalDim,
-                                                        const std::vector<size_t>& globalIndexGridDestSendToServer,
-                                                        CArray<size_t,1>& globalIndexDestGrid,
+                                                        const GlobalLocalMap& globalLocalIndexDestSendToServerMap,
+                                                        std::vector<std::pair<size_t,int> >& globalLocalIndexDestMap,
                                                         std::vector<std::vector<size_t> >& globalIndexSrcGrid);
 
Index: XIOS/trunk/src/transformation/domain_algorithm_interpolate.cpp
===================================================================
--- XIOS/trunk/src/transformation/domain_algorithm_interpolate.cpp	(revision 828)
+++ XIOS/trunk/src/transformation/domain_algorithm_interpolate.cpp	(revision 829)
@@ -417,5 +417,5 @@
 
   domainIndexClientClientMapping.computeServerIndexMapping(globalIndexInterp);
-  const std::map<int, std::vector<size_t> >& globalIndexInterpSendToClient = domainIndexClientClientMapping.getGlobalIndexOnServer();
+  const CClientServerMapping::GlobalIndexMap& globalIndexInterpSendToClient = domainIndexClientClientMapping.getGlobalIndexOnServer();
 
   //Inform each client number of index they will receive
@@ -429,6 +429,6 @@
   }
   int sendBuffSize = 0;
-  std::map<int, std::vector<size_t> >::const_iterator itbMap = globalIndexInterpSendToClient.begin(), itMap,
-                                                      iteMap = globalIndexInterpSendToClient.end();
+  CClientServerMapping::GlobalIndexMap::const_iterator itbMap = globalIndexInterpSendToClient.begin(), itMap,
+                                                       iteMap = globalIndexInterpSendToClient.end();
   for (itMap = itbMap; itMap != iteMap; ++itMap)
   {
Index: XIOS/trunk/src/transformation/domain_algorithm_transformation.cpp
===================================================================
--- XIOS/trunk/src/transformation/domain_algorithm_transformation.cpp	(revision 828)
+++ XIOS/trunk/src/transformation/domain_algorithm_transformation.cpp	(revision 829)
@@ -42,6 +42,6 @@
                                                                           const std::vector<int>& gridDestGlobalDim,
                                                                           const std::vector<int>& gridSrcGlobalDim,
-                                                                          const std::vector<size_t>& globalIndexGridDestSendToServer,
-                                                                          CArray<size_t,1>& globalIndexDestGrid,
+                                                                          const GlobalLocalMap& globalLocalIndexDestSendToServerMap,
+                                                                          std::vector<std::pair<size_t,int> >& globalLocalIndexDestMap,
                                                                           std::vector<std::vector<size_t> >& globalIndexSrcGrid)
 {
@@ -79,6 +79,6 @@
   for (int i = 0; i< numElement; ++i) ssize *= gridDomainGlobalDim[i];
 
-  std::vector<size_t>::const_iterator itbArr = globalIndexGridDestSendToServer.begin(), itArr,
-                                      iteArr = globalIndexGridDestSendToServer.end();
+  GlobalLocalMap::const_iterator iteArr = globalLocalIndexDestSendToServerMap.end(), it;
+
   idx = 0;
   while (idx < ssize)
@@ -112,11 +112,11 @@
     }
 
-    if (std::binary_search(itbArr, iteArr, globIndex)) ++realGlobalIndexSize;
+    if (iteArr != globalLocalIndexDestSendToServerMap.find(globIndex)) ++realGlobalIndexSize;
     ++idxLoop[0];
     ++idx;
   }
 
-  if (globalIndexDestGrid.numElements() != realGlobalIndexSize)
-    globalIndexDestGrid.resize(realGlobalIndexSize);
+  if (globalLocalIndexDestMap.size() != realGlobalIndexSize)
+    globalLocalIndexDestMap.resize(realGlobalIndexSize);
 
   if (realGlobalIndexSize != globalIndexSrcGrid.size()) globalIndexSrcGrid.resize(realGlobalIndexSize);
@@ -158,7 +158,8 @@
     }
 
-    if (std::binary_search(itbArr, iteArr, globIndex))
+    it = globalLocalIndexDestSendToServerMap.find(globIndex);
+    if (iteArr != it)
     {
-      globalIndexDestGrid(realGlobalIndex) = globIndex;
+      globalLocalIndexDestMap[realGlobalIndex] = (std::make_pair(it->first,it->second));
       for (int i = 0; i < globalIndexSrcGrid[realGlobalIndex].size(); ++i)
       {
Index: XIOS/trunk/src/transformation/domain_algorithm_transformation.hpp
===================================================================
--- XIOS/trunk/src/transformation/domain_algorithm_transformation.hpp	(revision 828)
+++ XIOS/trunk/src/transformation/domain_algorithm_transformation.hpp	(revision 829)
@@ -33,6 +33,6 @@
                                                         const std::vector<int>& gridDestGlobalDim,
                                                         const std::vector<int>& gridSrcGlobalDim,
-                                                        const std::vector<size_t>& globalIndexGridDestSendToServer,
-                                                        CArray<size_t,1>& globalIndexDestGrid,
+                                                        const GlobalLocalMap& globalLocalIndexDestSendToServerMap,
+                                                        std::vector<std::pair<size_t,int> >& globalLocalIndexDestMap,
                                                         std::vector<std::vector<size_t> >& globalIndexSrcGrid);
 
Index: XIOS/trunk/src/transformation/generic_algorithm_transformation.cpp
===================================================================
--- XIOS/trunk/src/transformation/generic_algorithm_transformation.cpp	(revision 828)
+++ XIOS/trunk/src/transformation/generic_algorithm_transformation.cpp	(revision 829)
@@ -3,5 +3,5 @@
    \author Ha NGUYEN
    \since 14 May 2015
-   \date 29 June 2015
+   \date 21 Mars 2016
 
    \brief Interface for all transformation algorithms.
@@ -23,6 +23,7 @@
   \param[in] gridSrcGlobalDim dimension size of source grid (it should share the same size for all dimension, maybe except the domain on which transformation is performed)
   \param[in] globalIndexGridDestSendToServer global index of grid destination on the current client to send to server
+  \param[in] localIndexGridSendToServer local index of grid destination on the current client to send to server
   \param[in/out] globaIndexWeightFromDestToSource mapping between transformed global index of grid destination
-             and the weighted value as long as global index from grid index source
+             and the weighted value as well as global index from grid index source
 */
 void CGenericAlgorithmTransformation::computeGlobalSourceIndex(int elementPositionInGrid,
@@ -30,9 +31,15 @@
                                                              const std::vector<int>& gridSrcGlobalDim,
                                                              const std::vector<size_t>& globalIndexGridDestSendToServer,
-                                                             std::map<size_t, std::vector<std::pair<size_t,double> > >& globaIndexWeightFromDestToSource)
+                                                             const std::vector<int>& localIndexGridSendToServer,
+                                                             DestinationIndexMap& globaIndexWeightFromDestToSource)
 {
   bool isTransPosEmpty = transformationPosition_.empty();
-  std::vector<size_t> vecGlobalIndexGridSendToServer(globalIndexGridDestSendToServer.begin(), globalIndexGridDestSendToServer.end());
-  std::sort(vecGlobalIndexGridSendToServer.begin(), vecGlobalIndexGridSendToServer.end());
+  boost::unordered_map<size_t,int> globalLocalIndexDestSendToServerMap;
+  size_t nbGlobalIndexDest = globalIndexGridDestSendToServer.size();
+  for (size_t idx = 0; idx < nbGlobalIndexDest; ++idx)
+  {
+    globalLocalIndexDestSendToServerMap[globalIndexGridDestSendToServer[idx]] = localIndexGridSendToServer[idx];
+  }
+
   for (size_t idxTrans = 0; idxTrans < transformationMapping_.size(); ++idxTrans)
   {
@@ -51,20 +58,19 @@
 
     std::vector<std::vector<size_t> > globalIndexSrcGrid;
-    CArray<size_t,1> globalIndexDestGrid;
-//    std::vector<size_t> vecGlobalIndexGridSendToServer(globalIndexGridDestSendToServer.begin(), globalIndexGridDestSendToServer.end());
-//    std::sort(vecGlobalIndexGridSendToServer.begin(), vecGlobalIndexGridSendToServer.end());
+    std::vector<std::pair<size_t,int> > globalLocalIndexDest;
     for (itTransMap = itbTransMap; itTransMap != iteTransMap; ++itTransMap, ++itTransWeight)
     {
+      boost::unordered_map<size_t,int> globalLocalIndexDestMap;
       if (!isTransPosEmpty)
       {
         this->computeGlobalGridIndexFromGlobalIndexElement(itTransMap->first,
-                                                       itTransMap->second,
-                                                       itTransPos->second,
-                                                       elementPositionInGrid,
-                                                       gridDestGlobalDim,
-                                                       gridSrcGlobalDim,
-                                                       vecGlobalIndexGridSendToServer,
-                                                       globalIndexDestGrid,
-                                                       globalIndexSrcGrid);
+                                                           itTransMap->second,
+                                                           itTransPos->second,
+                                                           elementPositionInGrid,
+                                                           gridDestGlobalDim,
+                                                           gridSrcGlobalDim,
+                                                           globalLocalIndexDestSendToServerMap,
+                                                           globalLocalIndexDest,
+                                                           globalIndexSrcGrid);
         ++itTransPos;
       }
@@ -72,21 +78,23 @@
       {
         this->computeGlobalGridIndexFromGlobalIndexElement(itTransMap->first,
-                                                       itTransMap->second,
-                                                       emptyTransPos,
-                                                       elementPositionInGrid,
-                                                       gridDestGlobalDim,
-                                                       gridSrcGlobalDim,
-                                                       vecGlobalIndexGridSendToServer,
-                                                       globalIndexDestGrid,
-                                                       globalIndexSrcGrid);
+                                                           itTransMap->second,
+                                                           emptyTransPos,
+                                                           elementPositionInGrid,
+                                                           gridDestGlobalDim,
+                                                           gridSrcGlobalDim,
+                                                           globalLocalIndexDestSendToServerMap,
+                                                           globalLocalIndexDest,
+                                                           globalIndexSrcGrid);
       }
-      size_t globalIndexSize = globalIndexDestGrid.numElements();
+      std::vector<std::pair<size_t,int> >::const_iterator it = globalLocalIndexDest.begin(), ite = globalLocalIndexDest.end();
       const std::vector<double>& currentVecWeight = itTransWeight->second;
-      for (size_t idx = 0; idx < globalIndexSize; ++idx)
+
+      for (size_t idx = 0; it != ite; ++it, ++idx)
       {
-        size_t globalIndex = globalIndexDestGrid(idx);
-        for (int i = 0; i < globalIndexSrcGrid[idx].size(); ++i)
+        size_t srcGridSize = globalIndexSrcGrid[idx].size();
+        globaIndexWeightFromDestToSource[(it->first)].reserve(srcGridSize);
+        for (int i = 0; i < srcGridSize; ++i)
         {
-          globaIndexWeightFromDestToSource[globalIndex].push_back(make_pair(globalIndexSrcGrid[idx][i], currentVecWeight[i]));
+          globaIndexWeightFromDestToSource[(it->first)].push_back(make_pair(it->second, make_pair(globalIndexSrcGrid[idx][i], currentVecWeight[i])));
         }
       }
Index: XIOS/trunk/src/transformation/generic_algorithm_transformation.hpp
===================================================================
--- XIOS/trunk/src/transformation/generic_algorithm_transformation.hpp	(revision 828)
+++ XIOS/trunk/src/transformation/generic_algorithm_transformation.hpp	(revision 829)
@@ -22,4 +22,11 @@
 {
 public:
+  // Stupid global index map, it must be replaced by tuple
+  // Mapping between global index map of DESTINATION and its local index with pair of global index of SOURCE and weights
+  typedef boost::unordered_map<size_t, std::vector<std::pair<int, std::pair<size_t,double> > > > DestinationIndexMap;
+protected:
+  typedef boost::unordered_map<size_t,int> GlobalLocalMap;
+
+public:
   CGenericAlgorithmTransformation();
 
@@ -30,5 +37,6 @@
                                 const std::vector<int>& gridSrcGlobalDim,
                                 const std::vector<size_t>& globalIndexGridDestSendToServer,
-                                std::map<size_t, std::vector<std::pair<size_t,double> > >& globaIndexWeightFromDestToSource);
+                                const std::vector<int>& localIndexGridSendToServer,
+                                DestinationIndexMap& globaIndexWeightFromDestToSource);
 
   std::vector<StdString> getIdAuxInputs();
@@ -46,6 +54,6 @@
     \param[in] elementPositionInGrid position of the element in the grid (for example: a grid with one domain and one axis, position of domain is 1, position of axis is 2)
     \param[in] gridDestGlobalDim dimension size of destination grid (it should share the same size for all dimension, maybe except the element on which transformation is performed)
-    \param[in] globalIndexGridDestSendToServer global index of destination grid which are to be sent to server(s), this array is already acsending sorted
-    \param[in/out] globalIndexDestGrid array of global index (for 2d grid, this array maybe a line, for 3d, this array may represent a plan). It should be preallocated
+    \param[in] globalLocalIndexDestSendToServerMap pair of global index and local index of destination grid which are to be sent to server(s), this array is already acsending sorted
+    \param[in/out] globalLocalIndexDestMap array of global index (for 2d grid, this array maybe a line, for 3d, this array may represent a plan). It should be preallocated
     \param[in/out] globalIndexSrcGrid array of global index of source grid (for 2d grid, this array is a line, for 3d, this array represents a plan). It should be preallocated
   */
@@ -56,6 +64,6 @@
                                                         const std::vector<int>& gridDestGlobalDim,
                                                         const std::vector<int>& gridSrcGlobalDim,
-                                                        const std::vector<size_t>& globalIndexGridDestSendToServer,
-                                                        CArray<size_t,1>& globalIndexDestGrid,
+                                                        const GlobalLocalMap& globalLocalIndexDestSendToServerMap,
+                                                        std::vector<std::pair<size_t,int> >& globalLocalIndexDestMap,
                                                         std::vector<std::vector<size_t> >& globalIndexSrcGrid) = 0;
 
Index: XIOS/trunk/src/transformation/grid_transformation.cpp
===================================================================
--- XIOS/trunk/src/transformation/grid_transformation.cpp	(revision 828)
+++ XIOS/trunk/src/transformation/grid_transformation.cpp	(revision 829)
@@ -19,4 +19,5 @@
 #include "distribution_client.hpp"
 #include "mpi_tag.hpp"
+#include <boost/unordered_map.hpp>
 
 namespace xios {
@@ -359,5 +360,5 @@
   if (nbAlgos_ < 1) return;
   if (!auxInputs_.empty() && !dynamicalTransformation_) { dynamicalTransformation_ = true; return; }
-  if (dynamicalTransformation_) GlobalIndexMap().swap(currentGridIndexToOriginalGridIndex_);  // Reset map
+  if (dynamicalTransformation_) DestinationIndexMap().swap(currentGridIndexToOriginalGridIndex_);  // Reset map
 
   CContext* context = CContext::getCurrent();
@@ -374,5 +375,5 @@
     ETranformationType transType = (it->second).first;
     int transformationOrder = (it->second).second;
-    std::map<size_t, std::vector<std::pair<size_t,double> > > globaIndexWeightFromDestToSource;
+    DestinationIndexMap globaIndexWeightFromDestToSource;
 
     // First of all, select an algorithm
@@ -392,4 +393,5 @@
       CDistributionClient distributionClientDest(client->clientRank, gridDestination_);
       const std::vector<size_t>& globalIndexGridDestSendToServer = distributionClientDest.getGlobalDataIndexSendToServer();
+      const std::vector<int>& localIndexGridDestSendToServer = distributionClientDest.getLocalDataIndexSendToServer();
 
       // ComputeTransformation of global index of each element
@@ -401,4 +403,5 @@
                                      gridSrcDimensionSize,
                                      globalIndexGridDestSendToServer,
+                                     localIndexGridDestSendToServer,
                                      globaIndexWeightFromDestToSource);
 
@@ -446,5 +449,5 @@
   iteArr = globalIndexOnClientDest.end();
 
-  GlobalIndexMap::const_iterator iteGlobalMap = currentGridIndexToOriginalGridIndex_.end();
+  DestinationIndexMap::const_iterator iteGlobalMap = currentGridIndexToOriginalGridIndex_.end();
   const size_t sfmax = NumTraits<unsigned long>::sfmax();
   int maskIndexNum = 0;
@@ -453,8 +456,8 @@
     if (iteGlobalMap != currentGridIndexToOriginalGridIndex_.find(*itArr))
     {
-      const std::vector<std::pair<size_t,double> >& vecIndex = currentGridIndexToOriginalGridIndex_[*itArr];
+      const std::vector<std::pair<int, std::pair<size_t,double> > >& vecIndex = currentGridIndexToOriginalGridIndex_[*itArr];
       for (int idx = 0; idx < vecIndex.size(); ++idx)
       {
-        if (sfmax == vecIndex[idx].first)
+        if (sfmax == (vecIndex[idx].second).first)
         {
           ++maskIndexNum;
@@ -471,8 +474,8 @@
     if (iteGlobalMap != currentGridIndexToOriginalGridIndex_.find(*itArr))
     {
-      const std::vector<std::pair<size_t,double> >& vecIndex = currentGridIndexToOriginalGridIndex_[*itArr];
+      const std::vector<std::pair<int, std::pair<size_t,double> > >& vecIndex = currentGridIndexToOriginalGridIndex_[*itArr];
       for (int idx = 0; idx < vecIndex.size(); ++idx)
       {
-        if (sfmax == vecIndex[idx].first)
+        if (sfmax == (vecIndex[idx].second).first)
         {
           int localIdx = std::distance(itbArr, itArr);
@@ -493,5 +496,5 @@
 the final grid destination
 */
-void CGridTransformation::computeTransformationFromOriginalGridSource(const std::map<size_t, std::vector<std::pair<size_t,double> > >& globaIndexMapFromDestToSource)
+void CGridTransformation::computeTransformationFromOriginalGridSource(const DestinationIndexMap& globaIndexMapFromDestToSource)
 {
   CContext* context = CContext::getCurrent();
@@ -509,10 +512,10 @@
   transformationMap.computeTransformationMapping(globaIndexMapFromDestToSource);
 
-  const std::map<int,std::vector<std::vector<std::pair<size_t,double> > > >& globalIndexToReceive = transformationMap.getGlobalIndexReceivedOnGridDestMapping();
-  const std::map<int,std::vector<size_t> >& globalIndexToSend = transformationMap.getGlobalIndexSendToGridDestMapping();
+  const CTransformationMapping::ReceivedIndexMap& globalIndexToReceive = transformationMap.getGlobalIndexReceivedOnGridDestMapping();
+  const CTransformationMapping::SentIndexMap& globalIndexToSend = transformationMap.getGlobalIndexSendToGridDestMapping();
 
  // Sending global index of original grid source
-  std::map<int,std::vector<size_t> >::const_iterator itbSend = globalIndexToSend.begin(), itSend,
-                                                     iteSend = globalIndexToSend.end();
+  CTransformationMapping::SentIndexMap::const_iterator itbSend = globalIndexToSend.begin(), itSend,
+                                                       iteSend = globalIndexToSend.end();
  int sendBuffSize = 0;
  for (itSend = itbSend; itSend != iteSend; ++itSend) sendBuffSize += (itSend->second).size();
@@ -526,6 +529,6 @@
  for (StdSize idx = 0; idx < sendBuffSize; ++idx) sendBuff[idx] = NumTraits<Scalar>::sfmax();
 
- std::map<int, MPI_Request> requestsCurrentGrid, requestsOriginalGrid, requestsWeightGrid;
- GlobalIndexMap::const_iterator iteGlobalIndex = currentGridIndexToOriginalGridIndex_.end();
+ std::map<int, MPI_Request> requestsCurrentGrid, requestsOriginalGridGlobalIndex, requestsOriginalGridLocalIndex, requestsWeightGrid;
+ DestinationIndexMap::const_iterator iteGlobalIndex = currentGridIndexToOriginalGridIndex_.end();
 
   // Only send global index of original source corresponding to non-masked index
@@ -536,11 +539,11 @@
  {
    int destRank = itSend->first;
-   const std::vector<size_t>& globalIndexOfCurrentGridSourceToSend = itSend->second;
+   const std::vector<std::pair<int, size_t> >& globalIndexOfCurrentGridSourceToSend = itSend->second;
    int countSize  = globalIndexOfCurrentGridSourceToSend.size();
    size_t countBlock = 0;
    for (int idx = 0; idx < countSize; ++idx)
    {
-     size_t index = globalIndexOfCurrentGridSourceToSend[idx];
-     if (iteGlobalIndex != currentGridIndexToOriginalGridIndex_.find(index))// searchCurrentSrc.search(itbIndex, iteIndex, globalIndexOfCurrentGridSourceToSend[idx], itIndex))
+     size_t index = globalIndexOfCurrentGridSourceToSend[idx].second;
+     if (iteGlobalIndex != currentGridIndexToOriginalGridIndex_.find(index))
      {
        globalIndexOriginalSrcSendBuffSize += currentGridIndexToOriginalGridIndex_[index].size() + 1; // 1 for number of elements in this block
@@ -555,6 +558,6 @@
  }
 
- Scalar* sendOriginalIndexBuff, *currentOriginalIndexSendBuff;
- if (0 != globalIndexOriginalSrcSendBuffSize) sendOriginalIndexBuff = new Scalar [globalIndexOriginalSrcSendBuffSize];
+ Scalar* sendOriginalGlobalIndexBuff, *currentOriginalGlobalIndexSendBuff;
+ if (0 != globalIndexOriginalSrcSendBuffSize) sendOriginalGlobalIndexBuff = new Scalar [globalIndexOriginalSrcSendBuffSize];
  double* sendOriginalWeightBuff, *currentOriginalWeightSendBuff;
  if (0 != globalIndexOriginalSrcSendBuffSize) sendOriginalWeightBuff = new double [globalIndexOriginalSrcSendBuffSize];
@@ -564,21 +567,21 @@
  {
    int destRank = itSend->first;
-   const std::vector<size_t>& globalIndexOfCurrentGridSourceToSend = itSend->second;
+   const std::vector<std::pair<int, size_t> >& globalIndexOfCurrentGridSourceToSend = itSend->second;
    int countSize = globalIndexOfCurrentGridSourceToSend.size();
    int increaseStep = 0;
    for (int idx = 0; idx < countSize; ++idx)
    {
-     size_t index = globalIndexOfCurrentGridSourceToSend[idx];
+     size_t index = globalIndexOfCurrentGridSourceToSend[idx].second;
      if (iteGlobalIndex != currentGridIndexToOriginalGridIndex_.find(index))
      {
        size_t vectorSize = currentGridIndexToOriginalGridIndex_[index].size();
-       sendOriginalIndexBuff[currentBuffPosition+increaseStep]  = vectorSize;
+       sendOriginalGlobalIndexBuff[currentBuffPosition+increaseStep]  = vectorSize;
        sendOriginalWeightBuff[currentBuffPosition+increaseStep] = (double)vectorSize;
-       const std::vector<std::pair<size_t,double> >& indexWeightPair = currentGridIndexToOriginalGridIndex_[index];
+       const std::vector<std::pair<int, std::pair<size_t,double> > >& indexWeightPair = currentGridIndexToOriginalGridIndex_[index];
        for (size_t i = 0; i < vectorSize; ++i)
        {
          ++increaseStep;
-         sendOriginalIndexBuff[currentBuffPosition+increaseStep]  = indexWeightPair[i].first;
-         sendOriginalWeightBuff[currentBuffPosition+increaseStep] = indexWeightPair[i].second;
+         sendOriginalGlobalIndexBuff[currentBuffPosition+increaseStep]  = (indexWeightPair[i].second).first;
+         sendOriginalWeightBuff[currentBuffPosition+increaseStep] = (indexWeightPair[i].second).second;
        }
        ++increaseStep;
@@ -586,10 +589,12 @@
    }
 
-   currentOriginalIndexSendBuff = sendOriginalIndexBuff + currentBuffPosition;
+   currentOriginalGlobalIndexSendBuff = sendOriginalGlobalIndexBuff + currentBuffPosition;
    currentOriginalWeightSendBuff = sendOriginalWeightBuff + currentBuffPosition;
    if (0 != increaseStep)
    {
-     MPI_Isend(currentOriginalIndexSendBuff, increaseStep, MPI_UNSIGNED_LONG, destRank, MPI_GRID_TRANSFORMATION_ORIGINAL_GRID_INDEX, client->intraComm, &requestsOriginalGrid[destRank]);
-     MPI_Isend(currentOriginalWeightSendBuff, increaseStep, MPI_DOUBLE, destRank, MPI_GRID_TRANSFORMATION_ORIGINAL_GRID_WEIGHT, client->intraComm, &requestsWeightGrid[destRank]);
+     MPI_Isend(currentOriginalGlobalIndexSendBuff, increaseStep, MPI_UNSIGNED_LONG, destRank,
+               MPI_GRID_TRANSFORMATION_ORIGINAL_GRID_GLOBAL_INDEX, client->intraComm, &requestsOriginalGridGlobalIndex[destRank]);
+     MPI_Isend(currentOriginalWeightSendBuff, increaseStep, MPI_DOUBLE, destRank,
+               MPI_GRID_TRANSFORMATION_ORIGINAL_GRID_WEIGHT, client->intraComm, &requestsWeightGrid[destRank]);
    }
    currentBuffPosition += increaseStep;
@@ -598,6 +603,6 @@
 
  // Receiving global index of grid source sending from current grid source
- std::map<int,std::vector<std::vector<std::pair<size_t,double> > > >::const_iterator itbRecv = globalIndexToReceive.begin(), itRecv,
-                                                                                     iteRecv = globalIndexToReceive.end();
+ CTransformationMapping::ReceivedIndexMap::const_iterator itbRecv = globalIndexToReceive.begin(), itRecv,
+                                                          iteRecv = globalIndexToReceive.end();
  int recvBuffSize = 0;
  for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv) recvBuffSize += (itRecv->second).size();
@@ -623,6 +628,6 @@
  }
 
- Scalar* recvOriginalIndexBuff, *currentOriginalIndexRecvBuff;
- if (0 != globalIndexOriginalSrcRecvBuffSize) recvOriginalIndexBuff = new Scalar [globalIndexOriginalSrcRecvBuffSize];
+ Scalar* recvOriginalGlobalIndexBuff, *currentOriginalGlobalIndexRecvBuff;
+ if (0 != globalIndexOriginalSrcRecvBuffSize) recvOriginalGlobalIndexBuff = new Scalar [globalIndexOriginalSrcRecvBuffSize];
  double* recvOriginalWeightBuff, *currentOriginalWeightRecvBuff;
  if (0 != globalIndexOriginalSrcRecvBuffSize) recvOriginalWeightBuff = new double [globalIndexOriginalSrcRecvBuffSize];
@@ -633,12 +638,12 @@
  for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv)
  {
-   MPI_Status statusIndex, statusWeight;
+   MPI_Status statusGlobalIndex, statusLocalIndex, statusWeight;
    int srcRank = itRecv->first;
    countBlock = countBlockMap[srcRank];
-   currentOriginalIndexRecvBuff = recvOriginalIndexBuff + currentBuffPosition;
+   currentOriginalGlobalIndexRecvBuff = recvOriginalGlobalIndexBuff + currentBuffPosition;
    currentOriginalWeightRecvBuff = recvOriginalWeightBuff + currentBuffPosition;
    if (0 != countBlock)
    {
-     MPI_Recv(currentOriginalIndexRecvBuff, countBlock, MPI_UNSIGNED_LONG, srcRank, MPI_GRID_TRANSFORMATION_ORIGINAL_GRID_INDEX, client->intraComm, &statusIndex);
+     MPI_Recv(currentOriginalGlobalIndexRecvBuff, countBlock, MPI_UNSIGNED_LONG, srcRank, MPI_GRID_TRANSFORMATION_ORIGINAL_GRID_GLOBAL_INDEX, client->intraComm, &statusGlobalIndex);
      MPI_Recv(currentOriginalWeightRecvBuff, countBlock, MPI_DOUBLE, srcRank, MPI_GRID_TRANSFORMATION_ORIGINAL_GRID_WEIGHT, client->intraComm, &statusWeight);
    }
@@ -649,9 +654,9 @@
  // The way to process masked index needs discussing
  const size_t sfmax = NumTraits<unsigned long>::sfmax();
- GlobalIndexMap currentToOriginalTmp;
+ DestinationIndexMap currentToOriginalTmp;
 
  currentRecvBuffPosition = 0;
  currentRecvBuff = recvBuff;
- currentOriginalIndexRecvBuff  = recvOriginalIndexBuff;
+ currentOriginalGlobalIndexRecvBuff  = recvOriginalGlobalIndexBuff;
  currentOriginalWeightRecvBuff = recvOriginalWeightBuff;
  for (itRecv = itbRecv; itRecv != iteRecv; ++itRecv)
@@ -669,12 +674,13 @@
        if (0 != countBlockRank)
        {
-         countBlock = *(currentOriginalIndexRecvBuff+currentRecvBuffPosition);
+         countBlock = *(currentOriginalGlobalIndexRecvBuff+currentRecvBuffPosition);
          for (int i = 0; i < ssize; ++i)
          {
            for (int j = 0; j < countBlock; ++j)
            {
-             size_t globalOriginalIndex = *(currentOriginalIndexRecvBuff+currentRecvBuffPosition+j+1);
-             double weightGlobal = *(currentOriginalWeightRecvBuff+currentRecvBuffPosition+j+1) * (itRecv->second)[idx][i].second;
-             currentToOriginalTmp[(itRecv->second)[idx][i].first].push_back(make_pair(globalOriginalIndex,weightGlobal));
+             size_t globalOriginalIndex = *(currentOriginalGlobalIndexRecvBuff+currentRecvBuffPosition+j+1);
+             int currentGridLocalIndex = (itRecv->second)[idx][i].first;
+             double weightGlobal = *(currentOriginalWeightRecvBuff+currentRecvBuffPosition+j+1) * (itRecv->second)[idx][i].second.second;
+             currentToOriginalTmp[(itRecv->second)[idx][i].second.first].push_back(make_pair(currentGridLocalIndex,make_pair(globalOriginalIndex,weightGlobal)));
            }
          }
@@ -697,5 +703,5 @@
  for (itRequest = requestsCurrentGrid.begin(); itRequest != requestsCurrentGrid.end(); ++itRequest)
    MPI_Wait(&itRequest->second, MPI_STATUS_IGNORE);
- for (itRequest = requestsOriginalGrid.begin(); itRequest != requestsOriginalGrid.end(); ++itRequest)
+ for (itRequest = requestsOriginalGridGlobalIndex.begin(); itRequest != requestsOriginalGridGlobalIndex.end(); ++itRequest)
    MPI_Wait(&itRequest->second, MPI_STATUS_IGNORE);
  for (itRequest = requestsWeightGrid.begin(); itRequest != requestsWeightGrid.end(); ++itRequest)
@@ -704,7 +710,7 @@
  if (0 != sendBuffSize) delete [] sendBuff;
  if (0 != recvBuffSize) delete [] recvBuff;
- if (0 != globalIndexOriginalSrcSendBuffSize) delete [] sendOriginalIndexBuff;
+ if (0 != globalIndexOriginalSrcSendBuffSize) delete [] sendOriginalGlobalIndexBuff;
  if (0 != globalIndexOriginalSrcSendBuffSize) delete [] sendOriginalWeightBuff;
- if (0 != globalIndexOriginalSrcRecvBuffSize) delete [] recvOriginalIndexBuff;
+ if (0 != globalIndexOriginalSrcRecvBuffSize) delete [] recvOriginalGlobalIndexBuff;
  if (0 != globalIndexOriginalSrcRecvBuffSize) delete [] recvOriginalWeightBuff;
 }
@@ -724,26 +730,26 @@
   transformationMap.computeTransformationMapping(currentGridIndexToOriginalGridIndex_);
 
-  const std::map<int,std::vector<std::vector<std::pair<size_t,double> > > >& globalIndexToReceive = transformationMap.getGlobalIndexReceivedOnGridDestMapping();
-  const std::map<int,std::vector<size_t> >& globalIndexToSend = transformationMap.getGlobalIndexSendToGridDestMapping();
-
-  CDistributionClient distributionClientDest(client->clientRank, gridDestination_);
-  CDistributionClient distributionClientSrc(client->clientRank, originalGridSource_);
-
-  const std::vector<size_t>& globalIndexOnClientDest = distributionClientDest.getGlobalDataIndexSendToServer();
-  const std::vector<size_t>& globalIndexOnClientSrc = distributionClientSrc.getGlobalDataIndexSendToServer();
-
-  std::vector<size_t>::const_iterator itbArr, itArr, iteArr;
-  std::vector<int>::const_iterator itIndex, itbIndex, iteIndex;
-  std::map<int,std::vector<std::vector<std::pair<size_t,double> > > >::const_iterator itbMapRecv, itMapRecv, iteMapRecv;
-
-  std::vector<int> permutIndex;
-  typedef XIOSBinarySearchWithIndex<size_t> BinarySearch;
-
-  // Find out local index on grid destination (received)
-  XIOSAlgorithms::fillInIndex(globalIndexOnClientDest.size(), permutIndex);
-  XIOSAlgorithms::sortWithIndex<size_t, CVectorStorage>(globalIndexOnClientDest, permutIndex);
-  itbIndex = permutIndex.begin();
-  iteIndex = permutIndex.end();
-  BinarySearch searchClientDest(globalIndexOnClientDest);
+  const CTransformationMapping::ReceivedIndexMap& globalIndexToReceive = transformationMap.getGlobalIndexReceivedOnGridDestMapping();
+  const CTransformationMapping::SentIndexMap& globalIndexToSend = transformationMap.getGlobalIndexSendToGridDestMapping();
+
+//  CDistributionClient distributionClientDest(client->clientRank, gridDestination_);
+//  CDistributionClient distributionClientSrc(client->clientRank, originalGridSource_);
+//
+//  const std::vector<size_t>& globalIndexOnClientDest = distributionClientDest.getGlobalDataIndexSendToServer();
+//  const std::vector<size_t>& globalIndexOnClientSrc = distributionClientSrc.getGlobalDataIndexSendToServer();
+
+//  std::vector<size_t>::const_iterator itbArr, itArr, iteArr;
+//  std::vector<int>::const_iterator itIndex, itbIndex, iteIndex;
+  CTransformationMapping::ReceivedIndexMap::const_iterator itbMapRecv, itMapRecv, iteMapRecv;
+
+//  std::vector<int> permutIndex;
+//  typedef XIOSBinarySearchWithIndex<size_t> BinarySearch;
+//
+//  // Find out local index on grid destination (received)
+//  XIOSAlgorithms::fillInIndex(globalIndexOnClientDest.size(), permutIndex);
+//  XIOSAlgorithms::sortWithIndex<size_t, CVectorStorage>(globalIndexOnClientDest, permutIndex);
+//  itbIndex = permutIndex.begin();
+//  iteIndex = permutIndex.end();
+//  BinarySearch searchClientDest(globalIndexOnClientDest);
   itbMapRecv = globalIndexToReceive.begin();
   iteMapRecv = globalIndexToReceive.end();
@@ -756,25 +762,27 @@
     {
       int vecSize = ((itMapRecv->second)[i]).size();
-      std::vector<std::pair<int,double> > tmpVec;
+//      std::vector<std::pair<int,double> > tmpVec;
       for (int idx = 0; idx < vecSize; ++idx)
       {
-        size_t globalIndex = (itMapRecv->second)[i][idx].first;
-        double weight = (itMapRecv->second)[i][idx].second;
-        if (searchClientDest.search(itbIndex, iteIndex, globalIndex, itIndex))
-        {
-          tmpVec.push_back(make_pair(*itIndex, weight));
-        }
+        const std::pair<int, std::pair<size_t,double> >& tmpPair = (itMapRecv->second)[i][idx];
+        localIndexToReceiveOnGridDest_[sourceRank][i].push_back(make_pair(tmpPair.first, tmpPair.second.second));
+//        size_t globalIndex = (itMapRecv->second)[i][idx].first;
+//        double weight = (itMapRecv->second)[i][idx].second;
+//        if (searchClientDest.search(itbIndex, iteIndex, globalIndex, itIndex))
+//        {
+//          tmpVec.push_back(make_pair(*itIndex, weight));
+//        }
       }
-      localIndexToReceiveOnGridDest_[sourceRank][i] = tmpVec;
+//      localIndexToReceiveOnGridDest_[sourceRank][i] = tmpVec;
     }
   }
 
   // Find out local index on grid source (to send)
-  std::map<int,std::vector<size_t> >::const_iterator itbMap, itMap, iteMap;
-  XIOSAlgorithms::fillInIndex(globalIndexOnClientSrc.size(), permutIndex);
-  XIOSAlgorithms::sortWithIndex<size_t, CVectorStorage>(globalIndexOnClientSrc, permutIndex);
-  itbIndex = permutIndex.begin();
-  iteIndex = permutIndex.end();
-  BinarySearch searchClientSrc(globalIndexOnClientSrc);
+  CTransformationMapping::SentIndexMap::const_iterator itbMap, itMap, iteMap;
+//  XIOSAlgorithms::fillInIndex(globalIndexOnClientSrc.size(), permutIndex);
+//  XIOSAlgorithms::sortWithIndex<size_t, CVectorStorage>(globalIndexOnClientSrc, permutIndex);
+//  itbIndex = permutIndex.begin();
+//  iteIndex = permutIndex.end();
+//  BinarySearch searchClientSrc(globalIndexOnClientSrc);
   itbMap = globalIndexToSend.begin();
   iteMap = globalIndexToSend.end();
@@ -786,8 +794,8 @@
     for (int idx = 0; idx < vecSize; ++idx)
     {
-      if (searchClientSrc.search(itbIndex, iteIndex, itMap->second[idx], itIndex))
-      {
-        localIndexToSendFromGridSource_[destRank](idx) = *itIndex;
-      }
+//      if (searchClientSrc.search(itbIndex, iteIndex, itMap->second[idx], itIndex))
+//      {
+        localIndexToSendFromGridSource_[destRank](idx) = itMap->second[idx].first; //*itIndex;
+//      }
     }
   }
Index: XIOS/trunk/src/transformation/grid_transformation.hpp
===================================================================
--- XIOS/trunk/src/transformation/grid_transformation.hpp	(revision 828)
+++ XIOS/trunk/src/transformation/grid_transformation.hpp	(revision 829)
@@ -35,4 +35,5 @@
 public:
   typedef std::list<std::pair<int,std::pair<ETranformationType,int> > > ListAlgoType;
+  typedef boost::unordered_map<size_t, std::vector<std::pair<int, std::pair<size_t,double> > > > DestinationIndexMap;
 
 public:
@@ -63,5 +64,5 @@
   void setUpGrid(int elementPositionInGrid, ETranformationType transType, int nbTransformation);
   void computeFinalTransformationMapping();
-  void computeTransformationFromOriginalGridSource(const std::map<size_t, std::vector<std::pair<size_t,double> > >& globaIndexMapFromDestToSource);
+  void computeTransformationFromOriginalGridSource(const DestinationIndexMap& globaIndexMapFromDestToSource);
   void updateFinalGridDestination();
   bool isSpecialTransformation(ETranformationType transType);
@@ -84,6 +85,4 @@
   int nbAlgos_;
 
-  typedef std::map<size_t, std::vector<std::pair<size_t,double> > > GlobalIndexMap;
-
   // true if domain algorithm and false if axis algorithm (can be replaced by tuple with listAlgos_
   std::vector<bool> algoTypes_;
@@ -105,5 +104,5 @@
 
   //! (Grid) Global index of grid source
-  GlobalIndexMap currentGridIndexToOriginalGridIndex_;
+  DestinationIndexMap currentGridIndexToOriginalGridIndex_;
 
   std::vector<CGrid*> tempGrids_;
Index: XIOS/trunk/src/transformation/transformation_mapping.cpp
===================================================================
--- XIOS/trunk/src/transformation/transformation_mapping.cpp	(revision 828)
+++ XIOS/trunk/src/transformation/transformation_mapping.cpp	(revision 829)
@@ -13,4 +13,7 @@
 #include "context_client.hpp"
 #include "distribution_client.hpp"
+#include "client_client_dht_template.hpp"
+#include "dht_data_types.hpp"
+#include "mpi_tag.hpp"
 
 namespace xios {
@@ -26,14 +29,20 @@
 
   const std::vector<size_t>& globalIndexGridSrc = distributionClientSrc.getGlobalDataIndexSendToServer(); //gridSource_->getDistributionClient()->getGlobalDataIndexSendToServer();
-  boost::unordered_map<size_t,int> globalIndexOfServer;
+  const std::vector<int>& localIndexGridSrc = distributionClientSrc.getLocalDataIndexSendToServer();
+
+  // Mapping of global index and pair containing rank and local index
+  CClientClientDHTPairIntInt::Index2InfoTypeMap globalIndexOfServer;
   int globalIndexSize = globalIndexGridSrc.size();
+  PairIntInt pii;
   for (int idx = 0; idx < globalIndexSize; ++idx)
   {
-    globalIndexOfServer[globalIndexGridSrc[idx]] = clientRank;
-  }
-
-  gridIndexClientClientMapping_ = new CClientServerMappingDistributed(globalIndexOfServer,
-                                                                      client->intraComm,
-                                                                      true);
+    pii.first  = clientRank;
+    pii.second = localIndexGridSrc[idx];
+    globalIndexOfServer[globalIndexGridSrc[idx]] = pii; //std::make_pair(clientRank, localIndexGridSrc[idx]);
+  }
+
+  gridIndexClientClientMapping_ = new CClientClientDHTPairIntInt(globalIndexOfServer,
+                                                                 client->intraComm,
+                                                                 true);
 }
 
@@ -48,13 +57,16 @@
   int ibeginSrc = source->begin.getValue();
 
-  boost::unordered_map<size_t,int> globalIndexOfAxisSource;
+  CClientClientDHTPairIntInt::Index2InfoTypeMap globalIndexOfAxisSource;
+  PairIntInt pii;
   for (int idx = 0; idx < niSrc; ++idx)
   {
-    globalIndexOfAxisSource[idx+ibeginSrc] = clientRank;
-  }
-
-  gridIndexClientClientMapping_ = new CClientServerMappingDistributed(globalIndexOfAxisSource,
-                                                                      client->intraComm,
-                                                                      true);
+    pii.first  = clientRank;
+    pii.second = idx;
+    globalIndexOfAxisSource[idx+ibeginSrc] = pii; //std::make_pair(clientRank,idx);
+  }
+
+  gridIndexClientClientMapping_ = new CClientClientDHTPairIntInt(globalIndexOfAxisSource,
+                                                                 client->intraComm,
+                                                                 true);
 }
 
@@ -71,16 +83,17 @@
   \param [in] globaIndexWeightFromDestToSource mapping representing the transformations
 */
-void CTransformationMapping::computeTransformationMapping(const std::map<size_t, std::vector<std::pair<size_t,double> > >& globaIndexWeightFromDestToSource)
+void CTransformationMapping::computeTransformationMapping(const DestinationIndexMap& globaIndexWeightFromDestToSource)
 {
   CContext* context = CContext::getCurrent();
   CContextClient* client=context->client;
 
-  std::map<size_t, std::vector<std::pair<size_t,double> > >::const_iterator itbMap = globaIndexWeightFromDestToSource.begin(), itMap,
-                                                                            iteMap = globaIndexWeightFromDestToSource.end();
+  DestinationIndexMap::const_iterator itbMap = globaIndexWeightFromDestToSource.begin(), itMap,
+                                      iteMap = globaIndexWeightFromDestToSource.end();
 
   // Not only one index on grid destination can demande two indexes from grid source
   // but an index on grid source has to be sent to two indexes of grid destination
-  std::map<size_t, std::vector<std::pair<size_t,double> > > globalIndexMapFromSrcToDest;
-  std::vector<std::pair<size_t,double> >::const_iterator itbVecPair, itVecPair, iteVecPair;
+  DestinationIndexMap globalIndexMapFromSrcToDest;
+  boost::unordered_map<size_t, int> nbGlobalIndexMapFromSrcToDest;
+  std::vector<std::pair<int, std::pair<size_t,double> > >::const_iterator itbVecPair, itVecPair, iteVecPair;
   for (itMap = itbMap; itMap != iteMap; ++itMap)
   {
@@ -89,5 +102,21 @@
     for (itVecPair = itbVecPair; itVecPair != iteVecPair; ++itVecPair)
     {
-      globalIndexMapFromSrcToDest[itVecPair->first].push_back(std::make_pair(itMap->first, itVecPair->second));
+      ++nbGlobalIndexMapFromSrcToDest[(itVecPair->second).first];
+    }
+  }
+
+  for (boost::unordered_map<size_t, int>::const_iterator it = nbGlobalIndexMapFromSrcToDest.begin();
+                                                         it != nbGlobalIndexMapFromSrcToDest.end(); ++it)
+  {
+    globalIndexMapFromSrcToDest[it->first].reserve(it->second);
+  }
+
+  for (itMap = itbMap; itMap != iteMap; ++itMap)
+  {
+    itbVecPair = (itMap->second).begin();
+    iteVecPair = (itMap->second).end();
+    for (itVecPair = itbVecPair; itVecPair != iteVecPair; ++itVecPair)
+    {
+      globalIndexMapFromSrcToDest[(itVecPair->second).first].push_back(std::make_pair(itVecPair->first, std::make_pair(itMap->first, (itVecPair->second).second)));
     }
   }
@@ -95,46 +124,42 @@
   // All global indexes of a client on grid destination
   CArray<size_t,1> globalIndexMap(globalIndexMapFromSrcToDest.size());
-  itbMap = globalIndexMapFromSrcToDest.begin();
-  iteMap = globalIndexMapFromSrcToDest.end();
+  DestinationIndexMap::const_iterator itbMapBoost = globalIndexMapFromSrcToDest.begin(), itMapBoost;
+  DestinationIndexMap::const_iterator iteMapBoost = globalIndexMapFromSrcToDest.end();
   int idx = 0;
-  for (itMap = itbMap; itMap != iteMap; ++itMap)
-  {
-    globalIndexMap(idx) = itMap->first;
+  for (itMapBoost = itbMapBoost; itMapBoost != iteMapBoost; ++itMapBoost)
+  {
+    globalIndexMap(idx) = itMapBoost->first;
     ++idx;
   }
 
   // Find out on which clients the necessary indexes of grid source are.
-  gridIndexClientClientMapping_->computeServerIndexMapping(globalIndexMap);
-  const std::map<int, std::vector<size_t> >& globalIndexSentFromGridSource = gridIndexClientClientMapping_->getGlobalIndexOnServer();
-  std::map<int, std::vector<size_t> >::const_iterator itbMapSrc = globalIndexSentFromGridSource.begin(), itMapSrc,
-                                                      iteMapSrc = globalIndexSentFromGridSource.end();
+  gridIndexClientClientMapping_->computeIndexInfoMapping(globalIndexMap);
+  const CClientClientDHTPairIntInt::Index2InfoTypeMap& globalIndexSentFromGridSource = gridIndexClientClientMapping_->getInfoIndexMap();
+  CClientClientDHTPairIntInt::Index2InfoTypeMap::const_iterator itbMapSrc = globalIndexSentFromGridSource.begin(), itMapSrc,
+                                                                iteMapSrc = globalIndexSentFromGridSource.end();
   std::vector<size_t>::const_iterator itbVec, itVec, iteVec;
+    // Inform client about the destination to which it needs to send global indexes
+  int nbClient = client->clientSize;
+  std::vector<int> sendNbClientBuff(nbClient,0);
+  std::vector<int> recvNbClientBuff(nbClient,0);
+  std::vector<int> sendIndexBuff(nbClient,0);
+  std::vector<int> recvIndexBuff(nbClient,0);
+  boost::unordered_map<int,std::vector<size_t> > sendIndexMap;
   for (itMapSrc = itbMapSrc; itMapSrc != iteMapSrc; ++itMapSrc)
   {
-    int sourceRank = itMapSrc->first;
-    itbVec = (itMapSrc->second).begin();
-    iteVec = (itMapSrc->second).end();
-    for (itVec = itbVec; itVec != iteVec; ++itVec)
-    {
-       (globalIndexReceivedOnGridDestMapping_[sourceRank]).push_back(globalIndexMapFromSrcToDest[*itVec]);
-    }
-  }
-
-  // Inform client about the destination to which it needs to send global indexes
-  int nbClient = client->clientSize;
-  int* sendBuff = new int[nbClient];
-  int* recvBuff = new int[nbClient];
-  for (int i = 0; i < nbClient; ++i) sendBuff[i] = 0;
-
-  // First of all, inform the number of destination a client needs to send global index
-  for (itMapSrc = itbMapSrc; itMapSrc != iteMapSrc; ++itMapSrc) sendBuff[itMapSrc->first] = 1;
-  MPI_Allreduce(sendBuff, recvBuff, nbClient, MPI_INT, MPI_SUM, client->intraComm);
-  int numClientToReceive = recvBuff[client->clientRank];
+    int sourceRank = (itMapSrc->second).first;
+    (globalIndexReceivedOnGridDestMapping_[sourceRank]).push_back(globalIndexMapFromSrcToDest[itMapSrc->first]);
+    sendIndexMap[sourceRank].push_back((itMapSrc->second).second);
+    sendIndexMap[sourceRank].push_back(itMapSrc->first);
+    sendNbClientBuff[sourceRank] = 1;
+    ++sendIndexBuff[sourceRank];
+  }
+
+  MPI_Allreduce(&sendNbClientBuff[0], &recvNbClientBuff[0], nbClient, MPI_INT, MPI_SUM, client->intraComm);
+  int numClientToReceive = recvNbClientBuff[client->clientRank];
 
   // Then specify the size of receiving buffer, because we use synch send/receive so only necessary to know maximum size
-  for (itMapSrc = itbMapSrc; itMapSrc != iteMapSrc; ++itMapSrc) sendBuff[itMapSrc->first] = (itMapSrc->second).size();
-  MPI_Allreduce(sendBuff, recvBuff, nbClient, MPI_INT, MPI_MAX, client->intraComm);
-
-  int buffSize = recvBuff[client->clientRank];
+  MPI_Allreduce(&sendIndexBuff[0], &recvIndexBuff[0], nbClient, MPI_INT, MPI_MAX, client->intraComm);
+  int buffSize = 2*recvIndexBuff[client->clientRank]; // we send global as well as local index
   unsigned long* recvBuffGlobalIndex;
   if (0 != buffSize) recvBuffGlobalIndex = new unsigned long [buffSize];
@@ -143,14 +168,16 @@
 
   // Inform all "source clients" about index that they need to send
-  for (itMapSrc = itbMapSrc; itMapSrc != iteMapSrc; ++itMapSrc)
-  {
-    unsigned long* sendPtr = const_cast<unsigned long*>(&(itMapSrc->second)[0]);
+  boost::unordered_map<int,std::vector<size_t> >::const_iterator itSendIndex = sendIndexMap.begin(),
+                                                                 iteSendIndex= sendIndexMap.end();
+  for (; itSendIndex != iteSendIndex; ++itSendIndex)
+  {
+    unsigned long* sendPtr = const_cast<unsigned long*>(&(itSendIndex->second)[0]);
     MPI_Isend(sendPtr,
-              (itMapSrc->second).size(),
+              (itSendIndex->second).size(),
               MPI_UNSIGNED_LONG,
-              itMapSrc->first,
-              11,
+              (itSendIndex->first),
+              MPI_TRANSFORMATION_MAPPING_INDEX,
               client->intraComm,
-              &requests[itMapSrc->first]);
+              &requests[(itSendIndex->first)]);
   }
 
@@ -165,5 +192,5 @@
              MPI_UNSIGNED_LONG,
              MPI_ANY_SOURCE,
-             11,
+             MPI_TRANSFORMATION_MAPPING_INDEX,
              client->intraComm,
              &status);
@@ -171,7 +198,7 @@
     MPI_Get_count(&status, MPI_UNSIGNED_LONG, &countBuff);
     int clientDestRank = status.MPI_SOURCE;
-    for (int idx = 0; idx < countBuff; ++idx)
+    for (int idx = 0; idx < countBuff; idx += 2)
     {
-      globalIndexSendToGridDestMapping_[clientDestRank].push_back(recvBuffGlobalIndex[idx]);
+      globalIndexSendToGridDestMapping_[clientDestRank].push_back(std::make_pair<int,size_t>(recvBuffGlobalIndex[idx], recvBuffGlobalIndex[idx+1]));
     }
     ++numClientReceived;
@@ -182,6 +209,4 @@
     MPI_Wait(&itRequest->second, MPI_STATUS_IGNORE);
 
-  delete [] sendBuff;
-  delete [] recvBuff;
   if (0 != buffSize) delete [] recvBuffGlobalIndex;
 }
@@ -192,5 +217,5 @@
   \return global index mapping to receive on grid destination
 */
-const std::map<int,std::vector<std::vector<std::pair<size_t,double> > > >& CTransformationMapping::getGlobalIndexReceivedOnGridDestMapping() const
+const CTransformationMapping::ReceivedIndexMap& CTransformationMapping::getGlobalIndexReceivedOnGridDestMapping() const
 {
   return globalIndexReceivedOnGridDestMapping_;
@@ -202,5 +227,5 @@
   \return global index mapping to send on grid source
 */
-const std::map<int,std::vector<size_t> >& CTransformationMapping::getGlobalIndexSendToGridDestMapping() const
+const CTransformationMapping::SentIndexMap& CTransformationMapping::getGlobalIndexSendToGridDestMapping() const
 {
   return globalIndexSendToGridDestMapping_;
Index: XIOS/trunk/src/transformation/transformation_mapping.hpp
===================================================================
--- XIOS/trunk/src/transformation/transformation_mapping.hpp	(revision 828)
+++ XIOS/trunk/src/transformation/transformation_mapping.hpp	(revision 829)
@@ -28,4 +28,9 @@
 {
 public:
+  typedef boost::unordered_map<size_t, std::vector<std::pair<int, std::pair<size_t,double> > > > DestinationIndexMap;
+  typedef boost::unordered_map<int,std::vector<std::vector<std::pair<int, std::pair<size_t,double> > > > > ReceivedIndexMap;
+  typedef boost::unordered_map<int,std::vector<std::pair<int, size_t> > > SentIndexMap;
+
+public:
   /** Default constructor */
   CTransformationMapping(CGrid* destination, CGrid* source);
@@ -34,7 +39,7 @@
   ~CTransformationMapping();
 
-  void computeTransformationMapping(const std::map<size_t, std::vector<std::pair<size_t,double> > >& globaIndexMapFromDestToSource);
-  const std::map<int,std::vector<std::vector<std::pair<size_t,double> > > >& getGlobalIndexReceivedOnGridDestMapping() const;
-  const std::map<int,std::vector<size_t> >& getGlobalIndexSendToGridDestMapping() const;
+  void computeTransformationMapping(const DestinationIndexMap& globaIndexMapFromDestToSource);
+  const ReceivedIndexMap& getGlobalIndexReceivedOnGridDestMapping() const;
+  const SentIndexMap& getGlobalIndexSendToGridDestMapping() const;
 
 protected:
@@ -43,11 +48,11 @@
 
   //! Global index mapping of grid source and grid destination between two clients
-  CClientServerMappingDistributed* gridIndexClientClientMapping_;
+  CClientClientDHTPairIntInt* gridIndexClientClientMapping_;
 
   //! Mapping of client rank of grid source and global index received in grid destination
-  std::map<int,std::vector<std::vector<std::pair<size_t,double> > > > globalIndexReceivedOnGridDestMapping_;
+  ReceivedIndexMap globalIndexReceivedOnGridDestMapping_;
 
   //! Mapping of client rank of grid destination and global index to send from grid source
-  std::map<int,std::vector<size_t> > globalIndexSendToGridDestMapping_;
+  SentIndexMap globalIndexSendToGridDestMapping_;
 };
 
