docs: def parse(ascii_armor_message: str, signing_key: Optional[SigningKey] = None,
                sender_pubkeys: Optional[List[str]] = None) -> dict:
          """
          Return a dict with parsed content (decrypted message, signature validation) ::
  
              {
                 'message':
                     {
                         'fields': {},
                         'content': str,
                      },
                 'signatures': [
                     {'pubkey': str, 'valid': bool, fields: {}}
                 ]
             }
  
          :param ascii_armor_message: The Ascii Armor Message Block including BEGIN and END headers
          :param signing_key: Optional Libnacl SigningKey instance to decrypt message
          :param sender_pubkeys: Optional sender's public keys list to verify signatures
          :exception libnacl.CryptError: Raise an exception if keypair fail to decrypt the message
          :exception MissingSigningKeyException: Raise an exception if no keypair given for encrypted message
  
          :return:
          """
          # regex patterns
          regex_begin_message = compile(BEGIN_MESSAGE_HEADER)
          regex_end_message = compile(END_MESSAGE_HEADER)
          regex_begin_signature = compile(BEGIN_SIGNATURE_HEADER)
          regex_end_signature = compile(END_SIGNATURE_HEADER)
          regex_fields = compile("^(Version|Comment): (.+)$")
  
          # trim message to get rid of empty lines
          ascii_armor_message = ascii_armor_message.strip(" \t\n\r")
  
          # init vars
          parsed_result = {
              'message':
                  {
                      'fields': {},
                      'content': '',
                  },
              'signatures': []
          }  # type: Dict[str, Any]
          cursor_status = 0
          message = ''
          signatures_index = 0
  
          # parse each line...
          for line in ascii_armor_message.splitlines(True):
  
              # if begin message header detected...
              if regex_begin_message.match(line):
                  cursor_status = ON_MESSAGE_FIELDS
                  continue
  
              # if we are on the fields lines...
              if cursor_status == ON_MESSAGE_FIELDS:
                  # parse field
                  m = regex_fields.match(line.strip())
                  if m:
                      # capture field
                      msg_field_name = m.groups()[0]
                      msg_field_value = m.groups()[1]
                      parsed_result['message']['fields'][msg_field_name] = msg_field_value
                      continue
  
                  # if blank line...
                  if line.strip("\n\t\r ") == '':
                      cursor_status = ON_MESSAGE_CONTENT
                      continue
  
              # if we are on the message content lines...
              if cursor_status == ON_MESSAGE_CONTENT:
  
                  # if a header is detected, end of message content...
                  if line.startswith(HEADER_PREFIX):
  
                      # if field Version is present, the message is encrypted...
                      if 'Version' in parsed_result['message']['fields']:
  
                          # If keypair instance to decrypt not given...
                          if signing_key is None:
                              # SigningKey keypair is mandatory to decrypt the message...
                              raise PARSER_MISSING_SIGNING_KEY_EXCEPTION
  
                          # decrypt message with secret key from keypair
                          message = AsciiArmor._decrypt(message, signing_key)
  
                      # save message content in result
                      parsed_result['message']['content'] = message
  
                      # if message end header...
                      if regex_end_message.match(line):
                          # stop parsing
                          break
  
                      # if signature begin header...
                      if regex_begin_signature.match(line):
                          # add signature dict in list
                          parsed_result['signatures'].append({
                              'fields': {}
                          })
                          cursor_status = ON_SIGNATURE_FIELDS
                          continue
                  else:
                      # if field Version is present, the message is encrypted...
                      if 'Version' in parsed_result['message']['fields']:
                          # concatenate encrypted line to message content
                          message += line
                      else:
                          # concatenate cleartext striped dash escaped line to message content
                          message += AsciiArmor._parse_dash_escaped_line(line)
  
              # if we are on a signature fields zone...
              if cursor_status == ON_SIGNATURE_FIELDS:
  
                  # parse field
                  m = regex_fields.match(line.strip())
                  if m:
                      # capture field
                      sig_field_name = m.groups()[0]
                      sig_field_value = m.groups()[1]
                      parsed_result['signatures'][signatures_index]['fields'][sig_field_name] = sig_field_value
                      continue
  
                  # if blank line...
                  if line.strip("\n\t\r ") == '':
                      cursor_status = ON_SIGNATURE_CONTENT
                      continue
  
              # if we are on the signature content...
              if cursor_status == ON_SIGNATURE_CONTENT:
  
                  # if no public keys provided...
                  if sender_pubkeys is None:
                      # raise exception
                      raise PARSER_MISSING_PUBLIC_KEYS_EXCEPTION
  
                  # if end signature header detected...
                  if regex_end_signature.match(line):
                      # end of parsing
                      break
  
                  # if begin signature header detected...
                  if regex_begin_signature.match(line):
                      signatures_index += 1
                      cursor_status = ON_SIGNATURE_FIELDS
                      continue
  
                  for pubkey in sender_pubkeys:
                      verifier = VerifyingKey(pubkey)
                      signature = base64.b64decode(line)
                      parsed_result['signatures'][signatures_index]['pubkey'] = pubkey
                      try:
                          libnacl.crypto_sign_verify_detached(signature, message, verifier.vk)
                          parsed_result['signatures'][signatures_index]['valid'] = True
                      except ValueError:
                          parsed_result['signatures'][signatures_index]['valid'] = False
  
          return parsed_result