def _extract_message_parts(msg: email.message.EmailMessage) -> Tuple[str, str, List[Dict[str, Union[str, bool]]]]:
        """Extract the ebXML and payload parts of the message and return them as a tuple.

        :param msg: The message to extract parts from.
        :return: A tuple containing the ebXML and payload (if present, otherwise None) parts of the message provided.
        """
        # EIS section 2.5.4 defines that the first MIME part must contain the ebML SOAP message and the message payload
        # (if present) must be the first additional attachment.

        if not msg.is_multipart():
            logger.error('Non-multipart message received')
            raise ebxml_envelope.EbXmlParsingError("Non-multipart message received")

        message_parts: Sequence[email.message.EmailMessage] = tuple(msg.iter_parts())

        EbxmlRequestEnvelope._report_any_defects_in_message_parts(message_parts)

        # ebXML part is the first part of the message
        ebxml_part = EbxmlRequestEnvelope._extract_ebxml_part(message_parts[0])

        payload_part = None
        attachments = []
        if len(message_parts) > 1:
            # HL7 payload part is the second part of the message
            payload_part = EbxmlRequestEnvelope._extract_hl7_payload_part(message_parts[1])

            # Any additional attachments are from the third part of the message onwards
            attachments.extend(EbxmlRequestEnvelope._extract_additional_attachments_parts(message_parts[2:]))

        return ebxml_part, payload_part, attachments
    def _get_payload(self, message: email.message.EmailMessage) -> str:
        """
        Get the body of the email.

        Note: MODIFIES message fetched to be seen.
        """
        if message.is_multipart():
            return message.get_payload(0).get_payload()
        else:
            return message.get_payload(0)