// Path: core/src/main/java/net/onedaybeard/constexpr/exec/ConstExprScannerTask.java
// public class ConstExprScannerTask extends CallableVisitor<ClassMetadata> {
// 	private Path path;
// 
// 	public ConstExprScannerTask(Path p) {
// 		super(p.toFile());
// 		path = p;
// 	}
// 
// 	@Override
// 	protected ClassMetadata process(ClassReader cr) throws IOException {
// 		ClassMetadata info = new ClassMetadata(Type.getType(cr.getClassName()), null);
// 		info.path = path.toFile().getAbsolutePath();
// 
// 		ClassVisitor cv = new ConstExprScanner(info);
// 		cr.accept(cv, 0);
// 
// 		return info;
// 	}
// }
// 
// Path: core/src/main/java/net/onedaybeard/constexpr/exec/ConstExprTransformer.java
// public class ConstExprTransformer extends CallableVisitor<byte[]> {
// 	private final ClassMetadata metadata;
// 
// 	public ConstExprTransformer(ClassMetadata metadata) {
// 		super(metadata.classType != null
// 			? AsmUtil.classReader(metadata.classType)
// 			: AsmUtil.classReader(new File(metadata.path)));
// 		this.metadata = metadata;
// 	}
// 
// 	@Override
// 	protected byte[] process(ClassReader cr) throws IOException {
// 		if (!metadata.containsConstExpr())
// 			return null;
// 
// 		ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
// 
// 		ClassVisitor cv = cw;
// 		cv = new ConstExprFieldWeaver(metadata, cv);
// 		cv = new ConstExprMethodWeaver(metadata, cv);
// 
// 		cr.accept(cv, ClassReader.EXPAND_FRAMES);
// 
// 		byte[] bytes = getBytes(cw);
// 		if (metadata.path != null) // pretty null-y when testing
// 			ClassUtil.writeClass(bytes, metadata.path);
// 
// 		return bytes;
// 	}
// 
// 	private byte[] getBytes(ClassWriter cw) {
// 		if (metadata.emptyClinit) {
// 			//only the shell remains - remove it all
// 			return withRemovedClinit(cw.toByteArray());
// 		} else {
// 			return cw.toByteArray();
// 		}
// 	}
// 
// 	private byte[] withRemovedClinit(byte[] klazz) {
// 		ClassReader cr = AsmUtil.classReader(klazz);
// 		ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
// 		ClassVisitor cv = new ClinitRemoverWeaver(cw);
// 
// 		cr.accept(cv, ClassReader.EXPAND_FRAMES);
// 		return cw.toByteArray();
// 	}
// }
// 
// Path: core/src/main/java/net/onedaybeard/constexpr/inspect/ClassMetadata.java
// public class ClassMetadata {
// 	public Type type;
// 	public Class<?> classType;
// 	public String path;
// 	public List<FieldDescriptor> fields = new ArrayList<>();
// 	public List<MethodDescriptor> methods = new ArrayList<>();
// 	public boolean emptyClinit;
// 
// 	public ClassMetadata(Class<?> type) {
// 		this(type != null ? Type.getType(type) : null, type);
// 	}
// 
// 	public ClassMetadata(Type type, Class<?> klazz) {
// 		this.type = type;
// 		this.classType = klazz;
// 	}
// 
// 	public FieldDescriptor field(String f) {
// 		return fields.stream()
// 			.filter(fd -> fd.name.equals(f))
// 			.findFirst()
// 			.get();
// 	}
// 
// 	public void add(FieldDescriptor fieldDescriptor) {
// 		fields.add(fieldDescriptor);
// 	}
// 
// 	public void add(MethodDescriptor descriptor) {
// 		methods.add(descriptor);
// 	}
// 
// 	public boolean containsConstExpr() {
// 		return fields.stream().anyMatch(fd -> fd.isConstExpr)
// 			|| methods.stream().anyMatch(md -> md.isConstExpr);
// 	}
// }


import net.onedaybeard.constexpr.exec.ConstExprScannerTask;
import net.onedaybeard.constexpr.exec.ConstExprTransformer;
import net.onedaybeard.constexpr.inspect.ClassMetadata;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.stream.Stream;
import static java.util.stream.Collectors.toList;
package net.onedaybeard.constexpr;




public class ConstExprMain {
	private final ExecutorService executor;

	public ConstExprMain() {
		executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
	}

