@SuppressWarnings({"rawtypes", "unchecked"})
    public static boolean validateOutboundMessageAndMigrate(String testCaseName, MessageInput<?> messageInput, Element referenceXml, byte[] data, ByteOrder byteOrder, boolean autoMigrate, URI siteURI) throws DriverTestsuiteException {
        final ReadBufferByteBased readBuffer = new ReadBufferByteBased(data, byteOrder);

        try {
            final Message parsedOutput = (Message) messageInput.parse(readBuffer);
            final String referenceXmlString = referenceXml.asXML();
            try {
                // First try to use the native xml writer
                WriteBufferXmlBased writeBufferXmlBased = new WriteBufferXmlBased();
                parsedOutput.serialize(writeBufferXmlBased);
                String xmlString = writeBufferXmlBased.getXmlString();
                final Diff diff = DiffBuilder.compare(referenceXmlString)
                    .withAttributeFilter(new SkipAttributeFilter())
                    .withDifferenceEvaluator(new SkipDifferenceEvaluator())
                    .withTest(xmlString).checkForSimilar().ignoreComments().ignoreWhitespace()
                    .build();
                if (diff.hasDifferences()) {
                    String border = StringUtils.repeat("=", 100);
                    String centeredDiffDetectedMessage = StringUtils.center(" Diff detected ", 100, "=");
                    String centeredTestCaseName = StringUtils.center(testCaseName, 100, "=");
                    LOGGER.warn(String.format(
                        "\n" +
                            // Border
                            "%1$s\n" +
                            // Testcase name
                            "%5$s\n" +
                            // diff detected message
                            "%2$s\n" +
                            // Border
                            "%1$s\n" +
                            // xml
                            "%3$s\n" +
                            // Border
                            "%1$s\n%1$s\n" +
                            // Text
                            "Differences were found after parsing (Use the above xml in the testsuite to disable this warning).\n" +
                            // Diff
                            "%4$s\n" +
                            // Location
                            "%6$s\n" +
                            // Double Border
                            "%1$s\n%1$s\n",
                        border,
                        centeredDiffDetectedMessage,
                        xmlString,
                        diff,
                        centeredTestCaseName,
                        ((LocationAwareElement) referenceXml).getLocation().toString()));
                    throw new MigrationException(xmlString);
                }
                return false;
            } catch (RuntimeException | SerializationException e) {
                if (!(e instanceof MigrationException)) {
                    LOGGER.error("Error in serializer", e);
                }
                if (autoMigrate && e instanceof MigrationException) {
                    Path path = Paths.get(siteURI);
                    LOGGER.info("Migrating {} now", path);
                    Charset charset = StandardCharsets.UTF_8;

                    String content;
                    try {
                        // REMARK: In know IntelliJ tells us this is "optimizable", don't do it as it will break the build.
                        content = new String(Files.readAllBytes(path), charset);
                        // Make sure this also works on Windows
                        // (Mainly when using git to check out Windows style and commit in Unix style)
                        content = content.replaceAll("\r\n", "\n");
                    } catch (IOException ioException) {
                        throw new RuntimeException(ioException);
                    }
                    String indent = TestCasePatcher.determineIndent(content, referenceXmlString);
                    String newXml = ((MigrationException) e).newXml;
                    newXml = TestCasePatcher.indent(newXml, indent);
                    Pattern patternForReferenceXmlString = TestCasePatcher.getPatternForFragment(referenceXmlString);
                    if (!patternForReferenceXmlString.matcher(content).find()) {
                        throw new RuntimeException("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\nAuto migration failed: Can't match content. Patching won't work..\nTry to copy the above xml manually. \n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
                    }
                    content = RegExUtils.replaceFirst(content, patternForReferenceXmlString, newXml + "\n");
                    try {
                        Files.write(path, content.getBytes(charset));
                    } catch (IOException ioException) {
                        throw new RuntimeException(ioException);
                    }
                    LOGGER.info("Done migrating {}", path);
                    return true;
                } else if(e instanceof MigrationException) {
                    MigrationException me = (MigrationException) e;
                    throw new RuntimeException("Output doesn't match.\nGot:\n" + me.newXml + "\nSet to auto migrate to fix", e);
                } else {
                    throw new RuntimeException("Output doesn't match. Set to auto migrate to fix", e);
                }
            }
        } catch (ParseException e) {
            throw new DriverTestsuiteException("Error parsing message", e);
        } catch (RuntimeException e) {
            LOGGER.error("Something went wrong: siteURI='{}'", siteURI, e);
            throw e;
        }
    }
Validates a outbound message and migrates it to the expectation if the parameter
{@code autoMigrate} is set to true

@param testCaseName name of the testcase
@param messageInput the pre-constructed MessageInput
@param referenceXml the xml we expect the outbound message to be
@param data the bytes of the message
@param byteOrder the byte-order being used
@param autoMigrate indicates if we want to migrate to a new version
@param siteURI the file which we want to auto migrate
@return true if migration happened
@throws DriverTestsuiteException if something goes wrong
plc4j/utils/test-utils/src/main/java/org/apache/plc4x/test/migration/MessageValidatorAndMigrator.java