@VisibleForTesting
    static String generateMigrationFile(QualifiedVersion version, String template, List<ChangelogEntry> entries) throws IOException {
        final Map<Boolean, Map<String, List<ChangelogEntry.Deprecation>>> deprecationsByNotabilityByArea = entries.stream()
            .map(ChangelogEntry::getDeprecation)
            .filter(Objects::nonNull)
            .sorted(comparing(ChangelogEntry.Deprecation::getTitle))
            .collect(
                groupingBy(
                    ChangelogEntry.Deprecation::isNotable,
                    TreeMap::new,
                    groupingBy(ChangelogEntry.Deprecation::getArea, TreeMap::new, toList())
                )
            );

        final Map<Boolean, Map<String, List<ChangelogEntry.Breaking>>> breakingByNotabilityByArea = entries.stream()
            .map(ChangelogEntry::getBreaking)
            .filter(Objects::nonNull)
            .sorted(comparing(ChangelogEntry.Breaking::getTitle))
            .collect(
                groupingBy(
                    ChangelogEntry.Breaking::isNotable,
                    TreeMap::new,
                    groupingBy(ChangelogEntry.Breaking::getArea, TreeMap::new, toList())
                )
            );

        final Map<String, Object> bindings = new HashMap<>();
        bindings.put("breakingByNotabilityByArea", breakingByNotabilityByArea);
        bindings.put("deprecationsByNotabilityByArea", deprecationsByNotabilityByArea);
        bindings.put("isElasticsearchSnapshot", version.isSnapshot());
        bindings.put("majorDotMinor", version.major() + "." + version.minor());
        bindings.put("majorDotMinorDotRevision", version.major() + "." + version.minor() + "." + version.revision());
        bindings.put("majorMinor", String.valueOf(version.major()) + version.minor());
        bindings.put("nextMajor", (version.major() + 1) + ".0");
        bindings.put("version", version);

        return TemplateUtils.render(template, bindings);
    }
@Test
    public void generateIndexFile_rendersCorrectMarkup() throws Exception {
        // given:
        final String template = getResource("/templates/breaking-changes.asciidoc");
        final String expectedOutput = getResource(
            "/org/elasticsearch/gradle/internal/release/BreakingChangesGeneratorTest.generateMigrationFile.asciidoc"
        );

        final List<ChangelogEntry> entries = getEntries();

        // when:
        final String actualOutput = BreakingChangesGenerator.generateMigrationFile(
            QualifiedVersion.of("8.4.0-SNAPSHOT"),
            template,
            entries
        );

        // then:
        assertThat(actualOutput, equalTo(expectedOutput));
    }