package org.minimallycorrect.javatransformer.internal.util;

import lombok.experimental.UtilityClass;

import java.util.*;
import java.util.function.*;
import java.util.stream.*;

@UtilityClass
public class CollectionUtil {
	@SafeVarargs
	@SuppressWarnings("varargs")
	public static <T> Stream<T> union(Collection<T>... collections) {
		return union(Arrays.asList(collections));
	}

	public static <T> Stream<T> union(Collection<Collection<T>> collections) {
		return collections.stream().flatMap(x -> x == null ? Stream.empty() : x.stream());
	}

	public static <T> Stream<T> stream(Supplier<T> supplier) {
		return stream(iterable(supplier));
	}

	public static <T> Stream<T> stream(Iterable<T> iterable) {
		if (iterable instanceof Collection)
			return ((Collection<T>) iterable).stream();

		return StreamSupport.stream(iterable.spliterator(), false);
	}

	public static <T> Iterable<T> iterable(Stream<T> supplier) {
		return supplier::iterator;
	}

	public static <T> Iterable<T> iterable(Supplier<T> supplier) {
		return () -> new IteratorFromSupplier<>(supplier);
	}

	private static class IteratorFromSupplier<T> implements Iterator<T> {
		private final Supplier<T> supplier;
		private T next;

		public IteratorFromSupplier(Supplier<T> supplier) {
			this.supplier = supplier;
			next = supplier.get();
		}

		@Override
		public boolean hasNext() {
			return next != null;
		}

		@Override
		public T next() {
			if (next == null)
				throw new NoSuchElementException();

			try {
				return next;
			} finally {
				next = supplier.get();
			}
		}
	}
}

@@ -94,16 +94,35 @@
 tyClass;
+%0Aimport lombok.val;
 %0A%0Aimport
@@ -1089,16 +1089,384 @@
 r);%0A%09%7D%0A%0A
+%09public static %3CT%3E boolean equals(Collection%3CT%3E a, Collection%3CT%3E b, Comparer%3CT%3E c) %7B%0A%09%09if (a.size() != b.size())%0A%09%09%09return false;%0A%09%09val bIterator = b.iterator();%0A%09%09for (val aa : a) %7B%0A%09%09%09val bb = bIterator.next();%0A%09%09%09if (!c.compare(aa, bb))%0A%09%09%09%09return false;%0A%09%09%7D%0A%09%09return true;%0A%09%7D%0A%0A%09@FunctionalInterface%0A%09public interface Comparer%3CT%3E %7B%0A%09%09boolean compare(T a, T b);%0A%09%7D%0A%0A
 %09private

Add collection comparison with custom equality to CollectionUtil