Index: code/branches/presentation2/src/libraries/network/packet/Acknowledgement.cc
===================================================================
--- code/branches/presentation2/src/libraries/network/packet/Acknowledgement.cc	(revision 7787)
+++ code/branches/presentation2/src/libraries/network/packet/Acknowledgement.cc	(revision 7788)
@@ -31,4 +31,5 @@
 #include "util/Debug.h"
 #include "network/GamestateHandler.h"
+#include "network/Host.h"
 
 namespace orxonox {
@@ -39,5 +40,5 @@
 #define _ACKID              _PACKETID + sizeof(packet::Type::Value)
 
-Acknowledgement::Acknowledgement( unsigned int id, unsigned int clientID )
+Acknowledgement::Acknowledgement( unsigned int id, unsigned int peerID )
  : Packet()
 {
@@ -46,9 +47,9 @@
   *(Type::Value *)(data_ + _PACKETID ) = Type::Acknowledgement;
   *(uint32_t *)(data_ + _ACKID ) = id;
-  clientID_=clientID;
+  peerID_=peerID;
 }
 
-Acknowledgement::Acknowledgement( uint8_t *data, unsigned int clientID )
-  : Packet(data, clientID)
+Acknowledgement::Acknowledgement( uint8_t *data, unsigned int peerID )
+  : Packet(data, peerID)
 {
 }
@@ -62,7 +63,7 @@
 }
 
