Index: XIOS/trunk/src/node/context.cpp
===================================================================
--- XIOS/trunk/src/node/context.cpp	(revision 501)
+++ XIOS/trunk/src/node/context.cpp	(revision 509)
@@ -16,21 +16,21 @@
 
 namespace xios {
-  
+
   shared_ptr<CContextGroup> CContext::root ;
-   
+
    /// ////////////////////// DÃ©finitions ////////////////////// ///
 
    CContext::CContext(void)
       : CObjectTemplate<CContext>(), CContextAttributes()
-      , calendar(),hasClient(false),hasServer(false)
+      , calendar(),hasClient(false),hasServer(false), isPostProcessed(false), dataSize_()
    { /* Ne rien faire de plus */ }
 
    CContext::CContext(const StdString & id)
       : CObjectTemplate<CContext>(id), CContextAttributes()
-      , calendar(),hasClient(false),hasServer(false)
+      , calendar(),hasClient(false),hasServer(false), isPostProcessed(false), dataSize_()
    { /* Ne rien faire de plus */ }
 
    CContext::~CContext(void)
-   { 
+   {
      if (hasClient) delete client ;
      if (hasServer) delete server ;
@@ -38,5 +38,5 @@
 
    //----------------------------------------------------------------
-
+   //! Get name of context
    StdString CContext::GetName(void)   { return (StdString("context")); }
    StdString CContext::GetDefName(void){ return (CContext::GetName()); }
@@ -44,21 +44,30 @@
 
    //----------------------------------------------------------------
-
+   /*!
+   \brief Get context group (context root)
+   \return Context root
+   */
    CContextGroup* CContext::getRoot(void)
-   {  
+   {
       if (root.get()==NULL) root=shared_ptr<CContextGroup>(new CContextGroup(xml::CXMLNode::GetRootName())) ;
-      return root.get(); 
-   }
-   
-
-   //----------------------------------------------------------------
-
+      return root.get();
+   }
+
+
+   //----------------------------------------------------------------
+   /*!
+   \brief Get calendar of a context
+   \return Calendar
+   */
    boost::shared_ptr<CCalendar> CContext::getCalendar(void) const
    {
       return (this->calendar);
    }
-   
-   //----------------------------------------------------------------
-   
+
+   //----------------------------------------------------------------
+   /*!
+   \brief Set a context with a calendar
+   \param[in] newCalendar new calendar
+   */
    void CContext::setCalendar(boost::shared_ptr<CCalendar> newCalendar)
    {
@@ -67,7 +76,7 @@
       start_date.setValue(this->calendar->getInitDate().toString());
    }
-   
-   //----------------------------------------------------------------
-
+
+   //----------------------------------------------------------------
+   //! Process all information of calendar
    void CContext::solveCalendar(void)
    {
@@ -97,7 +106,10 @@
             << "The calendar is not defined !");
    }
-   
-   //----------------------------------------------------------------
-
+
+   //----------------------------------------------------------------
+   /*!
+   \brief Parse xml file and write information into context object
+   \param [in] node xmld node corresponding in xml file
+   */
    void CContext::parse(xml::CXMLNode & node)
    {
@@ -135,6 +147,8 @@
 
             if (attributes.end() != attributes.find("id"))
-            { DEBUG(<< "Definition node has an id,"
-                    << "it will not be taking account !"); }
+            {
+              DEBUG(<< "Definition node has an id,"
+                    << "it will not be taking account !");
+            }
 
 #define DECLARE_NODE(Name_, name_)    \
@@ -155,5 +169,5 @@
 
    //----------------------------------------------------------------
-
+   //! Show tree structure of context
    void CContext::ShowTree(StdOStream & out)
    {
@@ -166,19 +180,20 @@
       out << "<? xml version=\"1.0\" ?>" << std::endl;
       out << "<"  << xml::CXMLNode::GetRootName() << " >" << std::endl;
-      
+
       for (; it != end; it++)
       {
-         CContext* context = *it;         
-         CContext::setCurrent(context->getId());         
+         CContext* context = *it;
+         CContext::setCurrent(context->getId());
          out << *context << std::endl;
       }
-      
+
       out << "</" << xml::CXMLNode::GetRootName() << " >" << std::endl;
-      CContext::setCurrent(currentContextId);  
-   }
-   
-
-   //----------------------------------------------------------------
-
+      CContext::setCurrent(currentContextId);
+   }
+
+
+   //----------------------------------------------------------------
+
+   //! Convert context object into string (to print)
    StdString CContext::toString(void) const
    {
@@ -209,4 +224,10 @@
    //----------------------------------------------------------------
 
+   /*!
+   \brief Find all inheritace among objects in a context.
+   \param [in] apply (true) write attributes of parent into ones of child if they are empty
+                     (false) write attributes of parent into a new container of child
+   \param [in] parent unused
+   */
    void CContext::solveDescInheritance(bool apply, const CAttributeMap * const UNUSED(parent))
    {
@@ -220,4 +241,5 @@
    //----------------------------------------------------------------
 
+   //! Verify if all root definition in the context have child.
    bool CContext::hasChild(void) const
    {
@@ -230,20 +252,20 @@
 }
 
-   //----------------------------------------------------------------
-
-   void CContext::solveFieldRefInheritance(bool apply)
-   {
-      if (!this->hasId()) return;
-      vector<CField*> allField = CField::getAll() ;
-//              = CObjectTemplate<CField>::GetAllVectobject(this->getId());
-      std::vector<CField*>::iterator 
-         it = allField.begin(), end = allField.end();
-            
-      for (; it != end; it++)
-      {
-         CField* field = *it;
-         field->solveRefInheritance(apply);
-      }
-   }
+//   //----------------------------------------------------------------
+//
+//   void CContext::solveFieldRefInheritance(bool apply)
+//   {
+//      if (!this->hasId()) return;
+//      vector<CField*> allField = CField::getAll() ;
+////              = CObjectTemplate<CField>::GetAllVectobject(this->getId());
+//      std::vector<CField*>::iterator
+//         it = allField.begin(), end = allField.end();
+//
+//      for (; it != end; it++)
+//      {
+//         CField* field = *it;
+//         field->solveRefInheritance(apply);
+//      }
+//   }
 
    //----------------------------------------------------------------
@@ -256,27 +278,40 @@
    }
    ///---------------------------------------------------------------
-   
+
+   //! Initialize client side
    void CContext::initClient(MPI_Comm intraComm, MPI_Comm interComm)
    {
      hasClient=true ;
      client = new CContextClient(this,intraComm, interComm) ;
-   } 
-
+   }
+
+   void CContext::setClientServerBuffer()
+   {
+     if (hasClient)
+     {
+       client->setBufferSize(getDataSize());
+     }
+   }
+
+   //! Verify whether a context is initialized
    bool CContext::isInitialized(void)
    {
      return hasClient ;
    }
-    
+
+   //! Initialize server
    void CContext::initServer(MPI_Comm intraComm,MPI_Comm interComm)
    {
      hasServer=true ;
      server = new CContextServer(this,intraComm,interComm) ;
-   } 
-
+   }
+
+   //! Server side: Put server into a loop in order to listen message from client
    bool CContext::eventLoop(void)
    {
      return server->eventLoop() ;
-   } 
-   
+   }
+
+   //! Terminate a context
    void CContext::finalize(void)
    {
@@ -290,24 +325,84 @@
       }
    }
