Index: /code/branches/network6/src/libraries/network/Client.cc
===================================================================
--- /code/branches/network6/src/libraries/network/Client.cc	(revision 7877)
+++ /code/branches/network6/src/libraries/network/Client.cc	(revision 7878)
@@ -207,5 +207,5 @@
     if( packet->isReliable() )
     {
-      if( this->getLastProcessedGamestateID(packet->getPeerID()) >= packet->getRequiredGamestateID() )
+      if( this->getLastReceivedGamestateID(packet->getPeerID()) >= packet->getRequiredGamestateID() )
         packet->process(static_cast<Host*>(this));
       else
Index: /code/branches/network6/src/libraries/network/ClientConnection.cc
===================================================================
--- /code/branches/network6/src/libraries/network/ClientConnection.cc	(revision 7877)
+++ /code/branches/network6/src/libraries/network/ClientConnection.cc	(revision 7878)
@@ -123,4 +123,6 @@
       return true;
     this->established_ = false;
+    
+    // stop communication thread and disconnect server
     Connection::stopCommunicationThread();
     enet_peer_disconnect(this->server_, 0);
Index: /code/branches/network6/src/libraries/network/Connection.cc
===================================================================
--- /code/branches/network6/src/libraries/network/Connection.cc	(revision 7877)
+++ /code/branches/network6/src/libraries/network/Connection.cc	(revision 7878)
@@ -38,8 +38,10 @@
 
 #include "packet/Packet.h"
+#include <util/Sleep.h>
 
 namespace orxonox
 {
   const boost::posix_time::millisec NETWORK_COMMUNICATION_THREAD_WAIT_TIME(20);
+  const unsigned int                NETWORK_DISCONNECT_TIMEOUT = 500;
 
   Connection::Connection(uint32_t firstPeerID):
@@ -50,4 +52,5 @@
     this->incomingEventsMutex_ = new boost::mutex;
     this->outgoingEventsMutex_ = new boost::mutex;
+    this->overallMutex_ = new boost::mutex;
   }
 
@@ -77,4 +80,5 @@
   void Connection::disconnectPeer(uint32_t peerID)
   {
+    this->overallMutex_->lock();
     outgoingEvent outEvent = { peerID, outgoingEventType::disconnectPeer, 0, 0 };
     
@@ -82,4 +86,5 @@
     this->outgoingEvents_.push_back(outEvent);
     this->outgoingEventsMutex_->unlock();
+    this->overallMutex_->unlock();
   }
   
@@ -95,4 +100,5 @@
   void Connection::addPacket(ENetPacket* packet, uint32_t peerID, uint8_t channelID)
   {
+    this->overallMutex_->lock();
     outgoingEvent outEvent = { peerID, outgoingEventType::sendPacket, packet, channelID };
     
@@ -100,8 +106,10 @@
     this->outgoingEvents_.push_back(outEvent);
     this->outgoingEventsMutex_->unlock();
+    this->overallMutex_->unlock();
   }
   
   void Connection::broadcastPacket(ENetPacket* packet, uint8_t channelID)
   {
+    this->overallMutex_->lock();
     outgoingEvent outEvent = { 0, outgoingEventType::broadcastPacket, packet, channelID };
     
@@ -109,4 +117,5 @@
     this->outgoingEvents_.push_back(outEvent);
     this->outgoingEventsMutex_->unlock();
+    this->overallMutex_->unlock();
   }
 
@@ -116,4 +125,5 @@
     ENetEvent event;
     
+    this->overallMutex_->lock();
     while( bCommunicationThreadRunning_ )
     {
@@ -123,4 +133,8 @@
         processIncomingEvent(event);
       }
+      
+      this->overallMutex_->unlock();
+      msleep(10);
+      this->overallMutex_->lock();
       
       // Send all waiting outgoing packets
@@ -149,4 +163,5 @@
       }
     }
+    this->overallMutex_->unlock();
   }
   
@@ -209,9 +224,5 @@
         break;
       case outgoingEventType::disconnectPeers:
-        while( this->peerMap_.size()!=0 )
-        {
-          peer = this->peerMap_.begin()->second;
-          enet_peer_disconnect(peer, 0);
-        }
+        disconnectPeersInternal();
         break;
       case outgoingEventType::broadcastPacket:
@@ -223,4 +234,23 @@
   }
 
+
+  void Connection::disconnectPeersInternal()
+  {
+    std::map<uint32_t, ENetPeer*>::iterator it;
+    for( it=this->peerMap_.begin(); it!=this->peerMap_.end(); ++it )
+    {
+      enet_peer_disconnect(it->second, 0);
+    }
+    uint32_t iterations = NETWORK_DISCONNECT_TIMEOUT/NETWORK_WAIT_TIMEOUT;
+    uint32_t i = 0;
+    while( this->peerMap_.size() && i++ < iterations )
+    {
+      ENetEvent event;
+      if( enet_host_service( this->host_, &event, NETWORK_WAIT_TIMEOUT ) > 0 )
+      {
+        processIncomingEvent(event);
+      }
+    }
+  }
 
   void Connection::processQueue()