	public Stats execute(String root) {
		Stats stats = new Stats();

		long startScan = System.currentTimeMillis();
		List<ClassMetadata> scanned = scan(root);
		stats.scanned = scanned;
		stats.scanTime = System.currentTimeMillis() - startScan;

		long startTransform = System.currentTimeMillis();
		scanned.stream()
// Path: core/src/main/java/net/onedaybeard/constexpr/exec/ConstExprScannerTask.java
// public class ConstExprScannerTask extends CallableVisitor<ClassMetadata> {
// 	private Path path;
// 
// 	public ConstExprScannerTask(Path p) {
// 		super(p.toFile());
// 		path = p;
// 	}
// 
// 	@Override
// 	protected ClassMetadata process(ClassReader cr) throws IOException {
// 		ClassMetadata info = new ClassMetadata(Type.getType(cr.getClassName()), null);
// 		info.path = path.toFile().getAbsolutePath();
// 
// 		ClassVisitor cv = new ConstExprScanner(info);
// 		cr.accept(cv, 0);
// 
// 		return info;
// 	}
// }
// 
// Path: core/src/main/java/net/onedaybeard/constexpr/exec/ConstExprTransformer.java
// public class ConstExprTransformer extends CallableVisitor<byte[]> {
// 	private final ClassMetadata metadata;
// 
// 	public ConstExprTransformer(ClassMetadata metadata) {
// 		super(metadata.classType != null
// 			? AsmUtil.classReader(metadata.classType)
// 			: AsmUtil.classReader(new File(metadata.path)));
// 		this.metadata = metadata;
// 	}
// 
// 	@Override
// 	protected byte[] process(ClassReader cr) throws IOException {
// 		if (!metadata.containsConstExpr())
// 			return null;
// 
// 		ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
// 
// 		ClassVisitor cv = cw;
// 		cv = new ConstExprFieldWeaver(metadata, cv);
// 		cv = new ConstExprMethodWeaver(metadata, cv);
// 
// 		cr.accept(cv, ClassReader.EXPAND_FRAMES);
// 
// 		byte[] bytes = getBytes(cw);
// 		if (metadata.path != null) // pretty null-y when testing
// 			ClassUtil.writeClass(bytes, metadata.path);
// 
// 		return bytes;
// 	}
// 
// 	private byte[] getBytes(ClassWriter cw) {
// 		if (metadata.emptyClinit) {
// 			//only the shell remains - remove it all
// 			return withRemovedClinit(cw.toByteArray());
// 		} else {
// 			return cw.toByteArray();
// 		}
// 	}
// 
// 	private byte[] withRemovedClinit(byte[] klazz) {
// 		ClassReader cr = AsmUtil.classReader(klazz);
// 		ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
// 		ClassVisitor cv = new ClinitRemoverWeaver(cw);
// 
// 		cr.accept(cv, ClassReader.EXPAND_FRAMES);
// 		return cw.toByteArray();
// 	}
// }
// 
// Path: core/src/main/java/net/onedaybeard/constexpr/inspect/ClassMetadata.java
// public class ClassMetadata {
// 	public Type type;
// 	public Class<?> classType;
// 	public String path;
// 	public List<FieldDescriptor> fields = new ArrayList<>();
// 	public List<MethodDescriptor> methods = new ArrayList<>();
// 	public boolean emptyClinit;
// 
// 	public ClassMetadata(Class<?> type) {
// 		this(type != null ? Type.getType(type) : null, type);
// 	}
// 
// 	public ClassMetadata(Type type, Class<?> klazz) {
// 		this.type = type;
// 		this.classType = klazz;
// 	}
// 
// 	public FieldDescriptor field(String f) {
// 		return fields.stream()
// 			.filter(fd -> fd.name.equals(f))
// 			.findFirst()
// 			.get();
// 	}
// 
// 	public void add(FieldDescriptor fieldDescriptor) {
// 		fields.add(fieldDescriptor);
// 	}
// 
// 	public void add(MethodDescriptor descriptor) {
// 		methods.add(descriptor);
// 	}
// 
// 	public boolean containsConstExpr() {
// 		return fields.stream().anyMatch(fd -> fd.isConstExpr)
// 			|| methods.stream().anyMatch(md -> md.isConstExpr);
// 	}
// }


// Path: core/src/main/java/net/onedaybeard/constexpr/ConstExprMain.java
import net.onedaybeard.constexpr.exec.ConstExprScannerTask;
import net.onedaybeard.constexpr.exec.ConstExprTransformer;
import net.onedaybeard.constexpr.inspect.ClassMetadata;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.stream.Stream;
import static java.util.stream.Collectors.toList;

package net.onedaybeard.constexpr;




public class ConstExprMain {
	private final ExecutorService executor;

	public ConstExprMain() {
		executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
	}

	public Stats execute(String root) {
		Stats stats = new Stats();

		long startScan = System.currentTimeMillis();
		List<ClassMetadata> scanned = scan(root);
		stats.scanned = scanned;
		stats.scanTime = System.currentTimeMillis() - startScan;

		long startTransform = System.currentTimeMillis();
		scanned.stream()
			.filter(ClassMetadata::containsConstExpr)