// Path: common/src/main/java/eu/mikroskeem/shuriken/common/SneakyThrow.java
// public class SneakyThrow {
//     /**
//      * Good old SneakyThrows! Throws checked exceptions everywhere you want
//      *
//      * @param t Throwable
//      */
//     @Contract("_ -> fail")
//     public static void throwException(Throwable t) {
//         throw SneakyThrow.<RuntimeException>_throwException(t);
//     }
// 
//     @Contract("_ -> fail")
//     @SuppressWarnings("unchecked")
//     private static <T extends Throwable> T _throwException(Throwable t) throws T {
//         throw (T) Ensure.notNull(t, "Throwable should not be null");
//     }
// }
// 
// Path: common/src/main/java/eu/mikroskeem/shuriken/common/data/Pair.java
// public class Pair<K, V> {
//     private final K key;
//     private final V value;
// 
//     /**
//      * Construct a new pair
//      *
//      * @param key Pair key
//      * @param value Pair value
//      */
//     public Pair(K key, V value) {
//         this.key = key;
//         this.value = value;
//     }
// 
//     /**
//      * Gets pair key
//      *
//      * @return Pair key
//      */
//     public K getKey() {
//         return this.key;
//     }
// 
//     /**
//      * Gets pair value
//      *
//      * @return Pair value
//      */
//     public V getValue() {
//         return this.value;
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (o == this) return true;
//         if (!(o instanceof Pair)) return false;
//         Pair other = (Pair) o;
//         return key == null ? other.getKey() == null : key.equals(other.getKey()) &&
//                 value == null ? other.getValue() == null : value.equals(other.getValue());
//     }
// 
//     @Override
//     public int hashCode() {
//         int result = 1;
//         result = result * 59 + (key == null ? 43 : key.hashCode());
//         result = result * 59 + (value == null ? 43 : value.hashCode());
//         return result;
//     }
// 
//     @Override
//     public String toString() {
//         return "eu.mikroskeem.shuriken.common.data.Pair(key=" + this.getKey() + ", value=" + this.getValue() + ")";
//     }
// }


import eu.mikroskeem.shuriken.common.SneakyThrow;
import eu.mikroskeem.shuriken.common.data.Pair;
import org.meteogroup.jbrotli.BrotliStreamCompressor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
package eu.mikroskeem.test.shuriken.classloader;




/**
 * @author Mark Vainomaa
 */
public class Utils {
    public static Path generateTestJar(Pair<String, byte[]>... files) {
        Path jarFile;
        try {
            jarFile = Files.createTempFile("testjar", ".jar");
            try(ZipOutputStream zos = new ZipOutputStream(Files.newOutputStream(jarFile))) {
                Map<String, List<Pair<String, byte[]>>> filesMap = new HashMap<>();
                for (Pair<String, byte[]> file : files) {
                    filesMap.compute(file.getKey(), (k, data) -> {
                        List<Pair<String, byte[]>> fileData = data != null ? data : new ArrayList<>();
                        fileData.add(new Pair<>(file.getKey(), compress(file.getValue())));
                        return fileData;
                    });
                }

                filesMap.forEach((path, data) -> {
                    putPath(Paths.get(path).getParent().toString(), zos);
                    data.forEach(file -> putFile(file.getKey(), file.getValue(), zos));
                });

                zos.closeEntry();
                zos.finish();
            }
        } catch (Throwable e) {
// Path: common/src/main/java/eu/mikroskeem/shuriken/common/SneakyThrow.java
// public class SneakyThrow {
//     /**
//      * Good old SneakyThrows! Throws checked exceptions everywhere you want
//      *
//      * @param t Throwable
//      */
//     @Contract("_ -> fail")
//     public static void throwException(Throwable t) {
//         throw SneakyThrow.<RuntimeException>_throwException(t);
//     }
// 
//     @Contract("_ -> fail")
//     @SuppressWarnings("unchecked")
//     private static <T extends Throwable> T _throwException(Throwable t) throws T {
//         throw (T) Ensure.notNull(t, "Throwable should not be null");
//     }
// }
// 
// Path: common/src/main/java/eu/mikroskeem/shuriken/common/data/Pair.java
// public class Pair<K, V> {
//     private final K key;
//     private final V value;
// 
//     /**
//      * Construct a new pair
//      *
//      * @param key Pair key
//      * @param value Pair value
//      */
//     public Pair(K key, V value) {
//         this.key = key;
//         this.value = value;
//     }
// 
//     /**
//      * Gets pair key
//      *
//      * @return Pair key
//      */
//     public K getKey() {
//         return this.key;
//     }
// 
//     /**
//      * Gets pair value
//      *
//      * @return Pair value
//      */
//     public V getValue() {
//         return this.value;
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (o == this) return true;
//         if (!(o instanceof Pair)) return false;
//         Pair other = (Pair) o;
//         return key == null ? other.getKey() == null : key.equals(other.getKey()) &&
//                 value == null ? other.getValue() == null : value.equals(other.getValue());
//     }
// 
//     @Override
//     public int hashCode() {
//         int result = 1;
//         result = result * 59 + (key == null ? 43 : key.hashCode());
//         result = result * 59 + (value == null ? 43 : value.hashCode());
//         return result;
//     }
// 
//     @Override
//     public String toString() {
//         return "eu.mikroskeem.shuriken.common.data.Pair(key=" + this.getKey() + ", value=" + this.getValue() + ")";
//     }
// }


// Path: classloader/src/test/java/eu/mikroskeem/test/shuriken/classloader/Utils.java
import eu.mikroskeem.shuriken.common.SneakyThrow;
import eu.mikroskeem.shuriken.common.data.Pair;
import org.meteogroup.jbrotli.BrotliStreamCompressor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

package eu.mikroskeem.test.shuriken.classloader;




/**
 * @author Mark Vainomaa
 */
public class Utils {
    public static Path generateTestJar(Pair<String, byte[]>... files) {
        Path jarFile;
        try {
            jarFile = Files.createTempFile("testjar", ".jar");
            try(ZipOutputStream zos = new ZipOutputStream(Files.newOutputStream(jarFile))) {
                Map<String, List<Pair<String, byte[]>>> filesMap = new HashMap<>();
                for (Pair<String, byte[]> file : files) {
                    filesMap.compute(file.getKey(), (k, data) -> {
                        List<Pair<String, byte[]>> fileData = data != null ? data : new ArrayList<>();
                        fileData.add(new Pair<>(file.getKey(), compress(file.getValue())));
                        return fileData;
                    });
                }

                filesMap.forEach((path, data) -> {
                    putPath(Paths.get(path).getParent().toString(), zos);
                    data.forEach(file -> putFile(file.getKey(), file.getValue(), zos));
                });

                zos.closeEntry();
                zos.finish();
            }
        } catch (Throwable e) {
            SneakyThrow.throwException(e);