Index: /trunk/FACT++/src/ServiceList.cc
===================================================================
--- /trunk/FACT++/src/ServiceList.cc	(revision 10297)
+++ /trunk/FACT++/src/ServiceList.cc	(revision 10298)
@@ -87,5 +87,8 @@
 {
     for (ServerMap::iterator i=fServerList.begin(); i!=fServerList.end(); i++)
-            delete i->second;
+    {
+            delete i->second.first;
+            delete i->second.second;
+    }
 }
 
@@ -108,5 +111,8 @@
 
     if (fHandler)
+    {
+        fHandler->itsService = 0;
         fHandler->infoHandler();
+    }
 }
 
@@ -121,7 +127,7 @@
 //!    a pointer to the newly created DimInfo
 //!
-DimInfo *ServiceList::CreateDimInfo(const string &str) const
-{
-    return new DimInfo((str+"/SERVICE_LIST").c_str(),
+DimInfo *ServiceList::CreateDimInfo(const string &str, const string &svc) const
+{
+    return new DimInfo((str+"/"+svc).c_str(),
                        const_cast<char*>(""),
                        const_cast<ServiceList*>(this));
@@ -150,5 +156,6 @@
         for (ServerMap::iterator i=fServerList.begin(); i!=fServerList.end(); i++)
         {
-            delete i->second;
+            delete i->second.first;
+            delete i->second.second;
 
             ServiceMap::iterator x = fServiceList.find(i->first);
@@ -156,4 +163,5 @@
             //wout << "Delete: " << i->first << endl;
         }
+
         fServerList.clear();
     }
@@ -186,5 +194,6 @@
 
             // Remove the server from the server list
-            delete v->second;
+            delete v->second.first;
+            delete v->second.second;
             fServerList.erase(v);
 
@@ -213,5 +222,5 @@
 
             // Add the new server to the server list
-            fServerList[trunc] = CreateDimInfo(trunc);
+            fServerList[trunc] = make_pair(CreateSL(trunc), CreateFMT(trunc));
 
             wout << " -> " << Time().GetAsStr() << " - " << trunc << "/SERVICE_LIST: Connected." << endl;
@@ -221,5 +230,5 @@
 
         // In any other case we just add the entry to the list
-        fServerList[server] = CreateDimInfo(server);
+        fServerList[server] = make_pair(CreateSL(server), CreateFMT(server));
         //wout << "Add  0: " << server << endl;
     }
@@ -251,36 +260,59 @@
     string buffer = info.getName();
 
-    // Get the server name from the service name
-    const string server = buffer.substr(0, buffer.find_first_of('/'));
-
-    // Initialize the entry with an empty list
-    if (str[0]!='+')
-        fServiceList[server] = vector<string>();
-
-    // For easy and fast access get the corresponding reference
-    vector<string> &list = fServiceList[server];
-
-    // Tokenize the stream into lines
-    stringstream stream(str);
-    while (getline(stream, buffer, '\n'))
-    {
-        if (buffer.empty())
-            continue;
-
-        // Get the type and compare it with fType
-        const string type = buffer.substr(buffer.find_last_of('|')+1);
-        if (type!=fType)
-            continue;
-
-        // Get format, name and command name
-        const string fmt  = buffer.substr(buffer.find_first_of('|')+1, buffer.find_last_of('|')-buffer.find_first_of('|')-1);
-        const string name = buffer.substr(buffer.find_first_of('/')+1, buffer.find_first_of('|')-buffer.find_first_of('/')-1);
-        const string cmd  = buffer.substr(0, buffer.find_first_of('|'));
-
-        // Add name the the list
-        list.push_back(name);
-
-        // Add format to the list
-        fFormatList[cmd] = fmt;
+    if (buffer.find("SERVICE_DESC")!=buffer.length()-12)
+    {
+        // Get the server name from the service name
+        const string server = buffer.substr(0, buffer.find_first_of('/'));
+
+        // Initialize the entry with an empty list
+        if (str[0]!='+')
+            fServiceList[server] = vector<string>();
+
+        // For easy and fast access get the corresponding reference
+        vector<string> &list = fServiceList[server];
+
+        // Tokenize the stream into lines
+        stringstream stream(str);
+        while (getline(stream, buffer, '\n'))
+        {
+            if (buffer.empty())
+                continue;
+
+            // Get the type and compare it with fType
+            const string type = buffer.substr(buffer.find_last_of('|')+1);
+            if (type!=fType)
+                continue;
+
+            // Get format, name and command name
+            const string fmt  = buffer.substr(buffer.find_first_of('|')+1, buffer.find_last_of('|')-buffer.find_first_of('|')-1);
+            const string name = buffer.substr(buffer.find_first_of('/')+1, buffer.find_first_of('|')-buffer.find_first_of('/')-1);
+            const string cmd  = buffer.substr(0, buffer.find_first_of('|'));
+
+            // Add name the the list
+            list.push_back(name);
+
+            // Add format to the list
+            fFormatList[cmd] = fmt;
+        }
+    }
+    else
+    {
+        fDescriptionMap.clear();
+
+        wout << str << endl;
+
+        stringstream stream(str);
+        while (getline(stream, buffer, '\n'))
+        {
+            if (buffer.empty())
+                continue;
+
+            const vector<Description> v = Description::SplitDescription(buffer);
+
+            const string svc = v[0].name;
+
+            fDescriptionMap[svc]  = v[0].comment;
+            fDescriptionList[svc] = vector<Description>(v.begin()+1, v.end());
+        }
     }
 }
@@ -306,4 +338,19 @@
 }
 
