public static AS2MessageDispositionNotificationEntity parseDispositionNotification(
            List<CharArrayBuffer> dispositionNotificationFields)
            throws ParseException {
        String reportingUA = null;
        String mtaName = null;
        String finalRecipient = null;
        String originalMessageId = null;
        DispositionMode dispositionMode = null;
        AS2DispositionType dispositionType = null;
        AS2DispositionModifier dispositionModifier = null;
        List<String> failures = new ArrayList<>();
        List<String> errors = new ArrayList<>();
        List<String> warnings = new ArrayList<>();
        Map<String, String> extensionFields = new HashMap<>();
        ReceivedContentMic receivedContentMic = null;
        CharArrayBuffer bodyPartFields = new CharArrayBuffer(DEFAULT_BUFFER_SIZE);

        for (int i = 0; i < dispositionNotificationFields.size(); i++) {
            final CharArrayBuffer fieldLine = dispositionNotificationFields.get(i);
            bodyPartFields.append(fieldLine);
            if (i < dispositionNotificationFields.size() - 1) {
                bodyPartFields.append('\r');
                bodyPartFields.append('\n');
            }
            final Field field = parseDispositionField(fieldLine);
            switch (field.getName().toLowerCase()) {
                case REPORTING_UA: {
                    if (field.getElements().length < 1) {
                        throw new ParseException("Invalid '" + MDNField.REPORTING_UA + "' field: UA name is missing");
                    }
                    reportingUA = field.getValue();
                    break;
                }
                case MDN_GATEWAY: {
                    Element[] elements = field.getElements();
                    if (elements.length < 2) {
                        throw new ParseException("Invalid '" + MDNField.MDN_GATEWAY + "' field: MTA name is missing");
                    }
                    mtaName = elements[1].getValue();
                    break;
                }
                case FINAL_RECIPIENT: {
                    Element[] elements = field.getElements();
                    if (elements.length < 2) {
                        throw new ParseException(
                                "Invalid '" + MDNField.FINAL_RECIPIENT + "' field: recipient address is missing");
                    }
                    finalRecipient = elements[1].getValue();
                    break;
                }
                case ORIGINAL_MESSAGE_ID: {
                    originalMessageId = field.getValue();
                    break;
                }
                case DISPOSITION: {
                    Element[] elements = field.getElements();
                    if (elements.length < 2) {
                        throw new ParseException("Invalid '" + MDNField.DISPOSITION + "' field: " + field.getValue());
                    }
                    dispositionMode = DispositionMode.parseDispositionMode(elements[0].getValue());
                    if (dispositionMode == null) {
                        throw new ParseException(
                                "Invalid '" + MDNField.DISPOSITION + "' field: invalid disposition mode '"
                                                 + elements[0].getValue() + "'");
                    }

                    String dispositionTypeString = elements[1].getValue();
                    int slash = dispositionTypeString.indexOf("/");
                    if (slash == -1) {
                        dispositionType = AS2DispositionType.parseDispositionType(dispositionTypeString);
                    } else {
                        dispositionType = AS2DispositionType.parseDispositionType(dispositionTypeString.substring(0, slash));
                        dispositionModifier
                                = AS2DispositionModifier.parseDispositionType(dispositionTypeString.substring(slash + 1));
                    }
                    break;
                }
                case FAILURE:
                    failures.add(field.getValue());
                    break;
                case ERROR:
                    errors.add(field.getValue());
                    break;
                case WARNING:
                    warnings.add(field.getValue());
                    break;
                case RECEIVED_CONTENT_MIC: {
                    Element[] elements = field.getElements();
                    if (elements.length < 1) {
                        throw new ParseException("Invalid '" + MDNField.RECEIVED_CONTENT_MIC + "' field: MIC is missing");
                    }
                    Element element = elements[0];
                    String[] parameters = element.getParameters();
                    if (parameters.length < 1) {
                        throw new ParseException(
                                "Invalid '" + MDNField.RECEIVED_CONTENT_MIC + "' field: digest algorithm ID is missing");
                    }
                    String digestAlgorithmId = parameters[0];
                    String encodedMessageDigest = element.getValue();
                    receivedContentMic = new ReceivedContentMic(digestAlgorithmId, encodedMessageDigest);
                    break;
                }
                default: // Extension Field
                    extensionFields.put(field.getName(), field.getValue());
            }
        }

        return new AS2MessageDispositionNotificationEntity(
                reportingUA,
                mtaName,
                finalRecipient,
                originalMessageId,
                dispositionMode,
                dispositionType,
                dispositionModifier,
                failures.toArray(new String[0]),
                errors.toArray(new String[0]),
                warnings.toArray(new String[0]),
                extensionFields,
                receivedContentMic,
                bodyPartFields.toString());
    }
