Index: code/trunk/src/network/CMakeLists.txt
===================================================================
--- code/trunk/src/network/CMakeLists.txt	(revision 1910)
+++ code/trunk/src/network/CMakeLists.txt	(revision 2087)
@@ -1,6 +1,8 @@
 SET( NETWORK_SRC_FILES
+  ChatListener.cc
   Client.cc
   ClientConnection.cc
   ClientInformation.cc
+  ClientConnectionListener.cc
   ConnectionManager.cc
   GamestateManager.cc
Index: code/trunk/src/network/ChatListener.cc
===================================================================
--- code/trunk/src/network/ChatListener.cc	(revision 2087)
+++ code/trunk/src/network/ChatListener.cc	(revision 2087)
@@ -0,0 +1,42 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#include "ChatListener.h"
+
+#include "core/CoreIncludes.h"
+#include "core/Core.h"
+
+namespace network
+{
+    ChatListener::ChatListener()
+    {
+        RegisterRootObject(ChatListener);
+    }
+}
+
+
Index: code/trunk/src/network/ChatListener.h
===================================================================
--- code/trunk/src/network/ChatListener.h	(revision 2087)
+++ code/trunk/src/network/ChatListener.h	(revision 2087)
@@ -0,0 +1,49 @@
+/*
+ *   ORXONOX - the hottest 3D action shooter ever to exist
+ *                    > www.orxonox.net <
+ *
+ *
+ *   License notice:
+ *
+ *   This program is free software; you can redistribute it and/or
+ *   modify it under the terms of the GNU General Public License
+ *   as published by the Free Software Foundation; either version 2
+ *   of the License, or (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ *   Author:
+ *      Fabian 'x3n' Landau
+ *   Co-authors:
+ *      ...
+ *
+ */
+
+#ifndef _NETWORK_ChatListener__
+#define _NETWORK_ChatListener__
+
+#include "NetworkPrereqs.h"
+
+#include "ClientInformation.h"
+#include "core/OrxonoxClass.h"
+
+namespace network
+{
+    class _NetworkExport ChatListener : virtual public orxonox::OrxonoxClass
+    {
+        public:
+            ChatListener();
+            virtual ~ChatListener() {}
+
+            virtual void incomingChat(const std::string& message, unsigned int senderID) = 0;
+    };
+}
+
+#endif /* _NETWORK_ChatListener__ */
Index: code/trunk/src/network/Client.cc
===================================================================
--- code/trunk/src/network/Client.cc	(revision 1910)
+++ code/trunk/src/network/Client.cc	(revision 2087)
@@ -39,4 +39,6 @@
 //
 
+#include <cassert>
+
 #include "Client.h"
 #include "Host.h"
@@ -44,4 +46,5 @@
 #include "core/CoreIncludes.h"
 #include "packet/Packet.h"
+
 // #include "packet/Acknowledgement.h"
 
@@ -67,5 +70,5 @@
   * @param port port of the application on the server
   */
-  Client::Client(std::string address, int port) : client_connection(port, address){
+  Client::Client(const std::string& address, int port) : client_connection(port, address){
     isConnected=false;
     isSynched_=false;
@@ -114,15 +117,15 @@
   }
 
-  bool Client::processChat(std::string message, unsigned int playerID){
-    COUT(1) << "Player " << playerID << ": " << message << std::endl;
+  bool Client::processChat(const std::string& message, unsigned int playerID){
+//    COUT(1) << "Player " << playerID << ": " << message << std::endl;
     return true;
   }
-  
+
   /**
    * This function implements the method of sending a chat message to the server
-   * @param message message to be sent 
+   * @param message message to be sent
    * @return result(true/false)
    */
-  bool Client::chat(std::string message){
+  bool Client::chat(const std::string& message){
     packet::Chat *m = new packet::Chat(message, Host::getPlayerID());
     return m->send();
@@ -132,5 +135,5 @@
   /**
    * Processes incoming packets, sends a gamestate to the server and does the cleanup
-   * @param time 
+   * @param time
    */
   void Client::tick(float time){
@@ -152,4 +155,5 @@
       COUT(5) << "tick packet size " << event->packet->dataLength << std::endl;
       packet::Packet *packet = packet::Packet::createPacket(event->packet, event->peer);
+      // note: packet commits suicide here except for the GameState. That is then deleted by a GamestateHandler
       bool b = packet->process();
       assert(b);
Index: code/trunk/src/network/Client.h
===================================================================
--- code/trunk/src/network/Client.h	(revision 1910)
+++ code/trunk/src/network/Client.h	(revision 2087)
@@ -66,30 +66,26 @@
   public:
     Client();
-    Client(std::string address, int port);
+    Client(const std::string& address, int port);
     Client(const char *address, int port);
     ~Client();
-    
+
     bool establishConnection();
     bool closeConnection();
     bool queuePacket(ENetPacket *packet, int clientID);
-    bool processChat(std::string message, unsigned int playerID);
-    virtual bool chat(std::string message);
+    bool processChat(const std::string& message, unsigned int playerID);
+    virtual bool chat(const std::string& message);
+    virtual bool broadcast(const std::string& message) { return false; }
     //bool sendChat(packet::Chat *chat);
-    
-//    static void Chat( std::string message );
-    
-    //static void setShipID( unsigned int shipID){ dynamic_cast<Client *>(instance_)->shipID_=shipID; }
-    static void setClientID( unsigned int clientID){ dynamic_cast<Client *>(instance_)->clientID_=clientID; }
-    
+
     void tick(float time);
 
   private:
     virtual bool isServer_(){return false;}
-    
+
     ClientConnection client_connection;
     GamestateClient gamestate;
     bool isConnected;
     bool isSynched_;
-    
+
     bool gameStateFailure_;
   };
Index: code/trunk/src/network/ClientConnection.cc
===================================================================
--- code/trunk/src/network/ClientConnection.cc	(revision 1910)
+++ code/trunk/src/network/ClientConnection.cc	(revision 2087)
@@ -54,5 +54,5 @@
   boost::recursive_mutex ClientConnection::enet_mutex_;
 
-  ClientConnection::ClientConnection(int port, std::string address) {
+  ClientConnection::ClientConnection(int port, const std::string& address) {
     quit=false;
     server=NULL;
@@ -72,5 +72,5 @@
   bool ClientConnection::waitEstablished(int milisec) {
     for(int i=0; i<=milisec && !established; i++)
-      usleep(1000);
+      msleep(1);
 
     return established;
@@ -184,5 +184,5 @@
       case ENET_EVENT_TYPE_NONE:
         //receiverThread_->yield();
-        usleep(1000);
+        msleep(1);
         break;
       }
Index: code/trunk/src/network/ClientConnection.h
===================================================================
--- code/trunk/src/network/ClientConnection.h	(revision 1910)
+++ code/trunk/src/network/ClientConnection.h	(revision 2087)
@@ -60,7 +60,7 @@
 
 
-  class ClientConnection{
+  class _NetworkExport ClientConnection{
   public:
-    ClientConnection(int port, std::string address);
+    ClientConnection(int port, const std::string& address);
     ClientConnection(int port, const char* address);
     ~ClientConnection();
@@ -96,5 +96,5 @@
     ENetPeer *server;
     boost::thread *receiverThread_;
-    
+
     static boost::recursive_mutex enet_mutex_;
   };
Index: code/trunk/src/network/ClientConnectionListener.cc
===================================================================
--- code/trunk/src/network/ClientConnectionListener.cc	(revision 2087)
+++ code/trunk/src/network/ClientConnectionListener.cc	(revision 2087)
@@ -0,0 +1,24 @@
+#include "ClientConnectionListener.h"
+#include "core/CoreIncludes.h"
+#include "core/Core.h"
+
+namespace network{
+
+  ClientConnectionListener::ClientConnectionListener()
+  { 
+    RegisterRootObject(ClientConnectionListener); 
+  }
+
+  void ClientConnectionListener::getConnectedClients(){
+    if(orxonox::Core::showsGraphics())
+      this->clientConnected(0); //server client id
+    ClientInformation *client = ClientInformation::getBegin();
+    while(client){
+      this->clientConnected(client->getID());
+      client=client->next();
+    }
+  }
+
+}
+
+
Index: code/trunk/src/network/ClientConnectionListener.h
===================================================================
--- code/trunk/src/network/ClientConnectionListener.h	(revision 2087)
+++ code/trunk/src/network/ClientConnectionListener.h	(revision 2087)
@@ -0,0 +1,28 @@
+#ifndef _NETWORK_CLIENTCONNECTIONLISTENER__
+#define _NETWORK_CLIENTCONNECTIONLISTENER__
+
+#include "NetworkPrereqs.h"
+#include "ClientInformation.h"
+#include "core/OrxonoxClass.h"
+
+namespace network{
+
+  class _NetworkExport ClientConnectionListener : virtual public orxonox::OrxonoxClass
+  {
+    friend class Server;
+
+  public:
+    ClientConnectionListener();
+    virtual ~ClientConnectionListener() {}
+
+    void getConnectedClients();
+
+  protected:
+    virtual void clientConnected(unsigned int clientID) = 0;
+    virtual void clientDisconnected(unsigned int clientID) = 0;
+  };
+
+}
+
+
+#endif
Index: code/trunk/src/network/ClientInformation.cc
===================================================================
--- code/trunk/src/network/ClientInformation.cc	(revision 1910)
+++ code/trunk/src/network/ClientInformation.cc	(revision 2087)
@@ -45,7 +45,7 @@
 namespace network
 {
-  
+
   ClientInformation *ClientInformation::head_=0;
-  
+
   ClientInformation::ClientInformation() {
     if(!head_)
@@ -59,10 +59,10 @@
 
   ClientInformation::~ClientInformation() {
-    if(this==head_)
-      head_=next();
     if(prev()!=0)
       prev()->setNext(this->next());
     if(next()!=0)
       next()->setPrev(this->prev());
+    if(this==head_)
+      head_=next();
   }
 
@@ -129,5 +129,5 @@
     return true;
   }
-  
+
   bool ClientInformation::setPartialGamestateID(int id){
     if(!this)
@@ -137,5 +137,5 @@
   }
 
-  int ClientInformation::getID() {
+  unsigned int ClientInformation::getID() {
     if(!this)
       return CLIENTID_UNKNOWN;
@@ -150,5 +150,5 @@
       return NULL;
   }
-  
+
   int ClientInformation::getFailures(){
     return failures_;
@@ -160,30 +160,30 @@
     failures_=0;
   }
-  
+
   enet_uint32 ClientInformation::getRTT(){
-    return peer_->roundTripTime;
-  }
-  
-  enet_uint32 ClientInformation::getPacketLoss(){
-    return peer_->packetLoss;
-  }
-
-  int ClientInformation::getGamestateID() {
+    return this->peer_->roundTripTime;
+  }
+
+  double ClientInformation::getPacketLoss(){
+    return ((double)this->peer_->packetLoss)/ENET_PEER_PACKET_LOSS_SCALE;
+  }
+
+  unsigned int ClientInformation::getGamestateID() {
     if(this)
       return gamestateID_;
     else
-      return -1;
-  }
-  
-  int ClientInformation::getPartialGamestateID() {
+      return (unsigned int)-1;
+  }
+
+  unsigned int ClientInformation::getPartialGamestateID() {
     if(this)
       return partialGamestateID_;
     else
-      return -1;
+      return (unsigned int)-1;
   }
 
   ClientInformation *ClientInformation::insertBack(ClientInformation *ins) {
     ClientInformation *temp = head_;
-    if(temp==head_){
+    if(temp==ins){
       return head_;
     }
@@ -196,6 +196,6 @@
   }
 
-  bool ClientInformation::removeClient(int clientID) {
-    if(clientID==CLIENTID_UNKNOWN)
+  bool ClientInformation::removeClient(unsigned int clientID) {
+    if((unsigned int)clientID==CLIENTID_UNKNOWN)
       return false;
     ClientInformation *temp = head_;
@@ -229,5 +229,5 @@
   * @return pointer to the last element in the list or 0 if the search was unsuccessfull
   */
-  ClientInformation *ClientInformation::findClient(int clientID, bool look_backwards) {
+  ClientInformation *ClientInformation::findClient(unsigned int clientID, bool look_backwards) {
     ClientInformation *temp = head_;
     while(temp!=0 && temp->getID()!=clientID){
Index: code/trunk/src/network/ClientInformation.h
===================================================================
--- code/trunk/src/network/ClientInformation.h	(revision 1910)
+++ code/trunk/src/network/ClientInformation.h	(revision 2087)
@@ -46,16 +46,16 @@
 #include <boost/thread/recursive_mutex.hpp>
 
-#define GAMESTATEID_INITIAL -1
-#define CLIENTID_UNKNOWN -2
-
 // WATCH OUT: THE CLIENTINFORMATION LIST IS NOT THREADSAFE ANYMORE
 
 namespace network
 {
+  static const unsigned int GAMESTATEID_INITIAL = (unsigned int)-1;
+  static const unsigned int CLIENTID_UNKNOWN = (unsigned int)-2;
+
   /**
   * This class implements a list for client informations
   * @author Oliver Scheuss
   */
-  class ClientInformation{
+  class _NetworkExport ClientInformation{
   public:
     ClientInformation();
@@ -66,5 +66,5 @@
     ClientInformation *prev();
     static ClientInformation *insertBack(ClientInformation *ins);
-    
+
     // set functions
     void setID(int clientID);
@@ -73,21 +73,21 @@
     bool setPartialGamestateID(int id);
     inline void setShipID(unsigned int id){ShipID_=id;}
-    
+
     // get functions
     inline unsigned int getShipID(){return ShipID_;}
-    int getID();
-    int getGamestateID();
-    int getPartialGamestateID();
+    unsigned int getID();
+    unsigned int getGamestateID();
+    unsigned int getPartialGamestateID();
     ENetPeer *getPeer();
-    
+
     int getFailures();
     void addFailure();
     void resetFailures();
     enet_uint32 getRTT();
-    enet_uint32 getPacketLoss();
-    
-    static bool removeClient(int clientID);
+    double getPacketLoss();
+
+    static bool removeClient(unsigned int clientID);
     static bool removeClient(ENetPeer *peer);
-    static ClientInformation *findClient(int clientID, bool look_backwards=false);
+    static ClientInformation *findClient(unsigned int clientID, bool look_backwards=false);
     static ClientInformation *findClient(ENetAddress *address, bool look_backwards=false);
     static ClientInformation *getBegin(){return head_;}
@@ -99,21 +99,21 @@
   private:
     static ClientInformation *head_;
-    
+
     bool setNext(ClientInformation *next);
     bool setPrev(ClientInformation *prev);
     ClientInformation *insertAfter(ClientInformation *ins);
     ClientInformation *insertBefore(ClientInformation *ins);
-    
+
     ClientInformation *preve;
     ClientInformation *nexte;
     //actual information:
     ENetPeer *peer_;
-    int clientID_;
-    int gamestateID_;
-    int partialGamestateID_;
+    unsigned int clientID_;
+    unsigned int gamestateID_;
+    unsigned int partialGamestateID_;
     unsigned int ShipID_;   // this is the unique objectID
     bool synched_;
     unsigned short failures_;
-    
+
   };
 
Index: code/trunk/src/network/ConnectionManager.cc
===================================================================
--- code/trunk/src/network/ConnectionManager.cc	(revision 1910)
+++ code/trunk/src/network/ConnectionManager.cc	(revision 2087)
@@ -49,5 +49,4 @@
 #include "core/BaseObject.h"
 #include "core/Iterator.h"
-#include "objects/SpaceShip.h"
 #include "util/Math.h"
 #include "util/Sleep.h"
@@ -89,5 +88,5 @@
   }
 
-  ConnectionManager::ConnectionManager(int port, std::string address) :receiverThread_(0) {
+  ConnectionManager::ConnectionManager(int port, const std::string& address) :receiverThread_(0) {
     assert(instance_==0);
     instance_=this;
@@ -228,5 +227,5 @@
         case ENET_EVENT_TYPE_NONE:
           //receiverThread_->yield();
-          usleep(1000);
+          msleep(1);
           break;
       }
@@ -331,17 +330,4 @@
 
 
-
-  bool ConnectionManager::removeShip(ClientInformation *client){
-    unsigned int id=client->getShipID();
-    orxonox::ObjectList<orxonox::SpaceShip>::iterator it;
-    for(it = orxonox::ObjectList<orxonox::SpaceShip>::begin(); it; ++it){
-      if(it->getObjectID()!=id)
-        continue;
-      delete *it;
-    }
-    return true;
-  }
-
-
   void ConnectionManager::disconnectClient(ClientInformation *client){
     {
@@ -350,5 +336,4 @@
       lock.unlock();
     }
-    removeShip(client);
   }
 
Index: code/trunk/src/network/ConnectionManager.h
===================================================================
--- code/trunk/src/network/ConnectionManager.h	(revision 1910)
+++ code/trunk/src/network/ConnectionManager.h	(revision 2087)
@@ -66,5 +66,5 @@
     const int NETWORK_DEFAULT_CHANNEL = 0;
 
-  struct ClientList{
+  struct _NetworkExport ClientList{
     ENetEvent *event;
     int ID;
@@ -72,5 +72,5 @@
   };
 
-  class ConnectionManager{
+  class _NetworkExport ConnectionManager{
     public:
     static boost::recursive_mutex enet_mutex;
@@ -79,5 +79,5 @@
     ConnectionManager(int port);
     ConnectionManager(int port, const char *address);
-    ConnectionManager(int port, std::string address);
+    ConnectionManager(int port, const std::string& address);
     ~ConnectionManager();
     //ENetPacket *getPacket(ENetAddress &address); // thread1
@@ -107,6 +107,4 @@
     int getClientID(ENetAddress address);
     ENetPeer *getClientPeer(int clientID);
-    //bool createShip(ClientInformation *client);
-    bool removeShip(ClientInformation *client);
     PacketBuffer buffer;
 
Index: code/trunk/src/network/GamestateClient.cc
===================================================================
--- code/trunk/src/network/GamestateClient.cc	(revision 1910)
+++ code/trunk/src/network/GamestateClient.cc	(revision 2087)
@@ -29,4 +29,5 @@
 #include "GamestateClient.h"
 
+#include <cassert>
 #include <zlib.h>
 
@@ -40,7 +41,7 @@
 namespace network
 {
-  struct GameStateItem{
+  struct _NetworkExport GameStateItem{
     packet::Gamestate *state;
-    int id;
+    unsigned int id;
   };
 
@@ -50,5 +51,4 @@
     last_gamestate_=GAMESTATEID_INITIAL-1;
     tempGamestate_=NULL;
-    myShip_=NULL;
   }
 
@@ -56,9 +56,9 @@
   }
 
-  bool GamestateClient::ack(int gamestateID, int clientID){
+  bool GamestateClient::ack(unsigned int gamestateID, unsigned int clientID){
     return true;
   }
 
-  bool GamestateClient::add(packet::Gamestate *gs, int clientID){
+  bool GamestateClient::add(packet::Gamestate *gs, unsigned int clientID){
     if(tempGamestate_!=NULL){
       //delete the obsolete gamestate
@@ -75,18 +75,12 @@
       return false;
     int id = GAMESTATEID_INITIAL;
-    bool b = saveShipCache();
     packet::Gamestate *processed = processGamestate(tempGamestate_);
-    if(!processed){
-      if(b)
-        loadShipCache();
-      return false;
-    }
 //    assert(processed);
+    if (!processed)
+        return false;
     //successfully loaded data from gamestate. now save gamestate for diff and delete the old gs
     tempGamestate_=NULL;
     gamestateMap_[processed->getID()]=processed;
     last_diff_ = processed->getID();
-    if(b)
-      loadShipCache();
     id = processed->getID();
     sendAck(id);
@@ -108,10 +102,13 @@
   packet::Gamestate *GamestateClient::getGamestate(){
     packet::Gamestate *gs = new packet::Gamestate();
-    gs->collectData(0);
+    if(!gs->collectData(0)){
+      delete gs;
+      return 0;
+    }
     return gs;
   }
 
   void GamestateClient::cleanup(){
-    std::map<int, packet::Gamestate*>::iterator temp, it = gamestateMap_.begin();
+    std::map<unsigned int, packet::Gamestate*>::iterator temp, it = gamestateMap_.begin();
     while(it!=gamestateMap_.end()){
       if(it->first>=last_diff_)
@@ -126,5 +123,5 @@
 
   void GamestateClient::printGamestateMap(){
-    std::map<int, packet::Gamestate*>::iterator it;
+    std::map<unsigned int, packet::Gamestate*>::iterator it;
     COUT(4) << "gamestates: ";
     for(it=gamestateMap_.begin(); it!=gamestateMap_.end(); it++){
@@ -134,5 +131,5 @@
 
   }
-  
+
   bool GamestateClient::sendAck(unsigned int gamestateID){
     packet::Acknowledgement *ack = new packet::Acknowledgement(gamestateID, 0);
@@ -142,40 +139,7 @@
     }
     else{
-      COUT(3) << "acked a gamestate: " << gamestateID << std::endl;
+      COUT(5) << "acked a gamestate: " << gamestateID << std::endl;
       return true;
     }
-  }
-
-  bool GamestateClient::saveShipCache(){
-    if(myShip_==NULL){
-      myShip_ = orxonox::SpaceShip::getLocalShip();
-//      COUT(2) << "myShip_: " << myShip_ << " getLocalShip(): " << orxonox::SpaceShip::getLocalShip() << std::endl;
-      if(!myShip_)
-	return false;
-    }
-    if(myShip_){
-      //      unsigned char *data = new unsigned char[myShip_->getSize()];
-      int size=myShip_->getSize(0, 0x1);
-      if(size==0)
-        return false;
-      shipCache_ = new unsigned char [size];
-      unsigned char *temp = shipCache_;
-      if(!myShip_->getData(temp, 0, 0x1))
-        COUT(3) << "could not save shipCache" << std::endl;
-      return true;
-    }else
-      return false;
-  }
-
-  bool GamestateClient::loadShipCache(){
-    myShip_=orxonox::SpaceShip::getLocalShip(); //TODO: remove this (only a hack)
-    if(myShip_ && shipCache_){
-      assert(myShip_->getIdentifier());
-      unsigned char *temp = shipCache_;
-      myShip_->updateData(temp, 0x2);
-      delete shipCache_;
-      return true;
-    }else
-      return false;
   }
 
@@ -196,5 +160,5 @@
       delete gs;
       gs=undiffed;
-      COUT(3) << "successfully undiffed gamestate id: " << undiffed->getID() << std::endl;
+      COUT(5) << "successfully undiffed gamestate id: " << undiffed->getID() << std::endl;
     }
     if(gs->spreadData())
Index: code/trunk/src/network/GamestateClient.h
===================================================================
--- code/trunk/src/network/GamestateClient.h	(revision 1910)
+++ code/trunk/src/network/GamestateClient.h	(revision 2087)
@@ -46,12 +46,11 @@
 #include "core/CorePrereqs.h"
 #include "packet/Gamestate.h"
-#include "objects/SpaceShip.h"
 #include "GamestateHandler.h"
 
-#define GAMESTATEID_INITIAL -1
+const unsigned int GAMESTATEID_INITIAL = (unsigned int)-1;
 
 namespace network
 {
-  class GamestateClient: public GamestateHandler
+  class _NetworkExport GamestateClient: public GamestateHandler
   {
   public:
@@ -59,6 +58,6 @@
     ~GamestateClient();
 
-    bool add(packet::Gamestate *gs, int clientID);
-    bool ack(int gamestateID, int clientID);
+    bool add(packet::Gamestate *gs, unsigned int clientID);
+    bool ack(unsigned int gamestateID, unsigned int clientID);
 
     bool processGamestates();
@@ -70,12 +69,9 @@
     void printGamestateMap();
     bool sendAck(unsigned int gamestateID);
-    bool saveShipCache();
-    bool loadShipCache();
 
-    int           last_diff_;
-    int           last_gamestate_;
-    std::map<int, packet::Gamestate *> gamestateMap_;
+    unsigned int           last_diff_;
+    unsigned int           last_gamestate_;
+    std::map<unsigned int, packet::Gamestate *> gamestateMap_;
     packet::Gamestate *tempGamestate_; // we save the received gamestates here during processQueue
-    orxonox::SpaceShip *myShip_;
     unsigned char *shipCache_;
 
Index: code/trunk/src/network/GamestateHandler.h
===================================================================
--- code/trunk/src/network/GamestateHandler.h	(revision 1910)
+++ code/trunk/src/network/GamestateHandler.h	(revision 2087)
@@ -39,8 +39,8 @@
 	@author Oliver Scheuss
 */
-class GamestateHandler{
+class _NetworkExport GamestateHandler{
   private:
-    virtual bool add(packet::Gamestate *gs, int clientID)=0;
-    virtual bool ack(int gamestateID, int clientID)=0;
+    virtual bool add(packet::Gamestate *gs, unsigned int clientID)=0;
+    virtual bool ack(unsigned int gamestateID, unsigned int clientID)=0;
 
     static GamestateHandler *instance_;
@@ -52,6 +52,6 @@
 
   public:
-    static bool addGamestate(packet::Gamestate *gs, int clientID){ return instance_->add(gs, clientID); }
-    static bool ackGamestate(int gamestateID, int clientID){ return instance_->ack(gamestateID, clientID); }
+    static bool addGamestate(packet::Gamestate *gs, unsigned int clientID){ return instance_->add(gs, clientID); }
+    static bool ackGamestate(unsigned int gamestateID, unsigned int clientID){ return instance_->ack(gamestateID, clientID); }
 };
 
Index: code/trunk/src/network/GamestateManager.cc
===================================================================
--- code/trunk/src/network/GamestateManager.cc	(revision 1910)
+++ code/trunk/src/network/GamestateManager.cc	(revision 2087)
@@ -64,8 +64,8 @@
     return getSnapshot();
   }
-  
-  bool GamestateManager::add(packet::Gamestate *gs, int clientID){
+
+  bool GamestateManager::add(packet::Gamestate *gs, unsigned int clientID){
     assert(gs);
-    std::map<int, packet::Gamestate*>::iterator it = gamestateQueue.find(clientID);
+    std::map<unsigned int, packet::Gamestate*>::iterator it = gamestateQueue.find(clientID);
     if(it!=gamestateQueue.end()){
       // delete obsolete gamestate
@@ -75,10 +75,11 @@
     return true;
   }
-  
+
   bool GamestateManager::processGamestates(){
-    std::map<int, packet::Gamestate*>::iterator it;
+    std::map<unsigned int, packet::Gamestate*>::iterator it;
     // now push only the most recent gamestates we received (ignore obsolete ones)
     for(it = gamestateQueue.begin(); it!=gamestateQueue.end(); it++){
-      assert(processGamestate(it->second));
+      bool b = processGamestate(it->second);
+      assert(b);
       delete it->second;
     }
@@ -87,20 +88,20 @@
     return true;
   }
-  
-  
+
+
   bool GamestateManager::getSnapshot(){
     reference = new packet::Gamestate();
-    reference->collectData(++id_);
-    //COUT(4) << "inserting gamestate: " << reference << std::endl;
-    //gamestateMap_.insert(std::pair<int, packet::Gamestate*>(id_, reference));
-//     gamestateUsed[id_]=0;
-    return true;
-  }
-  
+    if(!reference->collectData(++id_)){ //we have no data to send
+      delete reference;
+      reference=0;
+    }
+    return true;
+  }
+
   /**
    * this function is used to keep the memory usage low
    * it tries to delete all the unused gamestates
-   * 
-   * 
+   *
+   *
    */
 /*  void GamestateManager::cleanup(){
@@ -126,9 +127,11 @@
   }*/
 
-  packet::Gamestate *GamestateManager::popGameState(int clientID) {
+  packet::Gamestate *GamestateManager::popGameState(unsigned int clientID) {
     //why are we searching the same client's gamestate id as we searched in
     //Server::sendGameState?
     packet::Gamestate *gs;
-    int gID = ClientInformation::findClient(clientID)->getGamestateID();
+    unsigned int gID = ClientInformation::findClient(clientID)->getGamestateID();
+    if(!reference)
+      return 0;
     gs = reference->doSelection(clientID);
 //     gs = new packet::Gamestate(*reference);
@@ -139,7 +142,7 @@
     packet::Gamestate *client=NULL;
     if(gID != GAMESTATEID_INITIAL){
-      std::map<unsigned int, std::map<int, packet::Gamestate*> >::iterator clientMap = gamestateMap_.find(clientID);
+      std::map<unsigned int, std::map<unsigned int, packet::Gamestate*> >::iterator clientMap = gamestateMap_.find(clientID);
       if(clientMap!=gamestateMap_.end()){
-        std::map<int, packet::Gamestate*>::iterator it = clientMap->second.find(gID);
+        std::map<unsigned int, packet::Gamestate*>::iterator it = clientMap->second.find(gID);
         if(it!=clientMap->second.end())
           client = it->second;
@@ -158,19 +161,19 @@
     return gs;
   }
-  
-  
-  bool GamestateManager::ack(int gamestateID, int clientID) {
+
+
+  bool GamestateManager::ack(unsigned int gamestateID, unsigned int clientID) {
     ClientInformation *temp = ClientInformation::findClient(clientID);
     assert(temp);
-    int curid = temp->getGamestateID();
-    
+    unsigned int curid = temp->getGamestateID();
+
     if(gamestateID == 0){
       temp->setGamestateID(GAMESTATEID_INITIAL);
       return true;
     }
-    
-    assert(curid<gamestateID);
+
+    assert(curid==(unsigned int)GAMESTATEID_INITIAL || curid<gamestateID);
     COUT(4) << "acking gamestate " << gamestateID << " for clientid: " << clientID << " curid: " << curid << std::endl;
-    std::map<int, packet::Gamestate*>::iterator it, tempit;
+    std::map<unsigned int, packet::Gamestate*>::iterator it, tempit;
     for(it = gamestateMap_[clientID].begin(); it!=gamestateMap_[clientID].end() && it->first<gamestateID; it++){
       delete it->second;
@@ -184,7 +187,7 @@
   void GamestateManager::removeClient(ClientInformation* client){
     assert(client);
-    std::map<unsigned int, std::map<int, packet::Gamestate*> >::iterator clientMap = gamestateMap_.find(client->getID());
+    std::map<unsigned int, std::map<unsigned int, packet::Gamestate*> >::iterator clientMap = gamestateMap_.find(client->getID());
     // first delete all remained gamestates
-    std::map<int, packet::Gamestate*>::iterator it;
+    std::map<unsigned int, packet::Gamestate*>::iterator it;
     for(it=clientMap->second.begin(); it!=clientMap->second.end(); it++)
       delete it->second;
@@ -192,5 +195,5 @@
     gamestateMap_.erase(clientMap);
   }
-  
+
   bool GamestateManager::processGamestate(packet::Gamestate *gs){
     if(gs->isCompressed())
Index: code/trunk/src/network/GamestateManager.h
===================================================================
--- code/trunk/src/network/GamestateManager.h	(revision 1910)
+++ code/trunk/src/network/GamestateManager.h	(revision 2087)
@@ -66,17 +66,17 @@
   * @author Oliver Scheuss
   */
-  class GamestateManager: public GamestateHandler{
+  class _NetworkExport GamestateManager: public GamestateHandler{
   public:
     GamestateManager();
     ~GamestateManager();
 
-    bool add(packet::Gamestate *gs, int clientID);
+    bool add(packet::Gamestate *gs, unsigned int clientID);
     bool processGamestates();
     bool update();
-    packet::Gamestate *popGameState(int clientID);
+    packet::Gamestate *popGameState(unsigned int clientID);
 
     bool getSnapshot();
 
-    bool ack(int gamestateID, int clientID);
+    bool ack(unsigned int gamestateID, unsigned int clientID);
     void removeClient(ClientInformation *client);
     private:
@@ -84,10 +84,10 @@
     bool processGamestate(packet::Gamestate *gs);
 
-    std::map<unsigned int, std::map<int, packet::Gamestate*> > gamestateMap_;
+    std::map<unsigned int, std::map<unsigned int, packet::Gamestate*> > gamestateMap_;
     //std::map<int, packet::Gamestate*> gamestateMap; //map gsID to gamestate*
     //std::map<int, int> gamestateUsed; // save the number of clients, that use the specific gamestate
-    std::map<int, packet::Gamestate*> gamestateQueue;
+    std::map<unsigned int, packet::Gamestate*> gamestateQueue;
     packet::Gamestate *reference;
-    int id_;
+    unsigned int id_;
   };
 
Index: code/trunk/src/network/Host.cc
===================================================================
--- code/trunk/src/network/Host.cc	(revision 1910)
+++ code/trunk/src/network/Host.cc	(revision 2087)
@@ -32,4 +32,5 @@
 #include "core/ConsoleCommand.h"
 #include "packet/Packet.h"
+#include "ChatListener.h"
 
 namespace network {
@@ -38,5 +39,5 @@
 
 Host *Host::instance_=0;
-  
+
 /**
  * @brief Constructor: assures that only one reference will be created and sets the pointer
@@ -90,5 +91,5 @@
  * @return playerID
  */
-unsigned int Host::getPlayerID(){ 
+unsigned int Host::getPlayerID(){
   if(!instance_)
     return 0;
@@ -96,5 +97,5 @@
 }
 
-bool Host::Chat(std::string message){
+bool Host::Chat(const std::string& message){
   if(!instance_)
     return false;
@@ -102,5 +103,14 @@
 }
 
-bool Host::incomingChat(std::string message, unsigned int playerID){
+bool Host::Broadcast(const std::string& message){
+  if(!instance_)
+    return false;
+  return instance_->broadcast(message);
+}
+
+bool Host::incomingChat(const std::string& message, unsigned int playerID){
+  for (orxonox::ObjectList<ChatListener>::iterator it = orxonox::ObjectList<ChatListener>::begin(); it != orxonox::ObjectList<ChatListener>::end(); ++it)
+    it->incomingChat(message, playerID);
+
   return instance_->processChat(message, playerID);
 }
Index: code/trunk/src/network/Host.h
===================================================================
--- code/trunk/src/network/Host.h	(revision 1910)
+++ code/trunk/src/network/Host.h	(revision 2087)
@@ -44,5 +44,5 @@
 *	@author Oliver Scheuss
 */
-class Host{
+class _NetworkExport Host{
   private:
     //TODO add theese functions or adequate
@@ -50,6 +50,7 @@
     //virtual bool sendChat(packet::Chat *chat)=0;
     virtual bool queuePacket(ENetPacket *packet, int clientID)=0;
-    virtual bool chat(std::string message)=0;
-    virtual bool processChat(std::string message, unsigned int playerID)=0;
+    virtual bool chat(const std::string& message)=0;
+    virtual bool broadcast(const std::string& message)=0;
+    virtual bool processChat(const std::string& message, unsigned int playerID)=0;
     virtual bool isServer_()=0;
 
@@ -72,7 +73,8 @@
     static void setClientID(unsigned int id){ instance_->clientID_ = id; }
     static void setShipID(unsigned int id){ instance_->shipID_ = id; }
-    static bool isServer(){ return instance_->isServer_(); }		
-    static bool Chat(std::string message);
-    static bool incomingChat(std::string message, unsigned int playerID);
+    static bool isServer(){ return instance_->isServer_(); }
+    static bool Chat(const std::string& message);
+    static bool Broadcast(const std::string& message);
+    static bool incomingChat(const std::string& message, unsigned int playerID);
   private:
 };
Index: code/trunk/src/network/NetworkCallback.h
===================================================================
--- code/trunk/src/network/NetworkCallback.h	(revision 1910)
+++ code/trunk/src/network/NetworkCallback.h	(revision 2087)
@@ -2,6 +2,8 @@
 #define _NETWORK_CALLBACK__
 
+#include "NetworkPrereqs.h"
+
 namespace network{
-  class NetworkCallbackBase
+  class _NetworkExport NetworkCallbackBase
   {
     public:
@@ -9,5 +11,5 @@
 	  virtual ~NetworkCallbackBase() {}
   };
-  
+
   template <class T>
   class NetworkCallback: public NetworkCallbackBase
@@ -18,9 +20,9 @@
       virtual void call()
         { (this->object_->*function_)(); }
-  
+
     private:
       T* object_;
       void (T::*function_) (void);
-  }; 
+  };
 
 
Index: code/trunk/src/network/NetworkPrereqs.h
===================================================================
--- code/trunk/src/network/NetworkPrereqs.h	(revision 1910)
+++ code/trunk/src/network/NetworkPrereqs.h	(revision 2087)
@@ -63,4 +63,5 @@
   class Client;
   class ClientConnection;
+  class ClientConnectionListener;
   class ClientFrameListener;
   class ClientInformation;
Index: code/trunk/src/network/PacketBuffer.h
===================================================================
--- code/trunk/src/network/PacketBuffer.h	(revision 1910)
+++ code/trunk/src/network/PacketBuffer.h	(revision 2087)
@@ -49,10 +49,10 @@
 namespace network
 {
-  struct PacketEnvelope{
+  struct _NetworkExport PacketEnvelope{
     int length;
     int data;
   };
 
-  struct QueueItem{
+  struct _NetworkExport QueueItem{
     ENetEvent *event;
     //ENetAddress address;
@@ -60,5 +60,5 @@
   };
 
-  class PacketBuffer{
+  class _NetworkExport PacketBuffer{
   public:
     PacketBuffer();
Index: code/trunk/src/network/Server.cc
===================================================================
--- code/trunk/src/network/Server.cc	(revision 1910)
+++ code/trunk/src/network/Server.cc	(revision 2087)
@@ -46,8 +46,8 @@
 
 #include "ConnectionManager.h"
+#include "ClientConnectionListener.h"
 #include "GamestateManager.h"
 #include "ClientInformation.h"
 #include "util/Sleep.h"
-#include "objects/SpaceShip.h"
 #include "core/ConsoleCommand.h"
 #include "core/CoreIncludes.h"
@@ -58,9 +58,11 @@
 #include "packet/DeleteObjects.h"
 #include <util/Convert.h>
+#include "ChatListener.h"
 
 namespace network
 {
-  const int MAX_FAILURES = 20;
-  const int NETWORK_FREQUENCY = 30;
+  const unsigned int MAX_FAILURES = 20;
+  const unsigned int NETWORK_FREQUENCY = 25;
+  const float NETWORK_PERIOD = (float)1/NETWORK_FREQUENCY;
 
   /**
@@ -85,5 +87,5 @@
   * @param bindAddress Address to listen on
   */
-  Server::Server(int port, std::string bindAddress) {
+  Server::Server(int port, const std::string& bindAddress) {
     timeSinceLastUpdate_=0;
     connection = new ConnectionManager(port, bindAddress);
@@ -101,5 +103,5 @@
     gamestates_ = new GamestateManager();
   }
-  
+
   /**
   * @brief Destructor
@@ -128,5 +130,5 @@
   }
 
-  bool Server::processChat(std::string message, unsigned int playerID){
+  bool Server::processChat(const std::string& message, unsigned int playerID){
     ClientInformation *temp = ClientInformation::getBegin();
     packet::Chat *chat;
@@ -138,5 +140,5 @@
       temp = temp->next();
     }
-    COUT(1) << "Player " << playerID << ": " << message << std::endl;
+//    COUT(1) << "Player " << playerID << ": " << message << std::endl;
     return true;
   }
@@ -152,6 +154,6 @@
     //this steers our network frequency
     timeSinceLastUpdate_+=time;
-    if(timeSinceLastUpdate_>=(1./NETWORK_FREQUENCY)){
-      timeSinceLastUpdate_=(float)((int)(timeSinceLastUpdate_*NETWORK_FREQUENCY))/timeSinceLastUpdate_;
+    if(timeSinceLastUpdate_>=NETWORK_PERIOD){
+      timeSinceLastUpdate_ -= static_cast<unsigned int>( timeSinceLastUpdate_ / NETWORK_PERIOD ) * NETWORK_PERIOD;
       gamestates_->processGamestates();
       updateGamestate();
@@ -162,5 +164,21 @@
     return connection->addPacket(packet, clientID);
   }
-
+  
+  /**
+   * @brief: returns ping time to client in milliseconds 
+   */
+  unsigned int Server::getPing(unsigned int clientID){
+    assert(ClientInformation::findClient(clientID));
+    return ClientInformation::findClient(clientID)->getRTT();
+  }
+
+  /**
+   * @brief: return packet loss ratio to client (scales from 0 to 1)
+   */
+  double Server::getPacketLoss(unsigned int clientID){
+    assert(ClientInformation::findClient(clientID));
+    return ClientInformation::findClient(clientID)->getPacketLoss();
+  }
+  
   /**
   * processes all the packets waiting in the queue
@@ -239,4 +257,5 @@
       if(gs==NULL){
         COUT(2) << "Server: could not generate gamestate (NULL from compress)" << std::endl;
+        temp = temp->next();
         continue;
       }
@@ -281,4 +300,7 @@
 
   bool Server::addClient(ENetEvent *event){
+    static unsigned int newid=1;
+
+    COUT(2) << "Server: adding client" << std::endl;
     ClientInformation *temp = ClientInformation::insertBack(new ClientInformation);
     if(!temp){
@@ -286,13 +308,24 @@
       return false;
     }
-    if(temp==ClientInformation::getBegin()) { //not good if you use anything else than insertBack
-      temp->setID(1);
+    /*if(temp==ClientInformation::getBegin()) { //not good if you use anything else than insertBack
+      newid=1;
     }
     else
-      temp->setID(temp->prev()->getID()+1);
+      newid=temp->prev()->getID()+1;*/
+    temp->setID(newid);
     temp->setPeer(event->peer);
+
+    // inform all the listeners
+    orxonox::ObjectList<ClientConnectionListener>::iterator listener = orxonox::ObjectList<ClientConnectionListener>::begin();
+    while(listener){
+      listener->clientConnected(newid);
+      listener++;
+    }
+
+    newid++;
+
     COUT(3) << "Server: added client id: " << temp->getID() << std::endl;
     return createClient(temp->getID());
-  }
+}
 
   bool Server::createClient(int clientID){
@@ -304,10 +337,4 @@
     COUT(4) << "Con.Man: creating client id: " << temp->getID() << std::endl;
     connection->syncClassid(temp->getID());
-    COUT(5) << "creating spaceship for clientid: " << temp->getID() << std::endl;
-    // TODO: this is only a hack, untill we have a possibility to define default player-join actions
-    if(!createShip(temp))
-      COUT(2) << "Con.Man. could not create ship for clientid: " << clientID << std::endl;
-    else
-      COUT(3) << "created spaceship" << std::endl;
     temp->setSynched(true);
     COUT(3) << "sending welcome" << std::endl;
@@ -319,5 +346,6 @@
     g->setClientID(temp->getID());
     b = g->collectData(0);
-    assert(b);
+    if(!b)
+      return false; //no data for the client
     b = g->compressData();
     assert(b);
@@ -327,32 +355,4 @@
   }
 
-  bool Server::createShip(ClientInformation *client){
-    if(!client)
-      return false;
-    orxonox::Identifier* id = ClassByName("SpaceShip");
-    if(!id){
-      COUT(4) << "We could not create the SpaceShip for client: " << client->getID() << std::endl;
-      return false;
-    }
-    orxonox::SpaceShip *no = dynamic_cast<orxonox::SpaceShip *>(id->fabricate());
-    no->classID = id->getNetworkID();
-    client->setShipID(no->getObjectID());
-    no->setPosition(orxonox::Vector3(0,0,80));
-    no->setScale(10);
-    //no->setYawPitchRoll(orxonox::Degree(-90),orxonox::Degree(-90),orxonox::Degree(0));
-    no->setMesh("assff.mesh");
-    no->setMaxSpeed(500);
-    no->setMaxSideAndBackSpeed(50);
-    no->setMaxRotation(1.0);
-    no->setTransAcc(200);
-    no->setRotAcc(3.0);
-    no->setTransDamp(75);
-    no->setRotDamp(1.0);
-    no->setCamera(std::string("cam_") + convertToString(client->getID()));
-    no->create();
-
-    return true;
-  }
-
   bool Server::disconnectClient(ENetEvent *event){
     COUT(4) << "removing client from list" << std::endl;
@@ -360,20 +360,17 @@
 
     //boost::recursive_mutex::scoped_lock lock(head_->mutex_);
-    orxonox::ObjectList<orxonox::SpaceShip>::iterator it = orxonox::ObjectList<orxonox::SpaceShip>::begin();
     ClientInformation *client = ClientInformation::findClient(&event->peer->address);
     if(!client)
       return false;
     gamestates_->removeClient(client);
-    while(it){
-      if(it->getObjectID()!=client->getShipID()){
-        ++it;
-        continue;
-      }
-      orxonox::ObjectList<orxonox::SpaceShip>::iterator temp=it;
-      ++it;
-      delete  *temp;
-      return ClientInformation::removeClient(event->peer);
-    }
-    return false;
+
+// inform all the listeners
+    orxonox::ObjectList<ClientConnectionListener>::iterator listener = orxonox::ObjectList<ClientConnectionListener>::begin();
+    while(listener){
+      listener->clientDisconnected(client->getID());
+      listener++;
+    }
+
+    return ClientInformation::removeClient(event->peer);
   }
 
@@ -387,10 +384,18 @@
     gamestates_->removeClient(client);
   }
-  
-  bool Server::chat(std::string message){
+
+  bool Server::chat(const std::string& message){
+      return this->sendChat(message, Host::getPlayerID());
+  }
+
+  bool Server::broadcast(const std::string& message){
+      return this->sendChat(message, CLIENTID_UNKNOWN);
+  }
+
+  bool Server::sendChat(const std::string& message, unsigned int clientID){
     ClientInformation *temp = ClientInformation::getBegin();
     packet::Chat *chat;
     while(temp){
-      chat = new packet::Chat(message, Host::getPlayerID());
+      chat = new packet::Chat(message, clientID);
       chat->setClientID(temp->getID());
       if(!chat->send())
@@ -398,5 +403,8 @@
       temp = temp->next();
     }
-    COUT(1) << "Player " << Host::getPlayerID() << ": " << message << std::endl;
+//    COUT(1) << "Player " << Host::getPlayerID() << ": " << message << std::endl;
+    for (orxonox::ObjectList<ChatListener>::iterator it = orxonox::ObjectList<ChatListener>::begin(); it != orxonox::ObjectList<ChatListener>::end(); ++it)
+      it->incomingChat(message, clientID);
+
     return true;
   }
Index: code/trunk/src/network/Server.h
===================================================================
--- code/trunk/src/network/Server.h	(revision 1910)
+++ code/trunk/src/network/Server.h	(revision 2087)
@@ -52,5 +52,5 @@
 {
   const int CLIENTID_SERVER = 0;
-  
+
   /**
   * This class is the root class of the network module for a server.
@@ -61,13 +61,15 @@
     Server();
     Server(int port);
-    Server(int port, std::string bindAddress);
+    Server(int port, const std::string& bindAddress);
     Server(int port, const char *bindAddress);
     ~Server();
-    
+
     void open();
     void close();
-    bool processChat(std::string message, unsigned int playerID);
+    bool processChat(const std::string& message, unsigned int playerID);
     bool queuePacket(ENetPacket *packet, int clientID);
     void tick(float time);
+    unsigned int getPing(unsigned int clientID);
+    double getPacketLoss(unsigned int clientID);
   protected:
     void processQueue();
@@ -77,8 +79,7 @@
     unsigned int shipID(){return 0;}
     unsigned int playerID(){return 0;}
-    
+
     bool addClient(ENetEvent *event);
     bool createClient(int clientID);
-    bool createShip(ClientInformation *client);
     bool disconnectClient(ENetEvent *event);
     void disconnectClient(int clientID);
@@ -87,11 +88,13 @@
     bool sendGameState();
     bool sendObjectDeletes();
-    virtual bool chat(std::string message);
-    
+    virtual bool chat(const std::string& message);
+    virtual bool broadcast(const std::string& message);
+    bool sendChat(const std::string& message, unsigned int clientID);
+
     //void processChat( chat *data, int clientId);
     ConnectionManager *connection;
     GamestateManager *gamestates_;
 
-    
+
     float timeSinceLastUpdate_;
   };
Index: code/trunk/src/network/Synchronisable.cc
===================================================================
--- code/trunk/src/network/Synchronisable.cc	(revision 1910)
+++ code/trunk/src/network/Synchronisable.cc	(revision 2087)
@@ -42,4 +42,5 @@
 
 #include <cstring>
+#include <string>
 #include <iostream>
 #include <assert.h>
@@ -51,5 +52,5 @@
 namespace network
 {
-  
+
 
   std::map<unsigned int, Synchronisable *> Synchronisable::objectMap_;
@@ -62,5 +63,5 @@
   * Initializes all Variables and sets the right objectID
   */
-  Synchronisable::Synchronisable(){
+  Synchronisable::Synchronisable(orxonox::BaseObject* creator){
     RegisterRootObject(Synchronisable);
     static uint32_t idCounter=0;
@@ -68,9 +69,27 @@
     objectMode_=0x1; // by default do not send data to server
     objectID=idCounter++;
+    classID = (unsigned int)-1;
     syncList = new std::list<synchronisableVariable *>;
-  }
-
-  /**
-   * Destructor: 
+
+    this->creatorID = OBJECTID_UNKNOWN;
+
+    searchcreatorID:
+    if (creator)
+    {
+        Synchronisable* synchronisable_creator = dynamic_cast<Synchronisable*>(creator);
+        if (synchronisable_creator && synchronisable_creator->objectMode_)
+        {
+            this->creatorID = synchronisable_creator->getObjectID();
+        }
+        else if (creator != creator->getCreator())
+        {
+            creator = creator->getCreator();
+            goto searchcreatorID;
+        }
+    }
+  }
+
+  /**
+   * Destructor:
    * Delete all callback objects and remove objectID from the objectMap_
    */
@@ -80,5 +99,6 @@
       for(std::list<synchronisableVariable *>::iterator it = syncList->begin(); it!=syncList->end(); it++)
         delete (*it)->callback;
-      deletedObjects_.push(objectID);
+      if (this->objectMode_ != 0x0)
+        deletedObjects_.push(objectID);
 //       COUT(3) << "destruct synchronisable +++" << objectID << " | " << classID << std::endl;
 //       COUT(3) << " bump ---" << objectID << " | " << &objectMap_ << std::endl;
@@ -96,5 +116,5 @@
     this->classID = this->getIdentifier()->getNetworkID();
 //     COUT(4) << "creating synchronisable: setting classid from " << this->getIdentifier()->getName() << " to: " << classID << std::endl;
-    
+
 //     COUT(3) << "construct synchronisable +++" << objectID << " | " << classID << std::endl;
 //     objectMap_[objectID]=this;
@@ -127,23 +147,46 @@
     synchronisableHeader *header = (synchronisableHeader *)mem;
 
-    COUT(3) << "fabricating object with id: " << header->objectID << std::endl;
+    if(!header->dataAvailable)
+    {
+      mem += header->size;
+      return 0;
+    }
+    
+    COUT(4) << "fabricating object with id: " << header->objectID << std::endl;
 
     orxonox::Identifier* id = ClassByID(header->classID);
     assert(id);
-    orxonox::BaseObject *bo = id->fabricate();
+    orxonox::BaseObject* creator = 0;
+    if (header->creatorID != OBJECTID_UNKNOWN)
+    {
+      Synchronisable* synchronisable_creator = Synchronisable::getSynchronisable(header->creatorID);
+      if (!synchronisable_creator)
+      {
+        mem += header->size; //.TODO: this suckz.... remove size from header
+        return 0;
+      }
+      else
+        creator = dynamic_cast<orxonox::BaseObject*>(synchronisable_creator);
+    }
+    orxonox::BaseObject *bo = id->fabricate(creator);
+    assert(bo);
     Synchronisable *no = dynamic_cast<Synchronisable *>(bo);
     assert(no);
     no->objectID=header->objectID;
+    no->creatorID=header->creatorID; //TODO: remove this
     no->classID=header->classID;
-    COUT(3) << "fabricate objectID: " << no->objectID << " classID: " << no->classID << std::endl;
+    COUT(4) << "fabricate objectID: " << no->objectID << " classID: " << no->classID << std::endl;
           // update data and create object/entity...
-    bool b = no->updateData(mem, mode);
+    bool b = no->updateData(mem, mode, true);
     assert(b);
-    b = no->create();
-    assert(b);
+    if (b)
+    {
+        b = no->create();
+        assert(b);
+    }
     return no;
   }
 
-  
+
   /**
    * Finds and deletes the Synchronisable with the appropriate objectID
@@ -164,5 +207,5 @@
     return true;
   }
-  
+
   /**
    * This function looks up the objectID in the objectMap_ and returns a pointer to the right Synchronisable
@@ -185,5 +228,5 @@
   }
 
-  
+
   /**
   * This function is used to register a variable to be synchronized
@@ -196,4 +239,5 @@
   */
   void Synchronisable::registerVar(void *var, int size, variableType t, int mode, NetworkCallbackBase *cb){
+    assert( mode==direction::toclient || mode==direction::toserver || mode==direction::serverMaster || mode==direction::clientMaster);
     // create temporary synch.Var struct
     synchronisableVariable *temp = new synchronisableVariable;
@@ -203,4 +247,10 @@
     temp->type = t;
     temp->callback = cb;
+    if( ( mode & direction::bidirectional ) )
+    {
+      temp->varBuffer = new uint8_t[size];
+      memcpy(temp->varBuffer, temp->var, size); //now fill the buffer for the first time
+      temp->varReference = 0;
+    }
     COUT(5) << "Syncronisable::registering var with size: " << temp->size << " and type: " << temp->type << std::endl;
     //std::cout << "push temp to syncList (at the bottom) " << datasize << std::endl;
@@ -228,9 +278,9 @@
    *             0x2: client->server (not recommended)
    *             0x3: bidirectional
-   * @return true: if !isMyTick or if everything was successfully saved
+   * @return true: if !doSync or if everything was successfully saved
    */
   bool Synchronisable::getData(uint8_t*& mem, unsigned int id, int mode){
     //if this tick is we dont synchronise, then abort now
-    if(!isMyTick(id))
+    if(!doSync(id))
       return true;
     //std::cout << "inside getData" << std::endl;
@@ -240,4 +290,8 @@
     if(classID==0)
       COUT(3) << "classid 0 " << this->getIdentifier()->getName() << std::endl;
+
+    if (this->classID == (unsigned int)-1)
+        this->classID = this->getIdentifier()->getNetworkID();
+
     assert(this->classID==this->getIdentifier()->getNetworkID());
 //     this->classID=this->getIdentifier()->getNetworkID(); // TODO: correct this
@@ -250,4 +304,5 @@
     header->size = size;
     header->objectID = this->objectID;
+    header->creatorID = this->creatorID;
     header->classID = this->classID;
     header->dataAvailable = true;
@@ -263,4 +318,11 @@
         COUT(5) << "not getting data: " << std::endl;
         continue;  // this variable should only be received
+      }
+      // if the variable gets synchronised bidirectional, then add the reference to the bytestream
+      if( ( (*i)->mode & direction::bidirectional ) == direction::bidirectional )
+      {
+        *(uint8_t*)mem = (*i)->varReference;
+        mem += sizeof( (*i)->varReference );
+        tempsize += sizeof( (*i)->varReference );
       }
       switch((*i)->type){
@@ -271,11 +333,11 @@
           break;
         case STRING:
-          memcpy( (void *)(mem), (void *)&((*i)->size), sizeof(int) );
-          mem+=sizeof(int);
+          memcpy( (void *)(mem), (void *)&((*i)->size), sizeof(size_t) );
+          mem+=sizeof(size_t);
           const char *data = ( ( *(std::string *) (*i)->var).c_str());
           memcpy( mem, (void*)data, (*i)->size);
           COUT(5) << "synchronisable: char: " << (const char *)(mem) << " data: " << data << " string: " << *(std::string *)((*i)->var) << std::endl;
           mem+=(*i)->size;
-          tempsize+=(*i)->size + 4;
+          tempsize+=(*i)->size + sizeof(size_t);
           break;
       }
@@ -292,5 +354,5 @@
    * @return true/false
    */
-  bool Synchronisable::updateData(uint8_t*& mem, int mode){
+  bool Synchronisable::updateData(uint8_t*& mem, int mode, bool forceCallback){
     if(mode==0x0)
       mode=state_;
@@ -305,4 +367,5 @@
     synchronisableHeader *syncHeader = (synchronisableHeader *)mem;
     assert(syncHeader->objectID==this->objectID);
+//    assert(syncHeader->creatorID==this->creatorID);
     if(syncHeader->dataAvailable==false){
       mem+=syncHeader->size;
@@ -314,5 +377,5 @@
     assert(this->objectID==syncHeader->objectID);
 //    assert(this->classID==syncHeader->classID); //TODO: fix this!!! maybe a problem with the identifier ?
-    
+
     COUT(5) << "Synchronisable: objectID " << syncHeader->objectID << ", classID " << syncHeader->classID << " size: " << syncHeader->size << " synchronising data" << std::endl;
     for(i=syncList->begin(); i!=syncList->end() && mem <= data+syncHeader->size; i++){
@@ -325,4 +388,22 @@
       switch((*i)->type){
         case DATA:
+          if( ( (*i)->mode & direction::bidirectional ) == direction::bidirectional )
+          {
+            if( ( mode == 0x1 && (*i)->mode == direction::serverMaster ) || \
+                  ( mode == 0x2 && (*i)->mode == direction::clientMaster ) )    // if true we are master on this variable
+            {
+              uint8_t refNr = *(uint8_t *)mem;
+              if( refNr != (*i)->varReference )
+              {
+                mem += sizeof((*i)->varReference) + (*i)->size; // the reference for this variable is not recent, discard data
+                break;
+              }
+            }
+            else //we are slave for this variable
+            {
+              (*i)->varReference = *(uint8_t *)mem; //copy the reference value for this variable
+            }
+            mem += sizeof((*i)->varReference);
+          }
           if((*i)->callback) // check whether this variable changed (but only if callback was set)
             if(strncmp((char *)(*i)->var, (char *)mem, (*i)->size)!=0)
@@ -332,7 +413,25 @@
           break;
         case STRING:
-          (*i)->size = *(uint32_t *)mem;
+          if( ( (*i)->mode & direction::bidirectional ) == direction::bidirectional )
+          {
+            if( ( mode == 0x1 && (*i)->mode == direction::serverMaster ) || \
+                  ( mode == 0x2 && (*i)->mode == direction::clientMaster ) )    // if true we are master for this variable
+            {
+              uint8_t refNr = *(uint8_t *)mem;
+              mem += sizeof( (*i)->varReference );
+              if( refNr != (*i)->varReference ){
+                mem += sizeof(size_t) + *(size_t *)mem; // the reference for this variable is not recent, discard data
+                break;
+              }
+            }
+            else //we are slave for this variable
+            {
+              (*i)->varReference = *(uint8_t *)mem; //copy the reference value for this variable
+            }
+            mem += sizeof( (*i)->varReference );
+          }
+          (*i)->size = *(size_t *)mem;
           COUT(5) << "string size: " << (*i)->size << std::endl;
-          mem+=sizeof(int);
+          mem += sizeof(size_t);
           if((*i)->callback) // check whether this string changed
             if( *(std::string *)((*i)->var) != std::string((char *)mem) )
@@ -344,5 +443,5 @@
       }
       // call the callback function, if defined
-      if(callback && (*i)->callback)
+      if((callback || forceCallback) && (*i)->callback)
         (*i)->callback->call();
     }
@@ -357,5 +456,5 @@
   */
   uint32_t Synchronisable::getSize(unsigned int id, int mode){
-    if(!isMyTick(id))
+    if(!doSync(id))
       return 0;
     int tsize=sizeof(synchronisableHeader);
@@ -377,4 +476,8 @@
         break;
       }
+      if( ( (*i)->mode & direction::bidirectional ) == direction::bidirectional )
+      {
+        tsize+=sizeof( (*i)->varReference );
+      }
     }
     return tsize;
@@ -386,6 +489,6 @@
    * @return true/false
    */
-  bool Synchronisable::isMyTick(unsigned int id){
-    return ( (objectMode_&state_)!=0 );
+  bool Synchronisable::doSync(unsigned int id){
+    return ( (objectMode_&state_)!=0 && (!syncList->empty() ) );
   }
 
@@ -413,5 +516,5 @@
    */
   void Synchronisable::setObjectMode(int mode){
-    assert(mode==0x1 || mode==0x2 || mode==0x3);
+    assert(mode==0x0 || mode==0x1 || mode==0x2 || mode==0x3);
     objectMode_=mode;
   }
Index: code/trunk/src/network/Synchronisable.h
===================================================================
--- code/trunk/src/network/Synchronisable.h	(revision 1910)
+++ code/trunk/src/network/Synchronisable.h	(revision 2087)
@@ -41,24 +41,23 @@
 #include "util/Integers.h"
 
-#define REGISTERDATA(varname) registerVar(&varname, sizeof(varname), network::DATA)
-#define REGISTERDATA_WITHDIR(varname, mode) registerVar(&varname, sizeof(varname), network::DATA, mode)
-#define REGISTERSTRING(stringname) registerVar(&stringname, stringname.length()+1, network::STRING)
-#define REGISTERSTRING_WITHDIR(stringname, mode) registerVar(&stringname, stringname.length()+1, network::STRING, mode)
-
-//TODO: this is only a very ugly hack ...
-namespace orxonox{
-class SpaceShip;
-}
+#define REGISTERDATA(varname, ...) \
+    registerVar((void*)&varname, sizeof(varname), network::DATA, __VA_ARGS__)
+#define REGISTERSTRING(stringname, ...) \
+    registerVar(&stringname, stringname.length()+1, network::STRING, __VA_ARGS__)
 
 namespace network
 {
+  static const unsigned int OBJECTID_UNKNOWN = (unsigned int)-1;
+
   namespace direction{
     enum syncdirection{
       toclient=0x1,
       toserver=0x2,
-      bidirectional=0x3
+      bidirectional=0x3,
+      serverMaster=0x3,
+      clientMaster=0x7
     };
   }
-  
+
   namespace syncmode{
     enum mode{
@@ -67,5 +66,5 @@
     };
   }
-  
+
   enum variableType{
     DATA,
@@ -73,12 +72,13 @@
   };
 
-  struct synchronisableHeader{
+  struct _NetworkExport synchronisableHeader{
     uint32_t size:31;
     bool dataAvailable:1;
     uint32_t objectID;
+    uint32_t creatorID;
     uint32_t classID;
   };
 
-  typedef struct synchronisableVariable{
+  struct _NetworkExport synchronisableVariable{
     unsigned int size;
     int mode; // this determines in which direction the variable gets synchronised
@@ -86,5 +86,7 @@
     variableType type;
     NetworkCallbackBase *callback;
-  }SYNCVAR;
+    void *varBuffer;
+    uint8_t varReference;
+  };
 
   /**
@@ -98,11 +100,10 @@
     friend class GamestateClient;
     friend class Server;
-    friend class orxonox::SpaceShip;
     virtual ~Synchronisable();
 
-    
+
     virtual bool create();
     static void setClient(bool b);
-    
+
     static Synchronisable *fabricate(uint8_t*& mem, int mode=0x0);
     static bool deleteObject(unsigned int objectID);
@@ -110,26 +111,26 @@
     static unsigned int getNumberOfDeletedObject(){ return deletedObjects_.size(); }
     static unsigned int popDeletedObject(){ unsigned int i = deletedObjects_.front(); deletedObjects_.pop(); return i; }
-    
+
     inline unsigned int getObjectID(){return objectID;}
     inline unsigned int getClassID(){return classID;}
   protected:
-    Synchronisable();
+    Synchronisable(orxonox::BaseObject* creator);
     void registerVar(void *var, int size, variableType t, int mode=1, NetworkCallbackBase *cb=0);
     void setObjectMode(int mode);
     void setObjectFrequency(unsigned int freq){ objectFrequency_ = freq; }
-    virtual void registerAllVariables()=0;
-    
-    
+
+
   private:
     bool getData(uint8_t*& men, unsigned int id, int mode=0x0);
     uint32_t getSize(unsigned int id, int mode=0x0);
-    bool updateData(uint8_t*& mem, int mode=0x0);
+    bool updateData(uint8_t*& mem, int mode=0x0, bool forceCallback=false);
     bool isMyData(uint8_t* mem);
     bool doSelection(unsigned int id);
-    bool isMyTick(unsigned int id);
-    
+    bool doSync(unsigned int id);
+
     unsigned int objectID;
+    unsigned int creatorID;
     unsigned int classID;
-    
+
     std::list<synchronisableVariable *> *syncList;
     static int state_; // detemines wheter we are server (default) or client
Index: code/trunk/src/network/packet/Acknowledgement.h
===================================================================
--- code/trunk/src/network/packet/Acknowledgement.h	(revision 1910)
+++ code/trunk/src/network/packet/Acknowledgement.h	(revision 2087)
@@ -29,4 +29,5 @@
 #define NETWORKACKNOLEDGEMENT_H
 
+#include "../NetworkPrereqs.h"
 #include "Packet.h"
 
@@ -35,7 +36,7 @@
 namespace packet {
 /**
-	@author 
+	@author
 */
-class Acknowledgement : public Packet
+class _NetworkExport Acknowledgement : public Packet
 {
 public:
@@ -43,8 +44,8 @@
   Acknowledgement( uint8_t* data, unsigned int clientID );
   ~Acknowledgement();
-  
+
   inline unsigned int getSize() const;
   bool process();
-  
+
   unsigned int getAckID();
 private:
Index: code/trunk/src/network/packet/Chat.h
===================================================================
--- code/trunk/src/network/packet/Chat.h	(revision 1910)
+++ code/trunk/src/network/packet/Chat.h	(revision 2087)
@@ -2,4 +2,6 @@
 #ifndef NETWORKCHAT_H
 #define NETWORKCHAT_H
+
+#include "../NetworkPrereqs.h"
 
 #include <string>
@@ -11,7 +13,7 @@
 namespace packet {
 /**
-	@author 
+	@author
 */
-class Chat : public Packet
+class _NetworkExport Chat : public Packet
 {
 public:
@@ -19,8 +21,8 @@
   Chat( uint8_t* data, unsigned int clientID );
   ~Chat();
-  
+
   inline unsigned int getSize() const;
   bool process();
-  
+
   unsigned int getMessageLength(){ return messageLength_; };
   unsigned char *getMessage();
Index: code/trunk/src/network/packet/ClassID.h
===================================================================
--- code/trunk/src/network/packet/ClassID.h	(revision 1910)
+++ code/trunk/src/network/packet/ClassID.h	(revision 2087)
@@ -29,4 +29,6 @@
 #define NETWORKCLASSID_H
 
+#include "../NetworkPrereqs.h"
+
 #include <string>
 
@@ -37,7 +39,7 @@
 
 /**
-	@author 
+	@author
 */
-class ClassID : public Packet
+class _NetworkExport ClassID : public Packet
 {
 public:
@@ -45,8 +47,8 @@
   ClassID( uint8_t* data, unsigned int clientID );
   ~ClassID();
-  
+
   inline unsigned int getSize() const;
   bool process();
-  
+
   unsigned int getClassID();
   unsigned int getClassNameLength(){ return classNameLength_; }
Index: code/trunk/src/network/packet/DeleteObjects.h
===================================================================
--- code/trunk/src/network/packet/DeleteObjects.h	(revision 1910)
+++ code/trunk/src/network/packet/DeleteObjects.h	(revision 2087)
@@ -29,4 +29,6 @@
 #define NETWORKPACKETDELETEOBJECTS_H
 
+#include "../NetworkPrereqs.h"
+
 #include "Packet.h"
 
@@ -35,7 +37,7 @@
 namespace packet {
 /**
-	@author 
+	@author
 */
-class DeleteObjects : public Packet
+class _NetworkExport DeleteObjects : public Packet
 {
 public:
@@ -43,10 +45,10 @@
   DeleteObjects( uint8_t* data, unsigned int clientID );
   ~DeleteObjects();
-  
+
   bool fetchIDs();
-  
+
   inline unsigned int getSize() const;
   bool process();
-  
+
 private:
 };
Index: code/trunk/src/network/packet/Gamestate.cc
===================================================================
--- code/trunk/src/network/packet/Gamestate.cc	(revision 1910)
+++ code/trunk/src/network/packet/Gamestate.cc	(revision 2087)
@@ -46,7 +46,7 @@
 #define HEADER GAMESTATE_HEADER(data_)
 
-  
+
 #define PACKET_FLAG_GAMESTATE  ENET_PACKET_FLAG_RELIABLE
-  
+
 Gamestate::Gamestate()
 {
@@ -85,5 +85,5 @@
     return false;
   }
-  
+
 #ifndef NDEBUG
   std::list<Synchronisable*> slist;
@@ -115,5 +115,5 @@
     slist.push_back(*it);
 #endif
-    
+
     //if(it->doSelection(id))
     dataMap_[mem-data_]=(*it);  // save the mem location of the synchronisable data
@@ -157,8 +157,5 @@
     if(!s)
     {
-      s = Synchronisable::fabricate(mem, mode);
-      assert(s);
-//       if(!s)
-//         return false;
+      Synchronisable::fabricate(mem, mode);
     }
     else
@@ -257,5 +254,5 @@
   HEADER->compressed = true;
   assert(HEADER->compressed);
-  COUT(3) << "gamestate compress datasize: " << HEADER->datasize << " compsize: " << HEADER->compsize << std::endl;
+  COUT(4) << "gamestate compress datasize: " << HEADER->datasize << " compsize: " << HEADER->compsize << std::endl;
   return true;
 }
@@ -264,9 +261,9 @@
   assert(HEADER);
   assert(HEADER->compressed);
-  COUT(3) << "GameStateClient: uncompressing gamestate. id: " << HEADER->id << ", baseid: " << HEADER->base_id << ", datasize: " << HEADER->datasize << ", compsize: " << HEADER->compsize << std::endl;
+  COUT(4) << "GameStateClient: uncompressing gamestate. id: " << HEADER->id << ", baseid: " << HEADER->base_id << ", datasize: " << HEADER->datasize << ", compsize: " << HEADER->compsize << std::endl;
   unsigned int datasize = HEADER->datasize;
   unsigned int compsize = HEADER->compsize;
   unsigned int bufsize;
-  assert(compsize<=datasize);
+//  assert(compsize<=datasize);
   bufsize = datasize;
   assert(bufsize!=0);
@@ -289,6 +286,16 @@
   //copy over the header
   *GAMESTATE_HEADER(ndata) = *HEADER;
-  //delete old (compressed data)
-  delete[] data_;
+
+  if (this->bDataENetAllocated_){
+    // Memory was allocated by ENet. --> We let it be since enet_packet_destroy will
+    // deallocated it anyway. So data and packet stay together.
+    this->bDataENetAllocated_ = false;
+  }
+  else{
+    // We allocated the memory in the first place (unlikely). So we destroy the old data
+    // and overwrite it with the new decompressed data.
+    delete[] this->data_;
+  }
+
   //set new pointers
   data_ = ndata;
@@ -339,5 +346,5 @@
   assert(data_);
   std::map<unsigned int, Synchronisable *>::iterator it;
-  
+
   // allocate memory for new data
   uint8_t *gdata = new uint8_t[HEADER->datasize+sizeof(GamestateHeader)];
@@ -346,11 +353,11 @@
   uint8_t *newdata = gdata + sizeof(GamestateHeader);
   uint8_t *origdata = GAMESTATE_START(data_);
-  
+
   //copy the GamestateHeader
   *(GamestateHeader*)gdata = *HEADER;
-  
+
   synchronisableHeader *oldobjectheader, *newobjectheader;
   unsigned int objectOffset;
-  
+
   //copy in the zeros
   for(it=dataMap_.begin(); it!=dataMap_.end(); it++){
@@ -360,5 +367,5 @@
     assert(it->second->objectID==oldobjectheader->objectID);
     *newobjectheader = *oldobjectheader;
-    objectOffset=sizeof(uint8_t)+sizeof(bool); //skip the size and the availableDate variables in the objectheader
+    objectOffset=sizeof(uint8_t)+sizeof(bool); //skip the size and the availableData variables in the objectheader
     if(it->second->doSelection(HEADER->id)){
       newobjectheader->dataAvailable=true; //TODO: probably not neccessary
@@ -390,18 +397,18 @@
   assert(!HEADER->compressed);
   assert(!HEADER->diffed);
-  
+
   //preparations
   std::map<unsigned int, Synchronisable *>::iterator it;
   uint8_t *origdata, *basedata, *destdata, *ndata;
   unsigned int objectOffset, streamOffset=0;    //data offset
-  unsigned int minsize = (HEADER->datasize < GAMESTATE_HEADER(base->data_)->datasize) ? HEADER->datasize : GAMESTATE_HEADER(base->data_)->datasize; 
+  unsigned int minsize = (HEADER->datasize < GAMESTATE_HEADER(base->data_)->datasize) ? HEADER->datasize : GAMESTATE_HEADER(base->data_)->datasize;
   synchronisableHeader *origheader;
   synchronisableHeader *destheader;
-  
+
   origdata = GAMESTATE_START(this->data_);
   basedata = GAMESTATE_START(base->data_);
   ndata = new uint8_t[HEADER->datasize + sizeof(GamestateHeader)];
   destdata = ndata + sizeof(GamestateHeader);
-  
+
   // do the diff
   for(it=dataMap_.begin(); it!=dataMap_.end(); it++){
@@ -410,5 +417,5 @@
     origheader = (synchronisableHeader *)(origdata+streamOffset);
     destheader = (synchronisableHeader *)(destdata+streamOffset);
-    
+
     //copy and partially diff the object header
     assert(sizeof(synchronisableHeader)==3*sizeof(unsigned int)+sizeof(bool));
@@ -420,12 +427,12 @@
     }else{
       *(uint32_t*)(destdata+sizeof(uint32_t)+sizeof(bool)) = 0;
-      *(uint32_t*)(destdata+2*sizeof(uint32_t)+sizeof(bool)) = 0; 
+      *(uint32_t*)(destdata+2*sizeof(uint32_t)+sizeof(bool)) = 0;
     }
     objectOffset=sizeof(synchronisableHeader);
     streamOffset+=sizeof(synchronisableHeader);
-    
+
     //now handle the object data or fill with zeros
     while(objectOffset<origheader->size ){
-      
+
       if(sendData && streamOffset<minsize)
         *(destdata+objectOffset)=*(basedata+objectOffset)^*(origdata+objectOffset); // do the xor
@@ -434,5 +441,5 @@
       else
         *(destdata+objectOffset)=0; // set to 0 because this object should not be transfered
-      
+
       objectOffset++;
       streamOffset++;
@@ -442,5 +449,5 @@
     basedata+=objectOffset;
   }
-  
+
   //copy over the gamestate header and set the diffed flag
   *(GamestateHeader *)ndata = *HEADER; //copy over the header
@@ -458,18 +465,18 @@
   assert(!HEADER->compressed);
   assert(HEADER->diffed);
-  
+
   //preparations
   std::map<unsigned int, Synchronisable *>::iterator it;
   uint8_t *origdata, *basedata, *destdata, *ndata;
   unsigned int objectOffset, streamOffset=0;    //data offset
-  unsigned int minsize = (HEADER->datasize < GAMESTATE_HEADER(base->data_)->datasize) ? HEADER->datasize : GAMESTATE_HEADER(base->data_)->datasize; 
+  unsigned int minsize = (HEADER->datasize < GAMESTATE_HEADER(base->data_)->datasize) ? HEADER->datasize : GAMESTATE_HEADER(base->data_)->datasize;
   synchronisableHeader *origheader;
   synchronisableHeader *destheader;
-  
+
   origdata = GAMESTATE_START(this->data_);
   basedata = GAMESTATE_START(base->data_);
   ndata = new uint8_t[HEADER->datasize + sizeof(GamestateHeader)];
   destdata = ndata + sizeof(GamestateHeader);
-  
+
   // do the undiff
   for(it=dataMap_.begin(); it!=dataMap_.end(); it++){
@@ -478,5 +485,5 @@
     destheader = (synchronisableHeader *)(destdata+streamOffset);
     bool sendData;
-    
+
     //copy and partially diff the object header
     assert(sizeof(synchronisableHeader)==3*sizeof(unsigned int)+sizeof(bool));
@@ -489,12 +496,12 @@
     }else{
       *(unsigned int*)(destdata+sizeof(unsigned int)+sizeof(bool)) = 0;
-      *(unsigned int*)(destdata+2*sizeof(unsigned int)+sizeof(bool)) = 0; 
+      *(unsigned int*)(destdata+2*sizeof(unsigned int)+sizeof(bool)) = 0;
     }
     objectOffset=sizeof(synchronisableHeader);
     streamOffset+=sizeof(synchronisableHeader);
-    
+
     //now handle the object data or fill with zeros
     while(objectOffset<origheader->size ){
-      
+
       if(sendData && streamOffset<minsize)
         *(destdata+objectOffset)=*(basedata+objectOffset)^*(origdata+objectOffset); // do the xor
@@ -503,5 +510,5 @@
       else
         *(destdata+objectOffset)=0; // set to 0 because this object should not be transfered
-      
+
       objectOffset++;
       streamOffset++;
@@ -511,5 +518,5 @@
     basedata+=objectOffset;
   }
-  
+
   //copy over the gamestate header and set the diffed flag
   *(GamestateHeader *)ndata = *HEADER; //copy over the header
Index: code/trunk/src/network/packet/Gamestate.h
===================================================================
--- code/trunk/src/network/packet/Gamestate.h	(revision 1910)
+++ code/trunk/src/network/packet/Gamestate.h	(revision 2087)
@@ -27,4 +27,10 @@
  */
 
+
+#ifndef NETWORK_PACKETGAMESTATE_H
+#define NETWORK_PACKETGAMESTATE_H
+
+#include "../NetworkPrereqs.h"
+
 #include "Packet.h"
 #include "network/Synchronisable.h"
@@ -34,13 +40,9 @@
 #endif
 
-
-#ifndef NETWORK_PACKETGAMESTATE_H
-#define NETWORK_PACKETGAMESTATE_H
-
 namespace network {
 
 namespace packet {
 
-struct GamestateHeader{
+struct _NetworkExport GamestateHeader{
   ENUM::Type packetType;
   int32_t id; // id of the gamestate
@@ -59,5 +61,5 @@
 	@author Oliver Scheuss
 */
-class Gamestate: public Packet{
+class _NetworkExport Gamestate: public Packet{
   public:
     Gamestate();
Index: code/trunk/src/network/packet/Packet.cc
===================================================================
--- code/trunk/src/network/packet/Packet.cc	(revision 1910)
+++ code/trunk/src/network/packet/Packet.cc	(revision 2087)
@@ -49,10 +49,10 @@
 
 namespace packet{
-  
+
 #define PACKET_FLAG_DEFAULT ENET_PACKET_FLAG_NO_ALLOCATE
 #define _PACKETID           0
-  
+
 std::map<ENetPacket *, Packet *> Packet::packetMap_;
-  
+
 Packet::Packet(){
   flags_ = PACKET_FLAG_DEFAULT;
@@ -61,4 +61,5 @@
   data_=0;
   enetPacket_=0;
+  bDataENetAllocated_ = false;
 }
 
@@ -73,4 +74,5 @@
   data_=data;
   enetPacket_=0;
+  bDataENetAllocated_ = false;
 }
 
@@ -86,13 +88,32 @@
   }else
     data_=0;
-}
-
+  bDataENetAllocated_ = p.bDataENetAllocated_;
+}
+
+/**
+@brief
+    Destroys a packet completely.
+    
+    That also means destroying the ENetPacket if one exists. There 
+*/
 Packet::~Packet(){
-  if(enetPacket_){
-    assert(enetPacket_->freeCallback==0);
+  // Deallocate data_ memory if necessary.
+  if (this->bDataENetAllocated_){
+    // In this case ENet allocated data_ and will destroy it.
+  }
+  else if (this->data_) {
+    // This destructor was probably called as a consequence to ENet executing our callback.
+    // It simply serves us to be able to deallocate the packet content (data_) ourselves since
+    // we have created it in the first place.
+    delete[] this->data_;
+  }
+
+  // Destroy the ENetPacket if necessary.
+  // Note: For the case ENet used the callback to destroy the packet, we have already set
+  // enetPacket_ to NULL to avoid destroying it again.
+  if (this->enetPacket_){
+    // enetPacket_->data gets destroyed too by ENet if it was allocated by it.
     enet_packet_destroy(enetPacket_);
   }
-  if(data_)
-    delete[] data_;
 }
 
@@ -107,10 +128,13 @@
       return false;
     }
+    // We deliver ENet the data address so that it doesn't memcpy everything again.
+    // --> We have to delete data_ ourselves!
     enetPacket_ = enet_packet_create(getData(), getSize(), getFlags());
     enetPacket_->freeCallback = &Packet::deletePacket;
-//     enetPacket_->freeCallback = &blub;
+    // Add the packet to a global list so we can access it again once enet calls our
+    // deletePacket method. We can of course only give a one argument function to the ENet C library.
     packetMap_[enetPacket_] = this;
   }
-#ifndef NDEBUG 
+#ifndef NDEBUG
   switch( *(ENUM::Type *)(data_ + _PACKETID) )
   {
@@ -127,7 +151,7 @@
   }
 #endif
-  ENetPacket *temp = enetPacket_;
-  enetPacket_ = 0; // otherwise we have a double free because enet already handles the deallocation of the packet
-  network::Host::addPacket( temp, clientID_);
+//  ENetPacket *temp = enetPacket_;
+//  enetPacket_ = 0; // otherwise we have a double free because enet already handles the deallocation of the packet
+  network::Host::addPacket( enetPacket_, clientID_);
   return true;
 }
@@ -135,4 +159,5 @@
 Packet *Packet::createPacket(ENetPacket *packet, ENetPeer *peer){
   uint8_t *data = packet->data;
+  assert(ClientInformation::findClient(&peer->address)->getID() != (unsigned int)-2 || !Host::isServer());
   unsigned int clientID = ClientInformation::findClient(&peer->address)->getID();
   Packet *p;
@@ -169,11 +194,25 @@
       break;
   }
+
+  // Data was created by ENet
+  p->bDataENetAllocated_ = true;
+
   return p;
 }
 
-void Packet::deletePacket(ENetPacket *packet){
-  assert(packetMap_[packet]);
-  assert(packetMap_[packet]->enetPacket_==0);
-  delete packetMap_[packet];
+/**
+@brief
+    ENet calls this method whenever it wants to destroy a packet that contains
+    data we allocated ourselves.
+*/
+void Packet::deletePacket(ENetPacket *enetPacket){
+  // Get our Packet from a gloabal map with all Packets created in the send() method of Packet.
+  std::map<ENetPacket*, Packet*>::iterator it = packetMap_.find(enetPacket);
+  assert(it != packetMap_.end());
+  // Make sure we don't delete it again in the destructor
+  it->second->enetPacket_ = 0;
+  delete it->second;
+  //packetMap_.erase(it);
+  COUT(4) << "PacketMap size: " << packetMap_.size() << std::endl;
 }
 
Index: code/trunk/src/network/packet/Packet.h
===================================================================
--- code/trunk/src/network/packet/Packet.h	(revision 1910)
+++ code/trunk/src/network/packet/Packet.h	(revision 2087)
@@ -29,4 +29,6 @@
 #define NETWORKPACKET_H
 
+#include "../NetworkPrereqs.h"
+
 #include <map>
 #include <enet/enet.h>
@@ -37,5 +39,5 @@
 
 namespace packet{
-  
+
 namespace ENUM{
   enum Direction{
@@ -53,9 +55,9 @@
   };
 }
-  
+
 /**
 	@author Oliver Scheuss <scheusso [at] ee.ethz.ch>
 */
-class Packet{
+class _NetworkExport Packet{
   public:
     Packet(const Packet &p);
@@ -63,5 +65,5 @@
     static Packet *createPacket(ENetPacket *packet, ENetPeer *peer);
     static void deletePacket(ENetPacket *packet);
-    
+
     virtual unsigned char *getData(){ return data_; };
     virtual unsigned int getSize() const =0;
@@ -73,5 +75,5 @@
     void setClientID( int id )
       { clientID_ = id; }
-    
+
     bool send();
   protected:
@@ -82,5 +84,11 @@
     unsigned int clientID_;
     ENUM::Direction packetDirection_;
+    /** Pointer to the data. Be careful when deleting it because it might
+        point to a location that was allocated by ENet.
+        See bDataENetAllocated_ */
     uint8_t *data_;
+    /** Tells whether data_ was allocated by ENet or ourselves.
+        data_ might no correlate with enetPacket_->data. */
+    bool bDataENetAllocated_;
   private:
     static std::map<ENetPacket *, Packet *> packetMap_;
Index: code/trunk/src/network/packet/Welcome.h
===================================================================
--- code/trunk/src/network/packet/Welcome.h	(revision 1910)
+++ code/trunk/src/network/packet/Welcome.h	(revision 2087)
@@ -29,4 +29,6 @@
 #define NETWORKWELCOME_H
 
+#include "../NetworkPrereqs.h"
+
 #include "Packet.h"
 
@@ -35,7 +37,7 @@
 
 /**
-	@author 
+	@author
 */
-class Welcome : public Packet
+class _NetworkExport Welcome : public Packet
 {
 public:
@@ -43,9 +45,9 @@
   Welcome( uint8_t* data, unsigned int clientID );
   virtual ~Welcome();
-  
+
   uint8_t *getData();
   inline unsigned int getSize() const;
   bool process();
-  
+
 private:
 };