@@ -261,4 +291,20 @@
     }
   }
+  
+  void Connection::waitOutgoingQueue()
+  {
+    uint32_t outgoingEventsCount;
+    this->outgoingEventsMutex_->lock();
+    outgoingEventsCount = this->outgoingEvents_.size();
+    this->outgoingEventsMutex_->unlock();
+    while( outgoingEventsCount )
+    {
+      msleep(1);
+      this->outgoingEventsMutex_->lock();
+      outgoingEventsCount = this->outgoingEvents_.size();
+      this->outgoingEventsMutex_->unlock();
+    }
+  }
+
 
   incomingEvent Connection::preprocessConnectEvent(ENetEvent& event)
Index: /code/branches/network6/src/libraries/network/Connection.h
===================================================================
--- /code/branches/network6/src/libraries/network/Connection.h	(revision 7877)
+++ /code/branches/network6/src/libraries/network/Connection.h	(revision 7878)
@@ -118,4 +118,5 @@
 
     void processQueue();
+    void waitOutgoingQueue();     // wait for the outgoing queue to become empty (everything processed by communication thread)
     virtual void addPeer(uint32_t peerID)=0;
     virtual void removePeer(uint32_t peerID)=0;
@@ -128,4 +129,6 @@
     void processIncomingEvent(ENetEvent& event);
     void processOutgoingEvent(outgoingEvent& event);
+    
+    void disconnectPeersInternal();
 
     ENetHost*                     host_;
@@ -140,9 +143,8 @@
     boost::mutex*                 incomingEventsMutex_;
     boost::mutex*                 outgoingEventsMutex_;
+    boost::mutex*                 overallMutex_;
     std::map<uint32_t, ENetPeer*> peerMap_;
     std::map<ENetPeer*, uint32_t> peerIDMap_;
     uint32_t                      nextPeerID_;
-
-//     static Connection *instance_;
 
   };
Index: /code/branches/network6/src/libraries/network/GamestateHandler.h
===================================================================
--- /code/branches/network6/src/libraries/network/GamestateHandler.h	(revision 7877)
+++ /code/branches/network6/src/libraries/network/GamestateHandler.h	(revision 7878)
@@ -51,5 +51,5 @@
     virtual bool      addGamestate(packet::Gamestate* gs, unsigned int clientID) = 0;
     virtual bool      ackGamestate(unsigned int gamestateID, unsigned int clientID) = 0;
-    virtual uint32_t  getLastProcessedGamestateID( unsigned int clientID )=0;
+    virtual uint32_t  getLastReceivedGamestateID( unsigned int clientID )=0;
     virtual uint32_t  getCurrentGamestateID()=0;
 };
Index: /code/branches/network6/src/libraries/network/GamestateManager.cc
===================================================================
--- /code/branches/network6/src/libraries/network/GamestateManager.cc	(revision 7877)
+++ /code/branches/network6/src/libraries/network/GamestateManager.cc	(revision 7878)
@@ -110,5 +110,5 @@
       bool b = processGamestate(it->second);
       assert(b);
-      sendAck( it->second->getID(), it->second->getPeerID() );
+//       sendAck( it->second->getID(), it->second->getPeerID() );
       delete it->second;
     }
@@ -122,4 +122,5 @@
   bool GamestateManager::sendAck(unsigned int gamestateID, uint32_t peerID)
   {
+    assert( gamestateID != ACKID_NACK );
     packet::Acknowledgement *ack = new packet::Acknowledgement(gamestateID, peerID);
     if( !this->sendPacket(ack))
@@ -151,5 +152,5 @@
     {
       assert(peerMap_.size()!=0);
-      newID = peerMap_[NETWORK_PEER_ID_SERVER].lastProcessedGamestateID;
+      newID = peerMap_[NETWORK_PEER_ID_SERVER].lastReceivedGamestateID;
     }
     
@@ -190,5 +191,5 @@
       }
 
-      peerGamestates.push_back(0);  // insert an empty gamestate* to change
+      peerGamestates.push_back(0);  // insert an empty gamestate* to be changed
       finishGamestate( peerID, peerGamestates.back(), baseGamestate, currentGamestate_ );
       if( peerGamestates.back()==0 )
@@ -266,15 +267,16 @@
     unsigned int curid = it->second.lastAckedGamestateID;
 