-       
-       
- 
-   
+
+   /*!
+   \brief Close all the context defintion and do processing data
+      After everything is well defined on client side, they will be processed and sent to server
+   From the version 2.0, sever and client work no more on the same database. Moreover, client(s) will send
+   all necessary information to server, from which each server can build its own database.
+   Because the role of server is to write out field data on a specific netcdf file,
+   the only information that it needs is the enabled files
+   and the active fields (fields will be written onto active files)
+   */
    void CContext::closeDefinition(void)
    {
-      if (hasClient && !hasServer) sendCloseDefinition() ;
-      
-      solveCalendar();         
-         
-      // RÃ©solution des hÃ©ritages pour le context actuel.
-      this->solveAllInheritance();
-
-      //Initialisation du vecteur 'enabledFiles' contenant la liste des fichiers Ã  sortir.
-      this->findEnabledFiles();
-
-        
-      this->processEnabledFiles() ;
-
-/*        
+     if (hasClient && !hasServer)
+     {
+       // After xml is parsed, there are some more works with post processing
+       postProcessing();
+
+       setClientServerBuffer();
+
+      // Send all attributes of current context to server
+      this->sendAllAttributesToServer();
+
+      // We have enough information to send to server
+      // First of all, send all enabled files
+       sendEnabledFiles();
+
+      // Then, send all enabled fields
+       sendEnabledFields();
+
+      // After that, send all grid (if any)
+       sendRefGrid();
+
+      // At last, we have all info of domain and axis, then send them
+       sendRefDomainsAxis();
+    }
+
+    // Now tell server that it can process all messages from client
+    if (hasClient && !hasServer) this->sendCloseDefinition();
+
+    // We have a xml tree on the server side and now, it should be also processed
+    if (hasClient && !hasServer) sendPostProcessing();
+
+    // There are some processings that should be done after all of above. For example: check mask or index
+    if (hasClient && !hasServer)
+    {
+      this->solveAllRefOfEnabledFields(true);
+      this->buildAllExpressionOfEnabledFields();
+    }
+
+//      if (hasClient)
+//      {
+//        //solveCalendar();
+//
+//        // RÃ©solution des hÃ©ritages pour le context actuel.
+////        this->solveAllInheritance();
+//
+//
+////        //Initialisation du vecteur 'enabledFiles' contenant la liste des fichiers Ã  sortir.
+////        this->findEnabledFiles();
+//
+//        this->processEnabledFiles() ;
+//
+//        this->solveAllGridRef();
+//      }
+
+
+
+
+//      solveCalendar();
+//
+//      // RÃ©solution des hÃ©ritages pour le context actuel.
+//      this->solveAllInheritance();
+//
+//      //Initialisation du vecteur 'enabledFiles' contenant la liste des fichiers Ã  sortir.
+//      this->findEnabledFiles();
+//
+//
+//      this->processEnabledFiles() ;
+
+/*
       //Recherche des champs Ã  sortir (enable Ã  true + niveau de sortie correct)
       // pour chaque fichier prÃ©cÃ©demment listÃ©.
@@ -324,8 +419,9 @@
 */
       // Nettoyage de l'arborescence
-      CleanTree();
+      if (hasClient && !hasServer) CleanTree(); // Only on client side??
+//      if (hasClient) CleanTree();
       if (hasClient) sendCreateFileHeader() ;
    }
