### Question:
MessageDecryptVerifier { public static List<Part> findSignedParts(Part startPart, MessageCryptoAnnotations messageCryptoAnnotations) { List<Part> signedParts = new ArrayList<>(); Stack<Part> partsToCheck = new Stack<>(); partsToCheck.push(startPart); while (!partsToCheck.isEmpty()) { Part part = partsToCheck.pop(); if (messageCryptoAnnotations.has(part)) { CryptoResultAnnotation resultAnnotation = messageCryptoAnnotations.get(part); MimeBodyPart replacementData = resultAnnotation.getReplacementData(); if (replacementData != null) { part = replacementData; } } Body body = part.getBody(); if (isPartMultipartSigned(part)) { signedParts.add(part); continue; } if (body instanceof Multipart) { Multipart multipart = (Multipart) body; for (int i = multipart.getCount() - 1; i >= 0; i--) { BodyPart bodyPart = multipart.getBodyPart(i); partsToCheck.push(bodyPart); } } } return signedParts; }  static Part findPrimaryEncryptedOrSignedPart(Part part, List<Part> outputExtraParts); static List<Part> findEncryptedParts(Part startPart); static List<Part> findSignedParts(Part startPart, MessageCryptoAnnotations messageCryptoAnnotations); static List<Part> findPgpInlineParts(Part startPart); static byte[] getSignatureData(Part part); static boolean isPgpMimeEncryptedOrSignedPart(Part part); static boolean isSMimeEncryptedOrSignedPart(Part part); static boolean isPartPgpInlineEncrypted(@Nullable Part part);  }### Answer:
@Test public void findSigned__withSimpleMultipartSigned__shouldReturnRoot() throws Exception { Message message = messageFromBody( multipart("signed", bodypart("text/plain"), bodypart("application/pgp-signature") ) ); List<Part> signedParts = MessageDecryptVerifier.findSignedParts(message, messageCryptoAnnotations); assertEquals(1, signedParts.size()); assertSame(message, signedParts.get(0)); }
@Test public void findSigned__withComplexMultipartSigned__shouldReturnRoot() throws Exception { Message message = messageFromBody( multipart("signed", multipart("mixed", bodypart("text/plain"), bodypart("application/pdf") ), bodypart("application/pgp-signature") ) ); List<Part> signedParts = MessageDecryptVerifier.findSignedParts(message, messageCryptoAnnotations); assertEquals(1, signedParts.size()); assertSame(message, signedParts.get(0)); }
@Test public void findEncrypted__withMultipartMixedSubSigned__shouldReturnSigned() throws Exception { Message message = messageFromBody( multipart("mixed", multipart("signed", bodypart("text/plain"), bodypart("application/pgp-signature") ) ) ); List<Part> signedParts = MessageDecryptVerifier.findSignedParts(message, messageCryptoAnnotations); assertEquals(1, signedParts.size()); assertSame(getPart(message, 0), signedParts.get(0)); }
@Test public void findEncrypted__withMultipartMixedSubSignedAndText__shouldReturnSigned() throws Exception { Message message = messageFromBody( multipart("mixed", multipart("signed", bodypart("text/plain"), bodypart("application/pgp-signature") ), bodypart("text/plain") ) ); List<Part> signedParts = MessageDecryptVerifier.findSignedParts(message, messageCryptoAnnotations); assertEquals(1, signedParts.size()); assertSame(getPart(message, 0), signedParts.get(0)); }
@Test public void findEncrypted__withMultipartMixedSubTextAndSigned__shouldReturnSigned() throws Exception { Message message = messageFromBody( multipart("mixed", bodypart("text/plain"), multipart("signed", bodypart("text/plain"), bodypart("application/pgp-signature") ) ) ); List<Part> signedParts = MessageDecryptVerifier.findSignedParts(message, messageCryptoAnnotations); assertEquals(1, signedParts.size()); assertSame(getPart(message, 1), signedParts.get(0)); }