+vector<string> ServiceList::GetServiceList() const
+{
+    vector<string> vec;
+    for (ServerMap::const_iterator i=fServerList.begin(); i!=fServerList.end(); i++)
+    {
+        const string server = i->first;
+
+        const vector<string> v = GetServiceList(server);
+
+        for (vector<string>::const_iterator s=v.begin(); s<v.end(); s++)
+            vec.push_back(server+"/"+*s);
+    }
+
+    return vec;
+}
 
 // --------------------------------------------------------------------------
@@ -320,5 +367,5 @@
 string ServiceList::GetFormat(const string &service) const
 {
-    FormatMap::const_iterator i = fFormatList.find(service);
+    StringMap::const_iterator i = fFormatList.find(service);
     return i==fFormatList.end() ? "" : i->second;
 }
@@ -381,4 +428,13 @@
 }
 
+bool ServiceList::HasService(const string &svc) const
+{
+    const size_t p = svc.find_first_of('/');
+    if (p==string::npos)
+        return false;
+
+    return HasService(svc.substr(0, p), svc.substr(p+1));
+}
+
 // --------------------------------------------------------------------------
 //
@@ -440,7 +496,8 @@
     {
         const string &server = i->first;
-        DimInfo *ptr = i->second;
-
-        out << " " << server << " " << ptr->getName() << endl;
+        DimInfo *ptr1 = i->second.first;
+        DimInfo *ptr2 = i->second.second;
+
+        out << " " << server << " " << ptr1->getName() << "|" << ptr2->getName() << endl;
     }
     out << endl;
@@ -473,5 +530,63 @@
 // --------------------------------------------------------------------------
 //
-//! Request a SERVER_LIST from the name server and a SERVICE_LISZ from all
+//! Print the full available documentation (description) of all available
+//! services or comments to the the given stream.
+//!
+//! @param out
+//!    ostream to which the output is send.
+//
+void ServiceList::PrintDescription(std::ostream &out) const
+{
+    for (ServiceMap::const_iterator i=fServiceList.begin(); i!=fServiceList.end(); i++)
+    {
+        const string &server = i->first;
+        const vector<string> &lst = i->second;
+
+        out << "" << kRed << "----- " << server << " -----" << endl;
+
+        for (vector<string>::const_iterator s=lst.begin(); s!=lst.end(); s++)
+        {
+            out << " " << *s;
+
+            const string fmt = GetFormat(server, *s);
+            if (!fmt.empty())
+                out << "[" << fmt << "]";
+
+            const string svc = server + "/" + *s;
+
+            const DescriptionMap::const_iterator v = fDescriptionList.find(svc);
+            if (v==fDescriptionList.end())
+            {
+                out << endl;
+                continue;
+            }
+
+            for (vector<Description>::const_iterator j=v->second.begin();
+                 j!=v->second.end(); j++)
+                out << " <" << j->name << ">";
+            out << endl;
+
+            const StringMap::const_iterator d = fDescriptionMap.find(svc);
+            if (d!=fDescriptionMap.end() && !d->second.empty())
+                out << "    " << d->second << endl;
+
+            for (vector<Description>::const_iterator j=v->second.begin();
+                 j!=v->second.end(); j++)
+            {
+                out << "    " << kGreen << j->name;
+                if (!j->comment.empty())
+                    out << kReset << ": " << kBlue << j->comment;
+                if (!j->unit.empty())
+                    out << kYellow << " [" << j->unit << "]";
+                out << endl;
+            }
+        }
+        out << endl;
+    }
+}
+
+// --------------------------------------------------------------------------
+//
+//! Request a SERVER_LIST from the name server and a SERVICE_LIST from all
 //! servers in the list. Dumps the result to the given ostream.
 //!