-   
+
    void CContext::findAllEnabledFields(void)
    {
@@ -333,30 +429,48 @@
      (void)this->enabledFiles[i]->getEnabledFields();
    }
-   
-    void CContext::processEnabledFiles(void)
-   {
-     for (unsigned int i = 0; i < this->enabledFiles.size(); i++)
-     this->enabledFiles[i]->processEnabledFile();
-   }
-  
-
-   void CContext::solveAllGridRef(void)
-   {
-     for (unsigned int i = 0; i < this->enabledFiles.size(); i++)
-     this->enabledFiles[i]->solveEFGridRef();
-   }
-
-   void CContext::solveAllOperation(void)
-   {
-      for (unsigned int i = 0; i < this->enabledFiles.size(); i++)
-      this->enabledFiles[i]->solveEFOperation();
-   }
-
-   void CContext::solveAllExpression(void)
-   {
-      for (unsigned int i = 0; i < this->enabledFiles.size(); i++)
-      this->enabledFiles[i]->solveEFExpression();
-   }
-   
+
+//    void CContext::processEnabledFiles(void)
+//   {
+//     for (unsigned int i = 0; i < this->enabledFiles.size(); i++)
+//     this->enabledFiles[i]->processEnabledFile();
+//   }
+
+
+   void CContext::solveAllRefOfEnabledFields(bool sendToServer)
+   {
+     int size = this->enabledFiles.size();
+     for (int i = 0; i < size; ++i)
+     {
+       this->enabledFiles[i]->solveAllRefOfEnabledFields(sendToServer);
+     }
+   }
+
+   void CContext::buildAllExpressionOfEnabledFields()
+   {
+     int size = this->enabledFiles.size();
+     for (int i = 0; i < size; ++i)
+     {
+       this->enabledFiles[i]->buildAllExpressionOfEnabledFields();
+     }
+   }
+
+//   void CContext::solveAllGridRef(void)
+//   {
+//     for (unsigned int i = 0; i < this->enabledFiles.size(); i++)
+//     this->enabledFiles[i]->solveEFGridRef();
+//   }
+//
+//   void CContext::solveAllOperation(void)
+//   {
+//      for (unsigned int i = 0; i < this->enabledFiles.size(); i++)
+//      this->enabledFiles[i]->solveEFOperation();
+//   }
+//
+//   void CContext::solveAllExpression(void)
+//   {
+//      for (unsigned int i = 0; i < this->enabledFiles.size(); i++)
+//      this->enabledFiles[i]->solveEFExpression();
+//   }
+
    void CContext::solveAllInheritance(bool apply)
    {
@@ -368,4 +482,5 @@
       const vector<CFile*> allFiles=CFile::getAll() ;
 
+     if (hasClient && !hasServer)
       for (unsigned int i = 0; i < allFiles.size(); i++)
          allFiles[i]->solveFieldRefInheritance(apply);
@@ -383,5 +498,5 @@
          }
          else enabledFiles.push_back(allFiles[i]); // otherwise true by default
