private EMatchRemovalReason Compute_Removal_Reason( EMatchDestroyedReason destroy_reason )
        {
            switch ( destroy_reason )
            {
                case EMatchDestroyedReason.Player_Left_During_Creation:
                case EMatchDestroyedReason.Post_Halt_Timeout:
                case EMatchDestroyedReason.Match_Empty:
                    return EMatchRemovalReason.Match_Shutdown;

                default:
                    return EMatchRemovalReason.Invalid;
            }
        }
        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 );
        }