// Path: instrumenter/src/main/java/com/offbynull/coroutines/instrumenter/asm/VariableTable.java
// public final class Variable {
//     private Type type;
//     private int index;
//     private boolean used;
// 
//     private Variable(Type type, int index, boolean used) {
//         this.type = type;
//         this.index = index;
//         this.used = used;
//     }
// 
//     /**
//      * Get the type of this local variable table entry.
//      * @return type of this entry
//      * @throws IllegalArgumentException if this {@link Variable} has been released
//      */
//     public Type getType() {
//         Validate.isTrue(used);
//         return type;
//     }
// 
//     /**
//      * Get the index of this entry within the local variable table.
//      * @return index of this entry
//      * @throws IllegalArgumentException if this {@link Variable} has been released
//      */
//     public int getIndex() {
//         Validate.isTrue(used);
//         return index;
//     }
// 
//     /**
//      * Returns {@code true} if this object hasn't been released.
//      * @see VariableTable#releaseExtra(com.offbynull.coroutines.instrumenter.asm.VariableTable.Variable) 
//     
//      * @return index of this entry
//      * @throws IllegalArgumentException if this {@link Variable} has been released
//      */
//     public boolean isUsed() {
//         return used;
//     }
//         
//     private VariableTable getParent() {
//         return VariableTable.this;
//     }
// }


import com.offbynull.coroutines.instrumenter.asm.VariableTable.Variable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import java.util.function.Supplier;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.reflect.MethodUtils;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.IincInsnNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.InvokeDynamicInsnNode;
import org.objectweb.asm.tree.JumpInsnNode;
import org.objectweb.asm.tree.LabelNode;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.LineNumberNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.TableSwitchInsnNode;
import org.objectweb.asm.tree.TryCatchBlockNode;
import org.objectweb.asm.tree.TypeInsnNode;
import org.objectweb.asm.tree.VarInsnNode;
    /**
     * Generates instruction to push a string constant on to the stack.
     * @param s string constant to push
     * @return instructions to push a string constant
     * @throws NullPointerException if any argument is {@code null}
     */
    public static InsnList loadStringConst(String s) {
        Validate.notNull(s);
        InsnList ret = new InsnList();
        ret.add(new LdcInsnNode(s));
        return ret;
    }

    /**
     * Generates instruction to push a null on to the stack.
     * @return instructions to push a null
     */
    public static InsnList loadNull() {
        InsnList ret = new InsnList();
        ret.add(new InsnNode(Opcodes.ACONST_NULL));
        return ret;
    }
    
    /**
     * Copies a local variable on to the stack.
     * @param variable variable within the local variable table to load from
     * @return instructions to load a local variable on to the stack
     * @throws NullPointerException if any argument is {@code null}
     * @throws IllegalArgumentException if {@code variable} has been released
     */
// Path: instrumenter/src/main/java/com/offbynull/coroutines/instrumenter/asm/VariableTable.java
// public final class Variable {
//     private Type type;
//     private int index;
//     private boolean used;
// 
//     private Variable(Type type, int index, boolean used) {
//         this.type = type;
//         this.index = index;
//         this.used = used;
//     }
// 
//     /**
//      * Get the type of this local variable table entry.
//      * @return type of this entry
//      * @throws IllegalArgumentException if this {@link Variable} has been released
//      */
//     public Type getType() {
//         Validate.isTrue(used);
//         return type;
//     }
// 
//     /**
//      * Get the index of this entry within the local variable table.
//      * @return index of this entry
//      * @throws IllegalArgumentException if this {@link Variable} has been released
//      */
//     public int getIndex() {
//         Validate.isTrue(used);
//         return index;
//     }
// 
//     /**
//      * Returns {@code true} if this object hasn't been released.
//      * @see VariableTable#releaseExtra(com.offbynull.coroutines.instrumenter.asm.VariableTable.Variable) 
//     
//      * @return index of this entry
//      * @throws IllegalArgumentException if this {@link Variable} has been released
//      */
//     public boolean isUsed() {
//         return used;
//     }
//         
//     private VariableTable getParent() {
//         return VariableTable.this;
//     }
// }


// Path: instrumenter/src/main/java/com/offbynull/coroutines/instrumenter/generators/GenericGenerators.java
import com.offbynull.coroutines.instrumenter.asm.VariableTable.Variable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import java.util.function.Supplier;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.reflect.MethodUtils;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.IincInsnNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.InvokeDynamicInsnNode;
import org.objectweb.asm.tree.JumpInsnNode;
import org.objectweb.asm.tree.LabelNode;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.LineNumberNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.TableSwitchInsnNode;
import org.objectweb.asm.tree.TryCatchBlockNode;
import org.objectweb.asm.tree.TypeInsnNode;
import org.objectweb.asm.tree.VarInsnNode;

    /**
     * Generates instruction to push a string constant on to the stack.
     * @param s string constant to push
     * @return instructions to push a string constant
     * @throws NullPointerException if any argument is {@code null}
     */
    public static InsnList loadStringConst(String s) {
        Validate.notNull(s);
        InsnList ret = new InsnList();
        ret.add(new LdcInsnNode(s));
        return ret;
    }

    /**
     * Generates instruction to push a null on to the stack.
     * @return instructions to push a null
     */
    public static InsnList loadNull() {
        InsnList ret = new InsnList();
        ret.add(new InsnNode(Opcodes.ACONST_NULL));
        return ret;
    }
    
    /**
     * Copies a local variable on to the stack.
     * @param variable variable within the local variable table to load from
     * @return instructions to load a local variable on to the stack
     * @throws NullPointerException if any argument is {@code null}
     * @throws IllegalArgumentException if {@code variable} has been released
     */
    public static InsnList loadVar(Variable variable) {