-bool Acknowledgement::process(){
+bool Acknowledgement::process(orxonox::Host* host){
   COUT(5) << "processing ACK with ID: " << getAckID() << endl;
-  bool b = GamestateHandler::ackGamestate(getAckID(), clientID_);
+  bool b = host->ackGamestate(getAckID(), peerID_);
   delete this;
   return b;
Index: code/branches/presentation2/src/libraries/network/packet/Acknowledgement.h
===================================================================
--- code/branches/presentation2/src/libraries/network/packet/Acknowledgement.h	(revision 7787)
+++ code/branches/presentation2/src/libraries/network/packet/Acknowledgement.h	(revision 7788)
@@ -42,10 +42,10 @@
 {
 public:
-  Acknowledgement( unsigned int id, unsigned int clientID );
-  Acknowledgement( uint8_t* data, unsigned int clientID );
+  Acknowledgement( unsigned int id, unsigned int peerID );
+  Acknowledgement( uint8_t* data, unsigned int peerID );
   ~Acknowledgement();
 
   inline unsigned int getSize() const;
-  bool process();
+  virtual bool process(orxonox::Host* host);
 
   unsigned int getAckID();
Index: code/branches/presentation2/src/libraries/network/packet/Chat.cc
===================================================================
--- code/branches/presentation2/src/libraries/network/packet/Chat.cc	(revision 7787)
+++ code/branches/presentation2/src/libraries/network/packet/Chat.cc	(revision 7788)
@@ -80,6 +80,6 @@
 }
 
-bool Chat::process(){
-  bool b = Host::incomingChat(std::string((const char*)data_+_MESSAGE), *(uint32_t *)(data_+_PLAYERID));
+bool Chat::process(orxonox::Host* host){
+  bool b = host->incomingChat(std::string((const char*)data_+_MESSAGE), *(uint32_t *)(data_+_PLAYERID));
   delete this;
   return b;
Index: code/branches/presentation2/src/libraries/network/packet/Chat.h
===================================================================
--- code/branches/presentation2/src/libraries/network/packet/Chat.h	(revision 7787)
+++ code/branches/presentation2/src/libraries/network/packet/Chat.h	(revision 7788)
@@ -52,5 +52,5 @@
 
   /* process chat message packet and remove it afterwards */
-  bool process();
+  virtual bool process(orxonox::Host* host);
 
   /* Get the length of the message (not the full size of the packet) */
Index: code/branches/presentation2/src/libraries/network/packet/ClassID.cc
===================================================================
--- code/branches/presentation2/src/libraries/network/packet/ClassID.cc	(revision 7787)
+++ code/branches/presentation2/src/libraries/network/packet/ClassID.cc	(revision 7788)
@@ -120,5 +120,5 @@
 
 
-bool ClassID::process(){
+bool ClassID::process(orxonox::Host* host){
   int nrOfClasses;
   uint8_t *temp = data_+sizeof(uint32_t); //skip the packetid
Index: code/branches/presentation2/src/libraries/network/packet/ClassID.h
===================================================================
--- code/branches/presentation2/src/libraries/network/packet/ClassID.h	(revision 7787)
+++ code/branches/presentation2/src/libraries/network/packet/ClassID.h	(revision 7788)
@@ -48,5 +48,5 @@
 
   uint32_t getSize() const;
-  bool process();
+  virtual bool process(orxonox::Host* host);
 
 private:
Index: code/branches/presentation2/src/libraries/network/packet/DeleteObjects.cc
===================================================================
--- code/branches/presentation2/src/libraries/network/packet/DeleteObjects.cc	(revision 7787)
+++ code/branches/presentation2/src/libraries/network/packet/DeleteObjects.cc	(revision 7788)
@@ -57,5 +57,6 @@
 }
 
-bool DeleteObjects::fetchIDs(){
+bool DeleteObjects::fetchIDs()
+{
   unsigned int number = Synchronisable::getNumberOfDeletedObject();
   if(number==0)
@@ -79,11 +80,14 @@
 }
 
-unsigned int DeleteObjects::getSize() const{
+unsigned int DeleteObjects::getSize() const
+{
   assert(data_);
   return _OBJECTIDS + *(uint32_t*)(data_+_QUANTITY)*sizeof(uint32_t);
 }
 
-bool DeleteObjects::process(){
-  for(unsigned int i=0; i<*(unsigned int *)(data_+_QUANTITY); i++){
+bool DeleteObjects::process(orxonox::Host* host)
+{
+  for(unsigned int i=0; i<*(unsigned int *)(data_+_QUANTITY); i++)
+  {
     COUT(4) << "deleting object with id: " << *(uint32_t*)(data_+_OBJECTIDS+i*sizeof(uint32_t)) << std::endl;
     Synchronisable::deleteObject( *(uint32_t*)(data_+_OBJECTIDS+i*sizeof(uint32_t)) );
Index: code/branches/presentation2/src/libraries/network/packet/DeleteObjects.h
===================================================================
--- code/branches/presentation2/src/libraries/network/packet/DeleteObjects.h	(revision 7787)
+++ code/branches/presentation2/src/libraries/network/packet/DeleteObjects.h	(revision 7788)
@@ -32,6 +32,8 @@
 #include "Packet.h"
 
-namespace orxonox {
-namespace packet {
+namespace orxonox
+{
+namespace packet
+{
 /**
     @author
@@ -47,5 +49,5 @@
 
   inline unsigned int getSize() const;
-  bool process();
+  virtual bool process(orxonox::Host* host);
 
 private:
Index: code/branches/presentation2/src/libraries/network/packet/FunctionCalls.cc
===================================================================
--- code/branches/presentation2/src/libraries/network/packet/FunctionCalls.cc	(revision 7787)
+++ code/branches/presentation2/src/libraries/network/packet/FunctionCalls.cc	(revision 7788)
@@ -32,4 +32,5 @@
 #include "network/FunctionCall.h"
 #include "network/FunctionCallManager.h"
+#include "network/GamestateHandler.h"
 
 namespace orxonox {
@@ -40,13 +41,13 @@
 const unsigned int FUNCTIONCALLS_MEM_ALLOCATION = 1000;
 
-FunctionCalls::FunctionCalls()
- : Packet()
+FunctionCalls::FunctionCalls():
+  Packet(), minGamestateID_(GAMESTATEID_INITIAL)
 {
   flags_ = flags_ | PACKET_FLAGS_FUNCTIONCALLS;
-  currentSize_ = 2*sizeof(uint32_t); // for packetid and nrOfCalls
+  currentSize_ = 3*sizeof(uint32_t); // for packetid, nrOfCalls and minGamestateID_
 }
 
-FunctionCalls::FunctionCalls( uint8_t* data, unsigned int clientID )
-  : Packet(data, clientID)
+FunctionCalls::FunctionCalls( uint8_t* data, unsigned int clientID ): 
+  Packet(data, clientID), minGamestateID_(GAMESTATEID_INITIAL)
 {
 }
@@ -57,9 +58,12 @@
 
 
-bool FunctionCalls::process(){
+bool FunctionCalls::process(orxonox::Host* host)
+{
   assert(isDataENetAllocated());
   
   uint8_t* temp = data_+sizeof(uint32_t); //skip packetid
   uint32_t nrOfCalls = *(uint32_t*)temp;
+  temp += sizeof(uint32_t);
+  this->minGamestateID_ = *(uint32_t*)temp;
   temp += sizeof(uint32_t);
   for( unsigned int i = 0; i<nrOfCalls; i++ )
@@ -68,5 +72,7 @@
     fctCall.loadData(temp);
     if( !fctCall.execute() )
-      FunctionCallManager::bufferIncomingFunctionCall( fctCall );
+    {
+      FunctionCallManager::bufferIncomingFunctionCall( fctCall, minGamestateID_, this->getPeerID() );
+    }
   }
   
@@ -75,5 +81,6 @@
 }
 
-void FunctionCalls::addCallStatic( uint32_t networkID, const MultiType* mt1, const MultiType* mt2, const MultiType* mt3, const MultiType* mt4, const MultiType* mt5){
+void FunctionCalls::addCallStatic( uint32_t networkID, const MultiType* mt1, const MultiType* mt2, const MultiType* mt3, const MultiType* mt4, const MultiType* mt5)
+{
   assert(!isDataENetAllocated());
   
@@ -83,5 +90,6 @@
 }
 
-void FunctionCalls::addCallMember( uint32_t networkID, uint32_t objectID, const MultiType* mt1, const MultiType* mt2, const MultiType* mt3, const MultiType* mt4, const MultiType* mt5){
+void FunctionCalls::addCallMember( uint32_t networkID, uint32_t objectID, const MultiType* mt1, const MultiType* mt2, const MultiType* mt3, const MultiType* mt4, const MultiType* mt5)
+{
   assert(!isDataENetAllocated());
   
@@ -91,11 +99,13 @@
 }
 
-bool FunctionCalls::send()
+bool FunctionCalls::send(orxonox::Host* host)
 {
+  this->minGamestateID_ = host->getCurrentGamestateID();
   assert(this->functionCalls_.size());
   data_=new uint8_t[ currentSize_ ];
   *(Type::Value *)(data_ + _PACKETID ) = Type::FunctionCalls; // Set the Packet ID
-  *(uint32_t*)(data_+sizeof(uint32_t)) = this->functionCalls_.size(); // set nrOfCalls to 0
-  uint8_t* temp = data_+2*sizeof(uint32_t);
+  *(uint32_t*)(data_+sizeof(uint32_t)) = this->functionCalls_.size(); // set nrOfCalls
+  *(uint32_t*)(data_+2*sizeof(uint32_t)) = this->minGamestateID_; // set minGamestateID_
+  uint8_t* temp = data_+3*sizeof(uint32_t);
   
   while( this->functionCalls_.size() )
@@ -107,5 +117,5 @@
   assert( temp==data_+currentSize_ );
   
-  Packet::send();
+  Packet::send(host);
   return true;
 }
Index: code/branches/presentation2/src/libraries/network/packet/FunctionCalls.h
===================================================================
--- code/branches/presentation2/src/libraries/network/packet/FunctionCalls.h	(revision 7787)
+++ code/branches/presentation2/src/libraries/network/packet/FunctionCalls.h	(revision 7788)
@@ -54,12 +54,13 @@
   inline unsigned int getSize() const
     { assert(!this->isDataENetAllocated()); return currentSize_; }
-  bool process();
+  virtual bool process(orxonox::Host* host);
 
   void addCallStatic( uint32_t networkID, const MultiType* mt1=0, const MultiType* mt2=0, const MultiType* mt3=0, const MultiType* mt4=0, const MultiType* mt5=0);
   void addCallMember( uint32_t networkID, uint32_t objectID, const MultiType* mt1=0, const MultiType* mt2=0, const MultiType* mt3=0, const MultiType* mt4=0, const MultiType* mt5=0);
-  virtual bool send();
+  virtual bool send(orxonox::Host* host);
 private:
   std::queue<orxonox::FunctionCall> functionCalls_;
   unsigned int                      clientID_;
+  uint32_t                          minGamestateID_;
   uint32_t                          currentSize_;
 };
Index: code/branches/presentation2/src/libraries/network/packet/FunctionIDs.cc
===================================================================
--- code/branches/presentation2/src/libraries/network/packet/FunctionIDs.cc	(revision 7787)
+++ code/branches/presentation2/src/libraries/network/packet/FunctionIDs.cc	(revision 7788)
@@ -46,5 +46,6 @@
 
 
-FunctionIDs::FunctionIDs( ) : Packet(){
+FunctionIDs::FunctionIDs( ) : Packet()
+{
   unsigned int nrOfFunctions=0;
   unsigned int packetSize=2*sizeof(uint32_t); //space for the packetID and for the nroffunctions
@@ -55,5 +56,6 @@
   //calculate total needed size (for all strings and integers)
   ObjectList<NetworkFunctionBase>::iterator it;
-  for(it = ObjectList<NetworkFunctionBase>::begin(); it; ++it){
+  for(it = ObjectList<NetworkFunctionBase>::begin(); it; ++it)
+  {
     const std::string& functionname = it->getName();
     networkID = it->getNetworkID();
@@ -76,5 +78,6 @@
   // now save all classids and classnames
   std::pair<uint32_t, std::string> tempPair;
-  while( !tempQueue.empty() ){
+  while( !tempQueue.empty() )
+  {
     tempPair = tempQueue.front();
     tempQueue.pop();
@@ -98,5 +101,6 @@
 }
 
-uint32_t FunctionIDs::getSize() const{
+uint32_t FunctionIDs::getSize() const
+{
   assert(this->data_);
   uint8_t *temp = data_+sizeof(uint32_t); // packet identification
@@ -114,5 +118,6 @@
 
 
-bool FunctionIDs::process(){
+bool FunctionIDs::process(orxonox::Host* host)
+{
   int nrOfFunctions;
   uint8_t *temp = data_+sizeof(uint32_t); //skip the packetid
@@ -127,5 +132,6 @@
   temp += sizeof(uint32_t);
 
-  for( int i=0; i<nrOfFunctions; i++){
+  for( int i=0; i<nrOfFunctions; i++)
+  {
     networkID = *(uint32_t*)temp;
     stringsize = *(uint32_t*)(temp+sizeof(uint32_t));
Index: code/branches/presentation2/src/libraries/network/packet/FunctionIDs.h
===================================================================
--- code/branches/presentation2/src/libraries/network/packet/FunctionIDs.h	(revision 7787)
+++ code/branches/presentation2/src/libraries/network/packet/FunctionIDs.h	(revision 7788)
@@ -47,6 +47,6 @@
   ~FunctionIDs();
 
-  uint32_t getSize() const;
-  bool process();
+  virtual uint32_t getSize() const;
+  virtual bool process(orxonox::Host* host);
 
 private:
Index: code/branches/presentation2/src/libraries/network/packet/Gamestate.cc
===================================================================
--- code/branches/presentation2/src/libraries/network/packet/Gamestate.cc	(revision 7787)
+++ code/branches/presentation2/src/libraries/network/packet/Gamestate.cc	(revision 7788)
@@ -36,4 +36,5 @@
 #include "network/synchronisable/Synchronisable.h"
 #include "network/GamestateHandler.h"
+#include "network/Host.h"
 
 namespace orxonox {
@@ -43,5 +44,6 @@
 #define GAMESTATE_START(data) (data + GamestateHeader::getSize())
 
-#define PACKET_FLAG_GAMESTATE  PacketFlag::Reliable
+// #define PACKET_FLAG_GAMESTATE  PacketFlag::Reliable
+#define PACKET_FLAG_GAMESTATE  0
 
 inline bool memzero( uint8_t* data, uint32_t datalength)
@@ -65,5 +67,5 @@
 
 Gamestate::Gamestate():
-  header_(0)
+  header_()
 {
   flags_ = flags_ | PACKET_FLAG_GAMESTATE;
@@ -72,24 +74,22 @@
 
 Gamestate::Gamestate(uint8_t *data, unsigned int clientID):
-  Packet(data, clientID)
+  Packet(data, clientID), header_(data)
 {
   flags_ = flags_ | PACKET_FLAG_GAMESTATE;
-  header_ = new GamestateHeader(data_);
-}
-
-
-Gamestate::Gamestate(uint8_t *data)
+}
+
+
+Gamestate::Gamestate(uint8_t *data):
+  header_(data)
 {
   flags_ = flags_ | PACKET_FLAG_GAMESTATE;
   data_ = data;
-  header_ = new GamestateHeader(data_);
 }
 
 
 Gamestate::Gamestate(const Gamestate& g) :
-    Packet( *(Packet*)&g ), nrOfVariables_(0)
+  Packet( *(Packet*)&g ), header_(this->data_), nrOfVariables_(0)
 {
   flags_ = flags_ | PACKET_FLAG_GAMESTATE;
-  header_ = new GamestateHeader(data_);
   sizes_ = g.sizes_;
 }
@@ -98,6 +98,4 @@
 Gamestate::~Gamestate()
 {
-  if( header_ )
-    delete header_;
 }
 
@@ -105,5 +103,4 @@
 bool Gamestate::collectData(int id, uint8_t mode)
 {
-  assert(this->header_==0); // make sure the header didn't exist before
   uint32_t tempsize=0, currentsize=0;
   assert(data_==0);
@@ -120,7 +117,6 @@
   }
 
-  // create the header object
-  assert( header_ == 0 );
-  header_ = new GamestateHeader(data_);
+  // tell the gamestate header where to store the data
+  header_.setData(this->data_);
 
   //start collect data synchronisable by synchronisable
@@ -142,5 +138,5 @@
       assert(0); // if we don't use multithreading this part shouldn't be neccessary
       // start allocate additional memory
-      COUT(3) << "G.St.Man: need additional memory" << std::endl;
+      COUT(3) << "Gamestate: need additional memory" << std::endl;
       ObjectList<Synchronisable>::iterator temp = it;
       uint32_t addsize=tempsize;
@@ -161,14 +157,14 @@
 
   //start write gamestate header
-  header_->setDataSize( currentsize );
-  header_->setID( id );
-  header_->setBaseID( GAMESTATEID_INITIAL );
-  header_->setDiffed( false );
-  header_->setComplete( true );
-  header_->setCompressed( false );
+  header_.setDataSize( currentsize );
+  header_.setID( id );
+  header_.setBaseID( GAMESTATEID_INITIAL );
+  header_.setDiffed( false );
+  header_.setComplete( true );
+  header_.setCompressed( false );
   //stop write gamestate header
 
-  COUT(5) << "G.ST.Man: Gamestate size: " << currentsize << std::endl;
-  COUT(5) << "G.ST.Man: 'estimated' (and corrected) Gamestate size: " << size << std::endl;
+  COUT(5) << "Gamestate: Gamestate size: " << currentsize << std::endl;
+  COUT(5) << "Gamestate: 'estimated' (and corrected) Gamestate size: " << size << std::endl;
   return true;
 }
@@ -177,12 +173,12 @@
 bool Gamestate::spreadData(uint8_t mode)
 {
-  COUT(4) << "processing gamestate with id " << header_->getID() << endl;
+  COUT(5) << "processing gamestate with id " << header_.getID() << endl;
   assert(data_);
-  assert(!header_->isCompressed());
+  assert(!header_.isCompressed());
   uint8_t *mem=data_+GamestateHeader::getSize();
   Synchronisable *s;
-
+  
   // update the data of the objects we received
-  while(mem < data_+GamestateHeader::getSize()+header_->getDataSize())
+  while(mem < data_+GamestateHeader::getSize()+header_.getDataSize())
   {
     SynchronisableHeader objectheader(mem);
@@ -197,4 +193,5 @@
       else
       {
+//         COUT(4) << "not creating object of classid " << objectheader.getClassID() << endl;
         mem += objectheader.getDataSize() + ( objectheader.isDiffed() ? SynchronisableHeaderLight::getSize() : SynchronisableHeader::getSize() );
       }
@@ -202,8 +199,11 @@
     else
     {
+//       COUT(4) << "updating object of classid " << objectheader.getClassID() << endl;
       bool b = s->updateData(mem, mode);
       assert(b);
     }
   }
+  assert(mem-data_ == GamestateHeader::getSize()+header_.getDataSize());
+  
    // In debug mode, check first, whether there are no duplicate objectIDs
 #ifndef NDEBUG
@@ -249,9 +249,9 @@
 {
   assert(data_);
-  if(header_->isCompressed())
-    return header_->getCompSize()+GamestateHeader::getSize();
+  if(header_.isCompressed())
+    return header_.getCompSize()+GamestateHeader::getSize();
   else
   {
-    return header_->getDataSize()+GamestateHeader::getSize();
+    return header_.getDataSize()+GamestateHeader::getSize();
   }
 }
@@ -271,7 +271,7 @@
 
 
-bool Gamestate::process()
-{
-  return GamestateHandler::addGamestate(this, getClientID());
+bool Gamestate::process(orxonox::Host* host)
+{
+  return host->addGamestate(this, getPeerID());
 }
 
@@ -280,6 +280,6 @@
 {
   assert(data_);
-  assert(!header_->isCompressed());
-  uLongf buffer = (uLongf)(((header_->getDataSize() + 12)*1.01)+1);
+  assert(!header_.isCompressed());
+  uLongf buffer = (uLongf)(((header_.getDataSize() + 12)*1.01)+1);
   if(buffer==0)
     return false;
@@ -289,5 +289,5 @@
   uint8_t *source = data_ + GamestateHeader::getSize();
   int retval;
-  retval = compress( dest, &buffer, source, (uLong)(header_->getDataSize()) );
+  retval = compress( dest, &buffer, source, (uLong)(header_.getDataSize()) );
   switch ( retval )
   {
@@ -299,6 +299,7 @@
 
   //copy and modify header
-  GamestateHeader *temp = header_;
-  header_ = new GamestateHeader(ndata, temp);
+  GamestateHeader *temp = new GamestateHeader(data_);
+  header_.setData(ndata);
+  header_ = *temp;
   delete temp;
   //delete old data
@@ -306,7 +307,7 @@
   //save new data
   data_ = ndata;
-  header_->setCompSize( buffer );
-  header_->setCompressed( true );
-  COUT(0) << "gamestate compress datasize: " << header_->getDataSize() << " compsize: " << header_->getCompSize() << std::endl;
+  header_.setCompSize( buffer );
+  header_.setCompressed( true );
+  COUT(4) << "gamestate compress datasize: " << header_.getDataSize() << " compsize: " << header_.getCompSize() << std::endl;
   return true;
 }
@@ -316,8 +317,8 @@
 {
   assert(data_);
-  assert(header_->isCompressed());
-  COUT(4) << "GameStateClient: uncompressing gamestate. id: " << header_->getID() << ", baseid: " << header_->getBaseID() << ", datasize: " << header_->getDataSize() << ", compsize: " << header_->getCompSize() << std::endl;
-  uint32_t datasize = header_->getDataSize();
-  uint32_t compsize = header_->getCompSize();
+  assert(header_.isCompressed());
+  COUT(4) << "GameStateClient: uncompressing gamestate. id: " << header_.getID() << ", baseid: " << header_.getBaseID() << ", datasize: " << header_.getDataSize() << ", compsize: " << header_.getCompSize() << std::endl;
+  uint32_t datasize = header_.getDataSize();
+  uint32_t compsize = header_.getCompSize();
   uint32_t bufsize;
   bufsize = datasize;
@@ -338,6 +339,7 @@
 
   //copy over the header
-  GamestateHeader *temp = header_;
-  header_ = new GamestateHeader( data_, header_ );
+  GamestateHeader* temp = new GamestateHeader( data_ );
+  header_.setData(ndata);
+  header_ = *temp;
   delete temp;
 
@@ -357,219 +359,236 @@
   //set new pointers
   data_ = ndata;
-  header_->setCompressed( false );
-  assert(header_->getDataSize()==datasize);
-  assert(header_->getCompSize()==compsize);
+  header_.setCompressed( false );
+  assert(header_.getDataSize()==datasize);
+  assert(header_.getCompSize()==compsize);
   return true;
 }
 
 
+inline void /*Gamestate::*/diffObject( uint8_t*& newDataPtr, uint8_t*& origDataPtr, uint8_t*& baseDataPtr, SynchronisableHeader& objectHeader, std::vector<uint32_t>::iterator& sizes )
+{
+  assert( objectHeader.getDataSize() == SynchronisableHeader(baseDataPtr).getDataSize() );
+  
+  uint32_t objectOffset = SynchronisableHeader::getSize(); // offset inside the object in the origData and baseData
+  // Check whether the whole object stayed the same
+  if( memcmp( origDataPtr+objectOffset, baseDataPtr+objectOffset, objectHeader.getDataSize()) == 0 )
+  {
+//     COUT(4) << "skip object " << Synchronisable::getSynchronisable(objectHeader.getObjectID())->getIdentifier()->getName() << endl;
+    origDataPtr += objectOffset + objectHeader.getDataSize(); // skip the whole object
+    baseDataPtr += objectOffset + objectHeader.getDataSize();
+    sizes += Synchronisable::getSynchronisable(objectHeader.getObjectID())->getNrOfVariables();
+  }
+  else
+  {
+    // Now start to diff the Object
+    SynchronisableHeaderLight newObjectHeader(newDataPtr);
+    newObjectHeader = objectHeader; // copy over the objectheader
+    VariableID variableID = 0;
+    uint32_t diffedObjectOffset = SynchronisableHeaderLight::getSize();
+    // iterate through all variables
+    while( objectOffset < objectHeader.getDataSize()+SynchronisableHeader::getSize() )
+    {
+      // check whether variable changed and write id and copy over variable to the new stream
+      // otherwise skip variable
+      uint32_t varSize = *sizes;
+      assert( varSize == Synchronisable::getSynchronisable(objectHeader.getObjectID())->getVarSize(variableID) );
+      if ( varSize != 0 )
+      {
+        if ( memcmp(origDataPtr+objectOffset, baseDataPtr+objectOffset, varSize) != 0 )
+        {
+          *(VariableID*)(newDataPtr+diffedObjectOffset) = variableID; // copy over the variableID
+          diffedObjectOffset += sizeof(VariableID);
+          memcpy( newDataPtr+diffedObjectOffset, origDataPtr+objectOffset, varSize );
+          diffedObjectOffset += varSize;
+          objectOffset += varSize;
+        }
+        else
+        {
+          objectOffset += varSize;
+        }
+      }
+
+      ++variableID;
+      ++sizes;
+    }
+    
+    // if there are variables from this object with 0 size left in sizes
+    if( Synchronisable::getSynchronisable(objectHeader.getObjectID())->getNrOfVariables() != variableID )
+      sizes += Synchronisable::getSynchronisable(objectHeader.getObjectID())->getNrOfVariables() - variableID;
+    
+    newObjectHeader.setDiffed(true);
+    newObjectHeader.setDataSize(diffedObjectOffset-SynchronisableHeaderLight::getSize());
+    assert(objectOffset == objectHeader.getDataSize()+SynchronisableHeader::getSize());
+    assert(newObjectHeader.getDataSize()>0);
+    
+    origDataPtr += objectOffset;
+    baseDataPtr += objectOffset;
+    newDataPtr += diffedObjectOffset;
+  }
+}
+
+inline void /*Gamestate::*/copyObject( uint8_t*& newData, uint8_t*& origData, uint8_t*& baseData, SynchronisableHeader& objectHeader, std::vector<uint32_t>::iterator& sizes )
+{
+  //       COUT(4) << "docopy" << endl;
+  // Just copy over the whole Object
+  memcpy( newData, origData, objectHeader.getDataSize()+SynchronisableHeader::getSize() );
+  SynchronisableHeader(newData).setDiffed(false);
+  
+  newData += objectHeader.getDataSize()+SynchronisableHeader::getSize();
+  origData += objectHeader.getDataSize()+SynchronisableHeader::getSize();
+//   SynchronisableHeader baseHeader( baseData );
+//   baseData += baseHeader.getDataSize()+SynchronisableHeader::getSize();
+  //       COUT(4) << "copy " << h.getObjectID() << endl;
+  //       COUT(4) << "copy " << h.getObjectID() << ":";
+  sizes += Synchronisable::getSynchronisable(objectHeader.getObjectID())->getNrOfVariables();
+//   for( unsigned int i = 0; i < Synchronisable::getSynchronisable(objectHeader.getObjectID())->getNrOfVariables(); ++i )
+//   {
+//     //         COUT(4) << " " << *sizes;
+//     ++sizes;
+//   }
+    //       COUT(4) << endl;
+}
+
+inline bool findObject(uint8_t*& dataPtr, uint8_t* endPtr, SynchronisableHeader& objectHeader)
+{
+  // Some assertions to make sure the dataPtr is valid (pointing to a SynchronisableHeader)
+  {
+    SynchronisableHeader htemp2(dataPtr);
+    assert(htemp2.getClassID()<500);
+    assert(htemp2.getDataSize()!=0 && htemp2.getDataSize()<1000);
+    assert(htemp2.isDiffed()==false);
+  }
+  uint32_t objectID = objectHeader.getObjectID();
+  while ( dataPtr < endPtr )
+  {
+    SynchronisableHeader htemp(dataPtr);
+    assert( htemp.getDataSize()!=0 );
+    if ( htemp.getObjectID() == objectID )
+    {
+      assert( objectHeader.getClassID() == htemp.getClassID() );
+      assert( objectHeader.getCreatorID() == htemp.getCreatorID() );
+      return true;
+    }
+    {
+      if( dataPtr+htemp.getDataSize()+SynchronisableHeader::getSize() < endPtr )
+      {
+        SynchronisableHeader htemp2(dataPtr+htemp.getDataSize()+SynchronisableHeader::getSize());
+        assert(htemp2.getClassID()<500);
+        assert(htemp2.getDataSize()!=0 && htemp2.getDataSize()<1000);
+        assert(htemp2.isDiffed()==false);
+      }
+    }
+    dataPtr += htemp.getDataSize()+SynchronisableHeader::getSize();
+    
+  }
+  assert(dataPtr == endPtr);
+  
+  return false;
+}
+
 Gamestate* Gamestate::diffVariables(Gamestate *base)
 {
   assert(this && base); assert(data_ && base->data_);
-  assert(!header_->isCompressed() && !base->header_->isCompressed());
-  assert(!header_->isDiffed());
+  assert(!header_.isCompressed() && !base->header_.isCompressed());
+  assert(!header_.isDiffed());
+  assert( header_.getDataSize() && base->header_.getDataSize() );
 
 
   // *** first do a raw diff of the two gamestates
 
-  uint8_t *baseData = GAMESTATE_START(base->data_);
-  uint8_t *origData = GAMESTATE_START(this->data_);
-  uint32_t origLength = header_->getDataSize();
-  uint32_t baseLength = base->header_->getDataSize();
-
-  assert( origLength && baseLength );
-
-  uint8_t *nData = new uint8_t[origLength + GamestateHeader::getSize() + sizeof(uint32_t)*this->nrOfVariables_]; // this is the maximum size needed in the worst case
-  uint8_t *dest = GAMESTATE_START(nData);
-
-  uint32_t baseOffset = 0; //offset in the diffed stream
-  uint32_t origOffset = 0; //offset in the new stream with removed 0's
-  std::vector<uint32_t>::iterator sizes = this->sizes_.begin();
-
-  while( origOffset < origLength )
+  uint8_t *baseDataPtr = GAMESTATE_START(base->data_);
+  uint8_t *origDataPtr = GAMESTATE_START(this->data_);
+  uint8_t *origDataEnd = origDataPtr + header_.getDataSize();
+  uint8_t *baseDataEnd = baseDataPtr + base->header_.getDataSize();
+//   uint32_t origLength = header_.getDataSize();
+//   uint32_t baseLength = base->header_.getDataSize();
+
+  // Allocate new space for diffed gamestate
+  uint32_t newDataSize = header_.getDataSize() + GamestateHeader::getSize() + sizeof(uint32_t)*this->nrOfVariables_;
+  uint8_t *newData = new uint8_t[newDataSize]; // this is the maximum size needed in the worst case
+  uint8_t *destDataPtr = GAMESTATE_START(newData);
+
+  std::vector<uint32_t>::iterator sizesIt = this->sizes_.begin();
+
+  while( origDataPtr < origDataEnd )
   {
     //iterate through all objects
 
-    SynchronisableHeader h(origData+origOffset);
+    SynchronisableHeader origHeader(origDataPtr);
 
     // Find (if possible) the current object in the datastream of the old gamestate
     // Start at the current offset position
-    if(baseOffset >= baseLength)
-      baseOffset = 0;
-    uint8_t* temp = baseData + baseOffset;
-    uint32_t objectID = h.getObjectID();
-    assert(temp < baseData+baseLength);
-    assert(dest < nData + origLength + GamestateHeader::getSize() + sizeof(uint32_t)*this->nrOfVariables_);
-    assert(sizes != this->sizes_.end());
-    while ( temp < baseData+baseLength )
-    {
-      SynchronisableHeader htemp(temp);
-      assert( htemp.getDataSize()!=0 );
-      if ( htemp.getObjectID() == objectID )
-      {
-        assert( h.getClassID() == htemp.getClassID() );
-        goto DODIFF;
-      }
-//       {
-//         SynchronisableHeader htemp2(temp+htemp.getDataSize()+SynchronisableHeader::getSize());
-//         if( temp+htemp.getDataSize()+SynchronisableHeader::getSize() < baseData+baseLength )
-//         {
-//           assert(htemp2.getClassID()<500);
-//           assert(htemp2.getDataSize()!=0 && htemp2.getDataSize()<1000);
-//           assert(htemp2.isDiffed()==false);
-//         }
-//       }
-      temp += htemp.getDataSize()+SynchronisableHeader::getSize();
+    if(baseDataPtr == baseDataEnd)
+      baseDataPtr = GAMESTATE_START(base->data_);
+    uint8_t* oldBaseDataPtr = baseDataPtr;
+    
+    assert(baseDataPtr < baseDataEnd);
+    assert(destDataPtr < newData + newDataSize);
+    assert(sizesIt != this->sizes_.end());
+    
+    assert(Synchronisable::getSynchronisable(origHeader.getObjectID()));
+    assert(ClassByID(origHeader.getClassID()));
+    assert(origHeader.getDataSize() < 500);
+    
+    bool diffedObject = false;
+    if( findObject(baseDataPtr, baseDataEnd, origHeader) )
+    {
+      SynchronisableHeader baseHeader(baseDataPtr);
+      assert(Synchronisable::getSynchronisable(baseHeader.getObjectID()));
+      assert(ClassByID(baseHeader.getClassID()));
+      assert(baseHeader.getDataSize() < 500);
+      if( SynchronisableHeader(baseDataPtr).getDataSize()==origHeader.getDataSize() )
+      {
+//         COUT(4) << "diffing object in order: " << Synchronisable::getSynchronisable(origHeader.getObjectID())->getIdentifier()->getName() << endl;
+        diffObject(destDataPtr, origDataPtr, baseDataPtr, origHeader, sizesIt);
+        diffedObject = true;
+      }
+      else
+      {
+//         COUT(4) << "copy object because of different data sizes (1): " << Synchronisable::getSynchronisable(origHeader.getObjectID())->getIdentifier()->getName() << endl;
+        copyObject(destDataPtr, origDataPtr, baseDataPtr, origHeader, sizesIt);
+        assert(sizesIt != this->sizes_.end() || origDataPtr==origDataEnd);
+      }
         
     }
-    // If not found start looking at the beginning
-    assert( temp==baseData+baseLength );
-    temp = baseData;
-//     {
-//       SynchronisableHeader htemp2(temp);
-//       if( temp < baseData+baseLength )
-//       {
-//         assert(htemp2.getClassID()<500);
-//         assert(htemp2.getDataSize()!=0 && htemp2.getDataSize()<1000);
-//         assert(htemp2.isDiffed()==false);
-//       }
-//     }
-    while ( temp < baseData+baseOffset )
-    {
-      SynchronisableHeader htemp(temp);
-      if ( htemp.getObjectID() == objectID )
-      {
-        assert( h.getClassID() == htemp.getClassID() );
-        goto DODIFF;
-      }
-//       {
-//         SynchronisableHeader htemp2(temp+htemp.getDataSize()+SynchronisableHeader::getSize());
-//         if( temp+htemp.getDataSize()+SynchronisableHeader::getSize() < baseData+baseLength )
-//         {
-//           assert(htemp2.getClassID()<500);
-//           assert(htemp2.getDataSize()!=0 && htemp2.getDataSize()<1000);
-//           assert(htemp2.isDiffed()==false);
-//         }
-//       }
-      temp += htemp.getDataSize()+SynchronisableHeader::getSize();
-    }
-    // Object is new, thus never transmitted -> just copy over
-    goto DOCOPY;
-
-
-DODIFF:
-    {
-//       COUT(4) << "dodiff" << endl;
-//       if(baseOffset==0)
-//       {
-//         assert(origOffset==0);
-//       }
-      uint32_t objectOffset = SynchronisableHeader::getSize(); // offset inside the object in the origData and baseData
-      // Check whether the whole object stayed the same
-      if( memcmp( origData+origOffset+objectOffset, temp+objectOffset, h.getDataSize()) == 0 )
-      {
-//         COUT(4) << "skip object" << Synchronisable::getSynchronisable(h.getObjectID())->getIdentifier()->getName() << endl;
-        origOffset += objectOffset+ h.getDataSize(); // skip the whole object
-        baseOffset = temp + h.getDataSize()+SynchronisableHeader::getSize() - baseData;
-        sizes += Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables();
+    else
+    {
+      assert( baseDataPtr == baseDataEnd );
+      baseDataPtr = GAMESTATE_START(base->data_);
+      if( findObject(baseDataPtr, oldBaseDataPtr, origHeader) )
+      {
+        SynchronisableHeader baseHeader(baseDataPtr);
+        assert(Synchronisable::getSynchronisable(baseHeader.getObjectID()));
+        assert(ClassByID(baseHeader.getClassID()));
+        assert(baseHeader.getDataSize() < 500);
+        if( SynchronisableHeader(baseDataPtr).getDataSize()==origHeader.getDataSize() )
+        {
+//           COUT(4) << "diffing object out of order: " << Synchronisable::getSynchronisable(origHeader.getObjectID())->getIdentifier()->getName() << endl;
+          diffObject(destDataPtr, origDataPtr, baseDataPtr, origHeader, sizesIt);
+          diffedObject = true;
+        }
+        else
+        {
+//           COUT(4) << "copy object because of different data sizes (2): " << Synchronisable::getSynchronisable(origHeader.getObjectID())->getIdentifier()->getName() << endl;
+          copyObject(destDataPtr, origDataPtr, baseDataPtr, origHeader, sizesIt);
+          assert(sizesIt != this->sizes_.end() || origDataPtr==origDataEnd);
+        }
       }
       else
       {
-//         if( Synchronisable::getSynchronisable(h.getObjectID())->getIdentifier()->getName() == "Bot" )
-//           COUT(0) << "blub" << endl;
-//         COUT(4) << "object diff: " << Synchronisable::getSynchronisable(h.getObjectID())->getIdentifier()->getName() << endl;
-//         COUT(4) << "diff " << h.getObjectID() << ":";
-        // Now start to diff the Object
-        SynchronisableHeaderLight h2(dest);
-        h2 = h; // copy over the objectheader
-        VariableID variableID = 0;
-        uint32_t newObjectOffset = SynchronisableHeaderLight::getSize();
-        // iterate through all variables
-        while( objectOffset < h.getDataSize()+SynchronisableHeader::getSize() )
-        {
-          // check whether variable changed and write id and copy over variable to the new stream
-          // otherwise skip variable
-          assert(sizes != this->sizes_.end());
-          uint32_t varSize = *sizes;
-          assert( varSize == Synchronisable::getSynchronisable(h.getObjectID())->getVarSize(variableID) );
-          if ( varSize != 0 )
-          {
-            if ( memcmp(origData+origOffset+objectOffset, temp+objectOffset, varSize) != 0 )
-            {
-//               COUT(4) << "copy variable" << endl;
-              *(VariableID*)(dest+newObjectOffset) = variableID; // copy over the variableID
-              newObjectOffset += sizeof(VariableID);
-              memcpy( dest+newObjectOffset, origData+origOffset+objectOffset, varSize );
-              newObjectOffset += varSize;
-              objectOffset += varSize;
-            }
-            else
-            {
-//               COUT(4) << "skip variable" << endl;
-              objectOffset += varSize;
-            }
-          }
-//           else
-//             COUT(4) << "varsize 0" << endl;
-
-          ++variableID;
-          ++sizes;
-        }
-        
-        if( Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables() != variableID )
-          sizes += Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables() - variableID;
-//         COUT(4) << endl;
-        h2.setDiffed(true);
-        h2.setDataSize(newObjectOffset-SynchronisableHeaderLight::getSize());
-        assert(objectOffset == h.getDataSize()+SynchronisableHeader::getSize());
-        origOffset += objectOffset;
-//         baseOffset += temp + h.getDataSize()+SynchronisableHeader::getSize() - baseData;
-        //baseOffset += objectOffset;
-//         SynchronisableHeader htemp(temp);
-//         baseOffset += SynchronisableHeader::getSize() + htemp.getDataSize();
-//         {
-//           SynchronisableHeader htemp2( baseData+(temp-baseData+objectOffset) );
-//           if( baseData+(temp-baseData+objectOffset) < baseData+baseLength )
-//           {
-//             assert(htemp2.getClassID()<500);
-//             assert(htemp2.getDataSize()!=0 && htemp2.getDataSize()<1000);
-//             assert(htemp2.isDiffed()==false);
-//           }
-//         }
-        baseOffset = temp-baseData + objectOffset;
-        dest += newObjectOffset;
-      }
-
-      continue;
-    }
-
-DOCOPY:
-    {
-//       COUT(4) << "docopy" << endl;
-      // Just copy over the whole Object
-      memcpy( dest, origData+origOffset, h.getDataSize()+SynchronisableHeader::getSize() );
-      dest += h.getDataSize()+SynchronisableHeader::getSize();
-      origOffset += h.getDataSize()+SynchronisableHeader::getSize();
-      assert( Synchronisable::getSynchronisable(h.getObjectID()) );
-//       COUT(4) << "copy " << h.getObjectID() << endl;
-//       COUT(4) << "copy " << h.getObjectID() << ":";
-      //sizes += Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables();
-      for( unsigned int i = 0; i < Synchronisable::getSynchronisable(h.getObjectID())->getNrOfVariables(); ++i )
-      {
-//         COUT(4) << " " << *sizes;
-        ++sizes;
-      }
-//       COUT(4) << endl;
-      assert(sizes != this->sizes_.end() || origOffset>=origLength);
-      continue;
-    }
-  }
-
-
-  Gamestate *g = new Gamestate(nData, getClientID());
-  assert(g->header_);
-  *(g->header_) = *header_;
-  g->header_->setBaseID( base->getID() );
-  g->header_->setDataSize(dest - nData - GamestateHeader::getSize());
+//         COUT(4) << "copy object: " << Synchronisable::getSynchronisable(origHeader.getObjectID())->getIdentifier()->getName() << endl;
+        assert(baseDataPtr == oldBaseDataPtr);
+        copyObject(destDataPtr, origDataPtr, baseDataPtr, origHeader, sizesIt);
+        assert(sizesIt != this->sizes_.end() || origDataPtr==origDataEnd);
+      }
+    }
+  }
+  assert(sizesIt==this->sizes_.end());
+
+
+  Gamestate *g = new Gamestate(newData, getPeerID());
+  (g->header_) = header_;
+  g->header_.setBaseID( base->getID() );
+  g->header_.setDataSize(destDataPtr - newData - GamestateHeader::getSize());
   g->flags_=flags_;
   g->packetDirection_ = packetDirection_;
@@ -579,13 +598,13 @@
 
 
-Gamestate* Gamestate::diffData(Gamestate *base)
+/*Gamestate* Gamestate::diffData(Gamestate *base)
 {
   assert(this && base); assert(data_ && base->data_);
-  assert(!header_->isCompressed() && !base->header_->isCompressed());
-  assert(!header_->isDiffed());
+  assert(!header_.isCompressed() && !base->header_.isCompressed());
+  assert(!header_.isDiffed());
 
   uint8_t *basep = GAMESTATE_START(base->data_);
   uint8_t *gs = GAMESTATE_START(this->data_);
-  uint32_t dest_length = header_->getDataSize();
+  uint32_t dest_length = header_.getDataSize();
 
   if(dest_length==0)
@@ -595,8 +614,8 @@
   uint8_t *dest = GAMESTATE_START(ndata);
 
-  rawDiff( dest, gs, basep, header_->getDataSize(), base->header_->getDataSize() );
+  rawDiff( dest, gs, basep, header_.getDataSize(), base->header_.getDataSize() );
 #ifndef NDEBUG
   uint8_t *dest2 = new uint8_t[dest_length];
-  rawDiff( dest2, dest, basep, header_->getDataSize(), base->header_->getDataSize() );
+  rawDiff( dest2, dest, basep, header_.getDataSize(), base->header_.getDataSize() );
   assert( memcmp( dest2, gs, dest_length) == 0 );
   delete dest2;
@@ -606,6 +625,6 @@
   assert(g->header_);
   *(g->header_) = *header_;
-  g->header_->setDiffed( true );
-  g->header_->setBaseID( base->getID() );
+  g->header_.setDiffed( true );
+  g->header_.setBaseID( base->getID() );
   g->flags_=flags_;
   g->packetDirection_ = packetDirection_;
@@ -619,10 +638,10 @@
 {
   assert(this && base); assert(data_ && base->data_);
-  assert(!header_->isCompressed() && !base->header_->isCompressed());
-  assert(header_->isDiffed());
+  assert(!header_.isCompressed() && !base->header_.isCompressed());
+  assert(header_.isDiffed());
 
   uint8_t *basep = GAMESTATE_START(base->data_);
   uint8_t *gs = GAMESTATE_START(this->data_);
-  uint32_t dest_length = header_->getDataSize();
+  uint32_t dest_length = header_.getDataSize();
 
   if(dest_length==0)
@@ -632,10 +651,10 @@
   uint8_t *dest = ndata + GamestateHeader::getSize();
 
-  rawDiff( dest, gs, basep, header_->getDataSize(), base->header_->getDataSize() );
+  rawDiff( dest, gs, basep, header_.getDataSize(), base->header_.getDataSize() );
 
   Gamestate *g = new Gamestate(ndata, getClientID());
   assert(g->header_);
   *(g->header_) = *header_;
-  g->header_->setDiffed( false );
+  g->header_.setDiffed( false );
   g->flags_=flags_;
   g->packetDirection_ = packetDirection_;
@@ -670,13 +689,13 @@
   }
   assert(j==datalength);
-}
-
-
-Gamestate* Gamestate::doSelection(unsigned int clientID, unsigned int targetSize){
+}*/
+
+
+/*Gamestate* Gamestate::doSelection(unsigned int clientID, unsigned int targetSize){
   assert(data_);
   std::list<obj>::iterator it;
 
   // allocate memory for new data
-  uint8_t *gdata = new uint8_t[header_->getDataSize()+GamestateHeader::getSize()];
+  uint8_t *gdata = new uint8_t[header_.getDataSize()+GamestateHeader::getSize()];
   // create a gamestate out of it
   Gamestate *gs = new Gamestate(gdata);
@@ -694,5 +713,5 @@
 
   //call TrafficControl
-  TrafficControl::getInstance()->processObjectList( clientID, header_->getID(), dataVector_ );
+  TrafficControl::getInstance()->processObjectList( clientID, header_.getID(), dataVector_ );
 
   //copy in the zeros
@@ -725,5 +744,5 @@
 #ifndef NDEBUG
   uint32_t origsize = destsize;
-  while ( origsize < header_->getDataSize() )
+  while ( origsize < header_.getDataSize() )
   {
     SynchronisableHeader oldobjectheader(origdata);
@@ -732,13 +751,13 @@
     origsize += objectsize;
   }
-  assert(origsize==header_->getDataSize());
+  assert(origsize==header_.getDataSize());
   assert(destsize!=0);
 #endif
-  gs->header_->setDataSize( destsize );
+  gs->header_.setDataSize( destsize );
   return gs;
-}
-
-
-uint32_t Gamestate::calcGamestateSize(int32_t id, uint8_t mode)
+}*/
+
+
+uint32_t Gamestate::calcGamestateSize(uint32_t id, uint8_t mode)
 {
   uint32_t size = 0;
Index: code/branches/presentation2/src/libraries/network/packet/Gamestate.h
===================================================================
--- code/branches/presentation2/src/libraries/network/packet/Gamestate.h	(revision 7787)
+++ code/branches/presentation2/src/libraries/network/packet/Gamestate.h	(revision 7788)
@@ -42,30 +42,40 @@
 #include "Packet.h"
 
-namespace orxonox {
+namespace orxonox
+{
 
-namespace packet {
+namespace packet
+{
+    
+static const uint8_t GAMESTATE_MODE_SERVER = 0x1;
+static const uint8_t GAMESTATE_MODE_CLIENT = 0x2;
 
-class _NetworkExport GamestateHeader{
+class _NetworkExport GamestateHeader
+{
   public:
-    GamestateHeader(uint8_t *data){ assert(data); data_ = data; *(uint32_t*)data_ = Type::Gamestate; }
-    GamestateHeader(uint8_t *data, GamestateHeader* h)
-    { assert(data); data_=data; memcpy(data_, h->data_, getSize()); }
+    GamestateHeader(){ data_=0; }
+    GamestateHeader(uint8_t* data)
+      { assert(data); data_ = data; *(uint32_t*)data_ = Type::Gamestate; }
+    /*GamestateHeader(uint8_t* data, GamestateHeader* h)
+      { assert(data); data_=data; memcpy(data_, h->data_, getSize()); }*/
+    void setData(uint8_t* data)
+      { assert(data); data_ = data; *(uint32_t*)data_ = Type::Gamestate; }
     static inline uint32_t getSize()
-    { return 21; }
+      { return 21; }
 
-    inline int32_t getID() const
-    { assert(data_); return *(int32_t*)(data_+4); }
-    inline void setID(int32_t id)
-    { assert(data_); *(int32_t*)(data_+4) = id; }
+    inline uint32_t getID() const
+      { assert(data_); return *(uint32_t*)(data_+4); }
+    inline void setID(uint32_t id)
+      { assert(data_); *(uint32_t*)(data_+4) = id; }
 
-    inline int32_t getBaseID() const
-    { assert(data_); return *(int32_t*)(data_+8); }
-    inline void setBaseID(int32_t id)
-    { assert(data_); *(int32_t*)(data_+8) = id; }
+    inline uint32_t getBaseID() const
+      { assert(data_); return *(uint32_t*)(data_+8); }
+    inline void setBaseID(uint32_t id)
+      { assert(data_); *(uint32_t*)(data_+8) = id; }
 
     inline uint32_t getDataSize() const
-    { assert(data_); return *(uint32_t*)(data_+12); }
+      { assert(data_); return *(uint32_t*)(data_+12); }
     inline void setDataSize(uint32_t size)
-    { assert(data_); *(uint32_t*)(data_+12) = size; }
+      { assert(data_); *(uint32_t*)(data_+12) = size; }
 
     inline uint32_t getCompSize() const
@@ -75,22 +85,22 @@
 
     inline bool isDiffed() const
-    { assert(data_); return *(int8_t*)(data_+20) & 0x1; }
+      { assert(data_); return *(int8_t*)(data_+20) & 0x1; }
     inline void setDiffed(bool b)
-    { assert(data_); *(int8_t*)(data_+20) = (b<<0) | (*(int8_t*)(data_+20) & 0x6 ); }
+      { assert(data_); *(int8_t*)(data_+20) = (b<<0) | (*(int8_t*)(data_+20) & 0x6 ); }
 
     inline bool isComplete() const
-    { assert(data_); return *(int8_t*)(data_+20) & 0x2; }
+      { assert(data_); return *(int8_t*)(data_+20) & 0x2; }
     inline void setComplete(bool b)
-    { assert(data_); *(int8_t*)(data_+20) = (b<<1) | (*(int8_t*)(data_+20) & 0x5 ); }
+      { assert(data_); *(int8_t*)(data_+20) = (b<<1) | (*(int8_t*)(data_+20) & 0x5 ); }
 
     inline bool isCompressed() const
-    { assert(data_); return *(int8_t*)(data_+20) & 0x4; }
+      { assert(data_); return *(int8_t*)(data_+20) & 0x4; }
     inline void setCompressed(bool b)
-    { assert(data_); *(int8_t*)(data_+20) = (b<<2) | (*(int8_t*)(data_+20) & 0x3 ); }
+      { assert(data_); *(int8_t*)(data_+20) = (b<<2) | (*(int8_t*)(data_+20) & 0x3 ); }
 
     inline void operator=(GamestateHeader& h)
-    { assert(data_); assert(h.data_); memcpy( data_, h.data_, getSize()); }
+      { assert(data_); assert(h.data_); memcpy( data_, h.data_, getSize()); }
   private:
-    uint8_t *data_;
+    uint8_t* data_;
 
 };
@@ -99,5 +109,6 @@
     @author Oliver Scheuss
 */
-class _NetworkExport Gamestate: public Packet{
+class _NetworkExport Gamestate: public Packet
+{
   public:
     Gamestate();
@@ -110,13 +121,13 @@
     bool collectData(int id, uint8_t mode=0x0);
     bool spreadData( uint8_t mode=0x0);
-    inline int32_t getID() const { return header_->getID(); }
-    inline bool isDiffed() const { return header_->isDiffed(); }
-    inline bool isCompressed() const { return header_->isCompressed(); }
-    inline int32_t getBaseID() const { return header_->getBaseID(); }
-    inline uint32_t getDataSize() const { return header_->getDataSize(); }
+    inline uint32_t getID() const { return header_.getID(); }
+    inline bool isDiffed() const { return header_.isDiffed(); }
+    inline bool isCompressed() const { return header_.isCompressed(); }
+    inline int32_t getBaseID() const { return header_.getBaseID(); }
+    inline uint32_t getDataSize() const { return header_.getDataSize(); }
     Gamestate* diffVariables(Gamestate *base);
-    Gamestate* diffData(Gamestate *base);
-    Gamestate *undiff(Gamestate *base);
-    Gamestate* doSelection(unsigned int clientID, unsigned int targetSize);
+//     Gamestate* diffData(Gamestate *base);
+//     Gamestate *undiff(Gamestate *base);
+//     Gamestate* doSelection(unsigned int clientID, unsigned int targetSize);
     bool compressData();
     bool decompressData();
@@ -125,12 +136,14 @@
     // Packet functions
   private:
-    void rawDiff( uint8_t* newdata, uint8_t* data, uint8_t* basedata, uint32_t datalength, uint32_t baselength);
-    inline uint32_t findObject( const SynchronisableHeader& header, uint8_t* mem, uint32_t dataLength, uint32_t startPosition = 0 );
+//     void rawDiff( uint8_t* newdata, uint8_t* data, uint8_t* basedata, uint32_t datalength, uint32_t baselength);
+//     inline uint32_t findObject( const SynchronisableHeader& header, uint8_t* mem, uint32_t dataLength, uint32_t startPosition = 0 );
     virtual uint32_t getSize() const;
-    virtual inline bool process();
-    uint32_t calcGamestateSize(int32_t id, uint8_t mode=0x0);
+    virtual bool process(orxonox::Host* host);
+    uint32_t calcGamestateSize(uint32_t id, uint8_t mode=0x0);
+//     inline void diffObject( uint8_t*& newData, uint8_t*& origData, uint8_t*& baseData, SynchronisableHeader& objectHeader, std::vector<uint32_t>::iterator& sizes );
+//     inline void copyObject( uint8_t*& newData, uint8_t*& origData, uint8_t*& baseData, SynchronisableHeader& objectHeader, std::vector<uint32_t>::iterator& sizes );
     
     std::list<obj>          dataVector_;
-    GamestateHeader*        header_;
+    GamestateHeader         header_;
     std::vector<uint32_t>   sizes_;
     uint32_t                nrOfVariables_;
Index: code/branches/presentation2/src/libraries/network/packet/Packet.cc
===================================================================
--- code/branches/presentation2/src/libraries/network/packet/Packet.cc	(revision 7787)
+++ code/branches/presentation2/src/libraries/network/packet/Packet.cc	(revision 7788)
@@ -35,4 +35,5 @@
 #include <enet/enet.h>
 #include <boost/static_assert.hpp>
+#include <boost/thread/mutex.hpp>
 
 #include "util/Debug.h"
@@ -53,7 +54,7 @@
 
 // Make sure we assume the right values
-BOOST_STATIC_ASSERT(static_cast<int>(PacketFlag::Reliable)   == static_cast<int>(ENET_PACKET_FLAG_RELIABLE));
-BOOST_STATIC_ASSERT(static_cast<int>(PacketFlag::Unsequence) == static_cast<int>(ENET_PACKET_FLAG_UNSEQUENCED));
-BOOST_STATIC_ASSERT(static_cast<int>(PacketFlag::NoAllocate) == static_cast<int>(ENET_PACKET_FLAG_NO_ALLOCATE));
+BOOST_STATIC_ASSERT(static_cast<int>(PacketFlag::Reliable)    == static_cast<int>(ENET_PACKET_FLAG_RELIABLE));
+BOOST_STATIC_ASSERT(static_cast<int>(PacketFlag::Unsequenced) == static_cast<int>(ENET_PACKET_FLAG_UNSEQUENCED));
+BOOST_STATIC_ASSERT(static_cast<int>(PacketFlag::NoAllocate)  == static_cast<int>(ENET_PACKET_FLAG_NO_ALLOCATE));
 
 #define PACKET_FLAG_DEFAULT PacketFlag::NoAllocate
@@ -61,4 +62,5 @@
 
 std::map<size_t, Packet *> Packet::packetMap_;
+boost::mutex Packet::packetMapMutex_;
 
 Packet::Packet()
@@ -66,5 +68,5 @@
   flags_ = PACKET_FLAG_DEFAULT;
   packetDirection_ = Direction::Outgoing;
-  clientID_=0;
+  peerID_=0;
   data_=0;
   enetPacket_=0;
@@ -72,9 +74,9 @@
 }
 
-Packet::Packet(uint8_t *data, unsigned int clientID)
+Packet::Packet(uint8_t *data, unsigned int peerID)
 {
   flags_ = PACKET_FLAG_DEFAULT;
   packetDirection_ = Direction::Incoming;
-  clientID_=clientID;
+  peerID_=peerID;
   data_=data;
   enetPacket_=0;
@@ -87,5 +89,5 @@
   flags_=p.flags_;
   packetDirection_ = p.packetDirection_;
-  clientID_ = p.clientID_;
+  peerID_ = p.peerID_;
   if(p.data_){
     data_ = new uint8_t[p.getSize()];
@@ -123,5 +125,5 @@
 }
 
-bool Packet::send(){
+bool Packet::send(orxonox::Host* host){
   if(packetDirection_ != Direction::Outgoing && packetDirection_ != Direction::Bidirectional ){
     assert(0);
@@ -142,5 +144,7 @@
       // Assures we don't create a packet and destroy it right after in another thread
       // without having a reference in the packetMap_
+      Packet::packetMapMutex_.lock();
       packetMap_[reinterpret_cast<size_t>(enetPacket_)] = this;
+      Packet::packetMapMutex_.unlock();
     }
   }
@@ -164,6 +168,8 @@
 //  ENetPacket *temp = enetPacket_;
 //  enetPacket_ = 0; // otherwise we have a double free because enet already handles the deallocation of the packet
-  if(!Host::addPacket( enetPacket_, clientID_))
-    enet_packet_destroy(this->enetPacket_); // if we could not add the packet to the enet queue delete it manually
+  if( this->flags_ & PacketFlag::Reliable )
+    host->addPacket( enetPacket_, peerID_, NETWORK_CHANNEL_DEFAULT);
+  else
+    host->addPacket( enetPacket_, peerID_, NETWORK_CHANNEL_UNRELIABLE);
   return true;
 }
@@ -172,44 +178,46 @@
   uint8_t *data = packet->data;
   assert(ClientInformation::findClient(&peer->address)->getID() != static_cast<unsigned int>(-2) || !Host::isServer());
-  unsigned int clientID = ClientInformation::findClient(&peer->address)->getID();
+  unsigned int peerID = ClientInformation::findClient(&peer->address)->getID();
+  // HACK
+  if( peerID==static_cast<unsigned int>(-2))
+    peerID = NETWORK_PEER_ID_SERVER;
   Packet *p = 0;
-  COUT(6) << "packet type: " << *(Type::Value *)&data[_PACKETID] << std::endl;
+//   COUT(6) << "packet type: " << *(Type::Value *)&data[_PACKETID] << std::endl;
   switch( *(Type::Value *)(data + _PACKETID) )
   {
     case Type::Acknowledgement:
-      COUT(5) << "ack" << std::endl;
-      p = new Acknowledgement( data, clientID );
+//       COUT(5) << "ack" << std::endl;
+    p = new Acknowledgement( data, peerID );
       break;
     case Type::Chat:
-      COUT(5) << "chat" << std::endl;
-      p = new Chat( data, clientID );
+//       COUT(5) << "chat" << std::endl;
+      p = new Chat( data, peerID );
       break;
     case Type::ClassID:
-      COUT(5) << "classid" << std::endl;
-      p = new ClassID( data, clientID );
+//       COUT(5) << "classid" << std::endl;
+      p = new ClassID( data, peerID );
       break;
     case Type::Gamestate:
-      COUT(5) << "gamestate" << std::endl;
-      // TODO: remove brackets
-      p = new Gamestate( data, clientID );
+//       COUT(5) << "gamestate" << std::endl;
+      p = new Gamestate( data, peerID );
       break;
     case Type::Welcome:
-      COUT(5) << "welcome" << std::endl;
-      p = new Welcome( data, clientID );
+//       COUT(5) << "welcome" << std::endl;
+      p = new Welcome( data, peerID );
       break;
     case Type::DeleteObjects:
-      COUT(5) << "deleteobjects" << std::endl;
-      p = new DeleteObjects( data, clientID );
+//       COUT(5) << "deleteobjects" << std::endl;
+      p = new DeleteObjects( data, peerID );
       break;
     case Type::FunctionCalls:
-      COUT(5) << "functionCalls" << std::endl;
-      p = new FunctionCalls( data, clientID );
+//       COUT(5) << "functionCalls" << std::endl;
+      p = new FunctionCalls( data, peerID );
       break;
     case Type::FunctionIDs:
-      COUT(5) << "functionIDs" << std::endl;
-      p = new FunctionIDs( data, clientID );
+//       COUT(5) << "functionIDs" << std::endl;
+      p = new FunctionIDs( data, peerID );
       break;
     default:
-      assert(0); //TODO: repair this
+      assert(0);
       break;
   }
@@ -229,4 +237,5 @@
 void Packet::deletePacket(ENetPacket *enetPacket){
   // Get our Packet from a global map with all Packets created in the send() method of Packet.
+  Packet::packetMapMutex_.lock();
   std::map<size_t, Packet*>::iterator it = packetMap_.find(reinterpret_cast<size_t>(enetPacket));
   assert(it != packetMap_.end());
@@ -235,5 +244,6 @@
   delete it->second;
   packetMap_.erase(it);
-  COUT(6) << "PacketMap size: " << packetMap_.size() << std::endl;
+  Packet::packetMapMutex_.unlock();
+//   COUT(6) << "PacketMap size: " << packetMap_.size() << std::endl;
 }
 
Index: code/branches/presentation2/src/libraries/network/packet/Packet.h
===================================================================
--- code/branches/presentation2/src/libraries/network/packet/Packet.h	(revision 7787)
+++ code/branches/presentation2/src/libraries/network/packet/Packet.h	(revision 7788)
@@ -68,16 +68,20 @@
     virtual unsigned char *getData(){ return data_; };
     virtual unsigned int getSize() const =0;
-    virtual bool process()=0;
+    virtual bool process(orxonox::Host* host)=0;
     inline uint32_t getFlags()
       { return flags_; }
-    inline int getClientID()
-      { return clientID_; }
-    inline void setClientID( int id )
-      { clientID_ = id; }
+    inline int getPeerID()
+      { return peerID_; }
+    inline void setPeerID( int id )
+      { peerID_ = id; }
+    inline bool isReliable()
+      { return this->flags_ & PacketFlag::Reliable; }
+    inline uint32_t getRequiredGamestateID()
+      { return this->requiredGamestateID_; }
 
-    virtual bool send();
+    virtual bool send(orxonox::Host* host);
   protected:
     Packet();
-    Packet(uint8_t *data, unsigned int clientID);
+    Packet(uint8_t *data, unsigned int peerID);
 //    Packet(ENetPacket *packet, ENetPeer *peer);
     inline bool isDataENetAllocated() const
@@ -85,5 +89,6 @@
 
     uint32_t flags_;
-    unsigned int clientID_;
+    unsigned int peerID_;
+    uint32_t requiredGamestateID_;
     Direction::Value packetDirection_;
     /** Pointer to the data. Be careful when deleting it because it might
@@ -96,4 +101,5 @@
   private:
     static std::map<size_t, Packet *> packetMap_;
+    static boost::mutex               packetMapMutex_;
     ENetPacket *enetPacket_;
 };
Index: code/branches/presentation2/src/libraries/network/packet/Welcome.cc
===================================================================
--- code/branches/presentation2/src/libraries/network/packet/Welcome.cc	(revision 7787)
+++ code/branches/presentation2/src/libraries/network/packet/Welcome.cc	(revision 7788)
@@ -73,9 +73,9 @@
 }
 
-bool Welcome::process(){
+bool Welcome::process(orxonox::Host* host){
   uint32_t clientID;
   clientID = *(uint32_t *)(data_ + _CLIENTID );
   assert(*(uint32_t *)(data_ + _ENDIANTEST ) == 0xFEDC4321);
-  Host::setClientID(clientID);
+  host->setClientID(clientID);
   COUT(3) << "Welcome set clientId: " << clientID << endl;
   Synchronisable::setClient(true);
Index: code/branches/presentation2/src/libraries/network/packet/Welcome.h
===================================================================
--- code/branches/presentation2/src/libraries/network/packet/Welcome.h	(revision 7787)
+++ code/branches/presentation2/src/libraries/network/packet/Welcome.h	(revision 7788)
@@ -47,5 +47,5 @@
   uint8_t *getData();
   inline unsigned int getSize() const;
-  bool process();
+  virtual bool process(orxonox::Host* host);
 
 private:
