/**
   * Process the MimeMessage for signed mail with/without attachment.
   *
   * @param mime
   * @param mailMsg
   * @return
   * @throws MessagingException
   * @throws IOException
   * @throws ParseException
   */
  private String processSignedMail(MimeMessage mime, MailMessage mailMsg)
      throws IOException, MessagingException, ParseException {
    this.setMailBasicInfoForMailMsg(mime, mailMsg);

    String txtBody = null;
    String htmlBody = null;
    // Get the content of the messsage, it's an Multipart object like a package including all the
    // email text and attachment.
    Multipart multi1 = (Multipart) mime.getContent();
    // process each part in order.
    for (int i = 0, n = multi1.getCount(); i < n; i++) {
      // unpack, get each part of Multipart, part 0 may email text and part 1 may attachment. Or it
      // is another embedded Multipart.
      Part part2 = multi1.getBodyPart(i);
      // determine Part is email text or Multipart.
      if (part2.getContent() instanceof Multipart) {
        Multipart multi2 = (Multipart) part2.getContent();
        // First, verify the quantity and size of attachments.
        boolean isValidMailMsg = this.isValidMailMsg(multi2);
        if (isValidMailMsg) {
          // process the content in multi2.
          for (int j = 0; j < multi2.getCount(); j++) {
            Part part3 = multi2.getBodyPart(j);
            if (part3.isMimeType("text/plain")
                && !Part.ATTACHMENT.equalsIgnoreCase(part3.getDisposition())) {
              txtBody = part3.getContent().toString();
            } else if (part3.isMimeType("text/html")
                && !Part.ATTACHMENT.equalsIgnoreCase(part3.getDisposition())) {
              htmlBody = part3.getContent().toString();
            } else if (part3.isMimeType("multipart/alternative")) {
              // generally if the content type multipart/alternative, it is email text.
              if (part3.getContent() instanceof Multipart) {
                Multipart multi3 = (Multipart) part3.getContent();
                for (int k = 0; k < multi3.getCount(); k++) {
                  Part part4 = multi3.getBodyPart(k);
                  if (part4.isMimeType("text/plain")
                      && !Part.ATTACHMENT.equalsIgnoreCase(part4.getDisposition())) {
                    txtBody = part4.getContent().toString();
                  } else if (part4.isMimeType("text/html")
                      && !Part.ATTACHMENT.equalsIgnoreCase(part4.getDisposition())) {
                    htmlBody = part4.getContent().toString();
                  }
                }
              }
            } else if (part3.isMimeType("multipart/related")) {
              if (part3.getContent() instanceof Multipart) {
                Multipart multi3 = (Multipart) part3.getContent();
                for (int m = 0; m < multi3.getCount(); m++) {
                  Part part4 = multi3.getBodyPart(m);
                  if (part4.isMimeType("multipart/alternative")) {
                    if (part4.getContent() instanceof Multipart) {
                      Multipart multi4 = (Multipart) part4.getContent();
                      for (int p = 0; p < multi4.getCount(); p++) {
                        Part part5 = multi4.getBodyPart(p);
                        if (part5.isMimeType("text/plain")
                            && !Part.ATTACHMENT.equalsIgnoreCase(part5.getDisposition())) {
                          txtBody = part5.getContent().toString();
                        } else if (part5.isMimeType("text/html")
                            && !Part.ATTACHMENT.equalsIgnoreCase(part5.getDisposition())) {
                          htmlBody = part5.getContent().toString();
                        }
                      }
                    }
                  } else {
                    // This is an embedded picture, set it as an attachment.
                    mailMsg.setHasAttachments(true);
                  }
                }
              }
            } else {
              String disposition = part3.getDisposition();
              if (disposition != null && Part.ATTACHMENT.equalsIgnoreCase(disposition)) {
                mailMsg.setHasAttachments(true);
              }
            }
          }
        }
      } else {
        // This is a certificate file, set it as an attachment
        String disposition = part2.getDisposition();
        if (disposition != null && Part.ATTACHMENT.equalsIgnoreCase(disposition)) {
          mailMsg.setHasAttachments(true);
        }
      }
    }
    if (!isNull(txtBody)) {
      mailMsg.setBody(txtBody);
    } else {
      mailMsg.setBody(htmlBody);
    }
    return JSONObject.fromObject(mailMsg).toString();
  }