package nbmtools;

import java.io.Closeable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.function.Function;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
import lombok.Value;
import org.apache.commons.collections4.EnumerationUtils;
import org.apache.commons.io.IOUtils;

public class ZipUtils {
    public static interface Entry extends Closeable {};

    @Value
    public static class DirEntry implements Entry {
        ZipEntry zipEntry;

        @Override public void close() {}
    }

    @Value
    public static class FileEntry implements Entry {
        ZipEntry zipEntry;
        InputStream inputStream;

        @Override
        public void close() throws IOException {
            inputStream.close();
        }
    }

    public static ZipFile mapToFile(
            Function<Entry, Entry> f,
            ZipFile zipFile,
            File toFile)
            throws IOException {
        try (FileOutputStream fos = new FileOutputStream(toFile);
                ZipOutputStream zos = new ZipOutputStream(fos)) {
            List<ZipEntry> zipEntries =
                    EnumerationUtils.toList(zipFile.entries());
            for (ZipEntry zipEntry : zipEntries) {
                Entry entry = zipEntry.isDirectory()
                        ? new DirEntry(zipEntry)
                        : new FileEntry(
                                zipEntry, zipFile.getInputStream(zipEntry));
                try (Entry newEntry = f.apply(entry)) {
                    if (newEntry instanceof DirEntry) {
                        zos.putNextEntry(((DirEntry)newEntry).getZipEntry());
                    } else {
                        zos.putNextEntry(((FileEntry)newEntry).getZipEntry());
                        IOUtils.copy(
                                ((FileEntry)newEntry).getInputStream(), zos);
                    }
                }
            }
            zos.finish();
        }
        return new ZipFile(toFile);
    }
}

@@ -171,16 +171,54 @@
 l.List;%0A
+import java.util.function.BiFunction;%0A
 import j
@@ -919,24 +919,616 @@
    %7D%0A    %7D%0A%0A
+    public static %3CT%3E T fold(%0A            BiFunction%3CEntry, T, T%3E f,%0A            T init,%0A            ZipFile zipFile)%0A            throws IOException %7B%0A        T result = init;%0A        List%3CZipEntry%3E zipEntries = EnumerationUtils.toList(zipFile.entries());%0A        for (ZipEntry zipEntry : zipEntries) %7B%0A            Entry entry = zipEntry.isDirectory()%0A                    ? new DirEntry(zipEntry)%0A                    : new FileEntry(%0A                            zipEntry, zipFile.getInputStream(zipEntry));%0A            result = f.apply(entry, result);%0A        %7D%0A        return result;%0A    %7D%0A%0A
     public s

Add fold method