void client_MessageReceived(object sender, EventArgs e)
 {
     INetMessage msg = client.DequeueMessage();
       if(msg is HandshakeRequest)
       {
     lock(syncObject)
       handshake = (HandshakeRequest)msg;
       }
       else if(msg is ConfirmMessage)
       {
     lock(syncObject)
     {
       confirmed = true;
     }
       }
 }
 public bool Connect(IPAddress address, int port, string password, GameStartMode startMode, DeckItem deck, 
     out string errorMessage, out ServerData opponentData)
 {
     bool confirmed = false;
       errorMessage = string.Empty;
       opponentData = null;
       ServiceNetClient client = new ServiceNetClient(address, port);
       client.Disconnected += new EventHandler(client_Disconnected);
       connectionMessagesHandler = new ClientConnectionMessagesHandler(client);
       try
       {
     client.Subscribe();
     Version clientVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
     HandshakeRequest handshake = new HandshakeRequest()
     {
       PlayerInfo = playerInfo,
       Deck = new DeckDataContract(deck),
       StartMode = startMode,
       GameDatabaseCRC = servicesProvider.GameDatabaseCrc,
       CardDatabaseCRC = servicesProvider.CardDatabaseCrc,
       ClientVersion = clientVersion.ToString(),
       Password = password,
     };
     Thread.Sleep(100);
     client.SendMessage(handshake);
     if(!WaitForHandshakeResponse())
       throw new Exception("Opponent handshake not received!");
     if(connectionMessagesHandler.Handshake.ConnectionResult != ConnectionResult.Accepted)
     {
       switch(connectionMessagesHandler.Handshake.ConnectionResult)
       {
     case ConnectionResult.VersionMismatch:
       errorMessage = servicesProvider.SystemStringsService.GetString("NEW_SERVER_GAME_DIALOG", "MSG_CONNECTIONREFUSED_VERSIONMISMATCH");
       break;
     case ConnectionResult.GameIsRunning:
       errorMessage = servicesProvider.SystemStringsService.GetString("NEW_SERVER_GAME_DIALOG", "MSG_CONNECTIONREFUSED_GAMEISRUNNING");
       break;
     case ConnectionResult.InvalidStartMode:
       errorMessage = servicesProvider.SystemStringsService.GetString("NEW_SERVER_GAME_DIALOG", "MSG_CONNECTIONREFUSED_INVALIDSTARTMODE");
       break;
     case ConnectionResult.NicknameDuplicated:
       errorMessage = servicesProvider.SystemStringsService.GetString("NEW_SERVER_GAME_DIALOG", "MSG_CONNECTIONREFUSED_NICKNAMEDUPLICATED");
       break;
     case ConnectionResult.GameDatabaseMismatch:
       errorMessage = servicesProvider.SystemStringsService.GetString("NEW_SERVER_GAME_DIALOG", "MSG_CONNECTIONREFUSED_GAMEDATAMISMATCH");
       break;
     case ConnectionResult.CardDatabaseMismatch:
       errorMessage = servicesProvider.SystemStringsService.GetString("NEW_SERVER_GAME_DIALOG", "MSG_CONNECTIONREFUSED_CARDDATAMISMATCH");
       break;
     case ConnectionResult.PasswordRequired:
       errorMessage = servicesProvider.SystemStringsService.GetString("NEW_SERVER_GAME_DIALOG", "MSG_CONNECTIONREFUSED_PASSWORDREQUIRED");
       break;
       }
     }
     else
     {
       Thread.Sleep(100);
       client.SendMessage(new ConfirmMessage());
       opponentData = new ServerData()
       {
     Channel = client,
     Player = connectionMessagesHandler.Handshake.PlayerInfo,
     Deck = new DeckItem(connectionMessagesHandler.Handshake.Deck)
       };
       confirmed = true;
     }
       }
       catch(Exception ex)
       {
     errorMessage = ex.Message;
       }
       finally
       {
     connectionMessagesHandler.Dispose();
       }
       return confirmed;
 }