void handleAclsDelta(AclsImage prevImage, AclsImage image, AclsDelta delta, KRaftMigrationOperationConsumer operationConsumer) {
        // Need to collect all ACLs for any changed resource pattern
        Map<ResourcePattern, List<AccessControlEntry>> aclsToWrite = new HashMap<>();
        delta.changes().forEach((aclId, aclChange) -> {
            if (aclChange.isPresent()) {
                ResourcePattern resourcePattern = resourcePatternFromAcl(aclChange.get());
                aclsToWrite.put(resourcePattern, new ArrayList<>());
            } else {
                // We need to look in the previous image to get deleted ACLs resource pattern
                StandardAcl deletedAcl = prevImage.acls().get(aclId);
                if (deletedAcl == null) {
                    errorLogger.accept("Cannot delete ACL " + aclId + " from ZK since it is missing from previous AclImage");
                } else {
                    ResourcePattern resourcePattern = resourcePatternFromAcl(deletedAcl);
                    aclsToWrite.put(resourcePattern, new ArrayList<>());
                }
            }
        });

        // Iterate through the new image to collect any ACLs for these changed resources
        image.acls().forEach((uuid, standardAcl) -> {
            ResourcePattern resourcePattern = resourcePatternFromAcl(standardAcl);
            List<AccessControlEntry> entries = aclsToWrite.get(resourcePattern);
            if (entries != null) {
                entries.add(new AccessControlEntry(standardAcl.principal(), standardAcl.host(), standardAcl.operation(), standardAcl.permissionType()));
            }
        });

        // If there are no more ACLs for a resource, delete it. Otherwise, update it with the new set of ACLs
        aclsToWrite.forEach((resourcePattern, accessControlEntries) -> {
            if (accessControlEntries.isEmpty()) {
                String logMsg = "Deleted resource " + resourcePattern + " which has no more ACLs";
                operationConsumer.accept(DELETE_ACL, logMsg, migrationState ->
                    migrationClient.aclClient().deleteResource(resourcePattern, migrationState));
            } else {
                String logMsg = "Wrote " + accessControlEntries.size() + " for resource " + resourcePattern;
                operationConsumer.accept(UPDATE_ACL, logMsg, migrationState ->
                    migrationClient.aclClient().writeResourceAcls(resourcePattern, accessControlEntries, migrationState));
            }
        });
    }
Handle a snapshot of the topic metadata. This requires scanning through all the topics and partitions
in ZooKeeper to determine what has changed. Topic configs are not handled here since they exist in the
ConfigurationsImage.
metadata/src/main/java/org/apache/kafka/metadata/migration/KRaftMigrationZkWriter.java