def swap_gender(sim_info: SimInfo, update_gender_options: bool=True) -> bool:
        """swap_gender(sim_info, update_gender_options=True)

        Swap the Gender of a Sim to it's opposite. i.e. Change a Sim from Male to Female or from Female to Male.

        :param sim_info: An instance of a Sim.
        :type sim_info: SimInfo
        :param update_gender_options: If True, gender option traits such as Toilet Usage, Clothing Preference, Pregnancy, and Body Frame will be updated to reflect the vanilla settings for each gender\
        For example, if a Human Sim is swapping from Female to Male, their gender options will be updated to Toilet Standing, Cannot Be Impregnated, Can Impregnate, Mens Wear clothing preference, and Masculine Frame.\
        If False, gender option traits will not be updated.\
        Default is True.
        :type update_gender_options: bool, optional
        :return: True, if the Gender of the Sim was swapped successfully. False, if not.
        :rtype: bool
        """
        from sims4communitylib.utils.sims.common_sim_gender_option_utils import CommonSimGenderOptionUtils
        result = False
        frame = CommonSimGenderOptionUtils.has_masculine_frame(sim_info)
        prefers_menswear = CommonSimGenderOptionUtils.prefers_menswear(sim_info)
        can_impregnate = CommonSimGenderOptionUtils.can_impregnate(sim_info)
        can_be_impregnated = CommonSimGenderOptionUtils.can_be_impregnated(sim_info)
        can_reproduce = CommonSimGenderOptionUtils.can_reproduce(sim_info)
        uses_toilet_standing = CommonSimGenderOptionUtils.uses_toilet_standing(sim_info)
        has_breasts = CommonSimGenderOptionUtils.has_breasts(sim_info)
        saved_outfits = sim_info.save_outfits()
        current_outfit = CommonOutfitUtils.get_current_outfit(sim_info)
        if CommonGenderUtils.is_male(sim_info):
            result = CommonGenderUtils.set_gender(sim_info, Gender.FEMALE)
            if update_gender_options:
                CommonSimGenderOptionUtils.update_gender_options_to_vanilla_female(sim_info)
        elif CommonGenderUtils.is_female(sim_info):
            result = CommonGenderUtils.set_gender(sim_info, Gender.MALE)
            if update_gender_options:
                CommonSimGenderOptionUtils.update_gender_options_to_vanilla_male(sim_info)
        if not update_gender_options:
            CommonSimGenderOptionUtils.update_body_frame(sim_info, frame)
            CommonSimGenderOptionUtils.update_clothing_preference(sim_info, prefers_menswear)
            CommonSimGenderOptionUtils.update_can_impregnate(sim_info, can_impregnate)
            CommonSimGenderOptionUtils.update_can_be_impregnated(sim_info, can_be_impregnated)
            CommonSimGenderOptionUtils.update_can_reproduce(sim_info, can_reproduce)
            CommonSimGenderOptionUtils.update_toilet_usage(sim_info, uses_toilet_standing)
            CommonSimGenderOptionUtils.update_has_breasts(sim_info, has_breasts)
            sim_info.load_outfits(saved_outfits)
            CommonOutfitUtils.resend_outfits(sim_info)
            CommonOutfitUtils.set_current_outfit(sim_info, current_outfit)
        return result
    def attach_cas_part_to_sim(
        sim_info: SimInfo,
        cas_part_id: int,
        body_type: Union[BodyType, int] = BodyType.NONE,
        outfit_category_and_index: Union[Tuple[OutfitCategory, int],
                                         None] = None
    ) -> bool:
        """attach_cas_part_to_sim(sim_info, cas_part_id, body_type=BodyType.NONE, outfit_category_and_index=None)

        Add a CAS part at the specified BodyType to the Sims outfit.

        :param sim_info: The SimInfo of a Sim to add the CAS part to.
        :type sim_info: SimInfo
        :param cas_part_id: The decimal identifier of a CAS part to attach to the Sim.
        :type cas_part_id: int
        :param body_type: The BodyType the CAS part will be attached to. If no value is provided or it is None, the BodyType of the CAS part itself will be used.
        :type body_type: Union[BodyType, int], optional
        :param outfit_category_and_index: The outfit category and index of the Sims outfit to modify. If no value is provided, the Sims current outfit will be used.
        :type outfit_category_and_index: Union[Tuple[OutfitCategory, int], None], optional
        :return: True if the CAS part was successfully attached to the Sim. False if the CAS part was not successfully attached to the Sim.
        :rtype: bool
        """
        log.format_with_message(
            'Attempting to attach CAS part to Sim',
            sim=sim_info,
            cas_part_id=cas_part_id,
            body_type=body_type,
            outfit_category_and_index=outfit_category_and_index)
        if cas_part_id == -1 or cas_part_id is None:
            raise RuntimeError('No cas_part_id was provided.')
        log.debug('Pre-saving outfits.')
        saved_outfits = sim_info.save_outfits()
        if outfit_category_and_index is None:
            outfit_category_and_index = CommonOutfitUtils.get_current_outfit(
                sim_info)
        log.format_with_message(
            'Using outfit category and index.',
            outfit_category_and_index=outfit_category_and_index)
        outfit_data = CommonOutfitUtils.get_outfit_data(
            sim_info, outfit_category_and_index=outfit_category_and_index)
        outfit_identifier = frozenset(
            dict(zip(list(outfit_data.body_types),
                     list(outfit_data.part_ids))).items())
        if body_type is None or body_type == BodyType.NONE:
            body_type = CommonCASUtils.get_body_type_of_cas_part(cas_part_id)
        log.format_with_message('Using body_type', body_type=body_type)
        for outfit in saved_outfits.outfits:
            log.format_with_message('Attempting to update outfit.',
                                    outfit=outfit)
            # noinspection PyUnresolvedReferences
            _outfit_identifier = frozenset(
                dict(
                    zip(list(outfit.body_types_list.body_types),
                        list(outfit.parts.ids))).items())
            if int(outfit.category) != int(
                    outfit_category_and_index[0]
            ) or outfit.outfit_id != outfit_data.outfit_id or _outfit_identifier != outfit_identifier:
                log.format_with_message(
                    'Outfit is not the outfit we want to update, skipping.',
                    outfit_id=outfit.outfit_id,
                    outfit_category=outfit.category)
                continue
            log.debug('Updating outfit.')
            # noinspection PyUnresolvedReferences
            previous_cas_parts_list = list(outfit.parts.ids)
            if cas_part_id not in previous_cas_parts_list:
                log.format_with_message('Adding CAS part id.',
                                        cas_part_id=cas_part_id)
                previous_cas_parts_list.append(cas_part_id)
            outfit.parts = S4Common_pb2.IdList()
            # noinspection PyUnresolvedReferences
            outfit.parts.ids.extend(previous_cas_parts_list)
            # noinspection PyUnresolvedReferences
            previous_body_types_list = list(outfit.body_types_list.body_types)
            if body_type not in previous_body_types_list:
                log.format_with_message('Adding BodyType.',
                                        body_type=body_type)
                previous_body_types_list.append(body_type)
            outfit.body_types_list = Outfits_pb2.BodyTypesList()
            # noinspection PyUnresolvedReferences
            outfit.body_types_list.body_types.extend(previous_body_types_list)
            log.debug('Done updating outfit.')
        log.debug('Done updating outfits.')
        sim_info._base.outfits = saved_outfits.SerializeToString()
        sim_info._base.outfit_type_and_index = outfit_category_and_index
        log.debug('Resending outfits.')
        CommonOutfitUtils.resend_outfits(sim_info)
        log.debug('Done adding CAS part to Sim.')
        return True