Index: branches/network/src/lib/network/handshake.cc
===================================================================
--- branches/network/src/lib/network/handshake.cc	(revision 7680)
+++ branches/network/src/lib/network/handshake.cc	(revision 7681)
@@ -24,5 +24,5 @@
 #include <cassert>
 
-Handshake::Handshake( bool server, int clientId, int networkGameManagerId )
+Handshake::Handshake( bool server, int clientId, int networkGameManagerId, int messageManagerId )
   : Synchronizeable()
 {
@@ -33,8 +33,10 @@
   this->localState.hostId = clientId;
   this->localState.networkManagerId = networkGameManagerId;
+  this->localState.messageManagerId = messageManagerId;
  
   orxId_handler = registerVarId( new SynchronizeableInt( &localState.orxId, &remoteState.orxId, "orxonoxId", PERMISSION_ALL ) );
   version_handler = registerVarId( new SynchronizeableInt( &localState.version, &remoteState.version, "version", PERMISSION_ALL ) );
   netManId_handler = registerVarId( new SynchronizeableInt( &localState.networkManagerId, &remoteState.networkManagerId, "networkManagerId", PERMISSION_ALL ) );
+  netManId_handler = registerVarId( new SynchronizeableInt( &localState.messageManagerId, &remoteState.messageManagerId, "networkManagerId", PERMISSION_ALL ) );
   hostId_handler = registerVarId( new SynchronizeableInt( &localState.hostId, &remoteState.hostId, "hostId", PERMISSION_ALL ) );
   completed_handler = registerVarId( new SynchronizeableInt( &localState.completed, &remoteState.completed, "completed", PERMISSION_ALL ) );
Index: branches/network/src/lib/network/handshake.h
===================================================================
--- branches/network/src/lib/network/handshake.h	(revision 7680)
+++ branches/network/src/lib/network/handshake.h	(revision 7681)
@@ -19,4 +19,5 @@
   
   int networkManagerId;
+  int messageManagerId;
   int hostId;
   
@@ -31,9 +32,10 @@
 {
   public:
-    Handshake( bool server, int clientId = 0, int networkGameManagerId = 0 );
+    Handshake( bool server, int clientId = 0, int networkGameManagerId = 0, int messageManagerId = 0 );
     inline bool       completed(){ return localState.completed != 0 && remoteState.completed != 0; }
     inline bool       ok(){ return localState.error == 0 && remoteState.error == 0; }
     inline int        getHostId(){ return remoteState.hostId; }
     inline int        getNetworkGameManagerId(){ return remoteState.networkManagerId; }
+    inline int        getMessageManagerId(){ return remoteState.messageManagerId; }
     inline void       doReject( std::string reason ){ localState.error = 1; localState.errorString = "the server rejected your connection ["+ reason +"]"; }
     
Index: branches/network/src/lib/network/message_manager.cc
===================================================================
--- branches/network/src/lib/network/message_manager.cc	(revision 7680)
+++ branches/network/src/lib/network/message_manager.cc	(revision 7681)
@@ -29,4 +29,6 @@
 {
   this->setClassID( CL_MESSAGE_MANAGER, "MessageManager" );
+  newNumber = 1;
+  setSynchronized( true );
 }
 
@@ -180,6 +182,31 @@
     assert( i + messageLength <= length );
     assert( messageHandlerMap.find( (MessageId)messageId ) != messageHandlerMap.end() );
-    (*(messageHandlerMap[(MessageId)messageId].cb))( (MessageId)messageId, data + i, messageLength, messageHandlerMap[(MessageId)messageId].someData, userId );
+    if ( std::find( messageQueue[userId].recievedMessages.begin(), messageQueue[userId].recievedMessages.end(), number )== messageQueue[userId].recievedMessages.end() )
+    {
+      (*(messageHandlerMap[(MessageId)messageId].cb))( (MessageId)messageId, data + i, messageLength, messageHandlerMap[(MessageId)messageId].someData, userId );
+      messageQueue[userId].recievedMessages.push_back( number );
+    }
     i += messageLength;
+  }
+  
+  
+  //walk throu message queue and remove acked messages
+  for ( std::list<NetworkMessage>::iterator it = messageQueue[userId].messages.begin(); it != messageQueue[userId].messages.end();  )
+  {
+    if ( std::find( acks.begin(), acks.end(), it->number) != acks.end() )
+    {
+      std::list<NetworkMessage>::iterator delIt = it;
+      it++;
+      messageQueue[userId].messages.erase( delIt );
+      continue;
+    }
+    it++;
+  }
+  
+  //TODO find bether way. maybe with timestamp
+  if ( messageQueue[userId].recievedMessages.size() > 1000 )
+  {
+    for ( int j = 0; j < messageQueue[userId].recievedMessages.size() - 1000; j++ )
+      messageQueue[userId].recievedMessages.erase( messageQueue[userId].recievedMessages.begin() );
   }
 
@@ -238,2 +265,41 @@
   assert( messageQueue[userId].messages.size() == 0 );
 }
