private int downgrade(int target, @Nonnull DoubleConsumer sink) {
		int classTarget = JavaVersion.VERSION_OFFSET + target;

		List<JvmClassInfo> targets = targetBundle.stream()
				.filter(c -> c.getVersion() > classTarget)
				.collect(Collectors.toCollection(ArrayList::new));
		int total = targets.size();
		AtomicDouble remaining = new AtomicDouble(target);

		ExecutorService service = ThreadPoolFactory.newFixedThreadPool("class-downgrade");
		for (JvmClassInfo classInfo : targets) {
			CompletableFuture.supplyAsync(() -> {
				try {
					ClassNode node = new ClassNode();
					ClassReader reader = classInfo.getClassReader();
					reader.accept(node, 0);
					JavaDowngrader.downgrade(node, target);
					ClassWriter writer = new ClassWriter(reader, 0);
					node.accept(writer);
					return new JvmClassInfoBuilder(writer.toByteArray()).build();
				} catch (Exception ex) {
					logger.error("Failed downgrading class '{}'", classInfo.getName(), ex);
					return null;
				} finally {
					sink.accept(1 - (remaining.addAndGet(-1) / total));
				}
			}, service).whenComplete((updated, error) -> {
				if (updated != null)
					targetBundle.put(updated);
			});
		}
		try {
			service.shutdown();
			service.awaitTermination(1, TimeUnit.HOURS);
		} catch (InterruptedException ex) {
			logger.info("Downgrade interrupted", ex);
		}
		return total;
	}
Popup for initiating the upgrading or downgrading of all classes.

@author Matt Coley
recaf-ui/src/main/java/software/coley/recaf/ui/control/popup/ChangeClassVersionForAllPopup.java