-    if(gamestateID == ACKID_NACK){
-      it->second.lastAckedGamestateID = GAMESTATEID_INITIAL;
-//       temp->setGamestateID(GAMESTATEID_INITIAL);
-      // now delete all saved gamestates for this client
-      std::map<uint32_t, packet::Gamestate*>::iterator it2;
-      for(it2 = it->second.gamestates.begin(); it2!=it->second.gamestates.end(); ++it2 ){
-        delete it2->second;
-      }
-      it->second.gamestates.clear();
-      return true;
-    }
+    assert(gamestateID != ACKID_NACK);
+//     if(gamestateID == ACKID_NACK){
+//       it->second.lastAckedGamestateID = GAMESTATEID_INITIAL;
+// //       temp->setGamestateID(GAMESTATEID_INITIAL);
+//       // now delete all saved gamestates for this client
+//       std::map<uint32_t, packet::Gamestate*>::iterator it2;
+//       for(it2 = it->second.gamestates.begin(); it2!=it->second.gamestates.end(); ++it2 ){
+//         delete it2->second;
+//       }
+//       it->second.gamestates.clear();
+//       return true;
+//     }
 
     assert(curid==GAMESTATEID_INITIAL || curid<=gamestateID);
@@ -303,9 +305,9 @@
   }
   
-  uint32_t GamestateManager::getLastProcessedGamestateID(unsigned int peerID)
+  uint32_t GamestateManager::getLastReceivedGamestateID(unsigned int peerID)
   {
     assert( this->peerMap_.find(peerID)!=this->peerMap_.end() );
     if( this->peerMap_.find(peerID) != this->peerMap_.end() )
-      return this->peerMap_[peerID].lastProcessedGamestateID;
+      return this->peerMap_[peerID].lastReceivedGamestateID;
     else
       return GAMESTATEID_INITIAL;
@@ -317,5 +319,5 @@
     assert(peerMap_.find(peerID)==peerMap_.end());
     peerMap_[peerID].peerID = peerID;
-    peerMap_[peerID].lastProcessedGamestateID = GAMESTATEID_INITIAL;
+    peerMap_[peerID].lastReceivedGamestateID = GAMESTATEID_INITIAL;
     peerMap_[peerID].lastAckedGamestateID = GAMESTATEID_INITIAL;
     if( GameMode::isMaster() )
@@ -363,5 +365,5 @@
     if( gs->spreadData(gsMode) )
     {
-      this->peerMap_[gs->getPeerID()].lastProcessedGamestateID = gs->getID();
+      this->peerMap_[gs->getPeerID()].lastReceivedGamestateID = gs->getID();
       return true;
     }
Index: /code/branches/network6/src/libraries/network/GamestateManager.h
===================================================================
--- /code/branches/network6/src/libraries/network/GamestateManager.h	(revision 7877)
+++ /code/branches/network6/src/libraries/network/GamestateManager.h	(revision 7878)
@@ -73,6 +73,6 @@
     {
       uint32_t  peerID;
-      uint32_t  lastProcessedGamestateID;
-      uint32_t  lastAckedGamestateID;
+      uint32_t  lastReceivedGamestateID;  //!< id of the last gamestate which was received (and processed) from the peer
+      uint32_t  lastAckedGamestateID;     //!< id of the last gamestate on which we received an ack from the peer
       bool      isSynched;
       std::map< uint32_t, packet::Gamestate* > gamestates;
@@ -86,5 +86,5 @@
     virtual bool      addGamestate(packet::Gamestate *gs, unsigned int peerID);
     virtual bool      ackGamestate(unsigned int gamestateID, unsigned int peerID);
-    virtual uint32_t  getLastProcessedGamestateID( unsigned int peerID );
+    virtual uint32_t  getLastReceivedGamestateID( unsigned int peerID );
     virtual uint32_t  getCurrentGamestateID(){ return currentGamestate_->getID(); }
     
Index: /code/branches/network6/src/libraries/network/Server.cc
===================================================================
--- /code/branches/network6/src/libraries/network/Server.cc	(revision 7877)
+++ /code/branches/network6/src/libraries/network/Server.cc	(revision 7878)
@@ -380,5 +380,5 @@
     if( packet->isReliable() )
     {
-      if( this->getLastProcessedGamestateID(packet->getPeerID()) >= packet->getRequiredGamestateID() )
+      if( this->getLastReceivedGamestateID(packet->getPeerID()) >= packet->getRequiredGamestateID() )
         packet->process(static_cast<Host*>(this));
       else
Index: /code/branches/network6/src/libraries/network/ServerConnection.cc
===================================================================
--- /code/branches/network6/src/libraries/network/ServerConnection.cc	(revision 7877)
+++ /code/branches/network6/src/libraries/network/ServerConnection.cc	(revision 7878)
@@ -35,4 +35,5 @@
 
 #include "util/Debug.h"
+#include <util/Sleep.h>
 // #include "ClientInformation.h"
 
@@ -133,10 +134,5 @@
   {
     Connection::disconnectPeers();
-//     ClientInformation *temp = ClientInformation::getBegin();
-//     while(temp!=0)
-//     {
-//       ServerConnection::disconnectClient( temp );
-//       temp = temp->next();
-//     }
+    Connection::waitOutgoingQueue();
     return;
   }
