Index: /XIOS/trunk/bld.cfg
===================================================================
--- /XIOS/trunk/bld.cfg	(revision 539)
+++ /XIOS/trunk/bld.cfg	(revision 540)
@@ -31,5 +31,5 @@
 bld::target libxios.a
 #bld::target generate_fortran_interface.exe 
-bld::target xios_server.exe test_client.exe parse_xml.exe test_complete.exe test_xios_interface.exe
+bld::target xios_server.exe test_client.exe parse_xml.exe test_complete.exe test_xios_interface.exe test_new_features.exe
 bld::exe_dep
 
Index: /XIOS/trunk/src/config/axis_attribute.conf
===================================================================
--- /XIOS/trunk/src/config/axis_attribute.conf	(revision 539)
+++ /XIOS/trunk/src/config/axis_attribute.conf	(revision 540)
@@ -12,3 +12,5 @@
 DECLARE_ARRAY(double, 1, value)
 
+DECLARE_ATTRIBUTE(StdString, axis_ref)
 
+
Index: /XIOS/trunk/src/config/domain_attribute.conf
===================================================================
--- /XIOS/trunk/src/config/domain_attribute.conf	(revision 539)
+++ /XIOS/trunk/src/config/domain_attribute.conf	(revision 540)
@@ -62,3 +62,4 @@
 
 DECLARE_ENUM3(type,regular,curvilinear,unstructured)
+DECLARE_ATTRIBUTE(StdString, domain_ref)
 
Index: /XIOS/trunk/src/config/grid_attribute.conf
===================================================================
--- /XIOS/trunk/src/config/grid_attribute.conf	(revision 539)
+++ /XIOS/trunk/src/config/grid_attribute.conf	(revision 540)
@@ -4,2 +4,8 @@
 DECLARE_ATTRIBUTE(StdString, axis_ref)
 DECLARE_ARRAY(bool, 3 , mask)
+
+// These attributes should be used privately
+// An array contains order of axis and domains composing of the grid
+DECLARE_ARRAY(int, 1 , axisDomOrder)
+//DECLARE_ARRAY(StdString, 1 , axisList)
+//DECLARE_ARRAY(StdString, 1 , domainList)
Index: /XIOS/trunk/src/data_output.cpp
===================================================================
--- /XIOS/trunk/src/data_output.cpp	(revision 539)
+++ /XIOS/trunk/src/data_output.cpp	(revision 540)
@@ -16,17 +16,19 @@
       void CDataOutput::writeGrid(CGrid* grid)
       {
-         if (grid->domain_ref.isEmpty())
-            ERROR("CDataOutput::writeGrid(grid)",
-                   << " domain is not defined !");
-
-         if (grid->axis_ref.isEmpty())
-         {
-            this->writeGrid(CDomain::get(grid->domain_ref.getValue()));
-         }
-         else
-         {
-            this->writeGrid(CDomain::get(grid->domain_ref.getValue()),
-                            CAxis::get(grid->axis_ref.getValue()));
-         }
+//         if (grid->domain_ref.isEmpty())
+//            ERROR("CDataOutput::writeGrid(grid)",
+//                   << " domain is not defined !");
+//
+//         if (grid->axis_ref.isEmpty())
+//         {
+//            this->writeGrid(CDomain::get(grid->domain_ref.getValue()));
+//         }
+//         else
+//         {
+//            this->writeGrid(CDomain::get(grid->domain_ref.getValue()),
+//                            CAxis::get(grid->axis_ref.getValue()));
+//         }
+//        this->writeGrid(grid->domain, grid->axis);
+        this->writeGrid(grid->getDomains(), grid->getAxis());
       }
 
@@ -61,4 +63,12 @@
       }
 
+      void CDataOutput::writeGrid(std::vector<CDomain*> domains, std::vector<CAxis*> axis)
+      {
+        int domSize = domains.size();
+        int aSize = axis.size();
+        for (int i = 0; i < domSize; ++i) this->writeDomain_(domains[i]);
+        for (int i = 0; i < aSize; ++i) this->writeAxis_(axis[i]);
+      }
+
       //----------------------------------------------------------------
 
@@ -79,5 +89,5 @@
          CContext* context = CContext::getCurrent() ;
          boost::shared_ptr<CCalendar> calendar = context->getCalendar();
-         
+
          this->writeField_(field);
          this->writeTimeAxis_(field, calendar);
@@ -90,14 +100,14 @@
          this->writeGrid(field->getRelGrid());
       }
-      
+
       //----------------------------------------------------------------
-      
+
       void CDataOutput::writeFieldData(CField* field)
       {
-         CGrid* grid = CGrid::get(field->grid_ref.getValue());
-         CDomain* domain = CDomain::get(grid->domain_ref.getValue());
+//         CGrid* grid = CGrid::get(field->grid_ref.getValue());
+//         CDomain* domain = CDomain::get(grid->domain_ref.getValue());
          this->writeFieldData_(field);
       }
-      
+
       ///----------------------------------------------------------------
 
Index: /XIOS/trunk/src/data_output.hpp
===================================================================
--- /XIOS/trunk/src/data_output.hpp	(revision 539)
+++ /XIOS/trunk/src/data_output.hpp	(revision 540)
@@ -44,4 +44,5 @@
                            CAxis*   axis);
             void writeGrid(CDomain* domain);
+            void writeGrid(std::vector<CDomain*> domain, std::vector<CAxis*> axis);
 
             virtual void writeFile_       (CFile*     file)   = 0;
