public void Shutdown_Lobby( ELobbyID lobby_id, ELobbyDestroyedReason reason )
        {
            CLog.Log( ELoggingChannel.Lobby, ELogLevel.Medium, String.Format( "Shutting down lobby {0} for reason {1}.",
                                                                                                    Get_Lobby_Log_Description( lobby_id ),
                                                                                                    reason.ToString() ) );

            CServerLobby lobby = Get_Lobby( lobby_id );
            if ( lobby == null )
            {
                return;
            }

            if ( lobby.IsPublic )
            {
                CServerLobbyBrowserManager.Instance.Notify_Browsers_Of_Removed_Lobby( lobby_id );
            }

            List< EPersistenceID > members = new List< EPersistenceID >( lobby.MemberIDs );
            members.Apply( member => Remove_From_Lobby( lobby.ID, member, Compute_Removal_Reason( reason ) ) );

            if ( lobby.ChatChannel != EChannelID.Invalid )
            {
                CDestroyChatChannelServerMessage destroy_channel_message = new CDestroyChatChannelServerMessage( lobby.ChatChannel );
                CServerMessageRouter.Send_Message_To_Chat_Server( destroy_channel_message );
            }

            m_Lobbies.Remove( lobby_id );
            m_LobbiesByCreator.Remove( lobby.Creator );
        }
        public void On_Match_Chat_Channel_Creation_Response( EMatchInstanceID match_id, CCreateChatChannelResponseServerMessage response_msg )
        {
            CServerMatchInstance match_instance = Get_Match_Instance( match_id );
            if ( match_instance == null )
            {
                if ( response_msg.ChannelID != EChannelID.Invalid )
                {
                    CDestroyChatChannelServerMessage destroy_channel_message = new CDestroyChatChannelServerMessage( response_msg.ChannelID );
                    CServerMessageRouter.Send_Message_To_Chat_Server( destroy_channel_message );
                }

                return;
            }

            // Chat creation and joining should never fail
            if ( response_msg.Error != EChannelCreationError.None )
            {
                Shutdown_Match( match_id, EMatchDestroyedReason.Chat_Channel_Creation_Failure );
                return;
            }

            match_instance.MatchChannel = response_msg.ChannelID;
            match_instance.Perform_Match_Channel_Joins();
        }
        public void On_Lobby_Chat_Channel_Creation_Response( ELobbyID lobby_id, EPersistenceID player_id, CCreateChatChannelResponseServerMessage response_msg )
        {
            CServerLobby lobby = Get_Lobby( lobby_id );
            if ( lobby == null )
            {
                if ( response_msg.ChannelID != EChannelID.Invalid )
                {
                    CDestroyChatChannelServerMessage destroy_channel_message = new CDestroyChatChannelServerMessage( response_msg.ChannelID );
                    CServerMessageRouter.Send_Message_To_Chat_Server( destroy_channel_message );
                }

                return;
            }

            CLog.Log( ELoggingChannel.Lobby, ELogLevel.Medium, String.Format( "Lobby {0} chat channel {1} creation result = {2}.",
                                                                                                    Get_Lobby_Log_Description( lobby_id ),
                                                                                                    response_msg.ChannelName,
                                                                                                    response_msg.Error.ToString() ) );

            if ( response_msg.Error != EChannelCreationError.None )
            {
                Shutdown_Lobby( lobby_id, ELobbyDestroyedReason.Chat_Channel_Creation_Failure );
                return;
            }

            lobby.Initialize_Chat_Channel( response_msg.ChannelID );
            lobby.ConnectedMemberIDs.Apply( pid => CAsyncBackendOperations.Player_Join_Lobby_Channel( pid, lobby_id, lobby.ChatChannel ) );
        }
        public void Shutdown_Match( EMatchInstanceID match_id, EMatchDestroyedReason reason )
        {
            CServerMatchInstance match_instance = Get_Match_Instance( match_id );
            if ( match_instance == null )
            {
                return;
            }

            match_instance.PlayersAndObservers.Duplicate_As_List().Apply( mid => Remove_From_Match( match_id, mid, Compute_Removal_Reason( reason ) ) );

            if ( match_instance.MatchChannel != EChannelID.Invalid )
            {
                CDestroyChatChannelServerMessage destroy_channel_message = new CDestroyChatChannelServerMessage( match_instance.MatchChannel );
                CServerMessageRouter.Send_Message_To_Chat_Server( destroy_channel_message );
            }

            if ( match_instance.ObserverChannel != EChannelID.Invalid )
            {
                CDestroyChatChannelServerMessage destroy_channel_message = new CDestroyChatChannelServerMessage( match_instance.ObserverChannel );
                CServerMessageRouter.Send_Message_To_Chat_Server( destroy_channel_message );
            }

            match_instance.Shutdown();

            m_MatchInstances.Remove( match_id );
        }