private boolean startSync(boolean dryRun, Path syncLocation, Map<PluginType, Set<String>> before, Map<PluginType, Set<String>> after) {
        Objects.requireNonNull(syncLocation, "syncLocation must be non-null");
        Objects.requireNonNull(before, "before must be non-null");
        Objects.requireNonNull(after, "after must be non-null");
        if (before.equals(after)) {
            return false;
        }
        Set<String> added = new HashSet<>();
        after.values().forEach(added::addAll);
        before.values().forEach(added::removeAll);
        Set<String> removed = new HashSet<>();
        before.values().forEach(removed::addAll);
        after.values().forEach(removed::removeAll);
        out.printf("%sSync\t%s Add %s Remove %s%n", dryRun ? "Dry Run " : "", syncLocation, added.size(), removed.size());
        for (String add : added) {
            out.printf("\tAdd\t%s%n", add);
        }
        for (String rem : removed) {
            out.printf("\tRemove\t%s%n", rem);
        }
        return true;
    }
The class hierarchy is similar to the single-jar because there can only be one manifest per type.
However, the path to that single manifest is accessed via the pluginLocation.
tools/src/main/java/org/apache/kafka/tools/ManifestWorkspace.java