@Test
    public void test() throws Exception {

        InputStream is = new ByteArrayInputStream(DISPOSITION_NOTIFICATION_CONTENT.getBytes());

        AS2SessionInputBuffer inbuffer = new AS2SessionInputBuffer(new BasicHttpTransportMetrics(), 8 * 1024);

        List<CharArrayBuffer> dispositionNotificationFields
                = EntityParser.parseBodyPartFields(inbuffer, is, null, BasicLineParser.INSTANCE,
                        new ArrayList<CharArrayBuffer>());
        AS2MessageDispositionNotificationEntity messageDispositionNotificationEntity
                = DispositionNotificationContentUtils.parseDispositionNotification(dispositionNotificationFields);

        assertEquals(EXPECTED_REPORTING_UA, messageDispositionNotificationEntity.getReportingUA(),
                "Unexpected Reporting UA value");
        assertEquals(EXPECTED_MTN_NAME, messageDispositionNotificationEntity.getMtnName(), "Unexpected MTN Name");
        assertEquals(EXPECTED_ORIGINAL_RECIPIENT,
                messageDispositionNotificationEntity.getExtensionFields().get("Original-Recipient"),
                "Unexpected Original Recipient");
        assertEquals(EXPECTED_FINAL_RECIPIENT, messageDispositionNotificationEntity.getFinalRecipient(),
                "Unexpected Final Reciptient");
        assertEquals(EXPECTED_ORIGINAL_MESSAGE_ID, messageDispositionNotificationEntity.getOriginalMessageId(),
                "Unexpected Original Message ID");
        assertEquals(EXPECTED_DISPOSITION_MODE, messageDispositionNotificationEntity.getDispositionMode(),
                "Unexpected Disposition Mode");
        assertNotNull(messageDispositionNotificationEntity.getDispositionModifier(), "Unexpected Null Disposition Modifier");
        assertEquals(EXPECTED_DISPOSITION_MODIFIER, messageDispositionNotificationEntity.getDispositionModifier().getModifier(),
                "Unexpected Disposition Modifier");
        assertEquals(EXPECTED_DISPOSITION_TYPE, messageDispositionNotificationEntity.getDispositionType(),
                "Unexpected Disposition Type");
        assertArrayEquals(EXPECTED_FAILURE, messageDispositionNotificationEntity.getFailureFields(),
                "Unexpected Failure Array value");
        assertArrayEquals(EXPECTED_ERROR, messageDispositionNotificationEntity.getErrorFields(),
                "Unexpected Error Array value");
        assertArrayEquals(EXPECTED_WARNING, messageDispositionNotificationEntity.getWarningFields(),
                "Unexpected Warning Array value");
        assertNotNull(messageDispositionNotificationEntity.getReceivedContentMic(), "Unexpected Null Received Content MIC");
        assertEquals(EXPECTED_ENCODED_MESSAGE_DIGEST,
                messageDispositionNotificationEntity.getReceivedContentMic().getEncodedMessageDigest(),
                "Unexpected Encoded Message Digest");
        assertEquals(EXPECTED_DIGEST_ALGORITHM_ID,
                messageDispositionNotificationEntity.getReceivedContentMic().getDigestAlgorithmId(),
                "Unexpected Digest Algorithm ID");
    }