public static <T> void forEachOn(Stream<T> stream, Consumer<? super T> consumer, Executor executor) {
		AtomicReference<Throwable> throwable = new AtomicReference<>();
		CountDown countDown = new CountDown();
		stream.forEach(x -> {
			Throwable thrown = throwable.get();
			if (thrown != null) {
				ReflectUtil.propagate(thrown);
			}
			countDown.register();
			executor.execute(() -> {
				try {
					if (throwable.get() == null) {
						try {
							consumer.accept(x);
						} catch (Throwable t) {
							throwable.compareAndSet(null, t);
						}
					}
				} finally {
					countDown.release();
				}
			});
		});
		try {
			countDown.await();
		} catch (InterruptedException ignored) {
		}
		Throwable thrown = throwable.get();
		if (thrown != null) {
			ReflectUtil.propagate(thrown);
		}
	}
Accepts all elements in the stream in the given executor.

@param stream
		Stream to accept.
@param consumer
		Element consumer.
@param executor
		Executor to use.
@param <T>
		Element type.
recaf-core/src/main/java/software/coley/recaf/util/Streams.java