Index: /trunk/FACT++/src/ServiceList.h
===================================================================
--- /trunk/FACT++/src/ServiceList.h	(revision 10297)
+++ /trunk/FACT++/src/ServiceList.h	(revision 10298)
@@ -10,10 +10,13 @@
 #include "dis.hxx"
 
+#include "Description.h"
+
 class ServiceList : public DimClient
 {
 public:
-    typedef std::map<const std::string, DimInfo*>                 ServerMap;
-    typedef std::map<const std::string, std::vector<std::string>> ServiceMap;
-    typedef std::map<const std::string, std::string>              FormatMap;
+    typedef std::map<const std::string, std::pair<DimInfo*, DimInfo*>> ServerMap;
+    typedef std::map<const std::string, std::vector<std::string>>      ServiceMap;
+    typedef std::map<const std::string, std::string>                   StringMap;
+    typedef std::map<const std::string, std::vector<Description>>      DescriptionMap;
 
 private:
@@ -24,11 +27,16 @@
     const std::string fType;   /// A filter for the type of the services to be collected, e.g. CMD
 
-    ServerMap  fServerList;   /// A map storing server names and a DimInfo for their SERVICE_LIST
-    ServiceMap fServiceList;  /// A map storing server names and vector with all their available commands
-    FormatMap  fFormatList;   /// A map storing all commands and their format strings
+    ServerMap      fServerList;      /// A map storing server names and a DimInfo for their SERVICE_LIST
+    ServiceMap     fServiceList;     /// A map storing server names and vector with all their available commands
+    StringMap      fFormatList;      /// A map storing all commands and their format strings
+    StringMap      fDescriptionMap;  /// A map storing all descriptions for commands and services
+    DescriptionMap fDescriptionList; /// A map storing all descriptions for arguments of command and services
 
     DimInfoHandler *fHandler;  /// A callback to signal updates
 
-    DimInfo *CreateDimInfo(const std::string &str) const;
+    DimInfo *CreateDimInfo(const std::string &str, const std::string &svc) const;
+
+    DimInfo *CreateSL(const std::string &str) const { return CreateDimInfo(str, "SERVICE_LIST"); }
+    DimInfo *CreateFMT(const std::string &str) const { return CreateDimInfo(str, "SERVICE_DESC"); }
 
     void ProcessServerList();
@@ -45,8 +53,10 @@
 
     std::vector<std::string> GetServerList() const;
+    std::vector<std::string> GetServiceList() const;
     std::vector<std::string> GetServiceList(const std::string &server) const;
 
     bool HasServer(const std::string &name) const;
     bool HasService(const std::string &server, const std::string &service) const;
+    bool HasService(const std::string &service) const;
 
     ServiceMap::const_iterator begin() const { return fServiceList.begin(); }
@@ -61,6 +71,8 @@
     void PrintServerList(std::ostream &out) const;
     void PrintServiceList(std::ostream &out) const;
+    void PrintDescription(std::ostream &out) const;
     void PrintServerList() const { PrintServerList(wout); }
     void PrintServiceList() const { PrintServiceList(wout); }
+    void PrintDescription() const { PrintDescription(wout); }
 
     static void DumpServiceList(std::ostream &out);
