Index: /trunk/FACT++/src/DimNetwork.cc
===================================================================
--- /trunk/FACT++/src/DimNetwork.cc	(revision 10396)
+++ /trunk/FACT++/src/DimNetwork.cc	(revision 10396)
@@ -0,0 +1,138 @@
+#include "DimNetwork.h"
+
+StateClient::StateClient(const std::string &name, MessageImp &imp) :
+    MessageDimRX(name, imp), fState(-2),
+    fInfoState((name + "/STATE").c_str(), const_cast<char*>(""), this)
+{
+}
+
+// --------------------------------------------------------------------------
+//
+//! Extract the information about the state and its message. Store the
+//! state and redirect the message to fMsg.
+//
+void StateClient::infoHandler()
+{
+    DimInfo *curr = getInfo(); // get current DimInfo address
+    if (!curr)
+        return;
+
+    if (curr==&fInfoState)
+    {
+        const char *txt = fInfoState.getString();
+
+        fState     = strlen(txt)==0 ? -2 : fInfoState.getQuality();
+        fStateTime = Time(fInfoState.getTimestamp(),
+                          fInfoState.getTimestampMillisecs());
+
+        const string name = fInfoState.getName();
+
+        fMsg.StateChanged(fStateTime, name.substr(0, name.length()-6), txt, fState);
+
+        return;
+    }
+
+    MessageDimRX::infoHandler();
+}
+
+// ==========================================================================
+
+// --------------------------------------------------------------------------
+//
+//! Delete all StateClient objects from teh list and clear the list.
+//
+void DimNetwork::DeleteClientList()
+{
+    for (ClientList::iterator i=fClientList.begin();
+         i!=fClientList.end(); i++)
+        delete i->second;
+
+    fClientList.clear();
+}
+
+// --------------------------------------------------------------------------
+//
+//! Adds the StateClient for the given server. Don't forget to
+//! call this function if it is overwritten in a derived class.
+//!
+//! @param s
+//!     server which should be added
+//!
+//! @throws
+//!     a runtime_error is the server is already in the list
+//
+void DimNetwork::AddServer(const string &s)
+{
+    DimServiceInfoList::AddServer(s);
+    if (s=="DIM_DNS")
+        return;
+
+    // Check if this server is already in the list.
+    // This should never happen if Dim works reliable
+    const ClientList::iterator v = fClientList.find(s);
+    if (v!=fClientList.end())
+    {
+        stringstream err;
+        err << "Server '" << s << "' in list not as it ought to be.";
+        throw runtime_error(err.str());
+    }
+
+    // Add the new server to the server list
+    fClientList[s] = new StateClient(s, *this);
+}
+
+// --------------------------------------------------------------------------
+//
+//! Removes the StateClient for the given server. Don't forget to
+//! call this function if it is overwritten in a derived class.
+//!
+//! @param s
+//!     server which should be removed
+//!
+//! @throws
+//!     a runtime_error is the server to be removed is not in the list
+//
+void DimNetwork::RemoveServer(const string &s)
+{
+    DimServiceInfoList::RemoveServer(s);
+    if (s=="DIM_DNS")
+        return;
+
+    const ClientList::iterator v = fClientList.find(s);
+    if (v==fClientList.end())
+    {
+        stringstream err;
+        err << "Server '" << s << "' not in list as it ought to be.";
+        throw runtime_error(err.str());
+    }
+
+    // Remove the server from the server list
+    delete v->second;
+
+    fClientList.erase(v);
+}
+
+// --------------------------------------------------------------------------
+//
+//! RemovesAll StateClients. Don't forget to call this function if it
+//! is overwritten in a derived class.
+//!
+void DimNetwork::RemoveAllServers()
+{
+    DimServiceInfoList::RemoveAllServers();
+    DeleteClientList();
+}
+
+// --------------------------------------------------------------------------
+//
+//! @param server
+//!    server for which the current state should be returned
+//!
+//! @returns
+//!    the current state of the given server, -2 if the server was not found
+//!
+int DimNetwork::GetCurrentState(const string &server) const
+{
+    const ClientList::const_iterator v = fClientList.find(server);
+    return v==fClientList.end() ? -2 : v->second->GetState();
+}
Index: /trunk/FACT++/src/DimNetwork.h
===================================================================
--- /trunk/FACT++/src/DimNetwork.h	(revision 10396)
+++ /trunk/FACT++/src/DimNetwork.h	(revision 10396)
@@ -0,0 +1,87 @@
+#ifndef FACT_DimNetwork
+#define FACT_DimNetwork
+
+// **************************************************************************
+/** @class StateClient
+
+@brief A simple Dim client diriving from MessageDimRX subscribing to the STATE service
+
+This is a simple dim client which subscribes to the MESSAGE and STATE
+service of a server. It stores the last state and its time as well as
+the last message sent.
+
+**/
+// **************************************************************************
+#include "MessageDim.h"
+#include "Time.h"
+
+class StateClient : public MessageDimRX
+{
+private:
+    Time fStateTime;           /// Combine into one MTime (together with value)
+    int  fState;               /// -2 not initialized, -1 not connected, 0>= state of client
+
+    DimStampedInfo fInfoState; /// The dim service subscription
+
+protected:
+    void infoHandler();
+
+public:
+    StateClient(const std::string &name, MessageImp &imp);
+
+    bool IsConnected() const { return fState>=0; }
+    int  GetState() const    { return fState;    }
+};
+
+
+
+// **************************************************************************
+/** @class DimNetwork
+
+@brief Implements automatic subscription to MESSAGE and STATE services
+
+This class derives from DimServiceInfoList, so that it has a full
+overview of all commands and services existing in the current Dim
+network. In addition it automatically subscribes to all available
+MESSAGE and STATE services and redirects them to its MessageImp base class.
+
+@todo
+- maybe the StateClient can be abondoned, this way it would be possible
+  to subscribe to only available MESSAGE and STATE services
+
+**/
+// **************************************************************************
+#include "DimServiceInfoList.h"
+#include "DimErrorRedirecter.h"
+
+using namespace std;
+
+class DimNetwork : public MessageImp, public DimErrorRedirecter, public DimServiceInfoList
+{
+private:
+    void DeleteClientList();
+
+protected:
+    typedef std::map<const std::string, StateClient*> ClientList;
+
+    ClientList fClientList; /// A list with all MESSAGE services to which we subscribed
+
+    void AddServer(const std::string &s);
+    void RemoveServer(const std::string &s);
+    void RemoveAllServers();
+
+public:
+    DimNetwork(std::ostream &out=std::cout)
+        : MessageImp(out), DimErrorRedirecter(static_cast<MessageImp&>(*this))
+    {
+    }
+    ~DimNetwork()
+    {
+        DeleteClientList();
+    }
+
+    int GetCurrentState(const string &server) const;
+};
+
+
+#endif