+
+/**
+ * send a message to one or more clients
+ * recieverType:
+ *               RT_ALL send to all users. reciever is ignored
+ *               RT_USER send only to reciever
+ *               RT_NOT_USER send to all but reciever
+ *
+ * @param messageId message id
+ * @param data pointer to data
+ * @param dataLength length of data
+ * @param recieverType 
+ * @param reciever 
+ */
+void MessageManager::sendMessage( MessageId messageId, byte * data, int dataLength, RecieverType recieverType, int reciever, MessagePriority messagePriority )
+{
+  for ( MessageQueue::iterator it = messageQueue.begin(); it != messageQueue.end(); it++ )
+  {
+    if ( 
+         recieverType == RT_ALL ||
+         recieverType == RT_USER && it->first == reciever ||
+         recieverType == RT_NOT_USER && it->first != reciever
+       )
+    {
+      NetworkMessage msg;
+      
+      msg.data = new byte[dataLength];
+      memcpy( msg.data, data, dataLength );
+      msg.length = dataLength;
+      msg.messageId = messageId;
+      msg.number = newNumber++;
+      msg.priority = messagePriority;
+      
+      it->second.messages.push_back( msg );
+    }
+  }
+}
+
+
Index: branches/network/src/lib/network/message_manager.h
===================================================================
--- branches/network/src/lib/network/message_manager.h	(revision 7680)
+++ branches/network/src/lib/network/message_manager.h	(revision 7681)
@@ -28,4 +28,5 @@
 enum MessageId 
 {
+  TESTMESSAGEID = 1
 };
 
@@ -39,10 +40,19 @@
 };
 
+//TODO implement priority handling
+enum MessagePriority
+{
+  MP_HIGHBANDWIDTH = 1,  //!< fast and reliable but uses a lot of bandwidth
+  MP_LOWBANDWIDTH,       //!< may take a long time to arrive. reliable
+  MP_UNRELIABLE          //!< unreliable. low bandwidth 
+};
+
 struct NetworkMessage
 {
-  MessageId messageId;
-  byte *    data;
-  int       length;
-  int       number;
+  MessageId        messageId;
+  byte *           data;
+  int              length;
+  int              number;
+  MessagePriority  priority;
 };
 
@@ -51,4 +61,5 @@
   std::list<NetworkMessage> messages;
   std::list<int>            toAck;
+  std::list<int>            recievedMessages;
 };
 
@@ -75,5 +86,5 @@
    bool registerMessageHandler( MessageId messageId, MessageCallback cb, void * someData );
    
-   void sendMessage( MessageId messageId, byte * data, int dataLength, RecieverType recieverType, int reciever );
+   void sendMessage( MessageId messageId, byte * data, int dataLength, RecieverType recieverType, int reciever, MessagePriority messagePriority );
 
    virtual int getStateDiff( int userId, byte* data, int maxLength, int stateId, int fromStateId, int priorityTH );
@@ -89,4 +100,6 @@
    MessageHandlerMap       messageHandlerMap;   //!< contains handlers for messages
 
+   int                     newNumber;           //!< used to create unique message numbers
+
 };
 
Index: branches/network/src/lib/network/network_stream.cc
===================================================================
--- branches/network/src/lib/network/network_stream.cc	(revision 7680)
+++ branches/network/src/lib/network/network_stream.cc	(revision 7681)
@@ -134,5 +134,5 @@
   // and one for handshake to reject client maxCon+1
   this->networkGameManager->setUniqueID( MAX_CONNECTIONS + 2 );
-
+  MessageManager::getInstance()->setUniqueID( SharedNetworkData::getInstance()->getNewUniqueID() );
 }
 
@@ -219,5 +219,5 @@
       freeSocketSlots.pop_back();
       peers[clientId].socket = tempNetworkSocket;
-      peers[clientId].handshake = new Handshake(true, clientId, this->networkGameManager->getUniqueID());
+      peers[clientId].handshake = new Handshake(true, clientId, this->networkGameManager->getUniqueID(), MessageManager::getInstance()->getUniqueID() );
       peers[clientId].handshake->setUniqueID(clientId);
       peers[clientId].userId = clientId;
@@ -232,5 +232,5 @@
       
       peers[clientId].socket = tempNetworkSocket;
-      peers[clientId].handshake = new Handshake(true, clientId, this->networkGameManager->getUniqueID());
+      peers[clientId].handshake = new Handshake(true, clientId, this->networkGameManager->getUniqueID(), MessageManager::getInstance()->getUniqueID());
       peers[clientId].handshake->setUniqueID(clientId);
       peers[clientId].userId = clientId;
@@ -333,4 +333,5 @@
             this->networkGameManager = NetworkGameManager::getInstance();
             this->networkGameManager->setUniqueID( it->second.handshake->getNetworkGameManagerId() );
+            MessageManager::getInstance()->setUniqueID( it->second.handshake->getMessageManagerId() );
           }
 
@@ -446,5 +447,5 @@
       continue;
 
-    while ( packetLength = peer->second.socket->readPacket( buf, UDP_PACKET_SIZE ) > 0 )
+    while ( 0 < (packetLength = peer->second.socket->readPacket( buf, UDP_PACKET_SIZE )) )
     {
 
