// 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/inspect/FieldDescriptor.java
// public class FieldDescriptor {
// 	public final int access;
// 	public final String name;
// 	public final String desc;
// 	public final String signature;
// 	public final Object value;
// 
// 	public boolean isConstExpr;
// 
// 	public FieldDescriptor(int access, String name, String desc, String signature, Object value) {
// 		this.access = access;
// 		this.name = name;
// 		this.desc = desc;
// 		this.signature = signature;
// 		this.value = value;
// 	}
// 
// 	public void validate() {
// 		if (!isConstExpr)
// 			return;
// 
// 		int access = this.access & (STATIC | FINAL);
// 		if (access != (STATIC | FINAL))
// 			throw new InvalidConstExprException("fields must be 'static final'", this);
// 
// 		boolean isPrimitive = desc.length() == 1;
// 		if (!isPrimitive && !isString())
// 			throw new InvalidConstExprException("fields can only be primitive values or strings", this);
// 	}
// 
// 	private boolean isString() {
// 		return desc.equals(Type.getDescriptor(String.class));
// 	}
// 
// 	@Override
// 	public String toString() {
// 		return "FieldDescriptor[" +
// 			"access=" + access +
// 			" name='" + name + '\'' +
// 			" desc='" + desc + '\'' +
// 			" signature='" + signature + '\'' +
// 			" value=" + value +
// 			" isConstExpr=" + isConstExpr +
// 			']';
// 	}
// }
// 
// Path: core/src/main/java/net/onedaybeard/constexpr/inspect/MethodDescriptor.java
// public class MethodDescriptor {
// 	public final int access;
// 	public final String name;
// 	public final String desc;
// 	public final String signature;
// 	public final String[] exceptions;
// 
// 	public boolean isConstExpr;
// 
// 	public MethodDescriptor(int access, String name, String desc, String signature, String[] exceptions) {
// 		this.access = access;
// 		this.name = name;
// 		this.desc = desc;
// 		this.signature = signature;
// 		this.exceptions = exceptions;
// 	}
// 
// 
// 	public void validate() {
// 		if (!isConstExpr)
// 			return;
// 
// 		if ((STATIC & access) != STATIC)
// 			throw new InvalidConstExprException("method must be 'static'", this);
// 	}
// }


import net.onedaybeard.constexpr.inspect.ClassMetadata;
import net.onedaybeard.constexpr.inspect.FieldDescriptor;
import net.onedaybeard.constexpr.inspect.MethodDescriptor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.*;
import java.util.*;
import java.util.stream.StreamSupport;
		while (it.hasNext()) {
			AbstractInsnNode node = it.next();
			if (node instanceof FieldInsnNode) {
				FieldInsnNode fin = (FieldInsnNode) node;
				if (fd.name.equals(fin.name)) {
					return instructions.indexOf(fin);
				}
			}
		}

		throw new RuntimeException("what the...");
	}

	private int beginIndexOf(int endIndex) {
		int i = endIndex - 1;
		for (int remaining = 1; remaining != 0; i--) {
			AbstractInsnNode insn = instructions.get(i);
			if (insn instanceof InsnNode) {
				remaining++;
			} else if (isInsnNodeDecrementing(insn)) {
				remaining--;
			}
		}

		return i + 1; // +1 due to final decrement in loop
	}

	private int beginStringIndexOf(int endIndex) {
		int i = endIndex - 1;
		while (i > 0) {
// 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/inspect/FieldDescriptor.java
// public class FieldDescriptor {
// 	public final int access;
// 	public final String name;
// 	public final String desc;
// 	public final String signature;
// 	public final Object value;
// 
// 	public boolean isConstExpr;
// 
// 	public FieldDescriptor(int access, String name, String desc, String signature, Object value) {
// 		this.access = access;
// 		this.name = name;
// 		this.desc = desc;
// 		this.signature = signature;
// 		this.value = value;
// 	}
// 
// 	public void validate() {
// 		if (!isConstExpr)
// 			return;
// 
// 		int access = this.access & (STATIC | FINAL);
// 		if (access != (STATIC | FINAL))
// 			throw new InvalidConstExprException("fields must be 'static final'", this);
// 
// 		boolean isPrimitive = desc.length() == 1;
// 		if (!isPrimitive && !isString())
// 			throw new InvalidConstExprException("fields can only be primitive values or strings", this);
// 	}
// 
// 	private boolean isString() {
// 		return desc.equals(Type.getDescriptor(String.class));
// 	}
// 
// 	@Override
// 	public String toString() {
// 		return "FieldDescriptor[" +
// 			"access=" + access +
// 			" name='" + name + '\'' +
// 			" desc='" + desc + '\'' +
// 			" signature='" + signature + '\'' +
// 			" value=" + value +
// 			" isConstExpr=" + isConstExpr +
// 			']';
// 	}
// }
// 
// Path: core/src/main/java/net/onedaybeard/constexpr/inspect/MethodDescriptor.java
// public class MethodDescriptor {
// 	public final int access;
// 	public final String name;
// 	public final String desc;
// 	public final String signature;
// 	public final String[] exceptions;
// 
// 	public boolean isConstExpr;
// 
// 	public MethodDescriptor(int access, String name, String desc, String signature, String[] exceptions) {
// 		this.access = access;
// 		this.name = name;
// 		this.desc = desc;
// 		this.signature = signature;
// 		this.exceptions = exceptions;
// 	}
// 
// 
// 	public void validate() {
// 		if (!isConstExpr)
// 			return;
// 
// 		if ((STATIC & access) != STATIC)
// 			throw new InvalidConstExprException("method must be 'static'", this);
// 	}
// }


// Path: core/src/main/java/net/onedaybeard/constexpr/transformer/CinitConstExprTransformer.java
import net.onedaybeard.constexpr.inspect.ClassMetadata;
import net.onedaybeard.constexpr.inspect.FieldDescriptor;
import net.onedaybeard.constexpr.inspect.MethodDescriptor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.*;
import java.util.*;
import java.util.stream.StreamSupport;

		while (it.hasNext()) {
			AbstractInsnNode node = it.next();
			if (node instanceof FieldInsnNode) {
				FieldInsnNode fin = (FieldInsnNode) node;
				if (fd.name.equals(fin.name)) {
					return instructions.indexOf(fin);
				}
			}
		}

		throw new RuntimeException("what the...");
	}

	private int beginIndexOf(int endIndex) {
		int i = endIndex - 1;
		for (int remaining = 1; remaining != 0; i--) {
			AbstractInsnNode insn = instructions.get(i);
			if (insn instanceof InsnNode) {
				remaining++;
			} else if (isInsnNodeDecrementing(insn)) {
				remaining--;
			}
		}

		return i + 1; // +1 due to final decrement in loop
	}

	private int beginStringIndexOf(int endIndex) {
		int i = endIndex - 1;
		while (i > 0) {
			AbstractInsnNode insn = instructions.get(i);