-               
+
 
       if (enabledFiles.size() == 0)
@@ -394,5 +509,5 @@
      std::vector<CFile*>::const_iterator
             it = this->enabledFiles.begin(), end = this->enabledFiles.end();
-         
+
      for (; it != end; it++)
      {
@@ -401,8 +516,15 @@
      }
    }
-   
+
+   /*!
+   \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 CContext::dispatchEvent(CEventServer& event)
    {
-      
+
       if (SuperClass::dispatchEvent(event)) return true ;
       else
@@ -422,4 +544,8 @@
              return true ;
              break ;
+           case EVENT_ID_POST_PROCESS:
+             recvPostProcessing(event) ;
+             return true ;
+             break ;
            default :
              ERROR("bool CContext::dispatchEvent(CEventServer& event)",
@@ -429,9 +555,9 @@
       }
    }
-   
+
+   //! Client side: Send a message to server to make it close
    void CContext::sendCloseDefinition(void)
    {
-
-     CEventClient event(getType(),EVENT_ID_CLOSE_DEFINITION) ;   
+     CEventClient event(getType(),EVENT_ID_CLOSE_DEFINITION) ;
      if (client->isServerLeader())
      {
@@ -443,19 +569,21 @@
      else client->sendEvent(event) ;
    }
-   
+
+   //! Server side: Receive a message of client announcing a context close
    void CContext::recvCloseDefinition(CEventServer& event)
    {
-      
+
       CBufferIn* buffer=event.subEvents.begin()->buffer;
       string id;
       *buffer>>id ;
-      get(id)->closeDefinition() ;
-   }
-   
+      get(id)->closeDefinition();
+   }
+
+   //! Client side: Send a message to update calendar in each time step
    void CContext::sendUpdateCalendar(int step)
    {
      if (!hasServer)
      {
-       CEventClient event(getType(),EVENT_ID_UPDATE_CALENDAR) ;   
+       CEventClient event(getType(),EVENT_ID_UPDATE_CALENDAR) ;
        if (client->isServerLeader())
        {
@@ -468,8 +596,9 @@
      }
    }
-   
+
+   //! Server side: Receive a message of client annoucing calendar update
    void CContext::recvUpdateCalendar(CEventServer& event)
    {
-      
+
       CBufferIn* buffer=event.subEvents.begin()->buffer;
       string id;
@@ -477,5 +606,6 @@
       get(id)->recvUpdateCalendar(*buffer) ;
    }
-   
+
+   //! Server side: Receive a message of client annoucing calendar update
    void CContext::recvUpdateCalendar(CBufferIn& buffer)
    {
@@ -484,9 +614,9 @@
       updateCalendar(step) ;
    }
-   
+
+   //! Client side: Send a message to create header part of netcdf file
    void CContext::sendCreateFileHeader(void)
    {
-
-     CEventClient event(getType(),EVENT_ID_CREATE_FILE_HEADER) ;   
+     CEventClient event(getType(),EVENT_ID_CREATE_FILE_HEADER) ;
      if (client->isServerLeader())
      {
@@ -498,8 +628,8 @@
      else client->sendEvent(event) ;
    }
-   
+
+   //! Server side: Receive a message of client annoucing the creation of header part of netcdf file
    void CContext::recvCreateFileHeader(CEventServer& event)
    {
-      
       CBufferIn* buffer=event.subEvents.begin()->buffer;
       string id;
@@ -507,10 +637,217 @@
       get(id)->recvCreateFileHeader(*buffer) ;
    }
-   
+
+   //! Server side: Receive a message of client annoucing the creation of header part of netcdf file
    void CContext::recvCreateFileHeader(CBufferIn& buffer)
    {
       createFileHeader() ;
    }
-   
+
+   //! Client side: Send a message to do some post processing on server
+   void CContext::sendPostProcessing()
+   {
+     if (!hasServer)
+     {
+       CEventClient event(getType(),EVENT_ID_POST_PROCESS) ;
+       if (client->isServerLeader())
+       {
+         CMessage msg ;
+         msg<<this->getId();
+         event.push(client->getServerLeader(),1,msg) ;
+         client->sendEvent(event) ;
+       }
+       else client->sendEvent(event) ;
+     }
+   }
+
+   //! Server side: Receive a message to do some post processing
+   void CContext::recvPostProcessing(CEventServer& event)
+   {
+      CBufferIn* buffer=event.subEvents.begin()->buffer;
+      string id;
+      *buffer>>id;
+      get(id)->recvPostProcessing(*buffer);
+   }
+
+   //! Server side: Receive a message to do some post processing
+   void CContext::recvPostProcessing(CBufferIn& buffer)
+   {
+      postProcessing();
+   }
+
+   /*!
+   \brief Do some simple post processings after parsing xml file
+      After the xml file (iodef.xml) is parsed, it is necessary to build all relations among
+   created object, e.g: inhertance among fields, domain, axis. After that, all fiels as well as their parents (reference fields),
+   which will be written out into netcdf files, are processed
+   */
+   void CContext::postProcessing()
+   {
+     if (isPostProcessed) return;
+
+     this->solveCalendar();
+
+     // Solve calendar for both side: client and server
+      this->solveCalendar();
+
+      // Find all inheritance in xml structure
+      this->solveAllInheritance();
+
+      //Initialisation du vecteur 'enabledFiles' contenant la liste des fichiers Ã  sortir.
+      this->findEnabledFiles();
+
+      // Find all enabled fields of each file
+      this->findAllEnabledFields();
+
+      // Search and rebuild all reference object of enabled fields
+      this->solveAllRefOfEnabledFields(false);
+      isPostProcessed = true;
+   }
+
+   std::map<int, StdSize>& CContext::getDataSize()
+   {
+     std::set<StdString> domainIds;
+
+     // Find all reference domain and axis of all active fields
+     int numEnabledFiles = this->enabledFiles.size();
+     for (int i = 0; i < numEnabledFiles; ++i)
+     {
+       std::vector<CField*> enabledFields = this->enabledFiles[i]->getEnabledFields();
+       int numEnabledFields = enabledFields.size();
+       for (int j = 0; j < numEnabledFields; ++j)
+       {
+         const std::pair<StdString, StdString>& prDomAxisId = enabledFields[j]->getDomainAxisIds();
+         const std::map<int, StdSize> mapSize = enabledFields[j]->getGridDataSize();
+         if (dataSize_.empty())
+         {
+           dataSize_ = mapSize;
+           domainIds.insert(prDomAxisId.first);
+         }
+         else
+         {
+           if (domainIds.find(prDomAxisId.first) == domainIds.end())
+           {
+             std::map<int, StdSize>::const_iterator it = mapSize.begin(), itE = mapSize.end();
+             for (; it != itE; ++it)
+             {
+               if (0 < dataSize_.count(it->first)) dataSize_[it->first] += it->second;
+               else dataSize_.insert(make_pair(it->first, it->second));
+             }
+           }
+
+         }
+
+       }
+     }
+
+     return dataSize_;
+   }
+
+   //! Client side: Send infomation of active files (files are enabled to write out)
+   void CContext::sendEnabledFiles()
+   {
+     int size = this->enabledFiles.size();
+
+     // In a context, each type has a root definition, e.g: axis, domain, field.
+     // Every object must be a child of one of these root definition. In this case
+     // all new file objects created on server must be children of the root "file_definition"
+     StdString fileDefRoot("file_definition");
+     CFileGroup* cfgrpPtr = CFileGroup::get(fileDefRoot);
+
+     for (int i = 0; i < size; ++i)
+     {
+       cfgrpPtr->sendCreateChild(this->enabledFiles[i]->getId());
+       this->enabledFiles[i]->sendAllAttributesToServer();
+       this->enabledFiles[i]->sendAddAllVariables();
+     }
+   }
+
+   //! Client side: Send information of active fields (ones are written onto files)
+   void CContext::sendEnabledFields()
+   {
+     int size = this->enabledFiles.size();
+     for (int i = 0; i < size; ++i)
+     {
+       this->enabledFiles[i]->sendEnabledFields();
+     }
+   }
+
+   //! Client side: Send information of reference grid of active fields
+   void CContext::sendRefGrid()
+   {
+     std::set<StdString> gridIds;
+     int sizeFile = this->enabledFiles.size();
+     CFile* filePtr(NULL);
+
+     // Firstly, find all reference grids of all active fields
+     for (int i = 0; i < sizeFile; ++i)
+     {
+       filePtr = this->enabledFiles[i];
+       std::vector<CField*> enabledFields = filePtr->getEnabledFields();
+       int sizeField = enabledFields.size();
+       for (int numField = 0; numField < sizeField; ++numField)
+       {
+         if (0 != enabledFields[numField]->getRelGrid())
+           gridIds.insert(CGrid::get(enabledFields[numField]->getRelGrid())->getId());
+       }
+     }
+
+     // Create all reference grids on server side
+     StdString gridDefRoot("grid_definition");
+     CGridGroup* gridPtr = CGridGroup::get(gridDefRoot);
+     std::set<StdString>::const_iterator it, itE = gridIds.end();
+     for (it = gridIds.begin(); it != itE; ++it)
+     {
+       gridPtr->sendCreateChild(*it);
+       CGrid::get(*it)->sendAllAttributesToServer();
+     }
+   }
+
+
+   //! Client side: Send information of reference domain and axis of active fields
+   void CContext::sendRefDomainsAxis()
+   {
+     std::set<StdString> domainIds;
+     std::set<StdString> axisIds;
+
+     // Find all reference domain and axis of all active fields
+     int numEnabledFiles = this->enabledFiles.size();
+     for (int i = 0; i < numEnabledFiles; ++i)
+     {
+       std::vector<CField*> enabledFields = this->enabledFiles[i]->getEnabledFields();
+       int numEnabledFields = enabledFields.size();
+       for (int j = 0; j < numEnabledFields; ++j)
+       {
+         const std::pair<StdString, StdString>& prDomAxisId = enabledFields[j]->getDomainAxisIds();
+         domainIds.insert(prDomAxisId.first);
+         axisIds.insert(prDomAxisId.second);
+       }
+     }
+
+     // Create all reference axis on server side
+     std::set<StdString>::iterator itDom, itAxis;
+     std::set<StdString>::const_iterator itE;
+
+     StdString axiDefRoot("axis_definition");
+     CAxisGroup* axisPtr = CAxisGroup::get(axiDefRoot);
+     itE = axisIds.end();
+     for (itAxis = axisIds.begin(); itAxis != itE; ++itAxis)
+     {
+       axisPtr->sendCreateChild(*itAxis);
+       CAxis::get(*itAxis)->sendAllAttributesToServer();
+     }
+
+     // Create all reference domains on server side
+     StdString domDefRoot("domain_definition");
+     CDomainGroup* domPtr = CDomainGroup::get(domDefRoot);
+     itE = domainIds.end();
+     for (itDom = domainIds.begin(); itDom != itE; ++itDom)
+     {
+       domPtr->sendCreateChild(*itDom);
+       CDomain::get(*itDom)->sendAllAttributesToServer();
+     }
+   }
+
+   //! Update calendar in each time step
    void CContext::updateCalendar(int step)
    {
@@ -519,20 +856,26 @@
       info(50)<<"updateCalendar : after : "<<calendar->getCurrentDate()<<endl ;
    }
- 
+
+   //! Server side: Create header of netcdf file
    void CContext::createFileHeader(void )
    {
       vector<CFile*>::const_iterator it ;
-         
+
       for (it=enabledFiles.begin(); it != enabledFiles.end(); it++)
       {
          (*it)->initFile();
       }
-   } 
-   
+   }
+
+   //! Get current context
    CContext* CContext::getCurrent(void)
    {
      return CObjectFactory::GetObject<CContext>(CObjectFactory::GetCurrentContextId()).get() ;
    }
-   
+
+   /*!
+   \brief Set context with an id be the current context
+   \param [in] id identity of context to be set to current
+   */
    void CContext::setCurrent(const string& id)
    {
@@ -540,9 +883,14 @@
      CGroupFactory::SetCurrentContextId(id);
    }
-   
+
+  /*!
+  \brief Create a context with specific id
+  \param [in] id identity of new context
+  \return pointer to the new context or already-existed one with identity id
+  */
   CContext* CContext::create(const StdString& id)
   {
     CContext::setCurrent(id) ;
- 
+
     bool hasctxt = CContext::has(id);
     CContext* context = CObjectFactory::CreateObject<CContext>(id).get();