Index: /XIOS/trunk/src/declare_ref_func.hpp
===================================================================
--- /XIOS/trunk/src/declare_ref_func.hpp	(revision 540)
+++ /XIOS/trunk/src/declare_ref_func.hpp	(revision 540)
@@ -0,0 +1,123 @@
+/*!
+   \file declare_ref_func.hpp
+   \author Ha NGUYEN
+   \date 02 Dec 2014
+   \since 02 Dec 2014
+
+   \brief Macro for some functions to solve reference of base object which are used in class Domain, Axis and Field
+ */
+#ifndef __XIOS_DECLARE_REF_FUNC_HPP__
+#define __XIOS_DECLARE_REF_FUNC_HPP__
+
+#define DECLARE_REF_FUNC(type,name)  \
+public:                                                             \
+ bool hasDirect##type##Reference(void) const;                       \
+ C##type * getDirect##type##Reference(void) const;                 \
+ C##type * getBase##type##Reference(void) const;                   \
+ void addReference(C##type * field);                               \
+ const std::vector<C##type *> & getAllReference(void) const;       \
+ void removeRefInheritance();                                       \
+ const StdString& getBase##type##Id(void) const;                   \
+ void solveRefInheritance(bool apply = true);                             \
+ void solveBaseReference(void);                                                                    \
+ std::vector<C##type *> refObject;                                 \
+ C##type * baseRefObject;                                          \
+
+// Defition of some function for solving reference in class Domain, Axis and Field
+
+#define DEFINE_REF_FUNC(type,name) \
+void C##type::solveRefInheritance(bool apply)                          \
+{                                                                     \
+  std::set<C##type *> sset;                                            \
+  C##type * refer_sptr;                                                 \
+  C##type * refer_ptr = this;                                          \
+                                                                      \
+  while (refer_ptr->hasDirect##type##Reference())                        \
+  {                                                                   \
+     refer_sptr = refer_ptr->getDirect##type##Reference();               \
+     refer_ptr  = refer_sptr;                                         \
+                                                                      \
+     if(sset.end() != sset.find(refer_ptr))                           \
+     {                                                                \
+        DEBUG (<< "Circular dependency stopped for #name object on "  \
+               << "\"" + refer_ptr->getId() + "\" !");                \
+        break;                                                        \
+     }                                                                \
+                                                                      \
+     SuperClassAttribute::setAttributes(refer_ptr, apply);            \
+     sset.insert(refer_ptr);                                          \
+  }                                                                   \
+}                                                                     \
+                                                                      \
+void C##type::removeRefInheritance()                                   \
+{                                                                     \
+ if (this->name##_ref.isEmpty()) return;                              \
+ this->clearAttribute("name##_ref");                                  \
+}                                                                     \
+                                                                      \
+void C##type::solveBaseReference(void)                                 \
+{                                                                     \
+  std::set<C##type *> sset;                                            \
+  C##type * refer_sptr;                                                 \
+  C##type * refer_ptr = this;                                          \
+                                                                      \
+  if (this->hasDirect##type##Reference())  baseRefObject = getDirect##type##Reference(); \
+  else  baseRefObject = C##type::get(this);                                         \
+                                                                                   \
+  while (refer_ptr->hasDirect##type##Reference())                                     \
+  {                                                                                \
+     refer_sptr = refer_ptr->getDirect##type##Reference();                            \
+     refer_ptr  = refer_sptr;                                                      \
+                                                                                   \
+     if(sset.end() != sset.find(refer_ptr))                                        \
+     {                                                                             \
+        DEBUG (<< "Circular dependency stopped for #name object on "              \
+               << "\"" + refer_ptr->getId() + "\" !");                             \
+        break;                                                                     \
+     }                                                                             \
+                                                                                   \
+     sset.insert(refer_ptr);                                                       \
+  }                                                                                \
+                                                                                   \
+  if (hasDirect##type##Reference()) baseRefObject->addReference(this) ;               \
+}                                                                                  \
+                                                                                   \
+C##type * C##type::getDirect##type##Reference(void) const                                \
+{                                                                                  \
+  if (this->name##_ref.isEmpty())                                                   \
+     return (this->getBase##type##Reference());                                       \
+                                                                                   \
+  if (! C##type::has(this->name##_ref.getValue()))                                   \
+     ERROR("C##type::getDirect##type##Reference(void)",                                \
+           << "[ ref_name = " << this->name##_ref.getValue() << "]"                 \
+           << " invalid #name name !");                                            \
+                                                                                   \
+  return (C##type::get(this->name##_ref.getValue()));                                \
+}                                                                                  \
+                                                                                   \
+C##type * C##type::getBase##type##Reference(void) const                                  \
+{                                                                                  \
+  return (baseRefObject);                                                          \
+}                                                                                  \
+                                                                                   \
+const std::vector<C##type *>& C##type::getAllReference(void) const                    \
+{                                                                                  \
+  return (refObject);                                                              \
+}                                                                                  \
+                                                                                   \
+const StdString & C##type::getBase##type##Id(void) const                               \
+{                                                                                  \
+  return (this->getBase##type##Reference()->getId());                                 \
+}                                                                                  \
+                                                                                   \
+void C##type::addReference(C##type * _##name##_)                                           \
+{                                                                                  \
+  refObject.push_back(_##name##_) ;                                                     \
+}                                                                                   \
+                                                                                    \
+bool C##type::hasDirect##type##Reference(void) const                                \
+{                                                                                   \
+ return (!this->name##_ref.isEmpty());                                               \
+}                                                                                   \
+
+#endif // __XIOS_DECLARE_REF_FUNC_HPP__
Index: /XIOS/trunk/src/node/axis.cpp
===================================================================
--- /XIOS/trunk/src/node/axis.cpp	(revision 539)
+++ /XIOS/trunk/src/node/axis.cpp	(revision 540)
@@ -9,15 +9,15 @@
 
 namespace xios {
-   
+
    /// ////////////////////// DÃ©finitions ////////////////////// ///
 
    CAxis::CAxis(void)
       : CObjectTemplate<CAxis>()
-      , CAxisAttributes(), isChecked(false), relFiles()
+      , CAxisAttributes(), isChecked(false), relFiles(), baseRefObject()
    { /* Ne rien faire de plus */ }
 
    CAxis::CAxis(const StdString & id)
       : CObjectTemplate<CAxis>(id)
-      , CAxisAttributes(), isChecked(false), relFiles()
+      , CAxisAttributes(), isChecked(false), relFiles(), baseRefObject()
    { /* Ne rien faire de plus */ }
 
@@ -56,15 +56,15 @@
          ERROR("CAxis::checkAttributes(void)",<< "Attribut <size> of the axis must be specified") ;
       StdSize size = this->size.getValue();
-      
+
       StdSize zoom_begin,zoom_end, zoom_size ;
-      
+
       zoom_begin = (this->zoom_begin.isEmpty()) ?  1 : this->zoom_begin.getValue() ;
-      zoom_end = (this->zoom_end.isEmpty()) ?  size : this->zoom_end.getValue() ; 
+      zoom_end = (this->zoom_end.isEmpty()) ?  size : this->zoom_end.getValue() ;
       zoom_size = (this->zoom_size.isEmpty()) ?  size : this->zoom_size.getValue() ;
-      
+
       if (this->zoom_begin.isEmpty()) zoom_begin=zoom_end-zoom_size+1 ;
       if (this->zoom_end.isEmpty()) zoom_end=zoom_begin+zoom_size-1 ;
       if (this->zoom_size.isEmpty()) zoom_size=zoom_end-zoom_begin+1 ;
-      
+
       if ( (zoom_begin < 1) || (zoom_begin > size) || (zoom_end<1) || (zoom_end>size) || (zoom_size<1) || (zoom_size>size) || (zoom_begin>zoom_end))
         ERROR("CAxis::checkAttributes(void)",<< "One or more attribut of <zoom_begin>, <zoom_end>, <zoom_size>, are not well specified") ;
@@ -72,5 +72,5 @@
       this->zoom_end.setValue(zoom_end) ;
       this->zoom_size.setValue(zoom_size) ;
-      
+
       StdSize true_size = value.numElements();
       if (size != true_size)
@@ -81,4 +81,6 @@
    }
 
+   DEFINE_REF_FUNC(Axis,axis)
+
    ///---------------------------------------------------------------
 
Index: /XIOS/trunk/src/node/axis.hpp
===================================================================
--- /XIOS/trunk/src/node/axis.hpp	(revision 539)
+++ /XIOS/trunk/src/node/axis.hpp	(revision 540)
@@ -7,4 +7,5 @@
 
 #include "declare_group.hpp"
+#include "declare_ref_func.hpp"
 #include "attribute_array.hpp"
 #include "attribute_enum.hpp"
@@ -12,5 +13,5 @@
 
 namespace xios {
-   
+
    /// ////////////////////// DÃ©clarations ////////////////////// ///
 
@@ -65,5 +66,5 @@
          static StdString GetName(void);
          static StdString GetDefName(void);
-         
+
          static ENodeType GetType(void);
 
@@ -72,4 +73,6 @@
          bool isChecked;
          std::set<StdString> relFiles;
+
+         DECLARE_REF_FUNC(Axis,axis)
 
 
Index: /XIOS/trunk/src/node/context.cpp
===================================================================
--- /XIOS/trunk/src/node/context.cpp	(revision 539)
+++ /XIOS/trunk/src/node/context.cpp	(revision 540)
@@ -353,6 +353,8 @@
    void CContext::closeDefinition(void)
    {
+
      if (hasClient)
      {
+       std::cout << "Current context " << *this << std::endl;
        // After xml is parsed, there are some more works with post processing
        postProcessing();
@@ -378,9 +380,11 @@
        sendEnabledFields();
 
+      // At last, we have all info of domain and axis, then send them
+       sendRefDomainsAxis();
+
       // After that, send all grid (if any)
        sendRefGrid();
 
-      // At last, we have all info of domain and axis, then send them
-       sendRefDomainsAxis();
+
     }
 
@@ -508,9 +512,18 @@
      // RÃ©solution des hÃ©ritages par rÃ©fÃ©rence au niveau des fichiers.
       const vector<CFile*> allFiles=CFile::getAll() ;
+      const vector<CGrid*> allGrids= CGrid::getAll();
 
      //if (hasClient && !hasServer)
       if (hasClient)
+      {
         for (unsigned int i = 0; i < allFiles.size(); i++)
           allFiles[i]->solveFieldRefInheritance(apply);
+      }
+
+      unsigned int vecSize = allGrids.size();
+      unsigned int i = 0;
+      for (i = 0; i < vecSize; ++i)
+        allGrids[i]->solveDomainAxisRefInheritance(apply);
+
    }
 
@@ -702,4 +715,5 @@
    {
       postProcessing();
+      std::cout << "server context " << *this << std::endl;
    }
 
@@ -848,4 +862,6 @@
        gridPtr->sendCreateChild(*it);
        CGrid::get(*it)->sendAllAttributesToServer();
+       CGrid::get(*it)->sendAllDomains();
+       CGrid::get(*it)->sendAllAxis();
      }
    }
@@ -881,6 +897,9 @@
      for (itAxis = axisIds.begin(); itAxis != itE; ++itAxis)
      {
-       axisPtr->sendCreateChild(*itAxis);
-       CAxis::get(*itAxis)->sendAllAttributesToServer();
+       if (!itAxis->empty())
+       {
+         axisPtr->sendCreateChild(*itAxis);
+         CAxis::get(*itAxis)->sendAllAttributesToServer();
+       }
      }
 
@@ -891,6 +910,8 @@
      for (itDom = domainIds.begin(); itDom != itE; ++itDom)
      {
-       domPtr->sendCreateChild(*itDom);
-       CDomain::get(*itDom)->sendAllAttributesToServer();
+       if (!itDom->empty()) {
+          domPtr->sendCreateChild(*itDom);
+          CDomain::get(*itDom)->sendAllAttributesToServer();
+       }
      }
    }
Index: /XIOS/trunk/src/node/domain.cpp
===================================================================
--- /XIOS/trunk/src/node/domain.cpp	(revision 539)
+++ /XIOS/trunk/src/node/domain.cpp	(revision 540)
@@ -1024,5 +1024,5 @@
    //----------------------------------------------------------------
 
-
+   DEFINE_REF_FUNC(Domain,domain)
 
    ///---------------------------------------------------------------
Index: /XIOS/trunk/src/node/domain.hpp
===================================================================
--- /XIOS/trunk/src/node/domain.hpp	(revision 539)
+++ /XIOS/trunk/src/node/domain.hpp	(revision 540)
@@ -7,4 +7,5 @@
 
 #include "declare_group.hpp"
+#include "declare_ref_func.hpp"
 #include "event_client.hpp"
 #include "event_server.hpp"
@@ -152,4 +153,6 @@
          bool isClientChecked; // Verify whether all attributes of domain on the client side is good
 
+         DECLARE_REF_FUNC(Domain,domain)
+
    }; // class CDomain
 
Index: /XIOS/trunk/src/node/field.cpp
===================================================================
--- /XIOS/trunk/src/node/field.cpp	(revision 539)
+++ /XIOS/trunk/src/node/field.cpp	(revision 540)
@@ -288,43 +288,4 @@
    //----------------------------------------------------------------
 
-   /*!
-   \brief Get pointer to direct field to which the current field refers.
-   */
-   CField* CField::getDirectFieldReference(void) const
-   {
-      if (this->field_ref.isEmpty())
-         return (this->getBaseFieldReference());
-
-      if (! CField::has(this->field_ref.getValue()))
-         ERROR("CField::getDirectFieldReference(void)",
-               << "[ ref_name = " << this->field_ref.getValue() << "]"
-               << " invalid field name !");
-
-      return (CField::get(this->field_ref.getValue()));
-   }
-
-   //----------------------------------------------------------------
-
-   CField* CField::getBaseFieldReference(void) const
-   {
-      return (baseRefObject);
-   }
-
-   //----------------------------------------------------------------
-
-   const std::vector<CField*>& CField::getAllReference(void) const
-   {
-      return (refObject);
-   }
-
-   //----------------------------------------------------------------
-
-   const StdString & CField::getBaseFieldId(void) const
-   {
-      return (this->getBaseFieldReference()->getId());
-   }
-
-   //----------------------------------------------------------------
-
    const CDuration & CField::getFreqOperation(void) const
    {
@@ -345,10 +306,4 @@
    }
 
-   //----------------------------------------------------------------
-
-   bool CField::hasDirectFieldReference(void) const
-   {
-     return (!this->field_ref.isEmpty());
-   }
 
    bool CField::isActive(void) const
@@ -431,74 +386,4 @@
        active=true;
      }
-   }
-
-   /*!
-   \brief Searching for all reference of a field
-   If a field refers to (an)other field(s), we will search for all its referenced parents.
-   Moreover, if any father, direct or indirect (e.g: two levels up), has non-empty attributes,
-   all its attributes will be added to the current field
-   \param [in] apply Flag to specify whether current field uses attributes of its father
-               in case the attribute is empty (true) or its attributes are replaced by ones of its father (false)
-   */
-   void CField::solveRefInheritance(bool apply)
-   {
-      std::set<CField *> sset;
-      CField* refer_sptr;
-      CField * refer_ptr = this;
-
-      while (refer_ptr->hasDirectFieldReference())
-      {
-         refer_sptr = refer_ptr->getDirectFieldReference();
-         refer_ptr  = refer_sptr;
-
-         if(sset.end() != sset.find(refer_ptr))
-         {
-            DEBUG (<< "Circular dependency stopped for field object on "
-                   << "\"" + refer_ptr->getId() + "\" !");
-            break;
-         }
-
-         SuperClassAttribute::setAttributes(refer_ptr, apply);
-         sset.insert(refer_ptr);
-      }
-   }
-
-
-   /*!
-   \brief Only on SERVER side. Remove all field_ref from current field
-   On creating a new field on server side, redundant "field_ref" is still kept in the attribute list
-   of the current field. This function removes this from current field
-   */
-   void CField::removeRefInheritance()
-   {
-     if (this->field_ref.isEmpty()) return;
-     this->clearAttribute("field_ref");
-   }
-
-   void CField::solveBaseReference(void)
-   {
-      std::set<CField *> sset;
-      CField* refer_sptr;
-      CField * refer_ptr = this;
-
-      if (this->hasDirectFieldReference())  baseRefObject = getDirectFieldReference();
-      else  baseRefObject = CField::get(this);
-
-      while (refer_ptr->hasDirectFieldReference())
-      {
-         refer_sptr = refer_ptr->getDirectFieldReference();
-         refer_ptr  = refer_sptr;
-
-         if(sset.end() != sset.find(refer_ptr))
-         {
-            DEBUG (<< "Circular dependency stopped for field object on "
-                   << "\"" + refer_ptr->getId() + "\" !");
-            break;
-         }
-
-         sset.insert(refer_ptr);
-      }
-
-      if (hasDirectFieldReference()) baseRefObject->addReference(this) ;
    }
 
@@ -652,62 +537,94 @@
       }
 
-      if (grid_ref.isEmpty() &&  domain_ref.isEmpty())
+      if (grid_ref.isEmpty() &&  domain_ref.isEmpty() && axis_ref.isEmpty())
       {
             ERROR("CField::solveGridReference(void)",
-                  << "The horizontal domain for this field is not defined");
-
+                  << "At least one dimension must be defined for this field.");
+      }
+
+//     if (!grid_ref.isEmpty())
+//     {
+//       domain = grid->domain;
+//       axis = grid->axis;
+//     }
+
+//     CType<string> goodDomain ;
+//     CType<string> goodAxis ;
+//     if (!grid_ref.isEmpty())
+//     {
+//       if (!grid->domain_ref.isEmpty()) goodDomain=grid->domain_ref ;
+//       if (!grid->axis_ref.isEmpty()) goodAxis=grid->axis_ref ;
+//     }
+//     if (!domain_ref.isEmpty()) goodDomain=domain_ref ;
+//     if (!axis_ref.isEmpty()) goodAxis=axis_ref ;
+
+//     CArray<std::string,1> domListTmp = grid->domainList.getValue();
+//     CArray<std::string,1> axisListTmp = grid->axisList.getValue();
+
+     std::vector<std::string> domList, axisList;
+     if (0 != grid)
+     {
+       domList = grid->getDomainList();
+       axisList = grid->getAxisList();
      }
 
-     CType<string> goodDomain ;
-     CType<string> goodAxis ;
-     if (!grid_ref.isEmpty())
+     if (domList.empty() && axisList.empty())
      {
-       if (!grid->domain_ref.isEmpty()) goodDomain=grid->domain_ref ;
-       if (!grid->axis_ref.isEmpty()) goodAxis=grid->axis_ref ;
+       std::vector<CDomain*> vecDom;
+       if (0 != domain) vecDom.push_back(domain);
+       std::vector<CAxis*> vecAxis;
+       if (0 != axis) vecAxis.push_back(axis);
+       this->grid = CGrid::createGrid(vecDom, vecAxis);
      }
-     if (!domain_ref.isEmpty()) goodDomain=domain_ref ;
-     if (!axis_ref.isEmpty()) goodAxis=axis_ref ;
-
-
-     if (goodDomain.isEmpty())
-     {
-       ERROR("CField::solveGridReference(void)", << "The horizontal domain for this field is not defined");
-     }
-     else
-     {
-       if (CDomain::has(goodDomain)) domain = CDomain::get(goodDomain) ;
-       else ERROR("CField::solveGridReference(void)",<< "Reference to the domain \'"<<goodDomain.get() << "\' is wrong") ;
-     }
-
-     if (!goodAxis.isEmpty())
-     {
-       if (CAxis::has(goodAxis))  axis = CAxis::get(goodAxis) ;
-       else  ERROR("CField::solveGridReference(void)", << "Reference to the axis \'"
-                  << goodAxis.get() <<"\' is wrong") ;
-     }
-
-     bool nothingToDo=false ;
-
-     if (!grid_ref.isEmpty())
-     {
-       if (!grid->domain_ref.isEmpty() && goodDomain.get() == grid->domain_ref.get())
-         if (goodAxis.isEmpty()) nothingToDo=true ;
-         else if (!grid->axis_ref.isEmpty())
-                 if (grid->axis_ref.get()==goodAxis.get()) nothingToDo=true ;
-     }
-
-     if (!nothingToDo)
-     {
-       if (!goodAxis.isEmpty())
-       {
-         this->grid = CGrid::createGrid(domain, axis) ;
-         this->grid_ref.setValue(this->grid->getId());
-       }
-       else
-       {
-         this->grid = CGrid::createGrid(domain) ;
-         this->grid_ref.setValue(this->grid->getId());
-       }
-     }
+
+//     std::string goodDomain = domListTmp[0];
+//     std::string goodAxis = axisListTmp[0];
+
+//     if (goodDomain.isEmpty())
+//     if (goodDomain.empty())
+//     {
+//       ERROR("CField::solveGridReference(void)", << "The horizontal domain for this field is not defined");
+//     }
+//     else
+//     {
+//       if (CDomain::has(goodDomain)) domain = CDomain::get(goodDomain) ;
+//       else ERROR("CField::solveGridReference(void)",<< "Reference to the domain \'"
+//                  <<goodDomain << "\' is wrong") ;
+////                  <<goodDomain.get() << "\' is wrong") ;
+//     }
+//
+////     if (!goodAxis.isEmpty())
+//     if (!goodAxis.empty())
+//     {
+//       if (CAxis::has(goodAxis))  axis = CAxis::get(goodAxis) ;
+//       else  ERROR("CField::solveGridReference(void)", << "Reference to the axis \'"
+//                  << goodAxis <<"\' is wrong") ;
+//                  << goodAxis.get() <<"\' is wrong") ;
+//     }
+
+//     bool nothingToDo=false ;
+//
+//     if (!grid_ref.isEmpty())
+//     {
+//       if (!grid->domain_ref.isEmpty() && goodDomain.get() == grid->domain_ref.get())
+//         if (goodAxis.isEmpty()) nothingToDo=true ;
+//         else if (!grid->axis_ref.isEmpty())
+//                 if (grid->axis_ref.get()==goodAxis.get()) nothingToDo=true ;
+//     }
+//
+//     nothingToDo = true;
+//     if (!nothingToDo)
+//     {
+//       if (!goodAxis.isEmpty())
+//       {
+//         this->grid = CGrid::createGrid(domain, axis) ;
+//         this->grid_ref.setValue(this->grid->getId());
+//       }
+//       else
+//       {
+//         this->grid = CGrid::createGrid(domain) ;
+//         this->grid_ref.setValue(this->grid->getId());
+//       }
+//     }
 
 //     grid->solveReference() ;
@@ -803,9 +720,4 @@
     }
     return &instantData ;
-  }
-
-  void CField::addReference(CField* field)
-  {
-    refObject.push_back(field) ;
   }
 
@@ -1047,6 +959,128 @@
    }
 
-
-
+   DEFINE_REF_FUNC(Field,field)
+
+//  void CField::addReference(CField* field)
+//  {
+//    refObject.push_back(field) ;
+//  }
+//
+//   //----------------------------------------------------------------
+//
+//   bool CField::hasDirectFieldReference(void) const
+//   {
+//     return (!this->field_ref.isEmpty());
+//   }
+//
+//   //----------------------------------------------------------------
+//
+//   const StdString & CField::getBaseFieldId(void) const
+//   {
+//      return (this->getBaseFieldReference()->getId());
+//   }
+//
+//
+//   //----------------------------------------------------------------
+//
+//   /*!
+//   \brief Get pointer to direct field to which the current field refers.
+//   */
+//   CField* CField::getDirectFieldReference(void) const
+//   {
+//      if (this->field_ref.isEmpty())
+//         return (this->getBaseFieldReference());
+//
+//      if (! CField::has(this->field_ref.getValue()))
+//         ERROR("CField::getDirectFieldReference(void)",
+//               << "[ ref_name = " << this->field_ref.getValue() << "]"
+//               << " invalid field name !");
+//
+//      return (CField::get(this->field_ref.getValue()));
+//   }
+//
+//   //----------------------------------------------------------------
+//
+//   CField* CField::getBaseFieldReference(void) const
+//   {
+//      return (baseRefObject);
+//   }
+//
+//   //----------------------------------------------------------------
+//
+//   const std::vector<CField*>& CField::getAllReference(void) const
+//   {
+//      return (refObject);
+//   }
+//
+//
+//   /*!
+//   \brief Searching for all reference of a field
+//   If a field refers to (an)other field(s), we will search for all its referenced parents.
+//   Moreover, if any father, direct or indirect (e.g: two levels up), has non-empty attributes,
+//   all its attributes will be added to the current field
+//   \param [in] apply Flag to specify whether current field uses attributes of its father
+//               in case the attribute is empty (true) or its attributes are replaced by ones of its father (false)
+//   */
+//   void CField::solveRefInheritance(bool apply)
+//   {
+//      std::set<CField *> sset;
+//      CField* refer_sptr;
+//      CField * refer_ptr = this;
+//
+//      while (refer_ptr->hasDirectFieldReference())
+//      {
+//         refer_sptr = refer_ptr->getDirectFieldReference();
+//         refer_ptr  = refer_sptr;
+//
+//         if(sset.end() != sset.find(refer_ptr))
+//         {
+//            DEBUG (<< "Circular dependency stopped for field object on "
+//                   << "\"" + refer_ptr->getId() + "\" !");
+//            break;
+//         }
+//
+//         SuperClassAttribute::setAttributes(refer_ptr, apply);
+//         sset.insert(refer_ptr);
+//      }
+//   }
+//
+//   /*!
+//   \brief Only on SERVER side. Remove all field_ref from current field
+//   On creating a new field on server side, redundant "field_ref" is still kept in the attribute list
+//   of the current field. This function removes this from current field
+//   */
+//   void CField::removeRefInheritance()
+//   {
+//     if (this->field_ref.isEmpty()) return;
+//     this->clearAttribute("field_ref");
+//   }
+//
+//   void CField::solveBaseReference(void)
+//   {
+//      std::set<CField *> sset;
+//      CField* refer_sptr;
+//      CField * refer_ptr = this;
+//
+//      if (this->hasDirectFieldReference())  baseRefObject = getDirectFieldReference();
+//      else  baseRefObject = CField::get(this);
+//
+//      while (refer_ptr->hasDirectFieldReference())
+//      {
+//         refer_sptr = refer_ptr->getDirectFieldReference();
+//         refer_ptr  = refer_sptr;
+//
+//         if(sset.end() != sset.find(refer_ptr))
+//         {
+//            DEBUG (<< "Circular dependency stopped for field object on "
+//                   << "\"" + refer_ptr->getId() + "\" !");
+//            break;
+//         }
+//
+//         sset.insert(refer_ptr);
+//      }
+//
+//      if (hasDirectFieldReference()) baseRefObject->addReference(this) ;
+//   }
+//
 
 } // namespace xios
Index: /XIOS/trunk/src/node/field.hpp
===================================================================
--- /XIOS/trunk/src/node/field.hpp	(revision 539)
+++ /XIOS/trunk/src/node/field.hpp	(revision 540)
@@ -14,5 +14,5 @@
 #include "attribute_array.hpp"
 #include "expr_node.hpp"
-//#include "context.hpp"
+#include "declare_ref_func.hpp"
 
 
@@ -64,8 +64,4 @@
 
          /// Accesseurs ///
-         CField* getDirectFieldReference(void) const;
-         CField* getBaseFieldReference(void)   const;
-         void addReference(CField* field) ;
-         const std::vector<CField*> & getAllReference(void) const;
 
          CGrid* getRelGrid(void) const ;
@@ -86,5 +82,5 @@
          CArray<double, 1> getData(void) const;
 
-         const StdString & getBaseFieldId(void) const;
+
 
          /// Mutateur ///
@@ -104,7 +100,4 @@
 
        public :
-
-         /// Test ///
-         bool hasDirectFieldReference(void) const;
          bool isActive(void) const;
          bool active ;
@@ -114,6 +107,5 @@
          /// Traitements ///
          void processEnabledField(void) ;
-         void solveRefInheritance(bool apply);
-         void solveBaseReference(void);
+
          void solveGridReference(void);
          void solveOperation(void);
@@ -122,5 +114,5 @@
          void buildAllExpressionEnabledField();
          void solveGridDomainAxisRef(bool checkAtt);
-         void removeRefInheritance();  // Remove all reference of current field (it refers to itself)
+
 
 //         virtual void fromBinary(StdIStream & is);
@@ -166,10 +158,7 @@
         const std::pair<StdString, StdString>& getDomainAxisIds();
       public :
-
          /// PropriÃ©tÃ©s privÃ©es ///
          CVariableGroup* vVariableGroup ;
 
-         std::vector<CField*> refObject;
-         CField* baseRefObject;
          CGrid*  grid ;
          CFile*  file;
@@ -208,4 +197,19 @@
          bool areAllExpressionBuilt;
          std::pair<StdString,StdString> domAxisIds_;
+         DECLARE_REF_FUNC(Field,field)
+//       public:
+//         bool hasDirectFieldReference(void) const;
+//         CField* getDirectFieldReference(void) const;
+//         CField* getBaseFieldReference(void) const;
+//         void addReference(CField* field);
+//         const std::vector<CField*> & getAllReference(void) const;
+//void solveRefInheritance(bool apply);
+//void solveBaseReference(void);
+//         void removeRefInheritance();
+//         const StdString & getBaseFieldId(void) const;
+//
+//         std::vector<CField*> refObject;
+//         CField* baseRefObject;
+
 
    }; // class CField
Index: /XIOS/trunk/src/node/grid.cpp
===================================================================
--- /XIOS/trunk/src/node/grid.cpp	(revision 539)
+++ /XIOS/trunk/src/node/grid.cpp	(revision 540)
@@ -21,5 +21,9 @@
       , withAxis(false), isChecked(false), isDomainAxisChecked(false), axis(), domain()
       , storeIndex(1), out_i_index(1), out_j_index(1), out_l_index(1), isDomConServerComputed_(false)
-   { /* Ne rien faire de plus */ }
+      , vDomainGroup_(), vAxisGroup_(), axisOrder_(), axisList_(), isAxisListSet(false), isDomListSet(false)
+   {
+     setVirtualDomainGroup();
+     setVirtualAxisGroup();
+   }
 
    CGrid::CGrid(const StdString & id)
@@ -27,5 +31,9 @@
       , withAxis(false), isChecked(false), isDomainAxisChecked(false), axis(), domain()
       , storeIndex(1), out_i_index(1), out_j_index(1), out_l_index(1), isDomConServerComputed_(false)
-   { /* Ne rien faire de plus */ }
+      , vDomainGroup_(), vAxisGroup_(), axisOrder_(), axisList_(), isAxisListSet(false), isDomListSet(false)
+   {
+     setVirtualDomainGroup();
+     setVirtualAxisGroup();
+   }
 
    CGrid::~CGrid(void)
@@ -317,14 +325,24 @@
    void CGrid::solveDomainRef(bool sendAtt)
    {
-      if (!domain_ref.isEmpty())
-      {
-         if (CDomain::has(domain_ref.getValue()))
-         {
-            this->domain = CDomain::get(domain_ref.getValue()) ;
-            if (sendAtt) domain->sendCheckedAttributes();
-            else domain->checkAttributesOnClient() ;
-         }
-         else ERROR("CGrid::solveDomainRef(void)",
-                     << "Wrong domain reference") ;
+//      if (!domain_ref.isEmpty())
+//      {
+//         if (CDomain::has(domain_ref.getValue()))
+//         {
+//            this->domain = CDomain::get(domain_ref.getValue()) ;
+//            if (sendAtt) domain->sendCheckedAttributes();
+//            else domain->checkAttributesOnClient() ;
+//         }
+//         else ERROR("CGrid::solveDomainRef(void)",
+//                     << "Wrong domain reference") ;
+//      }
+//      else ERROR("CGrid::solveDomainRef(void)",
+//                  << "Domain reference is not defined") ;
+      setDomainList();
+      this->domain = CDomain::get(domList_.at(0));
+      if (0 != this->domain)
+      {
+//        this->domain = this->getDomain();
+        if (sendAtt) domain->sendCheckedAttributes();
+        else domain->checkAttributesOnClient() ;
       }
       else ERROR("CGrid::solveDomainRef(void)",
@@ -336,15 +354,40 @@
    void CGrid::solveAxisRef(bool checkAtt)
    {
-      if (!axis_ref.isEmpty())
-      {
-         this->withAxis = true ;
-         if (CAxis::get(axis_ref.getValue()))
-         {
-            this->axis = CAxis::get(axis_ref.getValue()) ;
-            axis->checkAttributes() ;
-         }
-         else ERROR("CGrid::solveAxisRef(void)",
-                    << "Wrong axis reference") ;
-      }
+//      if (!axis_ref.isEmpty())
+//      {
+//         this->withAxis = true ;
+//         if (CAxis::get(axis_ref.getValue()))
+//         {
+//            this->axis = CAxis::get(axis_ref.getValue()) ;
+//            axis->checkAttributes() ;
+//         }
+//         else ERROR("CGrid::solveAxisRef(void)",
+//                    << "Wrong axis reference") ;
+//      }
+//      else withAxis = false ;
+//      getAllAxis();
+      setAxisList();
+      if (!axisList_.empty())
+      {
+        int sizeList = axisList_.size();
+        for (int i = 0; i < sizeList; ++i)
+        {
+          CAxis::get(axisList_.at(i))->checkAttributes();
+          this->axis = CAxis::get(axisList_.at(i));
+        }
+        withAxis = true;
+
+      }
+//      if (!axis_ref.isEmpty())
+//      {
+//         this->withAxis = true ;
+//         if (CAxis::get(axis_ref.getValue()))
+//         {
+//            this->axis = CAxis::get(axis_ref.getValue()) ;
+//            axis->checkAttributes() ;
+//         }
+//         else ERROR("CGrid::solveAxisRef(void)",
+//                    << "Wrong axis reference") ;
+//      }
       else withAxis = false ;
    }
@@ -445,5 +488,8 @@
       StdString new_id = StdString("__") + domain->getId() + StdString("__") ;
       CGrid* grid = CGridGroup::get("grid_definition")->createChild(new_id) ;
-      grid->domain_ref.setValue(domain->getId());
+
+      std::vector<CDomain*> vecDom(1,domain);
+      grid->setDomainList(vecDom);
+//      grid->domain_ref.setValue(domain->getId());
       return (grid);
    }
@@ -454,7 +500,35 @@
                          StdString("_") + axis->getId() + StdString("__") ;
       CGrid* grid = CGridGroup::get("grid_definition")->createChild(new_id) ;
-      grid->domain_ref.setValue(domain->getId());
-      grid->axis_ref.setValue(axis->getId());
+
+      std::vector<CDomain*> vecDom(1,domain);
+      std::vector<CAxis*> vecAxis(1,axis);
+      grid->setDomainList(vecDom);
+      grid->setAxisList(vecAxis);
+//      grid->domain_ref.setValue(domain->getId());
+//      grid->axis_ref.setValue(axis->getId());
       return (grid);
+   }
+
+   CGrid* CGrid::createGrid(std::vector<CDomain*> domains, std::vector<CAxis*> axis)
+   {
+      StdString new_id = StdString("__");
+      if (!domains.empty()) for (int i = 0; i < domains.size(); ++i) new_id += domains[i]->getId() + StdString("_");
+      if (!axis.empty()) for (int i = 0; i < axis.size(); ++i) new_id += axis[i]->getId() + StdString("_") ;
+      new_id += StdString("_");
+
+      CGrid* grid = CGridGroup::get("grid_definition")->createChild(new_id) ;
+      grid->setDomainList(domains);
+      grid->setAxisList(axis);
+      return (grid);
+   }
+
+   CDomainGroup* CGrid::getVirtualDomainGroup() const
+   {
+     return (this->vDomainGroup_);
+   }
+
+   CAxisGroup* CGrid::getVirtualAxisGroup() const
+   {
+     return (this->vAxisGroup_);
    }
 
@@ -679,4 +753,11 @@
   }
 
+   /*!
+   \brief Dispatch event received from client
+      Whenever a message is received in buffer of server, it will be processed depending on
+   its event type. A new event type should be added in the switch list to make sure
+   it processed on server side.
+   \param [in] event: Received message
+   */
   bool CGrid::dispatchEvent(CEventServer& event)
   {
@@ -692,4 +773,13 @@
           break ;
 
+         case EVENT_ID_ADD_DOMAIN :
+           recvAddDomain(event) ;
+           return true ;
+           break ;
+
+         case EVENT_ID_ADD_AXIS :
+           recvAddAxis(event) ;
+           return true ;
+           break ;
         default :
           ERROR("bool CDomain::dispatchEvent(CEventServer& event)",
@@ -724,3 +814,299 @@
    ///---------------------------------------------------------------
 
+   CDomain* CGrid::addDomain(const std::string& id)
+   {
+     return vDomainGroup_->createChild(id) ;
+   }
+
+   CAxis* CGrid::addAxis(const std::string& id)
+   {
+     return vAxisGroup_->createChild(id) ;
+   }
+
+   //! Change virtual field group to a new one
+   void CGrid::setVirtualDomainGroup(CDomainGroup* newVDomainGroup)
+   {
+      this->vDomainGroup_ = newVDomainGroup;
+   }
+
+   //! Change virtual variable group to new one
+   void CGrid::setVirtualAxisGroup(CAxisGroup* newVAxisGroup)
+   {
+      this->vAxisGroup_ = newVAxisGroup;
+   }
+
+   //----------------------------------------------------------------
+   //! Create virtual field group, which is done normally on initializing file
+   void CGrid::setVirtualDomainGroup(void)
+   {
+      this->setVirtualDomainGroup(CDomainGroup::create());
+   }
+
+   //! Create virtual variable group, which is done normally on initializing file
+   void CGrid::setVirtualAxisGroup(void)
+   {
+      this->setVirtualAxisGroup(CAxisGroup::create());
+   }
+
+   /*!
+   \brief Send a message to create a domain on server side
+   \param[in] id String identity of domain that will be created on server
+   */
+   void CGrid::sendAddDomain(const string& id)
+   {
+    CContext* context=CContext::getCurrent() ;
+
+    if (! context->hasServer )
+    {
+       CContextClient* client=context->client ;
+
+       CEventClient event(this->getType(),EVENT_ID_ADD_DOMAIN) ;
+       if (client->isServerLeader())
+       {
+         CMessage msg ;
+         msg<<this->getId() ;
+         msg<<id ;
+         event.push(client->getServerLeader(),1,msg) ;
+         client->sendEvent(event) ;
+       }
+       else client->sendEvent(event) ;
+    }
+   }
+
+   /*!
+   \brief Send a message to create an axis on server side
+   \param[in] id String identity of axis that will be created on server
+   */
+   void CGrid::sendAddAxis(const string& id)
+   {
+    CContext* context=CContext::getCurrent() ;
+
+    if (! context->hasServer )
+    {
+       CContextClient* client=context->client ;
+
+       CEventClient event(this->getType(),EVENT_ID_ADD_AXIS) ;
+       if (client->isServerLeader())
+       {
+         CMessage msg ;
+         msg<<this->getId() ;
+         msg<<id ;
+         event.push(client->getServerLeader(),1,msg) ;
+         client->sendEvent(event) ;
+       }
+       else client->sendEvent(event) ;
+    }
+   }
+
+   /*!
+   \brief Receive a message annoucing the creation of a domain on server side
+   \param[in] event Received event
+   */
+   void CGrid::recvAddDomain(CEventServer& event)
+   {
+
+      CBufferIn* buffer=event.subEvents.begin()->buffer;
+      string id;
+      *buffer>>id ;
+      get(id)->recvAddDomain(*buffer) ;
+   }
+
+   /*!
+   \brief Receive a message annoucing the creation of a domain on server side
+   \param[in] buffer Buffer containing message
+   */
+   void CGrid::recvAddDomain(CBufferIn& buffer)
+   {
+      string id ;
+      buffer>>id ;
+      addDomain(id) ;
+   }
+
+   /*!
+   \brief Receive a message annoucing the creation of an axis on server side
+   \param[in] event Received event
+   */
+   void CGrid::recvAddAxis(CEventServer& event)
+   {
+
+      CBufferIn* buffer=event.subEvents.begin()->buffer;
+      string id;
+      *buffer>>id ;
+      get(id)->recvAddAxis(*buffer) ;
+   }
+
+   /*!
+   \brief Receive a message annoucing the creation of an axis on server side
+   \param[in] buffer Buffer containing message
+   */
+   void CGrid::recvAddAxis(CBufferIn& buffer)
+   {
+      string id ;
+      buffer>>id ;
+      addAxis(id) ;
+   }
+
+  void CGrid::solveDomainAxisRefInheritance(bool apply)
+  {
+    CContext* context = CContext::getCurrent();
+    unsigned int vecSize, i;
+    std::vector<StdString>::iterator it, itE;
+    setDomainList();
+    it = domList_.begin(); itE = domList_.end();
+    for (; it != itE; ++it)
+    {
+      CDomain* pDom = CDomain::get(*it);
+      if (context->hasClient)
+      {
+        pDom->solveRefInheritance(apply);
+        pDom->solveBaseReference();
+        if ((!pDom->domain_ref.isEmpty()) && (pDom->name.isEmpty()))
+          pDom->name.setValue(pDom->getBaseDomainReference()->getId());
+
+      }
+    }
+
+    setAxisList();
+    it = axisList_.begin(); itE = axisList_.end();
+    for (; it != itE; ++it)
+    {
+      CAxis* pAxis = CAxis::get(*it);
+      if (context->hasClient)
+      {
+        pAxis->solveRefInheritance(apply);
+        pAxis->solveBaseReference();
+        if ((!pAxis->axis_ref.isEmpty()) && (pAxis->name.isEmpty()))
+          pAxis->name.setValue(pAxis->getBaseAxisReference()->getId());
+      }
+    }
+  }
+
+  std::vector<CDomain*> CGrid::getDomains()
+  {
+    std::vector<CDomain*> domList;
+    if (!domList_.empty())
+    {
+      for (int i = 0; i < domList_.size(); ++i) domList.push_back(CDomain::get(domList_[i]));
+    }
+    return domList;
+  }
+
+  std::vector<CAxis*> CGrid::getAxis()
+  {
+    std::vector<CAxis*> aList;
+    if (!axisList_.empty())
+      for (int i =0; i < axisList_.size(); ++i) aList.push_back(CAxis::get(axisList_[i]));
+
+    return aList;
+  }
+
+  void CGrid::setDomainList(const std::vector<CDomain*> domains)
+  {
+    if (isDomListSet) return;
+    std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren();
+    if (!domains.empty() && domList.empty()) domList = domains;
+    if (!domList.empty())
+    {
+      int sizeDom = domList.size();
+      domList_.resize(sizeDom);
+      for (int i = 0 ; i < sizeDom; ++i)
+      {
+        domList_[i] = domList[i]->getId();
+      }
+      isDomListSet = true;
+    }
+
+  }
+
+  void CGrid::setAxisList(const std::vector<CAxis*> axis)
+  {
+    if (isAxisListSet) return;
+    std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren();
+    if (!axis.empty() && aList.empty()) aList = axis;
+    if (!aList.empty())
+    {
+      int sizeAxis = aList.size();
+      axisList_.resize(sizeAxis);
+      for (int i = 0; i < sizeAxis; ++i)
+      {
+        axisList_[i] = aList[i]->getId();
+      }
+      isAxisListSet = true;
+    }
+  }
+
+  std::vector<StdString> CGrid::getDomainList()
+  {
+    setDomainList();
+    return domList_;
+  }
+
+  std::vector<StdString> CGrid::getAxisList()
+  {
+    setAxisList();
+    return axisList_;
+  }
+
+  void CGrid::sendAllDomains()
+  {
+    std::vector<CDomain*> domList = this->getVirtualDomainGroup()->getAllChildren();
+    int dSize = domList.size();
+    for (int i = 0; i < dSize; ++i)
+    {
+      sendAddDomain(domList[i]->getId());
+      domList[i]->sendAllAttributesToServer();
+    }
+  }
+
+  void CGrid::sendAllAxis()
+  {
+    std::vector<CAxis*> aList = this->getVirtualAxisGroup()->getAllChildren();
+    int aSize = aList.size();
+
+    for (int i = 0; i < aSize; ++i)
+    {
+      sendAddAxis(aList[i]->getId());
+      aList[i]->sendAllAttributesToServer();
+    }
+  }
+
+  void CGrid::parse(xml::CXMLNode & node)
+  {
+    SuperClass::parse(node);
+
+    if (node.goToChildElement())
+    {
+      int domainIdx = -1;
+      int posAxis = 0;
+      StdString domainName("domain");
+      StdString axisName("axis");
+      do
+      {
+        if (node.getElementName() == domainName) {
+          axisOrder_.push_back(domainIdx);
+          this->getVirtualDomainGroup()->parseChild(node);
+        }
+        if (node.getElementName() == axisName) {
+          axisOrder_.push_back(posAxis);
+          ++posAxis;
+          this->getVirtualAxisGroup()->parseChild(node);
+        }
+      } while (node.goToNextElement()) ;
+      node.goToParentElement();
+    }
+
+    if (!axisOrder_.empty())
+    {
+      int sizeOrd = axisOrder_.size();
+      axisDomOrder.resize(sizeOrd);
+      for (int i = 0; i < sizeOrd; ++i)
+      {
+        axisDomOrder(i) = axisOrder_[i];
+      }
+    }
+
+    setDomainList();
+    setAxisList();
+   }
+
 } // namespace xios
Index: /XIOS/trunk/src/node/grid.hpp
===================================================================
--- /XIOS/trunk/src/node/grid.hpp	(revision 539)
+++ /XIOS/trunk/src/node/grid.hpp	(revision 540)
@@ -18,4 +18,6 @@
    class CGridGroup;
    class CGridAttributes;
+   class CDomainGroup;
+   class CAxisGroup;
    class CGrid;
 
@@ -44,5 +46,5 @@
          enum EEventId
          {
-           EVENT_ID_INDEX
+           EVENT_ID_INDEX, EVENT_ID_ADD_DOMAIN, EVENT_ID_ADD_AXIS
          } ;
 
@@ -96,4 +98,6 @@
          void outputField(int rank, const CArray<double,1>& stored,  CArray<double,1>& field)  ;
 
+         virtual void parse(xml::CXMLNode & node);
+
          /// Destructeur ///
          virtual ~CGrid(void);
@@ -110,4 +114,5 @@
          static CGrid* createGrid(CDomain* domain);
          static CGrid* createGrid(CDomain* domain, CAxis* axis);
+         static CGrid* createGrid(std::vector<CDomain*> domains, std::vector<CAxis*> axis);
 
       public :
@@ -124,4 +129,15 @@
          void solveDomainRef(bool checkAtt);
          void solveAxisRef(bool checkAtt);
+         void solveDomainAxisRefInheritance(bool apply = true);
+
+         void sendAddDomain(const std::string& id="");
+         void sendAddAxis(const std::string& id="");
+         void sendAllDomains();
+         void sendAllAxis();
+
+         static void recvAddDomain(CEventServer& event) ;
+         void recvAddDomain(CBufferIn& buffer) ;
+         static void recvAddAxis(CEventServer& event) ;
+         void recvAddAxis(CBufferIn& buffer) ;
 
          static bool dispatchEvent(CEventServer& event) ;
@@ -134,4 +150,9 @@
          std::map<int, int> getDomConServerSide();
          std::map<int, StdSize> getConnectedServerDataSize();
+         std::vector<StdString> getDomainList();
+         std::vector<StdString> getAxisList();
+         std::vector<CDomain*> getDomains();
+         std::vector<CAxis*> getAxis();
+
       public:
 
@@ -167,4 +188,28 @@
          std::map<int, int> domConnectedServerSide_;
          bool isDomConServerComputed_;
+
+      private:
+        void setVirtualDomainGroup(CDomainGroup* newVDomainGroup);
+        void setVirtualDomainGroup();
+        void setVirtualAxisGroup(CAxisGroup* newVAxisGroup);
+        void setVirtualAxisGroup();
+//        void setAxisList();
+        void setAxisList(const std::vector<CAxis*> axis = std::vector<CAxis*>());
+//        void setDomainList();
+        void setDomainList(const std::vector<CDomain*> domains = std::vector<CDomain*>());
+
+        CDomain* addDomain(const std::string& id);
+        CAxis* addAxis(const std::string& id);
+
+        CAxisGroup* getVirtualAxisGroup() const;
+        CDomainGroup* getVirtualDomainGroup() const;
+      private:
+        CDomainGroup* vDomainGroup_;
+        CAxisGroup* vAxisGroup_;
+        std::vector<std::string> axisList_, domList_;
+        bool isAxisListSet, isDomListSet;
+
+        // List order of axis in a grid, if there is a domain, it will take value -1
+        std::vector<int> axisOrder_;
    }; // class CGrid
 
Index: /XIOS/trunk/src/output/nc4_data_output.cpp
===================================================================
--- /XIOS/trunk/src/output/nc4_data_output.cpp	(revision 539)
+++ /XIOS/trunk/src/output/nc4_data_output.cpp	(revision 540)
@@ -489,5 +489,5 @@
          std::vector<StdString> dims;
          StdString axisid = (!axis->name.isEmpty())
-                           ? axis->name.getValue() : axis->getId();
+                             ? axis->name.getValue() : axis->getId();
          try
          {
@@ -504,4 +504,8 @@
 
                  SuperClassWriter::addAttribute("axis", StdString("Z"), &axisid);
+
+                 if (!axis->name.isEmpty())
+                    SuperClassWriter::addAttribute
+                       ("name", axis->name.getValue(), &axisid);
 
                  if (!axis->standard_name.isEmpty())
@@ -644,10 +648,17 @@
          }
 
-         if (!grid->axis_ref.isEmpty())
-         {
-            CAxis* axis = grid->axis ;
-            StdString axisid = (!axis->name.isEmpty()) ? axis->name.getValue() : axis->getId();
-            dims.push_back(axisid);
-            coodinates.push_back(axisid);
+         std::vector<StdString> axisList = grid->getAxisList();
+         if (!axisList.empty())
+         {
+           std::vector<StdString>::const_iterator itAxis = axisList.begin(), iteAxis = axisList.end();
+           for (; itAxis != iteAxis; ++itAxis)
+           {
+             CAxis* axis = CAxis::get(*itAxis);
+             StdString axisid = (!axis->name.isEmpty())
+                                ? axis->name.getValue() : axis->getId();
+
+             dims.push_back(axisid);
+             coodinates.push_back(axisid);
+           }
          }
 
Index: /XIOS/trunk/src/test/test_new_features.f90
===================================================================
--- /XIOS/trunk/src/test/test_new_features.f90	(revision 540)
+++ /XIOS/trunk/src/test/test_new_features.f90	(revision 540)
@@ -0,0 +1,127 @@
+PROGRAM test_client
+
+  USE xios
+  USE mod_wait
+  IMPLICIT NONE
+  INCLUDE "mpif.h"
+  INTEGER :: rank
+  INTEGER :: size
+  INTEGER :: ierr
+
+  CHARACTER(len=*),PARAMETER :: id="client"
+  INTEGER :: comm
+  TYPE(xios_time)      :: dtime
+  TYPE(xios_context) :: ctx_hdl
+  INTEGER,PARAMETER :: ni_glo=5
+  INTEGER,PARAMETER :: nj_glo=5
+  INTEGER,PARAMETER :: llm=5
+  DOUBLE PRECISION  :: lval(llm)=1
+  DOUBLE PRECISION  :: lval2(llm)=1
+  TYPE(xios_field) :: field_hdl
+  TYPE(xios_fieldgroup) :: fieldgroup_hdl
+  TYPE(xios_file) :: file_hdl
+  LOGICAL :: ok
+
+  DOUBLE PRECISION,DIMENSION(ni_glo,nj_glo) :: lon_glo,lat_glo
+!  DOUBLE PRECISION :: field_A_glo(ni_glo,nj_glo,llm,llm)
+!  DOUBLE PRECISION,ALLOCATABLE :: lon(:,:),lat(:,:),field_A(:,:,:,:), lonvalue(:) ;
+  DOUBLE PRECISION :: field_A_glo(ni_glo,nj_glo,llm)
+  DOUBLE PRECISION,ALLOCATABLE :: lon(:,:),lat(:,:),field_A(:,:,:), lonvalue(:) ;
+  INTEGER :: ni,ibegin,iend,nj,jbegin,jend
+  INTEGER :: i,j,l,ts,n,k
+
+!!! MPI Initialization
+
+  CALL MPI_INIT(ierr)
+
+  CALL init_wait
+
+!!! XIOS Initialization (get the local communicator)
+
+  CALL xios_initialize(id,return_comm=comm)
+
+  CALL MPI_COMM_RANK(comm,rank,ierr)
+  CALL MPI_COMM_SIZE(comm,size,ierr)
+
+  DO j=1,nj_glo
+    DO i=1,ni_glo
+      lon_glo(i,j)=(i-1)+(j-1)*ni_glo
+      lat_glo(i,j)=1000+(i-1)+(j-1)*ni_glo
+      DO l=1,llm
+!        DO k=1,llm
+!          field_A_glo(i,j,l,k)=(i-1)+(j-1)*ni_glo+10000*l+100000*k
+!        ENDDO
+        field_A_glo(i,j,l)=(i-1)+(j-1)*ni_glo+10000*l
+      ENDDO
+    ENDDO
+  ENDDO
+  ni=ni_glo ; ibegin=1
+
+  jbegin=1
+  DO n=0,size-1
+    nj=nj_glo/size
+    IF (n<MOD(nj_glo,size)) nj=nj+1
+    IF (n==rank) exit
+    jbegin=jbegin+nj
+  ENDDO
+
+  iend=ibegin+ni-1 ; jend=jbegin+nj-1
+
+  ALLOCATE(lon(ni,nj),lat(ni,nj),field_A(0:ni+1,-1:nj+2,llm),lonvalue(ni*nj))
+!  ALLOCATE(lon(ni,nj),lat(ni,nj),field_A(0:ni+1,-1:nj+2,llm,llm),lonvalue(ni*nj))
+  lon(:,:)=lon_glo(ibegin:iend,jbegin:jend)
+  lat(:,:)=lat_glo(ibegin:iend,jbegin:jend)
+  field_A(1:ni,1:nj,:)=field_A_glo(ibegin:iend,jbegin:jend,:)
+
+  CALL xios_context_initialize("test",comm)
+  CALL xios_get_handle("test",ctx_hdl)
+  CALL xios_set_current_context(ctx_hdl)
+
+  CALL xios_set_context_attr("test",calendar_type="Gregorian")
+  CALL xios_set_axis_attr("axis_A",size=llm ,value=lval) ;
+  CALL xios_set_axis_attr("axis_B",size=llm ,value=lval2) ;
+  CALL xios_set_domain_attr("domain_A",ni_glo=ni_glo, nj_glo=nj_glo, ibegin=ibegin, ni=ni,jbegin=jbegin,nj=nj)
+  CALL xios_set_domain_attr("domain_A",data_dim=2, data_ibegin=-1, data_ni=ni+2, data_jbegin=-2, data_nj=nj+4)
+  CALL xios_set_domain_attr("domain_A",lonvalue=RESHAPE(lon,(/ni*nj/)),latvalue=RESHAPE(lat,(/ni*nj/)))
+  CALL xios_set_fieldgroup_attr("field_definition",enabled=.TRUE.)
+
+  CALL xios_get_handle("field_definition",fieldgroup_hdl)
+  CALL xios_add_child(fieldgroup_hdl,field_hdl,"field_B")
+  CALL xios_set_attr(field_hdl,field_ref="field_A",name="field_B")
+
+  CALL xios_get_handle("output",file_hdl)
+  CALL xios_add_child(file_hdl,field_hdl)
+  CALL xios_set_attr(field_hdl,field_ref="field_A",name="field_C")
+
+
+    dtime%second=3600
+    CALL xios_set_timestep(dtime)
+
+    ni=0 ; lonvalue(:)=0
+    CALL xios_get_domain_attr("domain_A",ni=ni,lonvalue=lonvalue)
+
+    print *,"ni",ni
+    print *,"lonvalue",lonvalue ;
+
+    CALL xios_is_defined_field_attr("field_A",enabled=ok)
+    PRINT *,"field_A : attribute enabled is defined ? ",ok
+    CALL xios_close_context_definition()
+
+    PRINT*,"field field_A is active ? ",xios_field_is_active("field_A")
+    DO ts=1,24*10
+      CALL xios_update_calendar(ts)
+      CALL xios_send_field("field_A",field_A)
+      CALL wait_us(5000) ;
+    ENDDO
+
+    CALL xios_context_finalize()
+    CALL xios_finalize()
+
+  CALL MPI_FINALIZE(ierr)
+
+END PROGRAM test_client
+
+
+
+
+
