/// <summary>
        /// Game session monitor (worker thread)
        /// </summary>
        public void GameSessionsMonitorThreadFunc()
        {
            NetworkBackgammonEventQueueElement queueElement = null;

            while (gameSessionsMonitorKeepRunning)
            {
                gameSessionsSemaphore.WaitOne();

                lock (gameSessionsEventQueue)
                {
                    if (gameSessionsEventQueue.Count > 0)
                    {
                        queueElement = gameSessionsEventQueue.Dequeue();
                    }
                }

                if (queueElement != null)
                {
                    if (queueElement.Notifier is NetworkBackgammonGameSession &&
                        queueElement.Event is NetworkBackgammonGameSessionEvent)
                    {
                        NetworkBackgammonGameSession      gameSession      = (NetworkBackgammonGameSession)queueElement.Notifier;
                        NetworkBackgammonGameSessionEvent gameSessionEvent = (NetworkBackgammonGameSessionEvent)queueElement.Event;

                        if (gameSessionEvent.EventType == NetworkBackgammonGameSessionEvent.GameSessionEventType.GameFinished)
                        {
                            // Broadcast the game active event to all registered listeners
                            Broadcast(new NetworkBackgammonGameRoomEvent(NetworkBackgammonGameRoomEvent.GameRoomEventType.PlayerFinished));

                            gameSession.Stop();

                            gameSessions.Remove(gameSession);

                            gameSession = null;

                            GC.Collect();
                        }
                    }
                }

                queueElement = null;
            }
        }
        /// <summary>
        /// Exit the game room by player
        /// </summary>
        /// <param name="_player">Backgammon player who wants to leave the game room</param>
        public void Leave(NetworkBackgammonPlayer _player)
        {
            if (connectedPlayers.Contains(_player))
            {
                // The disconnected player should no longer be listening...
                RemoveListener(_player);
                // Stop listening to this player
                _player.RemoveListener(this);

                // Check if player is associated with a game room and remove if necessary
                NetworkBackgammonGameSession _playerGameSession = GetGameSession(_player);

                if (_playerGameSession != null)
                {
                    // Disconnect the player from the game session
                    _player.RemoveListener(_playerGameSession);
                    // Disconnect the game session from the player
                    _playerGameSession.RemoveListener(_player);

                    // Get the opposing player
                    NetworkBackgammonPlayer opposingPlayer = _playerGameSession.GetOpponent(_player);

                    if (opposingPlayer != null)
                    {
                        // Disconnect the player from the game session
                        opposingPlayer.RemoveListener(_playerGameSession);
                        // Disconnect the game session from the player
                        _playerGameSession.RemoveListener(opposingPlayer);
                    }

                    // Halt the game sesssion
                    _playerGameSession.Stop();
                }

                // Remove player from connected player list
                connectedPlayers.Remove(_player);

                // Broadcast the player disconnected event to all registered listeners
                Broadcast(new NetworkBackgammonGameRoomEvent(NetworkBackgammonGameRoomEvent.GameRoomEventType.PlayerDisconnected));
            }
        }